Skip to content

Commit b22c118

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 7e80f5e commit b22c118

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

@@ -2295,6 +2296,11 @@ static int lan78xx_set_features(struct net_device *netdev,
22952296
pdata->rfe_ctl &= ~(RFE_CTL_ICMP_COE_ | RFE_CTL_IGMP_COE_);
22962297
}
22972298

2299+
if (features & NETIF_F_HW_VLAN_CTAG_RX)
2300+
pdata->rfe_ctl |= RFE_CTL_VLAN_STRIP_;
2301+
else
2302+
pdata->rfe_ctl &= ~RFE_CTL_VLAN_STRIP_;
2303+
22982304
if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
22992305
pdata->rfe_ctl |= RFE_CTL_VLAN_FILTER_;
23002306
else
@@ -2919,6 +2925,9 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
29192925
if (DEFAULT_TSO_CSUM_ENABLE)
29202926
dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
29212927

2928+
if (DEFAULT_VLAN_RX_OFFLOAD)
2929+
dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;
2930+
29222931
if (DEFAULT_VLAN_FILTER_ENABLE)
29232932
dev->net->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
29242933

@@ -2999,6 +3008,16 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev,
29993008
}
30003009
}
30013010

3011+
static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev,
3012+
struct sk_buff *skb,
3013+
u32 rx_cmd_a, u32 rx_cmd_b)
3014+
{
3015+
if ((dev->net->features & NETIF_F_HW_VLAN_CTAG_RX) &&
3016+
(rx_cmd_a & RX_CMD_A_FVTG_))
3017+
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
3018+
(rx_cmd_b & 0xffff));
3019+
}
3020+
30023021
static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
30033022
{
30043023
int status;
@@ -3063,6 +3082,8 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
30633082
if (skb->len == size) {
30643083
lan78xx_rx_csum_offload(dev, skb,
30653084
rx_cmd_a, rx_cmd_b);
3085+
lan78xx_rx_vlan_offload(dev, skb,
3086+
rx_cmd_a, rx_cmd_b);
30663087

30673088
skb_trim(skb, skb->len - 4); /* remove fcs */
30683089
skb->truesize = size + sizeof(struct sk_buff);
@@ -3081,6 +3102,7 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
30813102
skb_set_tail_pointer(skb2, size);
30823103

30833104
lan78xx_rx_csum_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
3105+
lan78xx_rx_vlan_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
30843106

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

0 commit comments

Comments
 (0)