From b018ec06c1b954a319a714dcbca3ae7c7b56f0d1 Mon Sep 17 00:00:00 2001 From: Alok Makhariya Date: Tue, 4 Feb 2014 09:00:43 +0530 Subject: GIANFAR : Porting ASF to non-DPA platform. Descripion : This patch add hooks for offloading packets to ASF. Change-Id: Icf765cbedf13cd92a5623e973b9e8111e22e34c6 CQID : ENGR00297244 Signed-off-by: Alok Makhariya Reviewed-on: http://git.am.freescale.net:8181/8517 Tested-by: Review Code-CDREVIEW Reviewed-by: Claudiu Manoil Reviewed-by: Jose Rivera diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index b14d790..922f347 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -104,6 +104,13 @@ #include "gianfar.h" +#ifdef CONFIG_AS_FASTPATH +devfp_hook_t devfp_rx_hook; +EXPORT_SYMBOL(devfp_rx_hook); + +devfp_hook_t devfp_tx_hook; +EXPORT_SYMBOL(devfp_tx_hook); +#endif #define TX_TIMEOUT (1*HZ) const char gfar_driver_version[] = "1.3"; @@ -2114,6 +2121,11 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; unsigned int nr_frags, nr_txbds, bytes_sent, fcb_len = 0; +#ifdef CONFIG_AS_FASTPATH + if (devfp_tx_hook && (skb->pkt_type != PACKET_FASTROUTE)) + if (devfp_tx_hook(skb, dev) == AS_FP_STOLEN) + return 0; +#endif rq = skb->queue_mapping; tx_queue = priv->tx_queue[rq]; txq = netdev_get_tx_queue(dev, rq); @@ -2675,6 +2687,7 @@ struct sk_buff *gfar_new_skb(struct net_device *dev) { return gfar_alloc_skb(dev); } +EXPORT_SYMBOL(gfar_new_skb); static inline void count_errors(unsigned short status, struct net_device *dev) { @@ -2765,6 +2778,26 @@ static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb, if (dev->features & NETIF_F_RXCSUM) gfar_rx_checksum(skb, fcb); +#ifdef CONFIG_AS_FASTPATH + if (devfp_rx_hook) { + + /* Drop the packet silently if IP Checksum is not correct */ + if ((fcb->flags & RXFCB_CIP) && (fcb->flags & RXFCB_EIP)) { + dev_kfree_skb_any(skb); + return; + } + + if (dev->features & NETIF_F_HW_VLAN_CTAG_RX && + fcb->flags & RXFCB_VLN) + __vlan_hwaccel_put_tag(skb, + htons(ETH_P_8021Q), 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); diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 114c58f..257d032 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -89,6 +89,28 @@ extern const char gfar_driver_version[]; /* MAXIMUM NUMBER OF GROUPS SUPPORTED */ #define MAXGROUPS 0x2 +#ifdef CONFIG_AS_FASTPATH +#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; +/* Overwrite the Rx/Tx Hooks pointers + * if already configured. + */ +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 + /* These need to be powers of 2 for this driver */ #define DEFAULT_TX_RING_SIZE 256 #define DEFAULT_RX_RING_SIZE 256 -- cgit v0.10.2