Skip to content

Commit

Permalink
net: lan78xx: Add support for VLAN tag stripping.
Browse files Browse the repository at this point in the history
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 <dave.stevenson@raspberrypi.org>
  • Loading branch information
6by9 authored and popcornmix committed Aug 29, 2018
1 parent 6af9c00 commit 8fd04c6
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/net/usb/lan78xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#define DEFAULT_RX_CSUM_ENABLE (true)
#define DEFAULT_TSO_CSUM_ENABLE (true)
#define DEFAULT_VLAN_FILTER_ENABLE (true)
#define DEFAULT_VLAN_RX_OFFLOAD (true)
#define TX_OVERHEAD (8)
#define RXW_PADDING 2

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

if (features & NETIF_F_HW_VLAN_CTAG_RX)
pdata->rfe_ctl |= RFE_CTL_VLAN_STRIP_;
else
pdata->rfe_ctl &= ~RFE_CTL_VLAN_STRIP_;

if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
pdata->rfe_ctl |= RFE_CTL_VLAN_FILTER_;
else
Expand Down Expand Up @@ -2921,6 +2927,9 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
if (DEFAULT_TSO_CSUM_ENABLE)
dev->net->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG;

if (DEFAULT_VLAN_RX_OFFLOAD)
dev->net->features |= NETIF_F_HW_VLAN_CTAG_RX;

if (DEFAULT_VLAN_FILTER_ENABLE)
dev->net->features |= NETIF_F_HW_VLAN_CTAG_FILTER;

Expand Down Expand Up @@ -3001,6 +3010,16 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev,
}
}

static void lan78xx_rx_vlan_offload(struct lan78xx_net *dev,
struct sk_buff *skb,
u32 rx_cmd_a, u32 rx_cmd_b)
{
if ((dev->net->features & NETIF_F_HW_VLAN_CTAG_RX) &&
(rx_cmd_a & RX_CMD_A_FVTG_))
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
(rx_cmd_b & 0xffff));
}

static void lan78xx_skb_return(struct lan78xx_net *dev, struct sk_buff *skb)
{
int status;
Expand Down Expand Up @@ -3065,6 +3084,8 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
if (skb->len == size) {
lan78xx_rx_csum_offload(dev, skb,
rx_cmd_a, rx_cmd_b);
lan78xx_rx_vlan_offload(dev, skb,
rx_cmd_a, rx_cmd_b);

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

lan78xx_rx_csum_offload(dev, skb2, rx_cmd_a, rx_cmd_b);
lan78xx_rx_vlan_offload(dev, skb2, rx_cmd_a, rx_cmd_b);

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

0 comments on commit 8fd04c6

Please sign in to comment.