[qca-nss-drv] Add new message type to request conn stats from FW
A new message type is added to request connection stats from FW.
The message may be larger then the ipv4/ipv6_msg so the caller
need to specify the actual size of the msg so ipv4/ipv6_tx can
allocate buffer that is large enough to carry this msg
Change-Id: Ia99ff4e3e42c669bf49aba630eb6f9dadb68d0c3
Signed-off-by: Stephen Wang <wstephen@codeaurora.org>
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index 3e8d786..eb103be 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -38,6 +38,7 @@
NSS_IPV4_RX_NODE_STATS_SYNC_MSG, /**< IPv4 generic statistics sync message */
NSS_IPV4_TX_CONN_CFG_RULE_MSG, /**< IPv4 number of connections supported rule message */
NSS_IPV4_TX_CREATE_MC_RULE_MSG, /**< IPv4 multicast create rule message */
+ NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG, /**< IPv4 request FW to send many conn sync message */
NSS_IPV4_MAX_MSG_TYPES, /**< IPv4 message max type number */
};
@@ -350,6 +351,20 @@
};
/**
+ * The NSS IPv4 conn sync many structure.
+ */
+struct nss_ipv4_conn_sync_many_msg {
+ /* Request */
+ uint16_t index; /**< Request conn stats from index */
+ uint16_t size; /**< The buf size of this msg */
+
+ /* Response */
+ uint16_t next; /**< FW response the next conn to be requested */
+ uint16_t count; /**< How many conn_sync included in this msg */
+ struct nss_ipv4_conn_sync conn_sync[]; /**< Array for the stats */
+};
+
+/**
* Exception events from bridge/route handler
*/
enum exception_events_ipv4 {
@@ -480,7 +495,8 @@
struct nss_ipv4_conn_sync conn_stats; /**< Message: connection stats sync */
struct nss_ipv4_node_sync node_stats; /**< Message: node stats sync */
struct nss_ipv4_rule_conn_cfg_msg rule_conn_cfg; /**< Message: rule connections supported */
- struct nss_ipv4_mc_rule_create_msg mc_rule_create; /**<Message: Multicast rule create */
+ struct nss_ipv4_mc_rule_create_msg mc_rule_create; /**< Message: Multicast rule create */
+ struct nss_ipv4_conn_sync_many_msg conn_stats_many; /**< Message: connection stats sync */
} msg;
};
@@ -511,6 +527,17 @@
extern nss_tx_status_t nss_ipv4_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *msg);
/**
+ * @brief Transmit an IPv4 message to the NSS with specified size
+ *
+ * @param nss_ctx NSS context
+ * @param msg The IPv4 message
+ * @param size Actual size of this msg
+ *
+ * @return nss_tx_status_t The status of the Tx operation
+ */
+extern nss_tx_status_t nss_ipv4_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *msg, uint32_t size);
+
+/**
* @brief Register a notifier callback for IPv4 messages from NSS
*
* @param cb The callback pointer
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index 8f6bbf7..b1b0d56 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -38,6 +38,7 @@
NSS_IPV6_RX_NODE_STATS_SYNC_MSG, /**< IPv6 generic statistics sync message */
NSS_IPV6_TX_CONN_CFG_RULE_MSG, /**< IPv6 connection cfg rule message */
NSS_IPV6_TX_CREATE_MC_RULE_MSG, /**< IPv6 create multicast rule message */
+ NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG, /**< IPv6 connection stats sync many message */
NSS_IPV6_MAX_MSG_TYPES,
};
@@ -394,6 +395,20 @@
};
/**
+ * NSS IPv6 connection stats sync many structure
+ */
+struct nss_ipv6_conn_sync_many_msg {
+ /* Request */
+ uint16_t index; /**< Request conn stats from index */
+ uint16_t size; /**< The buf size of this msg */
+
+ /* Response */
+ uint16_t next; /**< FW response the next conn to be requested */
+ uint16_t count; /**< How many conn_sync included in this msg */
+ struct nss_ipv6_conn_sync conn_sync[]; /**< Array for the stats */
+};
+
+/**
* NSS IPv6 node stats sync structure
*/
struct nss_ipv6_node_sync {
@@ -448,7 +463,8 @@
struct nss_ipv6_conn_sync conn_stats; /**< Message: stats sync */
struct nss_ipv6_node_sync node_stats; /**< Message: node stats sync */
struct nss_ipv6_rule_conn_cfg_msg rule_conn_cfg;/**< Message: rule conn cfg */
- struct nss_ipv6_mc_rule_create_msg mc_rule_create; /**<Message: Multicast rule create */
+ struct nss_ipv6_mc_rule_create_msg mc_rule_create; /**< Message: Multicast rule create */
+ struct nss_ipv6_conn_sync_many_msg conn_stats_many; /**< Message: stats sync many */
} msg;
};
@@ -477,6 +493,17 @@
extern nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *msg);
/**
+ * @brief Transmit an IPv6 message to the NSS with specified size
+ *
+ * @param nss_ctx NSS context
+ * @param msg The IPv6 message
+ * @param size Actual size of this message
+ *
+ * @return nss_tx_status_t The status of the Tx operation
+ */
+extern nss_tx_status_t nss_ipv6_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *msg, uint32_t size);
+
+/**
* @brief Register a notifier callback for IPv6 messages from NSS
*
* @param cb The callback pointer
diff --git a/nss_ipv4.c b/nss_ipv4.c
index de99ece..6c73c7c 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -54,6 +54,27 @@
}
/*
+ * nss_ipv4_driver_conn_sync_many_update()
+ * Update driver specific information from the conn_sync_many messsage.
+ */
+static void nss_ipv4_driver_conn_sync_many_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync_many_msg *nicsm)
+{
+ int i;
+
+ /*
+ * Sanity check for the stats count
+ */
+ if (nicsm->count * sizeof(struct nss_ipv4_conn_sync) >= nicsm->size) {
+ nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
+ return;
+ }
+
+ for (i = 0; i < nicsm->count; i++) {
+ nss_ipv4_driver_conn_sync_update(nss_ctx, &nicsm->conn_sync[i]);
+ }
+}
+
+/*
* nss_ipv4_driver_node_sync_update)
* Update driver specific information from the messsage.
*/
@@ -138,6 +159,13 @@
*/
nss_ipv4_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
break;
+
+ case NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG:
+ /*
+ * Update driver statistics on connection sync many.
+ */
+ nss_ipv4_driver_conn_sync_many_update(nss_ctx, &nim->msg.conn_stats_many);
+ break;
}
/*
@@ -164,10 +192,10 @@
}
/*
- * nss_ipv4_tx()
- * Transmit an ipv4 message to the FW.
+ * nss_ipv4_tx_with_size()
+ * Transmit an ipv4 message to the FW with a specified size.
*/
-nss_tx_status_t nss_ipv4_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim)
+nss_tx_status_t nss_ipv4_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim, uint32_t size)
{
struct nss_ipv4_msg *nim2;
struct nss_cmn_msg *ncm = &nim->cm;
@@ -198,7 +226,12 @@
return NSS_TX_FAILURE;
}
- nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
+ if(size > PAGE_SIZE) {
+ nss_warning("%p: tx request size too large: %u", nss_ctx, size);
+ return NSS_TX_FAILURE;
+ }
+
+ nbuf = dev_alloc_skb(size);
if (unlikely(!nbuf)) {
NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
@@ -226,6 +259,15 @@
}
/*
+ * nss_ipv4_tx()
+ * Transmit an ipv4 message to the FW.
+ */
+nss_tx_status_t nss_ipv4_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim)
+{
+ return nss_ipv4_tx_with_size(nss_ctx, nim, NSS_NBUF_PAYLOAD_SIZE);
+}
+
+/*
**********************************
Register/Unregister/Miscellaneous APIs
**********************************
@@ -487,6 +529,7 @@
}
EXPORT_SYMBOL(nss_ipv4_tx);
+EXPORT_SYMBOL(nss_ipv4_tx_with_size);
EXPORT_SYMBOL(nss_ipv4_notify_register);
EXPORT_SYMBOL(nss_ipv4_notify_unregister);
EXPORT_SYMBOL(nss_ipv4_get_mgr);
diff --git a/nss_ipv6.c b/nss_ipv6.c
index 16067a4..ffd2032 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -53,6 +53,27 @@
}
/*
+ * nss_ipv6_driver_conn_sync_many_update()
+ * Update driver specific information from the conn_sync_many messsage.
+ */
+static void nss_ipv6_driver_conn_sync_many_update(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm)
+{
+ uint32_t i;
+
+ /*
+ * Sanity check for the stats count
+ */
+ if (nicsm->count * sizeof(struct nss_ipv6_conn_sync) >= nicsm->size) {
+ nss_warning("%p: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size);
+ return;
+ }
+
+ for (i = 0; i < nicsm->count; i++) {
+ nss_ipv6_driver_conn_sync_update(nss_ctx, &nicsm->conn_sync[i]);
+ }
+}
+
+/*
* nss_ipv6_driver_node_sync_update)
* Update driver specific information from the messsage.
*/
@@ -141,6 +162,13 @@
*/
nss_ipv6_driver_conn_sync_update(nss_ctx, &nim->msg.conn_stats);
break;
+
+ case NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG:
+ /*
+ * Update driver statistics on connection sync many.
+ */
+ nss_ipv6_driver_conn_sync_many_update(nss_ctx, &nim->msg.conn_stats_many);
+ break;
}
/*
@@ -167,10 +195,10 @@
}
/*
- * nss_ipv6_tx()
- * Transmit an ipv6 message to the FW.
+ * nss_ipv6_tx_with_size()
+ * Transmit an ipv6 message to the FW with a specified size.
*/
-nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
+nss_tx_status_t nss_ipv6_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim, uint32_t size)
{
struct nss_ipv6_msg *nim2;
struct nss_cmn_msg *ncm = &nim->cm;
@@ -201,7 +229,12 @@
return NSS_TX_FAILURE;
}
- nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
+ if(size > PAGE_SIZE) {
+ nss_warning("%p: tx request size too large: %u", nss_ctx, size);
+ return NSS_TX_FAILURE;
+ }
+
+ nbuf = dev_alloc_skb(size);
if (unlikely(!nbuf)) {
NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
nss_warning("%p: msg dropped as command allocation failed", nss_ctx);
@@ -229,6 +262,15 @@
}
/*
+ * nss_ipv6_tx()
+ * Transmit an ipv4 message to the FW.
+ */
+nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
+{
+ return nss_ipv6_tx_with_size(nss_ctx, nim, NSS_NBUF_PAYLOAD_SIZE);
+}
+
+/*
**********************************
Register/Unregister/Miscellaneous APIs
**********************************
@@ -487,6 +529,7 @@
}
EXPORT_SYMBOL(nss_ipv6_tx);
+EXPORT_SYMBOL(nss_ipv6_tx_with_size);
EXPORT_SYMBOL(nss_ipv6_notify_register);
EXPORT_SYMBOL(nss_ipv6_notify_unregister);
EXPORT_SYMBOL(nss_ipv6_get_mgr);