From 932e908a07bb584119b7aee4280b95adf415f246 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 12 Mar 2014 17:41:12 +0000 Subject: net:fec: move skb allocation earlier Move the skb allocation before we sync the buffer for CPU access. In order to do this, we need to detect whether the packet contains a VLAN header so we can adjust the packet size appropriately. This allows us to tidy the code a little in the following patches. Signed-off-by: Russell King --- drivers/net/ethernet/freescale/fec_main.c | 45 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index c0f166538738..791d6f519256 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -977,7 +977,6 @@ fec_enet_rx(struct net_device *ndev, int budget) ushort pkt_len; __u8 *data; int pkt_received = 0; - bool vlan_packet_rcvd = false; u16 vlan_tag; unsigned int index = fep->rx_next; @@ -1053,13 +1052,6 @@ fec_enet_rx(struct net_device *ndev, int budget) pkt_len = bdp->bd.cbd_datlen - 4; ndev->stats.rx_bytes += pkt_len; - data = fep->rx_skbuff[index]->data; - dma_sync_single_for_cpu(&fep->pdev->dev, bdp->bd.cbd_bufaddr, - FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); - - if (fep->quirks & FEC_QUIRK_SWAP_FRAME) - swap_buffer(data, pkt_len); - if (fep->flags & FEC_FLAG_BUFDESC_EX) { cbd_esc = bdp->ebd.cbd_esc; if (!(fep->flags & FEC_FLAG_RX_VLAN)) @@ -1068,32 +1060,43 @@ fec_enet_rx(struct net_device *ndev, int budget) cbd_esc = 0; } + /* + * Detect the presence of the VLANG tag, and just + * the packet length appropriately. + */ + if (cbd_esc & BD_ENET_RX_VLAN) + pkt_len -= VLAN_HLEN; + + /* This does 16 byte alignment, exactly what we need. */ + skb = netdev_alloc_skb(ndev, pkt_len + NET_IP_ALIGN); + if (unlikely(!skb)) { + ndev->stats.rx_dropped++; + goto rx_processing_done; + } + + data = fep->rx_skbuff[index]->data; + dma_sync_single_for_cpu(&fep->pdev->dev, bdp->bd.cbd_bufaddr, + FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); + + if (fep->quirks & FEC_QUIRK_SWAP_FRAME) + swap_buffer(data, pkt_len); + /* If this is a VLAN packet remove the VLAN Tag */ - vlan_packet_rcvd = false; if (cbd_esc & BD_ENET_RX_VLAN) { /* Push and remove the vlan tag */ struct vlan_hdr *vlan_header = (struct vlan_hdr *) (data + ETH_HLEN); vlan_tag = ntohs(vlan_header->h_vlan_TCI); - pkt_len -= VLAN_HLEN; - - vlan_packet_rcvd = true; } - /* This does 16 byte alignment, exactly what we need. - */ - skb = netdev_alloc_skb(ndev, pkt_len + NET_IP_ALIGN); - - if (unlikely(!skb)) { - ndev->stats.rx_dropped++; - } else { + { int payload_offset = (2 * ETH_ALEN); skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pkt_len); /* Make room */ /* Extract the frame data without the VLAN header. */ skb_copy_to_linear_data(skb, data, (2 * ETH_ALEN)); - if (vlan_packet_rcvd) + if (cbd_esc & BD_ENET_RX_VLAN) payload_offset = (2 * ETH_ALEN) + VLAN_HLEN; skb_copy_to_linear_data_offset(skb, (2 * ETH_ALEN), data + payload_offset, @@ -1116,7 +1119,7 @@ fec_enet_rx(struct net_device *ndev, int budget) } /* Handle received VLAN packets */ - if (vlan_packet_rcvd) + if (cbd_esc & BD_ENET_RX_VLAN) __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); -- cgit