summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlok Makhariya <B46187@freescale.com>2014-03-28 12:27:26 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-03-31 18:56:06 (GMT)
commite054a24a775f4c91925693bcfefb4b9396a37345 (patch)
tree6b9b604b7909be551d85ca2f46db7125b829e3ce
parentc98664cd2bb7dada1aaec9f037d59ac90d5e4820 (diff)
downloadlinux-fsl-qoriq-e054a24a775f4c91925693bcfefb4b9396a37345.tar.xz
ASF : Adding hooks to offload packets to ASF
Hooks are added in asf_gianfar.c to offload packet to ASF. Change-Id: Id553d25510d18d7918d02e8375c5fc89d7e6e9a1 CQ ID : ENGR00304852 Signed-off-by: Alok Makhariya <B46187@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/10354 Reviewed-by: Rajan Gupta <rajan.gupta@freescale.com> Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r--drivers/net/ethernet/freescale/asf_gianfar.c25
-rw-r--r--drivers/net/ethernet/freescale/asf_gianfar.h20
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/asf_gianfar.c b/drivers/net/ethernet/freescale/asf_gianfar.c
index fba42ba..75102b8 100644
--- a/drivers/net/ethernet/freescale/asf_gianfar.c
+++ b/drivers/net/ethernet/freescale/asf_gianfar.c
@@ -26,6 +26,12 @@
#define GFAR_RXB_REC_SZ (DEFAULT_RX_BUFFER_SIZE + RXBUF_ALIGNMENT)
+devfp_hook_t devfp_rx_hook;
+EXPORT_SYMBOL(devfp_rx_hook);
+
+devfp_hook_t devfp_tx_hook;
+EXPORT_SYMBOL(devfp_tx_hook);
+
static inline void gfar_recycle_skb(struct sk_buff *skb)
{
struct sk_buff_head *h = &__get_cpu_var(skb_recycle_list);
@@ -81,6 +87,21 @@ 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 (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;
+ }
+
/* Tell the skb what kind of packet this is */
skb->protocol = eth_type_trans(skb, dev);
@@ -112,6 +133,10 @@ int gfar_asf_start_xmit(struct sk_buff *skb, struct net_device *dev)
int skb_curtx = 0;
unsigned int nr_frags, nr_txbds, bytes_sent, fcb_len = 0;
+ if (devfp_tx_hook && (skb->pkt_type != PACKET_FASTROUTE))
+ if (devfp_tx_hook(skb, dev) == AS_FP_STOLEN)
+ return 0;
+
rq = smp_processor_id();
tx_queue = priv->tx_queue[rq];
diff --git a/drivers/net/ethernet/freescale/asf_gianfar.h b/drivers/net/ethernet/freescale/asf_gianfar.h
index e53bcca..3abb1ea 100644
--- a/drivers/net/ethernet/freescale/asf_gianfar.h
+++ b/drivers/net/ethernet/freescale/asf_gianfar.h
@@ -35,4 +35,24 @@ int gfar_asf_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
extern void gfar_asf_process_frame(struct net_device *dev, struct sk_buff *skb,
int amount_pull, struct napi_struct *napi);
+#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 /* __ASF_GIANFAR_H */