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

Commit 7967168c authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[NET]: Merge TSO/UFO fields in sk_buff



Having separate fields in sk_buff for TSO/UFO (tso_size/ufo_size) is not
going to scale if we add any more segmentation methods (e.g., DCCP).  So
let's merge them.

They were used to tell the protocol of a packet.  This function has been
subsumed by the new gso_type field.  This is essentially a set of netdev
feature bits (shifted by 16 bits) that are required to process a specific
skb.  As such it's easy to tell whether a given device can process a GSO
skb: you just have to and the gso_type field and the netdev's features
field.

I've made gso_type a conjunction.  The idea is that you have a base type
(e.g., SKB_GSO_TCPV4) that can be modified further to support new features.
For example, if we add a hardware TSO type that supports ECN, they would
declare NETIF_F_TSO | NETIF_F_TSO_ECN.  All TSO packets with CWR set would
have a gso_type of SKB_GSO_TCPV4 | SKB_GSO_TCPV4_ECN while all other TSO
packets would be SKB_GSO_TCPV4.  This means that only the CWR packets need
to be emulated in software.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4828d85
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -797,7 +797,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
	entry = cp->tx_head;
	entry = cp->tx_head;
	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
	if (dev->features & NETIF_F_TSO)
	if (dev->features & NETIF_F_TSO)
		mss = skb_shinfo(skb)->tso_size;
		mss = skb_shinfo(skb)->gso_size;


	if (skb_shinfo(skb)->nr_frags == 0) {
	if (skb_shinfo(skb)->nr_frags == 0) {
		struct cp_desc *txd = &cp->tx_ring[entry];
		struct cp_desc *txd = &cp->tx_ring[entry];
+2 −2
Original line number Original line Diff line number Diff line
@@ -1640,7 +1640,7 @@ bnx2_tx_int(struct bnx2 *bp)
		skb = tx_buf->skb;
		skb = tx_buf->skb;
#ifdef BCM_TSO 
#ifdef BCM_TSO 
		/* partial BD completions possible with TSO packets */
		/* partial BD completions possible with TSO packets */
		if (skb_shinfo(skb)->tso_size) {
		if (skb_shinfo(skb)->gso_size) {
			u16 last_idx, last_ring_idx;
			u16 last_idx, last_ring_idx;


			last_idx = sw_cons +
			last_idx = sw_cons +
@@ -4428,7 +4428,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
	}
	}
#ifdef BCM_TSO 
#ifdef BCM_TSO 
	if ((mss = skb_shinfo(skb)->tso_size) &&
	if ((mss = skb_shinfo(skb)->gso_size) &&
		(skb->len > (bp->dev->mtu + ETH_HLEN))) {
		(skb->len > (bp->dev->mtu + ETH_HLEN))) {
		u32 tcp_opt_len, ip_tcp_len;
		u32 tcp_opt_len, ip_tcp_len;


+2 −2
Original line number Original line Diff line number Diff line
@@ -1418,7 +1418,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
	struct cpl_tx_pkt *cpl;
	struct cpl_tx_pkt *cpl;


#ifdef NETIF_F_TSO
#ifdef NETIF_F_TSO
	if (skb_shinfo(skb)->tso_size) {
	if (skb_shinfo(skb)->gso_size) {
		int eth_type;
		int eth_type;
		struct cpl_tx_pkt_lso *hdr;
		struct cpl_tx_pkt_lso *hdr;


@@ -1433,7 +1433,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
		hdr->ip_hdr_words = skb->nh.iph->ihl;
		hdr->ip_hdr_words = skb->nh.iph->ihl;
		hdr->tcp_hdr_words = skb->h.th->doff;
		hdr->tcp_hdr_words = skb->h.th->doff;
		hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
		hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
						skb_shinfo(skb)->tso_size));
						skb_shinfo(skb)->gso_size));
		hdr->len = htonl(skb->len - sizeof(*hdr));
		hdr->len = htonl(skb->len - sizeof(*hdr));
		cpl = (struct cpl_tx_pkt *)hdr;
		cpl = (struct cpl_tx_pkt *)hdr;
		sge->stats.tx_lso_pkts++;
		sge->stats.tx_lso_pkts++;
+5 −5
Original line number Original line Diff line number Diff line
@@ -2394,7 +2394,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
	int err;
	int err;


	if (skb_shinfo(skb)->tso_size) {
	if (skb_shinfo(skb)->gso_size) {
		if (skb_header_cloned(skb)) {
		if (skb_header_cloned(skb)) {
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
			if (err)
			if (err)
@@ -2402,7 +2402,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
		}
		}


		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
		mss = skb_shinfo(skb)->tso_size;
		mss = skb_shinfo(skb)->gso_size;
		if (skb->protocol == htons(ETH_P_IP)) {
		if (skb->protocol == htons(ETH_P_IP)) {
			skb->nh.iph->tot_len = 0;
			skb->nh.iph->tot_len = 0;
			skb->nh.iph->check = 0;
			skb->nh.iph->check = 0;
@@ -2519,7 +2519,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
		 * tso gets written back prematurely before the data is fully
		 * tso gets written back prematurely before the data is fully
		 * DMA'd to the controller */
		 * DMA'd to the controller */
		if (!skb->data_len && tx_ring->last_tx_tso &&
		if (!skb->data_len && tx_ring->last_tx_tso &&
		    !skb_shinfo(skb)->tso_size) {
		    !skb_shinfo(skb)->gso_size) {
			tx_ring->last_tx_tso = 0;
			tx_ring->last_tx_tso = 0;
			size -= 4;
			size -= 4;
		}
		}
@@ -2757,7 +2757,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
	}
	}


#ifdef NETIF_F_TSO
#ifdef NETIF_F_TSO
	mss = skb_shinfo(skb)->tso_size;
	mss = skb_shinfo(skb)->gso_size;
	/* The controller does a simple calculation to
	/* The controller does a simple calculation to
	 * make sure there is enough room in the FIFO before
	 * make sure there is enough room in the FIFO before
	 * initiating the DMA for each buffer.  The calc is:
	 * initiating the DMA for each buffer.  The calc is:
@@ -2807,7 +2807,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
#ifdef NETIF_F_TSO
#ifdef NETIF_F_TSO
	/* Controller Erratum workaround */
	/* Controller Erratum workaround */
	if (!skb->data_len && tx_ring->last_tx_tso &&
	if (!skb->data_len && tx_ring->last_tx_tso &&
	    !skb_shinfo(skb)->tso_size)
	    !skb_shinfo(skb)->gso_size)
		count++;
		count++;
#endif
#endif


+2 −2
Original line number Original line Diff line number Diff line
@@ -1495,8 +1495,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
	np->tx_skbuff[nr] = skb;
	np->tx_skbuff[nr] = skb;


#ifdef NETIF_F_TSO
#ifdef NETIF_F_TSO
	if (skb_shinfo(skb)->tso_size)
	if (skb_shinfo(skb)->gso_size)
		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT);
	else
	else
#endif
#endif
	tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
	tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
Loading