Skip to content

Commit

Permalink
net: usb: aqc111: Add checksum offload support
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Dmitry Bezrukov authored and David S. Miller committed Nov 27, 2018
1 parent 361459c commit 0203146
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
38 changes: 38 additions & 0 deletions drivers/net/usb/aqc111.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,26 @@ static void aqc111_configure_rx(struct usbnet *dev,
netdev_info(dev->net, "Link Speed %d, USB %d", link_speed, usb_host);
}

static void aqc111_configure_csum_offload(struct usbnet *dev)
{
u8 reg8 = 0;

if (dev->net->features & NETIF_F_RXCSUM) {
reg8 |= SFR_RXCOE_IP | SFR_RXCOE_TCP | SFR_RXCOE_UDP |
SFR_RXCOE_TCPV6 | SFR_RXCOE_UDPV6;
}
aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_RXCOE_CTL, 1, 1, &reg8);

reg8 = 0;
if (dev->net->features & NETIF_F_IP_CSUM)
reg8 |= SFR_TXCOE_IP | SFR_TXCOE_TCP | SFR_TXCOE_UDP;

if (dev->net->features & NETIF_F_IPV6_CSUM)
reg8 |= SFR_TXCOE_TCPV6 | SFR_TXCOE_UDPV6;

aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_TXCOE_CTL, 1, 1, &reg8);
}

static int aqc111_link_reset(struct usbnet *dev)
{
struct aqc111_data *aqc111_data = dev->driver_priv;
Expand Down Expand Up @@ -482,6 +502,8 @@ static int aqc111_link_reset(struct usbnet *dev)
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
2, &reg16);

aqc111_configure_csum_offload(dev);

aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
2, &reg16);

Expand Down Expand Up @@ -583,6 +605,21 @@ static int aqc111_stop(struct usbnet *dev)
return 0;
}

static void aqc111_rx_checksum(struct sk_buff *skb, u64 pkt_desc)
{
u32 pkt_type = 0;

skb->ip_summed = CHECKSUM_NONE;
/* checksum error bit is set */
if (pkt_desc & AQ_RX_PD_L4_ERR || pkt_desc & AQ_RX_PD_L3_ERR)
return;

pkt_type = pkt_desc & AQ_RX_PD_L4_TYPE_MASK;
/* It must be a TCP or UDP packet with a valid checksum */
if (pkt_type == AQ_RX_PD_L4_TCP || pkt_type == AQ_RX_PD_L4_UDP)
skb->ip_summed = CHECKSUM_UNNECESSARY;
}

static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
struct sk_buff *new_skb = NULL;
Expand Down Expand Up @@ -660,6 +697,7 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
skb_set_tail_pointer(new_skb, new_skb->len);

new_skb->truesize = SKB_TRUESIZE(new_skb->len);
aqc111_rx_checksum(new_skb, pkt_desc);

usbnet_skb_return(dev, new_skb);
if (pkt_count == 0)
Expand Down
16 changes: 14 additions & 2 deletions drivers/net/usb/aqc111.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
#define AQ_USB_SET_TIMEOUT 4000

/* Feature. ********************************************/
#define AQ_SUPPORT_FEATURE (NETIF_F_SG)
#define AQ_SUPPORT_HW_FEATURE (NETIF_F_SG)
#define AQ_SUPPORT_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)

#define AQ_SUPPORT_HW_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)

/* SFR Reg. ********************************************/

Expand Down Expand Up @@ -162,6 +165,15 @@ struct aqc111_data {
#define AQ_RX_HW_PAD 0x02

/* RX Packet Descriptor */
#define AQ_RX_PD_L4_ERR BIT(0)
#define AQ_RX_PD_L3_ERR BIT(1)
#define AQ_RX_PD_L4_TYPE_MASK 0x1C
#define AQ_RX_PD_L4_UDP 0x04
#define AQ_RX_PD_L4_TCP 0x10
#define AQ_RX_PD_L3_TYPE_MASK 0x60
#define AQ_RX_PD_L3_IP 0x20
#define AQ_RX_PD_L3_IP6 0x40

#define AQ_RX_PD_RX_OK BIT(11)
#define AQ_RX_PD_DROP BIT(31)
#define AQ_RX_PD_LEN_MASK 0x7FFF0000
Expand Down

0 comments on commit 0203146

Please sign in to comment.