diff options
author | Sachin Saxena <sachin.saxena@freescale.com> | 2013-03-04 10:24:31 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-04-15 15:47:11 (GMT) |
commit | 0aeda5a8344a29cf1e250dc224e4af3817a981a4 (patch) | |
tree | b848d0a7a2b52b644c7de218befc87d2c56f7188 | |
parent | 95c2fb2843acdb1b2b85d98120d75f13efa97216 (diff) | |
download | linux-fsl-qoriq-0aeda5a8344a29cf1e250dc224e4af3817a981a4.tar.xz |
gianfar: Add hooks for offloading packets to ASF
Change-Id: I3f7ba9fd42e0aa320bc59ecd5062d0e46f77c21c
Signed-off-by: Rajan Gupta <rajan.gupta@freescale.com>
Signed-off-by: Sachin Saxena <sachin.saxena@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/1336
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 21 |
2 files changed, 52 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 315db4e..492eec9 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -101,6 +101,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"; @@ -2212,6 +2219,11 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; +#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 /* TOE=1 frames larger than 2500 bytes may see excess delays * before start of transmission. */ @@ -3003,6 +3015,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); +#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_RX && + fcb->flags & RXFCB_VLN) + __vlan_hwaccel_put_tag(skb, 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 148a477..5c482e9 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -90,6 +90,27 @@ 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 |