Skip to content

Commit 44e626f

Browse files
IronShendavem330
authored andcommitted
net: hns3: fix VLAN offload handle for VLAN inserted by port
Currently, in TX direction, driver implements the TX VLAN offload by checking the VLAN header in skb, and filling it into TX descriptor. Usually it works well, but if enable inserting VLAN header based on port, it may conflict when out_tag field of TX descriptor is already used, and cause RAS error. In RX direction, hardware supports stripping max two VLAN headers. For vlan_tci in skb can only store one VLAN tag, when RX VLAN offload enabled, driver tells hardware to strip one VLAN header from RX packet; when RX VLAN offload disabled, driver tells hardware not to strip VLAN header from RX packet. Now if port based insert VLAN enabled, all RX packets will have the port based VLAN header. This header is useless for stack, driver needs to ask hardware to strip it. Unfortunately, hardware can't drop this VLAN header, and always fill it into RX descriptor, so driver has to identify and drop it. Signed-off-by: Jian Shen <[email protected]> Signed-off-by: Huazhong Tan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 741fca1 commit 44e626f

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

drivers/net/ethernet/hisilicon/hns3/hnae3.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ struct hnae3_handle {
585585

586586
u32 numa_node_mask; /* for multi-chip support */
587587

588+
enum hnae3_port_base_vlan_state port_base_vlan_state;
589+
588590
u8 netdev_flags;
589591
struct dentry *hnae3_dbgfs;
590592
};

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,16 @@ static int hns3_fill_desc_vtags(struct sk_buff *skb,
963963
{
964964
#define HNS3_TX_VLAN_PRIO_SHIFT 13
965965

966+
struct hnae3_handle *handle = tx_ring->tqp->handle;
967+
968+
/* Since HW limitation, if port based insert VLAN enabled, only one VLAN
969+
* header is allowed in skb, otherwise it will cause RAS error.
970+
*/
971+
if (unlikely(skb_vlan_tagged_multi(skb) &&
972+
handle->port_base_vlan_state ==
973+
HNAE3_PORT_BASE_VLAN_ENABLE))
974+
return -EINVAL;
975+
966976
if (skb->protocol == htons(ETH_P_8021Q) &&
967977
!(tx_ring->tqp->handle->kinfo.netdev->features &
968978
NETIF_F_HW_VLAN_CTAG_TX)) {
@@ -984,8 +994,16 @@ static int hns3_fill_desc_vtags(struct sk_buff *skb,
984994
* and use inner_vtag in one tag case.
985995
*/
986996
if (skb->protocol == htons(ETH_P_8021Q)) {
987-
hns3_set_field(*out_vlan_flag, HNS3_TXD_OVLAN_B, 1);
988-
*out_vtag = vlan_tag;
997+
if (handle->port_base_vlan_state ==
998+
HNAE3_PORT_BASE_VLAN_DISABLE){
999+
hns3_set_field(*out_vlan_flag,
1000+
HNS3_TXD_OVLAN_B, 1);
1001+
*out_vtag = vlan_tag;
1002+
} else {
1003+
hns3_set_field(*inner_vlan_flag,
1004+
HNS3_TXD_VLAN_B, 1);
1005+
*inner_vtag = vlan_tag;
1006+
}
9891007
} else {
9901008
hns3_set_field(*inner_vlan_flag, HNS3_TXD_VLAN_B, 1);
9911009
*inner_vtag = vlan_tag;
@@ -2390,6 +2408,7 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
23902408
struct hns3_desc *desc, u32 l234info,
23912409
u16 *vlan_tag)
23922410
{
2411+
struct hnae3_handle *handle = ring->tqp->handle;
23932412
struct pci_dev *pdev = ring->tqp->handle->pdev;
23942413

23952414
if (pdev->revision == 0x20) {
@@ -2402,14 +2421,35 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
24022421

24032422
#define HNS3_STRP_OUTER_VLAN 0x1
24042423
#define HNS3_STRP_INNER_VLAN 0x2
2424+
#define HNS3_STRP_BOTH 0x3
24052425

2426+
/* Hardware always insert VLAN tag into RX descriptor when
2427+
* remove the tag from packet, driver needs to determine
2428+
* reporting which tag to stack.
2429+
*/
24062430
switch (hnae3_get_field(l234info, HNS3_RXD_STRP_TAGP_M,
24072431
HNS3_RXD_STRP_TAGP_S)) {
24082432
case HNS3_STRP_OUTER_VLAN:
2433+
if (handle->port_base_vlan_state !=
2434+
HNAE3_PORT_BASE_VLAN_DISABLE)
2435+
return false;
2436+
24092437
*vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
24102438
return true;
24112439
case HNS3_STRP_INNER_VLAN:
2440+
if (handle->port_base_vlan_state !=
2441+
HNAE3_PORT_BASE_VLAN_DISABLE)
2442+
return false;
2443+
24122444
*vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
2445+
return true;
2446+
case HNS3_STRP_BOTH:
2447+
if (handle->port_base_vlan_state ==
2448+
HNAE3_PORT_BASE_VLAN_DISABLE)
2449+
*vlan_tag = le16_to_cpu(desc->rx.ot_vlan_tag);
2450+
else
2451+
*vlan_tag = le16_to_cpu(desc->rx.vlan_tag);
2452+
24132453
return true;
24142454
default:
24152455
return false;

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6915,10 +6915,16 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
69156915
{
69166916
struct hclge_vport *vport = hclge_get_vport(handle);
69176917

6918-
vport->rxvlan_cfg.strip_tag1_en = false;
6919-
vport->rxvlan_cfg.strip_tag2_en = enable;
6918+
if (vport->port_base_vlan_cfg.state == HNAE3_PORT_BASE_VLAN_DISABLE) {
6919+
vport->rxvlan_cfg.strip_tag1_en = false;
6920+
vport->rxvlan_cfg.strip_tag2_en = enable;
6921+
} else {
6922+
vport->rxvlan_cfg.strip_tag1_en = enable;
6923+
vport->rxvlan_cfg.strip_tag2_en = true;
6924+
}
69206925
vport->rxvlan_cfg.vlan1_vlan_prionly = false;
69216926
vport->rxvlan_cfg.vlan2_vlan_prionly = false;
6927+
vport->rxvlan_cfg.rx_vlan_offload_en = enable;
69226928

69236929
return hclge_set_vlan_rx_offload_cfg(vport);
69246930
}

0 commit comments

Comments
 (0)