Commit 741fca16 authored by Jian Shen's avatar Jian Shen Committed by David S. Miller

net: hns3: modify VLAN initialization to be compatible with port based VLAN

Our hardware supports inserting a specified VLAN header for each
function when sending packets. User can enable it with command
"ip link set <devname> vf  <vfid> vlan <vlan id>".
For this VLAN header is inserted by hardware, not from stack,
hardware also needs to strip it from received packets before
sending to stack.  In this case, driver needs to tell
hardware which VLAN to insert or strip.

The current VLAN initialization doesn't allow inserting
VLAN header by hardware, this patch modifies it, in order be
compatible with VLAN inserted base on port.
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 81f2eeb3
...@@ -147,6 +147,13 @@ enum hnae3_flr_state { ...@@ -147,6 +147,13 @@ enum hnae3_flr_state {
HNAE3_FLR_DONE, HNAE3_FLR_DONE,
}; };
enum hnae3_port_base_vlan_state {
HNAE3_PORT_BASE_VLAN_DISABLE,
HNAE3_PORT_BASE_VLAN_ENABLE,
HNAE3_PORT_BASE_VLAN_MODIFY,
HNAE3_PORT_BASE_VLAN_NOCHANGE,
};
struct hnae3_vector_info { struct hnae3_vector_info {
u8 __iomem *io_addr; u8 __iomem *io_addr;
int vector; int vector;
......
...@@ -1358,6 +1358,8 @@ static int hclge_alloc_vport(struct hclge_dev *hdev) ...@@ -1358,6 +1358,8 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
vport->back = hdev; vport->back = hdev;
vport->vport_id = i; vport->vport_id = i;
vport->mps = HCLGE_MAC_DEFAULT_FRAME; vport->mps = HCLGE_MAC_DEFAULT_FRAME;
vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
vport->rxvlan_cfg.rx_vlan_offload_en = true;
INIT_LIST_HEAD(&vport->vlan_list); INIT_LIST_HEAD(&vport->vlan_list);
INIT_LIST_HEAD(&vport->uc_mac_list); INIT_LIST_HEAD(&vport->uc_mac_list);
INIT_LIST_HEAD(&vport->mc_mac_list); INIT_LIST_HEAD(&vport->mc_mac_list);
...@@ -6680,6 +6682,52 @@ static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport) ...@@ -6680,6 +6682,52 @@ static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport)
return status; return status;
} }
static int hclge_vlan_offload_cfg(struct hclge_vport *vport,
u16 port_base_vlan_state,
u16 vlan_tag)
{
int ret;
if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_DISABLE) {
vport->txvlan_cfg.accept_tag1 = true;
vport->txvlan_cfg.insert_tag1_en = false;
vport->txvlan_cfg.default_tag1 = 0;
} else {
vport->txvlan_cfg.accept_tag1 = false;
vport->txvlan_cfg.insert_tag1_en = true;
vport->txvlan_cfg.default_tag1 = vlan_tag;
}
vport->txvlan_cfg.accept_untag1 = true;
/* accept_tag2 and accept_untag2 are not supported on
* pdev revision(0x20), new revision support them,
* this two fields can not be configured by user.
*/
vport->txvlan_cfg.accept_tag2 = true;
vport->txvlan_cfg.accept_untag2 = true;
vport->txvlan_cfg.insert_tag2_en = false;
vport->txvlan_cfg.default_tag2 = 0;
if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_DISABLE) {
vport->rxvlan_cfg.strip_tag1_en = false;
vport->rxvlan_cfg.strip_tag2_en =
vport->rxvlan_cfg.rx_vlan_offload_en;
} else {
vport->rxvlan_cfg.strip_tag1_en =
vport->rxvlan_cfg.rx_vlan_offload_en;
vport->rxvlan_cfg.strip_tag2_en = true;
}
vport->rxvlan_cfg.vlan1_vlan_prionly = false;
vport->rxvlan_cfg.vlan2_vlan_prionly = false;
ret = hclge_set_vlan_tx_offload_cfg(vport);
if (ret)
return ret;
return hclge_set_vlan_rx_offload_cfg(vport);
}
static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev) static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev)
{ {
struct hclge_rx_vlan_type_cfg_cmd *rx_req; struct hclge_rx_vlan_type_cfg_cmd *rx_req;
...@@ -6770,34 +6818,14 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -6770,34 +6818,14 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
return ret; return ret;
for (i = 0; i < hdev->num_alloc_vport; i++) { for (i = 0; i < hdev->num_alloc_vport; i++) {
vport = &hdev->vport[i]; u16 vlan_tag;
vport->txvlan_cfg.accept_tag1 = true;
vport->txvlan_cfg.accept_untag1 = true;
/* accept_tag2 and accept_untag2 are not supported on
* pdev revision(0x20), new revision support them. The
* value of this two fields will not return error when driver
* send command to fireware in revision(0x20).
* This two fields can not configured by user.
*/
vport->txvlan_cfg.accept_tag2 = true;
vport->txvlan_cfg.accept_untag2 = true;
vport->txvlan_cfg.insert_tag1_en = false; vport = &hdev->vport[i];
vport->txvlan_cfg.insert_tag2_en = false; vlan_tag = vport->port_base_vlan_cfg.vlan_info.vlan_tag;
vport->txvlan_cfg.default_tag1 = 0;
vport->txvlan_cfg.default_tag2 = 0;
ret = hclge_set_vlan_tx_offload_cfg(vport);
if (ret)
return ret;
vport->rxvlan_cfg.strip_tag1_en = false;
vport->rxvlan_cfg.strip_tag2_en = true;
vport->rxvlan_cfg.vlan1_vlan_prionly = false;
vport->rxvlan_cfg.vlan2_vlan_prionly = false;
ret = hclge_set_vlan_rx_offload_cfg(vport); ret = hclge_vlan_offload_cfg(vport,
vport->port_base_vlan_cfg.state,
vlan_tag);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -807,10 +807,11 @@ struct hclge_tx_vtag_cfg { ...@@ -807,10 +807,11 @@ struct hclge_tx_vtag_cfg {
/* VPort level vlan tag configuration for RX direction */ /* VPort level vlan tag configuration for RX direction */
struct hclge_rx_vtag_cfg { struct hclge_rx_vtag_cfg {
bool strip_tag1_en; /* Whether strip inner vlan tag */ u8 rx_vlan_offload_en; /* Whether enable rx vlan offload */
bool strip_tag2_en; /* Whether strip outer vlan tag */ u8 strip_tag1_en; /* Whether strip inner vlan tag */
bool vlan1_vlan_prionly;/* Inner VLAN Tag up to descriptor Enable */ u8 strip_tag2_en; /* Whether strip outer vlan tag */
bool vlan2_vlan_prionly;/* Outer VLAN Tag up to descriptor Enable */ u8 vlan1_vlan_prionly; /* Inner VLAN Tag up to descriptor Enable */
u8 vlan2_vlan_prionly; /* Outer VLAN Tag up to descriptor Enable */
}; };
struct hclge_rss_tuple_cfg { struct hclge_rss_tuple_cfg {
...@@ -829,6 +830,17 @@ enum HCLGE_VPORT_STATE { ...@@ -829,6 +830,17 @@ enum HCLGE_VPORT_STATE {
HCLGE_VPORT_STATE_MAX HCLGE_VPORT_STATE_MAX
}; };
struct hclge_vlan_info {
u16 vlan_proto; /* so far support 802.1Q only */
u16 qos;
u16 vlan_tag;
};
struct hclge_port_base_vlan_config {
u16 state;
struct hclge_vlan_info vlan_info;
};
struct hclge_vport { struct hclge_vport {
u16 alloc_tqps; /* Allocated Tx/Rx queues */ u16 alloc_tqps; /* Allocated Tx/Rx queues */
...@@ -845,6 +857,7 @@ struct hclge_vport { ...@@ -845,6 +857,7 @@ struct hclge_vport {
u16 bw_limit; /* VSI BW Limit (0 = disabled) */ u16 bw_limit; /* VSI BW Limit (0 = disabled) */
u8 dwrr; u8 dwrr;
struct hclge_port_base_vlan_config port_base_vlan_cfg;
struct hclge_tx_vtag_cfg txvlan_cfg; struct hclge_tx_vtag_cfg txvlan_cfg;
struct hclge_rx_vtag_cfg rxvlan_cfg; struct hclge_rx_vtag_cfg rxvlan_cfg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment