aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
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
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')
-rwxr-xr-x[-rw-r--r--]drivers/net/chelsio/cxgb2.c3
-rwxr-xr-x[-rw-r--r--]drivers/net/chelsio/sge.c34
-rwxr-xr-x[-rw-r--r--]drivers/net/chelsio/sge.h1
3 files changed, 18 insertions, 20 deletions
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 2dbf8dc116c6..2461f91b0996 100644..100755
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -401,7 +401,8 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
401 "TxTso", 401 "TxTso",
402 "RxVlan", 402 "RxVlan",
403 "TxVlan", 403 "TxVlan",
404 404 "TxNeedHeadroom",
405
405 /* Interrupt stats */ 406 /* Interrupt stats */
406 "rx drops", 407 "rx drops",
407 "pure_rsps", 408 "pure_rsps",
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) {
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
index 713d9c55f24d..285bbb272ed5 100644..100755
--- a/drivers/net/chelsio/sge.h
+++ b/drivers/net/chelsio/sge.h
@@ -64,6 +64,7 @@ struct sge_port_stats {
64 u64 tx_tso; /* # of TSO requests */ 64 u64 tx_tso; /* # of TSO requests */
65 u64 vlan_xtract; /* # of VLAN tag extractions */ 65 u64 vlan_xtract; /* # of VLAN tag extractions */
66 u64 vlan_insert; /* # of VLAN tag insertions */ 66 u64 vlan_insert; /* # of VLAN tag insertions */
67 u64 tx_need_hdrroom; /* # of TX skbs in need of more header room */
67}; 68};
68 69
69struct sk_buff; 70struct sk_buff;