summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin Saxena <sachin.saxena@freescale.com>2013-03-04 10:24:31 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-15 15:47:11 (GMT)
commit0aeda5a8344a29cf1e250dc224e4af3817a981a4 (patch)
treeb848d0a7a2b52b644c7de218befc87d2c56f7188
parent95c2fb2843acdb1b2b85d98120d75f13efa97216 (diff)
downloadlinux-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.c31
-rw-r--r--drivers/net/ethernet/freescale/gianfar.h21
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