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 | |
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')
-rw-r--r-- | drivers/net/ethernet/freescale/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 43 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 25 |
3 files changed, 64 insertions, 6 deletions
diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile index 0ffa880..ab0577f 100644 --- a/drivers/net/ethernet/freescale/Makefile +++ b/drivers/net/ethernet/freescale/Makefile @@ -18,8 +18,10 @@ obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o gianfar_driver-objs := gianfar.o \ gianfar_ethtool.o ifeq ($(CONFIG_GIANFAR),y) +ifdef CONFIG_PPC obj-$(CONFIG_AS_FASTPATH) += asf_gianfar.o endif +endif gianfar_driver-$(CONFIG_FSL_GIANFAR_1588) += gianfar_1588.o gianfar_driver-$(CONFIG_GFAR_DBG_LOOP) += gianfar_debugfs.o obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o 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 diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 042a698..802bef4 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -55,6 +55,27 @@ #include <linux/circ_buf.h> #endif +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_ARM) +#define AS_FP_PROCEED 1 +#define AS_FP_STOLEN 2 + +typedef int (*devfp_hook_t)(struct sk_buff *skb, struct net_device *dev); +extern devfp_hook_t devfp_rx_hook; +extern devfp_hook_t devfp_tx_hook; + +static inline int devfp_register_rx_hook(devfp_hook_t hook) +{ + devfp_rx_hook = hook; + return 0; +} + +static inline int devfp_register_tx_hook(devfp_hook_t hook) +{ + devfp_tx_hook = hook; + return 0; +} +#endif + struct ethtool_flow_spec_container { struct ethtool_rx_flow_spec fs; struct list_head list; @@ -80,7 +101,7 @@ struct ethtool_rx_list { /* Number of bytes to align the rx bufs to */ #define RXBUF_ALIGNMENT 64 -#ifdef CONFIG_AS_FASTPATH +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_PPC) /* Headroom required for IPSec processing in ASF */ #define EXTRA_HEADROOM 128 #endif @@ -1719,7 +1740,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) static inline void gfar_align_skb(struct sk_buff *skb) { -#ifdef CONFIG_AS_FASTPATH +#if defined(CONFIG_AS_FASTPATH) && defined(CONFIG_PPC) /* Reserving the extra headroom required for ASF IPSec processing */ skb_reserve(skb, EXTRA_HEADROOM); #endif |