[qca-nss-drv] Add acceleration mode control sysctl node
Change-Id: I9f534237fd80de7030682a1e553b3ec5b7fba77d
Signed-off-by: Stephen Wang <wstephen@codeaurora.org>
diff --git a/nss_ipv6.c b/nss_ipv6.c
index e441718..5a62d16 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -20,8 +20,23 @@
*/
#include "nss_tx_rx_common.h"
+#define NSS_IPV6_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv4 messages */
+
+/*
+ * Private data structure for ipv6 configure messages
+ */
+struct nss_ipv6_cfg_pvt {
+ struct semaphore sem; /* Semaphore structure */
+ struct completion complete; /* completion structure */
+ int current_value; /* valid entry */
+ int response; /* Response from FW */
+};
+
int nss_ipv6_conn_cfg __read_mostly = NSS_DEFAULT_NUM_CONN;
-static struct nss_conn_cfg_pvt i6cfgp;
+int nss_ipv6_accel_mode_cfg __read_mostly = 1;
+
+static struct nss_ipv6_cfg_pvt i6_conn_cfgp;
+static struct nss_ipv6_cfg_pvt i6_accel_mode_cfgp;
/*
* Callback for conn_sync_many request message.
@@ -151,7 +166,7 @@
nss_ipv6_log_rx_msg(nim);
/*
- * Handle deprecated messages. Eventually these messages should be removed.
+ * Handle deprecated messages. Eventually these messages should be removed.
*/
switch (nim->cm.type) {
case NSS_IPV6_RX_NODE_STATS_SYNC_MSG:
@@ -417,8 +432,8 @@
* Error, hence we are not updating the nss_ipv6_conn_cfg
* Restore the current_value to its previous state
*/
- i6cfgp.response = NSS_FAILURE;
- complete(&i6cfgp.complete);
+ i6_conn_cfgp.response = NSS_FAILURE;
+ complete(&i6_conn_cfgp.complete);
return;
}
@@ -427,8 +442,8 @@
* saved at the sysctl handler.
*/
nss_info("IPv6 connection configuration success: %d\n", nim->cm.error);
- i6cfgp.response = NSS_SUCCESS;
- complete(&i6cfgp.complete);
+ i6_conn_cfgp.response = NSS_SUCCESS;
+ complete(&i6_conn_cfgp.complete);
}
@@ -445,16 +460,16 @@
/*
* Acquiring semaphore
*/
- down(&i6cfgp.sem);
+ down(&i6_conn_cfgp.sem);
/*
* Take a snapshot of the current value
*/
- i6cfgp.current_value = nss_ipv6_conn_cfg;
+ i6_conn_cfgp.current_value = nss_ipv6_conn_cfg;
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
if (ret || (!write)) {
- up(&i6cfgp.sem);
+ up(&i6_conn_cfgp.sem);
return ret;
}
@@ -469,7 +484,7 @@
/*
* Blocking call, wait till we get ACK for this msg.
*/
- ret = wait_for_completion_timeout(&i6cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ ret = wait_for_completion_timeout(&i6_conn_cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
if (ret == 0) {
nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
goto failure;
@@ -478,21 +493,21 @@
/*
* ACK/NACK received from NSS FW
* If ACK: Callback function will update nss_ipv6_conn_cfg with
- * i6cfgp.num_conn_valid, which holds the user input
+ * i6_conn_cfgp.num_conn_valid, which holds the user input
*/
- if (NSS_FAILURE == i6cfgp.response) {
+ if (NSS_FAILURE == i6_conn_cfgp.response) {
goto failure;
}
- up(&i6cfgp.sem);
+ up(&i6_conn_cfgp.sem);
return 0;
failure:
/*
* Restore the current_value to its previous state
*/
- nss_ipv6_conn_cfg = i6cfgp.current_value;
- up(&i6cfgp.sem);
+ nss_ipv6_conn_cfg = i6_conn_cfgp.current_value;
+ up(&i6_conn_cfgp.sem);
return -EINVAL;
}
@@ -538,13 +553,106 @@
return -EINVAL;
}
+/*
+ * nss_ipv6_accel_mode_cfg_callback()
+ * call back function for the ipv6 acceleration mode configurate handler
+ */
+static void nss_ipv6_accel_mode_cfg_callback(void *app_data, struct nss_ipv6_msg *nim)
+{
+ if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("IPv6 acceleration mode configuration failed with error: %d\n", nim->cm.error);
+ i6_accel_mode_cfgp.response = NSS_FAILURE;
+ complete(&i6_accel_mode_cfgp.complete);
+ return;
+ }
+
+ nss_info("IPv6 acceleration mode configuration success\n");
+ i6_accel_mode_cfgp.response = NSS_SUCCESS;
+ complete(&i6_accel_mode_cfgp.complete);
+}
+
+/*
+ * nss_ipv6_accel_mode_cfg_handler()
+ * Configure acceleration mode for IPv6
+ */
+static int nss_ipv6_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
+ struct nss_ipv6_msg nim;
+ struct nss_ipv6_accel_mode_cfg_msg *nipcm;
+ nss_tx_status_t nss_tx_status;
+ int ret = NSS_FAILURE;
+
+ /*
+ * Acquiring semaphore
+ */
+ down(&i6_accel_mode_cfgp.sem);
+
+ /*
+ * Take snap shot of current value
+ */
+ i6_accel_mode_cfgp.current_value = nss_ipv6_accel_mode_cfg;
+
+ /*
+ * Write the variable with user input
+ */
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret || (!write)) {
+ up(&i6_accel_mode_cfgp.sem);
+ return ret;
+ }
+
+ memset(&nim, 0, sizeof(struct nss_ipv6_msg));
+ nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_ACCEL_MODE_CFG_MSG,
+ sizeof(struct nss_ipv6_accel_mode_cfg_msg), nss_ipv6_accel_mode_cfg_callback, NULL);
+
+ nipcm = &nim.msg.accel_mode_cfg;
+ nipcm->mode = htonl(nss_ipv6_accel_mode_cfg);
+ nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
+
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: Send acceleration mode message failed\n", nss_ctx);
+ goto fail;
+ }
+
+ /*
+ * Blocking call, wait till we get ACK for this msg.
+ */
+ ret = wait_for_completion_timeout(&i6_accel_mode_cfgp.complete, msecs_to_jiffies(NSS_IPV6_TX_MSG_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
+ goto fail;
+ }
+
+ if (NSS_FAILURE == i6_accel_mode_cfgp.response) {
+ nss_warning("%p: accel mode configure failed\n", nss_ctx);
+ goto fail;
+ }
+
+ up(&i6_accel_mode_cfgp.sem);
+ return 0;
+
+fail:
+ nss_ipv6_accel_mode_cfg = i6_accel_mode_cfgp.current_value;
+ up(&i6_accel_mode_cfgp.sem);
+ return -EIO;
+}
+
static struct ctl_table nss_ipv6_table[] = {
{
.procname = "ipv6_conn",
.data = &nss_ipv6_conn_cfg,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &nss_ipv6_conn_cfg_handler,
+ .proc_handler = &nss_ipv6_conn_cfg_handler,
+ },
+ {
+ .procname = "ipv6_accel_mode",
+ .data = &nss_ipv6_accel_mode_cfg,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_ipv6_accel_mode_cfg_handler,
},
{ }
};
@@ -584,9 +692,11 @@
*/
void nss_ipv6_register_sysctl(void)
{
- sema_init(&i6cfgp.sem, 1);
- init_completion(&i6cfgp.complete);
- i6cfgp.current_value = nss_ipv6_conn_cfg;
+ sema_init(&i6_conn_cfgp.sem, 1);
+ init_completion(&i6_conn_cfgp.complete);
+
+ sema_init(&i6_accel_mode_cfgp.sem, 1);
+ init_completion(&i6_accel_mode_cfgp.complete);
/*
* Register sysctl table.
@@ -610,7 +720,7 @@
/*
* nss_ipv6_msg_init()
- * Initialize IPv6 message.
+ * Initialize IPv6 message.
*/
void nss_ipv6_msg_init(struct nss_ipv6_msg *nim, uint16_t if_num, uint32_t type, uint32_t len,
nss_ipv6_msg_callback_t cb, void *app_data)