Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7832ee03 authored by Divy Le Ray's avatar Divy Le Ray Committed by Jeff Garzik
Browse files

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: default avatarDivy Le Ray <divy@chelsio.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent bd0ceaab
Loading
Loading
Loading
Loading

drivers/net/chelsio/cxgb2.c

100644 → 100755
+2 −1
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
	"TxTso",
	"RxVlan",
	"TxVlan",
	"TxNeedHeadroom", 
	
	/* Interrupt stats */
	"rx drops",

drivers/net/chelsio/sge.c

100644 → 100755
+15 −19
Original line number Diff line number Diff line
@@ -991,6 +991,7 @@ void t1_sge_get_port_stats(const struct sge *sge, int port,
		ss->tx_packets += st->tx_packets;
		ss->tx_cso += st->tx_cso;
		ss->tx_tso += st->tx_tso;
		ss->tx_need_hdrroom += st->tx_need_hdrroom;
		ss->vlan_xtract += st->vlan_xtract;
		ss->vlan_insert += st->vlan_insert;
	}
@@ -1848,7 +1849,8 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct adapter *adapter = dev->priv;
	struct sge *sge = adapter->sge;
	struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port], smp_processor_id());
	struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port],
						smp_processor_id());
	struct cpl_tx_pkt *cpl;
	struct sk_buff *orig_skb = skb;
	int ret;
@@ -1856,6 +1858,18 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
	if (skb->protocol == htons(ETH_P_CPL5))
		goto send;

	/*
	 * We are using a non-standard hard_header_len.
	 * Allocate more header room in the rare cases it is not big enough.
	 */
	if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
		skb = skb_realloc_headroom(skb, sizeof(struct cpl_tx_pkt_lso));
		++st->tx_need_hdrroom;
		dev_kfree_skb_any(orig_skb);
		if (!skb)
			return NETDEV_TX_OK;
	}

	if (skb_shinfo(skb)->gso_size) {
		int eth_type;
		struct cpl_tx_pkt_lso *hdr;
@@ -1889,24 +1903,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
			return NETDEV_TX_OK;
		}

		/*
		 * We are using a non-standard hard_header_len and some kernel
		 * components, such as pktgen, do not handle it right.
		 * Complain when this happens but try to fix things up.
		 */
		if (unlikely(skb_headroom(skb) < dev->hard_header_len - ETH_HLEN)) {
			pr_debug("%s: headroom %d header_len %d\n", dev->name,
				 skb_headroom(skb), dev->hard_header_len);

			if (net_ratelimit())
				printk(KERN_ERR "%s: inadequate headroom in "
				       "Tx packet\n", dev->name);
			skb = skb_realloc_headroom(skb, sizeof(*cpl));
			dev_kfree_skb_any(orig_skb);
			if (!skb)
				return NETDEV_TX_OK;
		}

		if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
		    skb->ip_summed == CHECKSUM_PARTIAL &&
		    ip_hdr(skb)->protocol == IPPROTO_UDP) {

drivers/net/chelsio/sge.h

100644 → 100755
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct sge_port_stats {
	u64 tx_tso;          /* # of TSO requests */
	u64 vlan_xtract;     /* # of VLAN tag extractions */
	u64 vlan_insert;     /* # of VLAN tag insertions */
	u64 tx_need_hdrroom; /* # of TX skbs in need of more header room */
};

struct sk_buff;