Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mv643xx_eth: use sw csum for big packets

Some controllers (KW, Dove) limits the TX IP/layer4 checksum offloading to a max size.

Signed-off-by: Saeed Bishara <saeed@marvell.com>
Acked-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Saeed Bishara and committed by
David S. Miller
9b2c2ff7 08e554b1

+12 -2
+7 -2
drivers/net/mv643xx_eth.c
··· 289 289 unsigned int t_clk; 290 290 int extended_rx_coal_limit; 291 291 int tx_bw_control; 292 + int tx_csum_limit; 292 293 }; 293 294 294 295 #define TX_BW_CONTROL_ABSENT 0 ··· 777 776 l4i_chk = 0; 778 777 779 778 if (skb->ip_summed == CHECKSUM_PARTIAL) { 779 + int hdr_len; 780 780 int tag_bytes; 781 781 782 782 BUG_ON(skb->protocol != htons(ETH_P_IP) && 783 783 skb->protocol != htons(ETH_P_8021Q)); 784 784 785 - tag_bytes = (void *)ip_hdr(skb) - (void *)skb->data - ETH_HLEN; 786 - if (unlikely(tag_bytes & ~12)) { 785 + hdr_len = (void *)ip_hdr(skb) - (void *)skb->data; 786 + tag_bytes = hdr_len - ETH_HLEN; 787 + if (skb->len - hdr_len > mp->shared->tx_csum_limit || 788 + unlikely(tag_bytes & ~12)) { 787 789 if (skb_checksum_help(skb) == 0) 788 790 goto no_csum; 789 791 kfree_skb(skb); ··· 2670 2666 * Detect hardware parameters. 2671 2667 */ 2672 2668 msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; 2669 + msp->tx_csum_limit = pd->tx_csum_limit ? pd->tx_csum_limit : 9 * 1024; 2673 2670 infer_hw_params(msp); 2674 2671 2675 2672 platform_set_drvdata(pdev, msp);
+5
include/linux/mv643xx_eth.h
··· 19 19 struct mbus_dram_target_info *dram; 20 20 struct platform_device *shared_smi; 21 21 unsigned int t_clk; 22 + /* 23 + * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default 24 + * limit of 9KiB will be used. 25 + */ 26 + int tx_csum_limit; 22 27 }; 23 28 24 29 #define MV643XX_ETH_PHY_ADDR_DEFAULT 0