From bdf21e9de593a3aa36fac4e5dd7e493ebb48e64b Mon Sep 17 00:00:00 2001 From: Ganga Negi Date: Tue, 4 Nov 2014 13:44:32 +0530 Subject: 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 Change-Id: I2f6c8fe40a2223013559bc6909a60e8963aa2a96 CR:ENGR00338962 (cherry picked from commit 509f3236615193c77e07797cde4729ccc8cb2ef5) Reviewed-on: http://git.am.freescale.net:8181/23585 Tested-by: Review Code-CDREVIEW Reviewed-by: Claudiu Manoil Reviewed-by: Richard Schmitt 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 #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 -- cgit v0.10.2