1 From 9d4c65d0e7ebfe20bd24e65d52b1df56e90d498e Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Tue, 10 Apr 2018 15:27:51 +0100
4 Subject: [PATCH 271/454] net: lan78xx: Add support for VLAN tag stripping.
6 The chip supports stripping the VLAN tag and reporting it
7 in metadata. Implement this as it also appears to solve the
8 issues observed in checksum computation.
12 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
14 drivers/net/usb/lan78xx.c | 22 ++++++++++++++++++++++
15 1 file changed, 22 insertions(+)
17 --- a/drivers/net/usb/lan78xx.c
18 +++ b/drivers/net/usb/lan78xx.c
20 #define DEFAULT_RX_CSUM_ENABLE (true)
21 #define DEFAULT_TSO_CSUM_ENABLE (true)
22 #define DEFAULT_VLAN_FILTER_ENABLE (true)
23 +#define DEFAULT_VLAN_RX_OFFLOAD (true)
24 #define TX_OVERHEAD (8)
27 @@ -2277,6 +2278,11 @@ static int lan78xx_set_features(struct n
28 pdata->rfe_ctl &= ~(RFE_CTL_ICMP_COE_ | RFE_CTL_IGMP_COE_);
31 + if (features & NETIF_F_HW_VLAN_CTAG_RX)
32 + pdata->rfe_ctl |= RFE_CTL_VLAN_STRIP_;
34 + pdata->rfe_ctl &= ~RFE_CTL_VLAN_STRIP_;
36 if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
37 pdata->rfe_ctl |= RFE_CTL_VLAN_FILTER_;
39 @@ -2826,6 +2832,9 @@ static int lan78xx_bind(struct lan78xx_n
40 if (DEFAULT_TSO_CSUM_ENABLE)
41 dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;
43 + if (DEFAULT_VLAN_RX_OFFLOAD)
44 + dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;
46 if (DEFAULT_VLAN_FILTER_ENABLE)
47 dev->net->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
49 @@ -2906,6 +2915,16 @@ static void lan78xx_rx_csum_offload(stru
53 +static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev,
54 + struct sk_buff *skb,
55 + u32 rx_cmd_a, u32 rx_cmd_b)
57 + if ((dev->net->features & NETIF_F_HW_VLAN_CTAG_RX) &&
58 + (rx_cmd_a & RX_CMD_A_FVTG_))
59 + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
60 + (rx_cmd_b & 0xffff));
63 static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
66 @@ -2970,6 +2989,8 @@ static int lan78xx_rx(struct lan78xx_net
67 if (skb->len == size) {
68 lan78xx_rx_csum_offload(dev, skb,
70 + lan78xx_rx_vlan_offload(dev, skb,
71 + rx_cmd_a, rx_cmd_b);
73 skb_trim(skb, skb->len - 4); /* remove fcs */
74 skb->truesize = size + sizeof(struct sk_buff);
75 @@ -2988,6 +3009,7 @@ static int lan78xx_rx(struct lan78xx_net
76 skb_set_tail_pointer(skb2, size);
78 lan78xx_rx_csum_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
79 + lan78xx_rx_vlan_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
81 skb_trim(skb2, skb2->len - 4); /* remove fcs */
82 skb2->truesize = size + sizeof(struct sk_buff);