aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/chelsio/sge.c
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2007-11-27 16:30:09 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-01 16:32:31 -0500
commit7832ee034b6ef78aab020c9ec1348544cd65ccbd (patch)
tree9a4fedc9bf3b6b9c31f35a50f3d7aa0deab358d4 /drivers/net/chelsio/sge.c
parentbd0ceaab86d3f0e3916b3b7868cfe20de490eebc (diff)
cxgb - fix T2 GSO
The patch ensures that a GSO skb has enough headroom to push an encapsulating cpl_tx_pkt_lso header. Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/chelsio/sge.c')
-rwxr-xr-x[-rw-r--r--]drivers/net/chelsio/sge.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 443666292a5c..e8b1036672ae 100644..100755
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -991,6 +991,7 @@ void t1_sge_get_port_stats(const struct sge *sge, int port,
991 ss->tx_packets += st->tx_packets; 991 ss->tx_packets += st->tx_packets;
992 ss->tx_cso += st->tx_cso; 992 ss->tx_cso += st->tx_cso;
993 ss->tx_tso += st->tx_tso; 993 ss->tx_tso += st->tx_tso;
994 ss->tx_need_hdrroom += st->tx_need_hdrroom;
994 ss->vlan_xtract += st->vlan_xtract; 995 ss->vlan_xtract += st->vlan_xtract;
995 ss->vlan_insert += st->vlan_insert; 996 ss->vlan_insert += st->vlan_insert;
996 } 997 }
@@ -1848,7 +1849,8 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1848{ 1849{
1849 struct adapter *adapter = dev->priv; 1850 struct adapter *adapter = dev->priv;
1850 struct sge *sge = adapter->sge; 1851 struct sge *sge = adapter->sge;
1851 struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port], smp_processor_id()); 1852 struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port],
1853 smp_processor_id());
1852 struct cpl_tx_pkt *cpl; 1854 struct cpl_tx_pkt *cpl;
1853 struct sk_buff *orig_skb = skb; 1855 struct sk_buff *orig_skb = skb;
1854 int ret; 1856 int ret;
@@ -1856,6 +1858,18 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1856 if (skb->protocol == htons(ETH_P_CPL5)) 1858 if (skb->protocol == htons(ETH_P_CPL5))
1857 goto send; 1859 goto send;
1858 1860
1861 /*
1862 * We are using a non-standard hard_header_len.
1863 * Allocate more header room in the rare cases it is not big enough.
1864 */
1865 if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
1866 skb = skb_realloc_headroom(skb, sizeof(struct cpl_tx_pkt_lso));
1867 ++st->tx_need_hdrroom;
1868 dev_kfree_skb_any(orig_skb);
1869 if (!skb)
1870 return NETDEV_TX_OK;
1871 }
1872
1859 if (skb_shinfo(skb)->gso_size) { 1873 if (skb_shinfo(skb)->gso_size) {
1860 int eth_type; 1874 int eth_type;
1861 struct cpl_tx_pkt_lso *hdr; 1875 struct cpl_tx_pkt_lso *hdr;
@@ -1889,24 +1903,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
1889 return NETDEV_TX_OK; 1903 return NETDEV_TX_OK;
1890 } 1904 }
1891 1905
1892 /*
1893 * We are using a non-standard hard_header_len and some kernel
1894 * components, such as pktgen, do not handle it right.
1895 * Complain when this happens but try to fix things up.
1896 */
1897 if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
1898 pr_debug("%s: headroom %d header_len %d\n", dev->name,
1899 skb_headroom(skb), dev->hard_header_len);
1900
1901 if (net_ratelimit())
1902 printk(KERN_ERR "%s: inadequate headroom in "
1903 "Tx packet\n", dev->name);
1904 skb = skb_realloc_headroom(skb, sizeof(*cpl));
1905 dev_kfree_skb_any(orig_skb);
1906 if (!skb)
1907 return NETDEV_TX_OK;
1908 }
1909
1910 if (!(adapter->flags & UDP_CSUM_CAPABLE) && 1906 if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
1911 skb->ip_summed == CHECKSUM_PARTIAL && 1907 skb->ip_summed == CHECKSUM_PARTIAL &&
1912 ip_hdr(skb)->protocol == IPPROTO_UDP) { 1908 ip_hdr(skb)->protocol == IPPROTO_UDP) {