1010
1111#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
1212#include <linux/clk.h>
13+ #include <linux/crc32.h>
1314#include <linux/module.h>
1415#include <linux/moduleparam.h>
1516#include <linux/kernel.h>
@@ -1565,6 +1566,9 @@ static unsigned int macb_tx_map(struct macb *bp,
15651566 if (i == queue -> tx_head ) {
15661567 ctrl |= MACB_BF (TX_LSO , lso_ctrl );
15671568 ctrl |= MACB_BF (TX_TCP_SEQ_SRC , seq_ctrl );
1569+ if ((bp -> dev -> features & NETIF_F_HW_CSUM ) &&
1570+ skb -> ip_summed != CHECKSUM_PARTIAL && !lso_ctrl )
1571+ ctrl |= MACB_BIT (TX_NOCRC );
15681572 } else
15691573 /* Only set MSS/MFS on payload descriptors
15701574 * (second or later descriptor)
@@ -1651,6 +1655,67 @@ static inline int macb_clear_csum(struct sk_buff *skb)
16511655 return 0 ;
16521656}
16531657
1658+ static int macb_pad_and_fcs (struct sk_buff * * skb , struct net_device * ndev )
1659+ {
1660+ bool cloned = skb_cloned (* skb ) || skb_header_cloned (* skb );
1661+ int padlen = ETH_ZLEN - (* skb )-> len ;
1662+ int headroom = skb_headroom (* skb );
1663+ int tailroom = skb_tailroom (* skb );
1664+ struct sk_buff * nskb ;
1665+ u32 fcs ;
1666+
1667+ if (!(ndev -> features & NETIF_F_HW_CSUM ) ||
1668+ !((* skb )-> ip_summed != CHECKSUM_PARTIAL ) ||
1669+ skb_shinfo (* skb )-> gso_size ) /* Not available for GSO */
1670+ return 0 ;
1671+
1672+ if (padlen <= 0 ) {
1673+ /* FCS could be appeded to tailroom. */
1674+ if (tailroom >= ETH_FCS_LEN )
1675+ goto add_fcs ;
1676+ /* FCS could be appeded by moving data to headroom. */
1677+ else if (!cloned && headroom + tailroom >= ETH_FCS_LEN )
1678+ padlen = 0 ;
1679+ /* No room for FCS, need to reallocate skb. */
1680+ else
1681+ padlen = ETH_FCS_LEN - tailroom ;
1682+ } else {
1683+ /* Add room for FCS. */
1684+ padlen += ETH_FCS_LEN ;
1685+ }
1686+
1687+ if (!cloned && headroom + tailroom >= padlen ) {
1688+ (* skb )-> data = memmove ((* skb )-> head , (* skb )-> data , (* skb )-> len );
1689+ skb_set_tail_pointer (* skb , (* skb )-> len );
1690+ } else {
1691+ nskb = skb_copy_expand (* skb , 0 , padlen , GFP_ATOMIC );
1692+ if (!nskb )
1693+ return - ENOMEM ;
1694+
1695+ dev_kfree_skb_any (* skb );
1696+ * skb = nskb ;
1697+ }
1698+
1699+ if (padlen ) {
1700+ if (padlen >= ETH_FCS_LEN )
1701+ skb_put_zero (* skb , padlen - ETH_FCS_LEN );
1702+ else
1703+ skb_trim (* skb , ETH_FCS_LEN - padlen );
1704+ }
1705+
1706+ add_fcs :
1707+ /* set FCS to packet */
1708+ fcs = crc32_le (~0 , (* skb )-> data , (* skb )-> len );
1709+ fcs = ~fcs ;
1710+
1711+ skb_put_u8 (* skb , fcs & 0xff );
1712+ skb_put_u8 (* skb , (fcs >> 8 ) & 0xff );
1713+ skb_put_u8 (* skb , (fcs >> 16 ) & 0xff );
1714+ skb_put_u8 (* skb , (fcs >> 24 ) & 0xff );
1715+
1716+ return 0 ;
1717+ }
1718+
16541719static netdev_tx_t macb_start_xmit (struct sk_buff * skb , struct net_device * dev )
16551720{
16561721 u16 queue_index = skb_get_queue_mapping (skb );
@@ -1667,6 +1732,11 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
16671732 return ret ;
16681733 }
16691734
1735+ if (macb_pad_and_fcs (& skb , dev )) {
1736+ dev_kfree_skb_any (skb );
1737+ return ret ;
1738+ }
1739+
16701740 is_lso = (skb_shinfo (skb )-> gso_size != 0 );
16711741
16721742 if (is_lso ) {
0 commit comments