Patchwork [20/21] net: via-velocity: use common rx_copybreak handling

login
register
mail settings
Submitter Michał Mirosław
Date July 9, 2011, 5:17 p.m.
Message ID <fde4e58b4575124aaa9878ea2329dcb3445c50f0.1310229312.git.mirq-linux@rere.qmqm.pl>
Download mbox | patch
Permalink /patch/103999/
State Superseded
Delegated to: David Miller
Headers show

Comments

Michał Mirosław - July 9, 2011, 5:17 p.m.
This also fixes a bug, where FCS was not stripped from copied packets.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/via-velocity.c |   59 +++++++------------------------------------
 1 files changed, 10 insertions(+), 49 deletions(-)
françois romieu - July 9, 2011, 10:19 p.m.
Michał Mirosław <mirq-linux@rere.qmqm.pl> :
[...]
> diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
> index f929242..cdc51de 100644
> --- a/drivers/net/via-velocity.c
> +++ b/drivers/net/via-velocity.c
[...]
> @@ -2027,10 +1996,10 @@ static int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
>   *	configured by the user.
>   */
>  static inline void velocity_iph_realign(struct velocity_info *vptr,
> -					struct sk_buff *skb, int pkt_size)
> +					struct sk_buff *skb)
>  {
>  	if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
> -		memmove(skb->data + 2, skb->data, pkt_size);
> +		memmove(skb->data + 2, skb->data, skb->len);
>  		skb_reserve(skb, 2);
>  	}
>  }
[...]
> @@ -2078,30 +2044,25 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
>  		}
>  	}
>  
> -	pci_action = pci_dma_sync_single_for_device;
> +	skb = dev_skb_finish_rx_dma(&rd_info->skb,
> +		pkt_len - ETH_FCS_LEN, rx_copybreak,
> +		&vptr->pdev->dev, rd_info->skb_dma, vptr->rx.buf_sz);
> +	if (!skb)
> +		/* not copied */
> +		velocity_iph_realign(vptr, skb);

s/if (!skb)/if (!rd_info->skb)/ ?

Patch

diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index f929242..cdc51de 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1987,37 +1987,6 @@  static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
 }
 
 /**
- *	velocity_rx_copy	-	in place Rx copy for small packets
- *	@rx_skb: network layer packet buffer candidate
- *	@pkt_size: received data size
- *	@rd: receive packet descriptor
- *	@dev: network device
- *
- *	Replace the current skb that is scheduled for Rx processing by a
- *	shorter, immediately allocated skb, if the received packet is small
- *	enough. This function returns a negative value if the received
- *	packet is too big or if memory is exhausted.
- */
-static int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
-			    struct velocity_info *vptr)
-{
-	int ret = -1;
-	if (pkt_size < rx_copybreak) {
-		struct sk_buff *new_skb;
-
-		new_skb = netdev_alloc_skb_ip_align(vptr->dev, pkt_size);
-		if (new_skb) {
-			new_skb->ip_summed = rx_skb[0]->ip_summed;
-			skb_copy_from_linear_data(*rx_skb, new_skb->data, pkt_size);
-			*rx_skb = new_skb;
-			ret = 0;
-		}
-
-	}
-	return ret;
-}
-
-/**
  *	velocity_iph_realign	-	IP header alignment
  *	@vptr: velocity we are handling
  *	@skb: network layer packet buffer
@@ -2027,10 +1996,10 @@  static int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
  *	configured by the user.
  */
 static inline void velocity_iph_realign(struct velocity_info *vptr,
-					struct sk_buff *skb, int pkt_size)
+					struct sk_buff *skb)
 {
 	if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
-		memmove(skb->data + 2, skb->data, pkt_size);
+		memmove(skb->data + 2, skb->data, skb->len);
 		skb_reserve(skb, 2);
 	}
 }
@@ -2064,9 +2033,6 @@  static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 
 	skb = rd_info->skb;
 
-	pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
-				    vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
-
 	/*
 	 *	Drop frame not meeting IEEE 802.3
 	 */
@@ -2078,30 +2044,25 @@  static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 		}
 	}
 
-	pci_action = pci_dma_sync_single_for_device;
+	skb = dev_skb_finish_rx_dma(&rd_info->skb,
+		pkt_len - ETH_FCS_LEN, rx_copybreak,
+		&vptr->pdev->dev, rd_info->skb_dma, vptr->rx.buf_sz);
+	if (!skb)
+		/* not copied */
+		velocity_iph_realign(vptr, skb);
 
 	velocity_rx_csum(rd, skb);
 
-	if (velocity_rx_copy(&skb, pkt_len, vptr) < 0) {
-		velocity_iph_realign(vptr, skb, pkt_len);
-		pci_action = pci_unmap_single;
-		rd_info->skb = NULL;
-	}
-
-	pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
-		   PCI_DMA_FROMDEVICE);
-
-	skb_put(skb, pkt_len - 4);
 	skb->protocol = eth_type_trans(skb, vptr->dev);
 
+	stats->rx_bytes += skb->len;
+
 	if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) {
 		vlan_hwaccel_rx(skb, vptr->vlgrp,
 				swab16(le16_to_cpu(rd->rdesc1.PQTAG)));
 	} else
 		netif_rx(skb);
 
-	stats->rx_bytes += pkt_len;
-
 	return 0;
 }