[PATCH net-next v2 08/13] r8152: support rx checksum
Support hw rx checksum for TCP and UDP packets. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 41 +++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 08f4e870..c76e018 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -466,9 +466,19 @@ enum rtl8152_flags { struct rx_desc { __le32 opts1; +#define RD_CRC (1 << 15) #define RX_LEN_MASK0x7fff + __le32 opts2; +#define RD_UDP_CS (1 << 23) +#define RD_TCP_CS (1 << 22) +#define RD_IPV4_CS (1 << 19) + __le32 opts3; +#define IPF(1 << 23) /* IP checksum fail */ +#define UDPF (1 << 22) /* UDP checksum fail */ +#define TCPF (1 << 21) /* TCP checksum fail */ + __le32 opts4; __le32 opts5; __le32 opts6; @@ -1404,6 +1414,31 @@ out_tx_fill: return ret; } +static int r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) +{ + int checksum = CHECKSUM_NONE; + u32 opts2, opts3; + + if (tp->version == RTL_VER_01) + goto return_result; + + opts2 = le32_to_cpu(rx_desc->opts2); + opts3 = le32_to_cpu(rx_desc->opts3); + + if (opts2 & RD_IPV4_CS) { + if (opts3 & IPF) + checksum = CHECKSUM_NONE; + else if (((opts2 & RD_UDP_CS) && (opts3 & UDPF)) || +((opts2 & RD_TCP_CS) && (opts3 & TCPF))) + checksum = CHECKSUM_NONE; + else + checksum = CHECKSUM_UNNECESSARY; + } + +return_result: + return checksum; +} + static void rx_bottom(struct r8152 *tp) { unsigned long flags; @@ -1458,6 +1493,8 @@ static void rx_bottom(struct r8152 *tp) stats->rx_dropped++; goto find_next_rx; } + + skb->ip_summed = r8152_rx_csum(tp, rx_desc); memcpy(skb->data, rx_data, pkt_len); skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, netdev); @@ -3103,8 +3140,8 @@ static int rtl8152_probe(struct usb_interface *intf, netdev->netdev_ops = _netdev_ops; netdev->watchdog_timeo = RTL8152_TX_TIMEOUT; - netdev->features |= NETIF_F_IP_CSUM; - netdev->hw_features = NETIF_F_IP_CSUM; + netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM; + netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(netdev, ); -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next v2 08/13] r8152: support rx checksum
Support hw rx checksum for TCP and UDP packets. Signed-off-by: Hayes Wang hayesw...@realtek.com --- drivers/net/usb/r8152.c | 41 +++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 08f4e870..c76e018 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -466,9 +466,19 @@ enum rtl8152_flags { struct rx_desc { __le32 opts1; +#define RD_CRC (1 15) #define RX_LEN_MASK0x7fff + __le32 opts2; +#define RD_UDP_CS (1 23) +#define RD_TCP_CS (1 22) +#define RD_IPV4_CS (1 19) + __le32 opts3; +#define IPF(1 23) /* IP checksum fail */ +#define UDPF (1 22) /* UDP checksum fail */ +#define TCPF (1 21) /* TCP checksum fail */ + __le32 opts4; __le32 opts5; __le32 opts6; @@ -1404,6 +1414,31 @@ out_tx_fill: return ret; } +static int r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) +{ + int checksum = CHECKSUM_NONE; + u32 opts2, opts3; + + if (tp-version == RTL_VER_01) + goto return_result; + + opts2 = le32_to_cpu(rx_desc-opts2); + opts3 = le32_to_cpu(rx_desc-opts3); + + if (opts2 RD_IPV4_CS) { + if (opts3 IPF) + checksum = CHECKSUM_NONE; + else if (((opts2 RD_UDP_CS) (opts3 UDPF)) || +((opts2 RD_TCP_CS) (opts3 TCPF))) + checksum = CHECKSUM_NONE; + else + checksum = CHECKSUM_UNNECESSARY; + } + +return_result: + return checksum; +} + static void rx_bottom(struct r8152 *tp) { unsigned long flags; @@ -1458,6 +1493,8 @@ static void rx_bottom(struct r8152 *tp) stats-rx_dropped++; goto find_next_rx; } + + skb-ip_summed = r8152_rx_csum(tp, rx_desc); memcpy(skb-data, rx_data, pkt_len); skb_put(skb, pkt_len); skb-protocol = eth_type_trans(skb, netdev); @@ -3103,8 +3140,8 @@ static int rtl8152_probe(struct usb_interface *intf, netdev-netdev_ops = rtl8152_netdev_ops; netdev-watchdog_timeo = RTL8152_TX_TIMEOUT; - netdev-features |= NETIF_F_IP_CSUM; - netdev-hw_features = NETIF_F_IP_CSUM; + netdev-features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM; + netdev-hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(netdev, ops); -- 1.8.4.2 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/