Skip to content

Commit 4e411be

Browse files
6by9popcornmix
authored andcommitted
net: lan78xx: Add support for VLAN tag stripping.
The chip supports stripping the VLAN tag and reporting it in metadata. Implement this as it also appears to solve the issues observed in checksum computation. See #2458. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 61eb2d0 commit 4e411be

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

drivers/net/usb/lan78xx.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#define DEFAULT_RX_CSUM_ENABLE (true)
6565
#define DEFAULT_TSO_CSUM_ENABLE (true)
6666
#define DEFAULT_VLAN_FILTER_ENABLE (true)
67+
#define DEFAULT_VLAN_RX_OFFLOAD (true)
6768
#define TX_OVERHEAD (8)
6869
#define RXW_PADDING 2
6970

@@ -2297,6 +2298,11 @@ static int lan78xx_set_features(struct net_device *netdev,
22972298
pdata->rfe_ctl &= ~(RFE_CTL_ICMP_COE_ | RFE_CTL_IGMP_COE_);
22982299
}
22992300

2301+
if (features & NETIF_F_HW_VLAN_CTAG_RX)
2302+
pdata->rfe_ctl |= RFE_CTL_VLAN_STRIP_;
2303+
else
2304+
pdata->rfe_ctl &= ~RFE_CTL_VLAN_STRIP_;
2305+
23002306
if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
23012307
pdata->rfe_ctl |= RFE_CTL_VLAN_FILTER_;
23022308
else
@@ -2921,6 +2927,9 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
29212927
if (DEFAULT_TSO_CSUM_ENABLE)
29222928
dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
29232929

2930+
if (DEFAULT_VLAN_RX_OFFLOAD)
2931+
dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;
2932+
29242933
if (DEFAULT_VLAN_FILTER_ENABLE)
29252934
dev->net->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
29262935

@@ -3001,6 +3010,16 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev,
30013010
}
30023011
}
30033012

3013+
static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev,
3014+
struct sk_buff *skb,
3015+
u32 rx_cmd_a, u32 rx_cmd_b)
3016+
{
3017+
if ((dev->net->features & NETIF_F_HW_VLAN_CTAG_RX) &&
3018+
(rx_cmd_a & RX_CMD_A_FVTG_))
3019+
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
3020+
(rx_cmd_b & 0xffff));
3021+
}
3022+
30043023
static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
30053024
{
30063025
int status;
@@ -3065,6 +3084,8 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
30653084
if (skb->len == size) {
30663085
lan78xx_rx_csum_offload(dev, skb,
30673086
rx_cmd_a, rx_cmd_b);
3087+
lan78xx_rx_vlan_offload(dev, skb,
3088+
rx_cmd_a, rx_cmd_b);
30683089

30693090
skb_trim(skb, skb->len - 4); /* remove fcs */
30703091
skb->truesize = size + sizeof(struct sk_buff);
@@ -3083,6 +3104,7 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
30833104
skb_set_tail_pointer(skb2, size);
30843105

30853106
lan78xx_rx_csum_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
3107+
lan78xx_rx_vlan_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
30863108

30873109
skb_trim(skb2, skb2->len - 4); /* remove fcs */
30883110
skb2->truesize = size + sizeof(struct sk_buff);

0 commit comments

Comments
 (0)