diff options
author | Ganga Negi <ganga.negi@freescale.com> | 2014-11-04 08:14:32 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:40:43 (GMT) |
commit | bdf21e9de593a3aa36fac4e5dd7e493ebb48e64b (patch) | |
tree | 8c735d2ca53b59da4993e00a69c8ea99cf8b51e6 /drivers/net/ethernet/freescale/gianfar.c | |
parent | b828a4f271836d36a1e5c59ac87b60b812f35efd (diff) | |
download | linux-fsl-qoriq-bdf21e9de593a3aa36fac4e5dd7e493ebb48e64b.tar.xz |
ASF: Placing hooks in gianfar driver for both PPC and ARM platforms.
Placing required compilation flags and hooks in gianfar
driver for both ARM and PowerPC platforms.
Signed-off-by: Ganga Negi <ganga.negi@freescale.com>
Change-Id: I2f6c8fe40a2223013559bc6909a60e8963aa2a96
CR:ENGR00338962
(cherry picked from commit 509f3236615193c77e07797cde4729ccc8cb2ef5)
Reviewed-on: http://git.am.freescale.net:8181/23585
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Claudiu Manoil <claudiu.manoil@freescale.com>
Reviewed-by: Richard Schmitt <richard.schmitt@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.c')
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 613d915..38cd3f2 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -114,7 +114,17 @@ #endif #ifdef CONFIG_AS_FASTPATH +#ifdef CONFIG_PPC #include "asf_gianfar.h" +#else + +devfp_hook_t devfp_rx_hook; +EXPORT_SYMBOL(devfp_rx_hook); + +devfp_hook_t devfp_tx_hook; +EXPORT_SYMBOL(devfp_tx_hook); + +#endif #endif #define TX_TIMEOUT (1*HZ) @@ -863,7 +873,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) return -EINVAL; } -#ifdef CONFIG_AS_FASTPATH +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_PPC) /* Creating multilple queues for avoiding lock in xmit function.*/ num_tx_qs = (num_tx_qs < 2) ? 2 : num_tx_qs; #endif @@ -2420,7 +2430,13 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned int nr_frags, nr_txbds, fcb_len = 0; #ifdef CONFIG_AS_FASTPATH +#ifdef CONFIG_PPC return gfar_asf_start_xmit(skb, dev); +#else + if (devfp_tx_hook && (skb->pkt_type != PACKET_FASTROUTE)) + if (devfp_tx_hook(skb, dev) == AS_FP_STOLEN) + return 0; +#endif #endif rq = skb->queue_mapping; @@ -2895,7 +2911,7 @@ static struct sk_buff *gfar_alloc_skb(struct net_device *dev) struct gfar_private *priv = netdev_priv(dev); struct sk_buff *skb; -#ifndef CONFIG_AS_FASTPATH +#if !defined(CONFIG_AS_FASTPATH) || defined(CONFIG_ARM) skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT); #else skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT + @@ -2963,7 +2979,7 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id) unsigned long flags; u32 imask; -#ifdef CONFIG_AS_FASTPATH +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_PPC) return gfar_enable_tx_queue(irq, grp_id); #endif @@ -3043,6 +3059,25 @@ static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb, if (dev->features & NETIF_F_RXCSUM) gfar_rx_checksum(skb, fcb); +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_ARM) + if (devfp_rx_hook) { + /* Drop the packet silently if IP Checksum is not correct */ + if ((be16_to_cpu(fcb->flags) & RXFCB_CIP) && + (be16_to_cpu(fcb->flags) & RXFCB_EIP)) { + dev_kfree_skb_any(skb); + return; + } + + if (dev->features & NETIF_F_HW_VLAN_CTAG_RX && + be16_to_cpu(fcb->flags) & RXFCB_VLN) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), + be16_to_cpu(fcb->vlctl)); + + skb->dev = dev; + if (devfp_rx_hook(skb, dev) == AS_FP_STOLEN) + return; + } +#endif /* Tell the skb what kind of packet this is */ skb->protocol = eth_type_trans(skb, dev); @@ -3083,7 +3118,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) int howmany = 0; struct gfar_private *priv = netdev_priv(dev); -#ifdef CONFIG_AS_FASTPATH +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_PPC) return gfar_asf_clean_rx_ring(rx_queue, rx_work_limit); #endif |