[qca-nss-drv] Callback notifier for GRE rx packet.
Notifier call back register/unregister.
Change-Id: I9350a2a52b1c92ce374ee719485f4e35df5ef82e
Signed-off-by: ratheesh kannoth <rkannoth@codeaurora.org>
diff --git a/exports/nss_gre.h b/exports/nss_gre.h
index a6fec7c..d2a2d19 100644
--- a/exports/nss_gre.h
+++ b/exports/nss_gre.h
@@ -21,6 +21,9 @@
#ifndef _NSS_GRE_H_
#define _NSS_GRE_H_
+#include <net/ip_tunnels.h>
+#include <net/ip6_tunnel.h>
+
/**
* @addtogroup nss_gre_subsystem
* @{
@@ -48,6 +51,21 @@
#define NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE 0x00000800 /**< Use provided next_node instead of existing next node. */
/**
+ * nss_gre_info
+ * GRE private information.
+ */
+struct nss_gre_info {
+ union {
+ struct ip_tunnel t4; /**< IPv4 tunnel */
+ struct ip6_tnl t6; /**< IPv6 tunnel */
+ } t;
+ int nss_if_number; /**< NSS interface number */
+ struct net_device *next_dev; /**< Next net device */
+ uint8_t gre_hlen; /**< GRE header length */
+ uint8_t pad_len; /**< Pad length */
+};
+
+/**
* nss_gre_msg_types
* Message types for GRE requests and responses.
*/
@@ -215,8 +233,8 @@
* nss_ctx_instance \n
* nss_gre_msg
*
- * @param[in] nss_ctx Pointer to the NSS context.
- * @param[in] msg Pointer to the message data.
+ * @param[in] nss_ctx Pointer to the NSS context.
+ * @param[in] msg Pointer to the message data.
*
* @return
* Status of the Tx operation.
@@ -231,8 +249,8 @@
* nss_ctx_instance \n
* nss_gre_msg
*
- * @param[in] nss_ctx Pointer to the NSS context.
- * @param[in] msg Pointer to the message data.
+ * @param[in] nss_ctx Pointer to the NSS context.
+ * @param[in] msg Pointer to the message data.
*
* @return
* Status of the Tx operation.
@@ -247,9 +265,9 @@
* nss_ctx_instance \n
* sk_buff
*
- * @param[in] nss_ctx Pointer to the NSS context.
- * @param[in] if_num Nss interface number.
- * @param[in] skb Pointer to sk_buff.
+ * @param[in] nss_ctx Pointer to the NSS context.
+ * @param[in] if_num Nss interface number.
+ * @param[in] skb Pointer to sk_buff.
*
* @return Tx status
*/
@@ -282,11 +300,10 @@
* nss_gre_base_debug_stats_get
* Gets NSS GRE base debug statistics.
*
- * @param[in] stats_mem Pointer to memory to which stats should be copied.
- * @param[in] size Stats memory size.
+ * @param[in] stats_mem Pointer to memory to which stats should be copied.
+ * @param[in] size Stats memory size.
* @param[out] stats_mem Pointer to the memory address, which must be large
* enough to hold all the statistics.
- *
* @return
* None.
*/
@@ -296,11 +313,10 @@
* nss_gre_session_debug_stats_get
* Gets NSS GRE session debug statistics.
*
- * @param[in] stats_mem Pointer to memory to which stats should be copied.
- * @param[in] size Stats memory size.
+ * @param[in] stats_mem Pointer to memory to which stats should be copied.
+ * @param[in] size Stats memory size.
* @param[out] stats_mem Pointer to the memory address, which must be large
* enough to hold all the statistics.
- *
* @return
* None.
*/
@@ -316,11 +332,11 @@
* nss_gre_msg_callback_t \n
* net_device
*
- * @param[in] if_num NSS interface number.
- * @param[in] nss_gre_data_callback Callback for the data.
- * @param[in] msg_callback Callback for the message.
- * @param[in] netdev Pointer to the associated network device.
- * @param[in] features Socket buffer types supported by this interface.
+ * @param[in] if_num NSS interface number.
+ * @param[in] nss_gre_data_callback Callback for the data.
+ * @param[in] msg_callback Callback for the message.
+ * @param[in] netdev Pointer to the associated network device.
+ * @param[in] features Socket buffer types supported by this interface.
*
* @return
* Pointer to the NSS core context.
@@ -371,6 +387,47 @@
extern void nss_gre_register_handler(void);
/**
+ * Callback function for updating stats.
+ *
+ * @datatypes
+ * net_device \n
+ * sk_buff \n
+ *
+ * @param[in] netdev Pointer to the associated network device.
+ * @param[in] skb Pointer to the data socket buffer.
+ *
+ * @return
+ * None.
+ */
+typedef void (*nss_gre_pkt_callback_t)(struct net_device *netdev, struct sk_buff *skb);
+
+/**
+ * nss_gre_register_pkt_callback
+ * Register for rx packet call back.
+ *
+ * @datatypes
+ * nss_gre_pkt_callback_t
+ *
+ * @param[in] cb Call back function which needs to be registered.
+ *
+ * @return
+ * None.
+ */
+extern void nss_gre_register_pkt_callback(nss_gre_pkt_callback_t cb);
+
+/**
+ * nss_gre_unregister_pkt_callback
+ * Unregister for rx packet call back.
+ *
+ * @datatypes
+ * nss_gre_pkt_callback_t
+ *
+ * @return
+ * None.
+ */
+extern void nss_gre_unregister_pkt_callback(void);
+
+/**
* @}
*/
diff --git a/nss_core.h b/nss_core.h
index 23243d4..7ab62a3 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -1127,6 +1127,8 @@
/* map-t interface event callback function */
nss_gre_msg_callback_t gre_msg_callback;
/* gre interface event callback function */
+ nss_gre_data_callback_t gre_data_callback;
+ /* gre data callback function */
nss_tunipip6_msg_callback_t tunipip6_msg_callback;
/* ipip6 tunnel interface event callback function */
nss_pptp_msg_callback_t pptp_msg_callback;
diff --git a/nss_gre.c b/nss_gre.c
index a86bbd1..78704ef 100644
--- a/nss_gre.c
+++ b/nss_gre.c
@@ -36,6 +36,29 @@
static struct nss_stats_gre_session_debug session_debug_stats[NSS_GRE_MAX_DEBUG_SESSION_STATS];
static struct nss_stats_gre_base_debug base_debug_stats;
+static atomic64_t pkt_cb_addr = ATOMIC64_INIT(0);
+
+/*
+ * nss_gre_rx_handler()
+ * GRE rx handler.
+ */
+static void nss_gre_rx_handler(struct net_device *dev, struct sk_buff *skb,
+ __attribute__((unused)) struct napi_struct *napi)
+{
+ nss_gre_data_callback_t cb;
+
+ nss_gre_pkt_callback_t scb = (nss_gre_pkt_callback_t)(unsigned long)atomic64_read(&pkt_cb_addr);
+ if (unlikely(scb)) {
+ struct nss_gre_info *info = (struct nss_gre_info *)netdev_priv(dev);
+ if (likely(info->next_dev)) {
+ scb(info->next_dev, skb);
+ }
+ }
+
+ cb = nss_top_main.gre_data_callback;
+ cb(dev, skb, 0);
+}
+
/*
* nss_gre_session_debug_stats_sync()
* debug statistics sync for GRE session.
@@ -56,34 +79,10 @@
}
/*
- * nss_gre_session_debug_stats_get()
- * Get GRE session debug statistics.
- */
-void nss_gre_session_debug_stats_get(void *stats_mem, int size)
-{
- struct nss_stats_gre_session_debug *stats = (struct nss_stats_gre_session_debug *)stats_mem;
- int i;
-
- if (!stats || (size < (sizeof(struct nss_stats_gre_session_debug) * NSS_STATS_GRE_SESSION_DEBUG_MAX))) {
- nss_warning("No memory to copy gre stats");
- return;
- }
-
- spin_lock_bh(&nss_gre_stats_lock);
- for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
- if (session_debug_stats[i].valid) {
- memcpy(stats, &session_debug_stats[i], sizeof(struct nss_stats_gre_session_debug));
- stats++;
- }
- }
- spin_unlock_bh(&nss_gre_stats_lock);
-}
-
-/*
* nss_gre_base_debug_stats_sync()
* Debug statistics sync for GRE base node.
*/
-void nss_gre_base_debug_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats)
+static void nss_gre_base_debug_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats)
{
int i;
spin_lock_bh(&nss_gre_stats_lock);
@@ -94,29 +93,6 @@
}
/*
- * nss_gre_base_debug_stats_get()
- * Get GRE debug base statistics.
- */
-void nss_gre_base_debug_stats_get(void *stats_mem, int size)
-{
- struct nss_stats_gre_base_debug *stats = (struct nss_stats_gre_base_debug *)stats_mem;
-
- if (!stats) {
- nss_warning("No memory to copy GRE base stats\n");
- return;
- }
-
- if (size < sizeof(struct nss_stats_gre_base_debug)) {
- nss_warning("Not enough memory to copy GRE base stats\n");
- return;
- }
-
- spin_lock_bh(&nss_gre_stats_lock);
- memcpy(stats, &base_debug_stats, sizeof(struct nss_stats_gre_base_debug));
- spin_unlock_bh(&nss_gre_stats_lock);
-}
-
-/*
* nss_gre_msg_handler()
* Handle NSS -> HLOS messages for GRE
*/
@@ -219,6 +195,73 @@
}
/*
+ * nss_gre_session_debug_stats_get()
+ * Get GRE session debug statistics.
+ */
+void nss_gre_session_debug_stats_get(void *stats_mem, int size)
+{
+ struct nss_stats_gre_session_debug *stats = (struct nss_stats_gre_session_debug *)stats_mem;
+ int i;
+
+ if (!stats || (size < (sizeof(struct nss_stats_gre_session_debug) * NSS_STATS_GRE_SESSION_DEBUG_MAX))) {
+ nss_warning("No memory to copy gre stats");
+ return;
+ }
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) {
+ if (session_debug_stats[i].valid) {
+ memcpy(stats, &session_debug_stats[i], sizeof(struct nss_stats_gre_session_debug));
+ stats++;
+ }
+ }
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_base_debug_stats_get()
+ * Get GRE debug base statistics.
+ */
+void nss_gre_base_debug_stats_get(void *stats_mem, int size)
+{
+ struct nss_stats_gre_base_debug *stats = (struct nss_stats_gre_base_debug *)stats_mem;
+
+ if (!stats) {
+ nss_warning("No memory to copy GRE base stats\n");
+ return;
+ }
+
+ if (size < sizeof(struct nss_stats_gre_base_debug)) {
+ nss_warning("Not enough memory to copy GRE base stats\n");
+ return;
+ }
+
+ spin_lock_bh(&nss_gre_stats_lock);
+ memcpy(stats, &base_debug_stats, sizeof(struct nss_stats_gre_base_debug));
+ spin_unlock_bh(&nss_gre_stats_lock);
+}
+
+/*
+ * nss_gre_register_pkt_callback()
+ * Register for data callback.
+ */
+void nss_gre_register_pkt_callback(nss_gre_pkt_callback_t cb)
+{
+ atomic64_set(&pkt_cb_addr, (unsigned long)cb);
+}
+EXPORT_SYMBOL(nss_gre_register_pkt_callback);
+
+/*
+ * nss_gre_unregister_pkt_callback()
+ * Unregister for data callback.
+ */
+void nss_gre_unregister_pkt_callback()
+{
+ atomic64_set(&pkt_cb_addr, 0);
+}
+EXPORT_SYMBOL(nss_gre_unregister_pkt_callback);
+
+/*
* nss_gre_tx_msg()
* Transmit a GRE message to NSS firmware
*/
@@ -359,7 +402,7 @@
* nss_gre_register_if()
* Register data and message handlers for GRE.
*/
-struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, nss_gre_data_callback_t gre_callback,
+struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, nss_gre_data_callback_t data_callback,
nss_gre_msg_callback_t event_callback, struct net_device *netdev, uint32_t features)
{
struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id];
@@ -369,11 +412,12 @@
nss_assert(nss_is_dynamic_interface(if_num));
nss_ctx->subsys_dp_register[if_num].ndev = netdev;
- nss_ctx->subsys_dp_register[if_num].cb = gre_callback;
+ nss_ctx->subsys_dp_register[if_num].cb = nss_gre_rx_handler;
nss_ctx->subsys_dp_register[if_num].app_data = netdev;
nss_ctx->subsys_dp_register[if_num].features = features;
nss_top_main.gre_msg_callback = event_callback;
+ nss_top_main.gre_data_callback = data_callback;
nss_core_register_handler(if_num, nss_gre_msg_handler, NULL);