[qca-nss-drv] Add acceleration mode control sysctl node
Change-Id: I9f534237fd80de7030682a1e553b3ec5b7fba77d
Signed-off-by: Stephen Wang <wstephen@codeaurora.org>
diff --git a/nss_ipv4.c b/nss_ipv4.c
index 4cfac64..73df6d8 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -21,8 +21,23 @@
#include <linux/sysctl.h>
#include "nss_tx_rx_common.h"
+#define NSS_IPV4_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv4 messages */
+
+/*
+ * Private data structure for ipv4 configure messages
+ */
+struct nss_ipv4_cfg_pvt {
+ struct semaphore sem; /* Semaphore structure */
+ struct completion complete; /* completion structure */
+ int current_value; /* valid entry */
+ int response; /* Response from FW */
+};
+
int nss_ipv4_conn_cfg __read_mostly = NSS_DEFAULT_NUM_CONN;
-static struct nss_conn_cfg_pvt i4cfgp;
+int nss_ipv4_accel_mode_cfg __read_mostly = 1;
+
+static struct nss_ipv4_cfg_pvt i4_conn_cfgp;
+static struct nss_ipv4_cfg_pvt i4_accel_mode_cfgp;
/*
* Callback for conn_sync_many request message.
@@ -415,8 +430,8 @@
* Error, hence we are not updating the nss_ipv4_conn_cfg
* Restore the current_value to its previous state
*/
- i4cfgp.response = NSS_FAILURE;
- complete(&i4cfgp.complete);
+ i4_conn_cfgp.response = NSS_FAILURE;
+ complete(&i4_conn_cfgp.complete);
return;
}
@@ -425,8 +440,8 @@
* saved at the sysctl handler.
*/
nss_info("IPv4 connection configuration success: %d\n", nim->cm.error);
- i4cfgp.response = NSS_SUCCESS;
- complete(&i4cfgp.complete);
+ i4_conn_cfgp.response = NSS_SUCCESS;
+ complete(&i4_conn_cfgp.complete);
}
/*
@@ -442,19 +457,19 @@
/*
* Acquiring semaphore
*/
- down(&i4cfgp.sem);
+ down(&i4_conn_cfgp.sem);
/*
* Take snap shot of current value
*/
- i4cfgp.current_value = nss_ipv4_conn_cfg;
+ i4_conn_cfgp.current_value = nss_ipv4_conn_cfg;
/*
* Write the variable with user input
*/
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
if (ret || (!write)) {
- up(&i4cfgp.sem);
+ up(&i4_conn_cfgp.sem);
return ret;
}
@@ -469,7 +484,7 @@
/*
* Blocking call, wait till we get ACK for this msg.
*/
- ret = wait_for_completion_timeout(&i4cfgp.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ ret = wait_for_completion_timeout(&i4_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_ipv4_conn_cfg with
- * i4cfgp.num_conn_valid, which holds the user input
+ * i4_conn_cfgp.num_conn_valid, which holds the user input
*/
- if (NSS_FAILURE == i4cfgp.response) {
+ if (NSS_FAILURE == i4_conn_cfgp.response) {
goto failure;
}
- up(&i4cfgp.sem);
+ up(&i4_conn_cfgp.sem);
return 0;
failure:
/*
* Restore the current_value to its previous state
*/
- nss_ipv4_conn_cfg = i4cfgp.current_value;
- up(&i4cfgp.sem);
+ nss_ipv4_conn_cfg = i4_conn_cfgp.current_value;
+ up(&i4_conn_cfgp.sem);
return -EINVAL;
}
@@ -536,13 +551,106 @@
return 0;
}
+/*
+ * nss_ipv4_accel_mode_cfg_callback()
+ * call back function for the ipv4 acceleration mode configurate handler
+ */
+static void nss_ipv4_accel_mode_cfg_callback(void *app_data, struct nss_ipv4_msg *nim)
+{
+ if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("IPv4 acceleration mode configuration failed with error: %d\n", nim->cm.error);
+ i4_accel_mode_cfgp.response = NSS_FAILURE;
+ complete(&i4_accel_mode_cfgp.complete);
+ return;
+ }
+
+ nss_info("IPv4 acceleration mode configuration success\n");
+ i4_accel_mode_cfgp.response = NSS_SUCCESS;
+ complete(&i4_accel_mode_cfgp.complete);
+}
+
+/*
+ * nss_ipv4_accel_mode_cfg_handler()
+ * Configure acceleration mode for IPv4
+ */
+static int nss_ipv4_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_ipv4_msg nim;
+ struct nss_ipv4_accel_mode_cfg_msg *nipcm;
+ nss_tx_status_t nss_tx_status;
+ int ret = NSS_FAILURE;
+
+ /*
+ * Acquiring semaphore
+ */
+ down(&i4_accel_mode_cfgp.sem);
+
+ /*
+ * Take snap shot of current value
+ */
+ i4_accel_mode_cfgp.current_value = nss_ipv4_accel_mode_cfg;
+
+ /*
+ * Write the variable with user input
+ */
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret || (!write)) {
+ up(&i4_accel_mode_cfgp.sem);
+ return ret;
+ }
+
+ memset(&nim, 0, sizeof(struct nss_ipv4_msg));
+ nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_ACCEL_MODE_CFG_MSG,
+ sizeof(struct nss_ipv4_accel_mode_cfg_msg), nss_ipv4_accel_mode_cfg_callback, NULL);
+
+ nipcm = &nim.msg.accel_mode_cfg;
+ nipcm->mode = htonl(nss_ipv4_accel_mode_cfg);
+ nss_tx_status = nss_ipv4_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(&i4_accel_mode_cfgp.complete, msecs_to_jiffies(NSS_IPV4_TX_MSG_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
+ goto fail;
+ }
+
+ if (NSS_FAILURE == i4_accel_mode_cfgp.response) {
+ nss_warning("%p: accel mode configure failed\n", nss_ctx);
+ goto fail;
+ }
+
+ up(&i4_accel_mode_cfgp.sem);
+ return 0;
+
+fail:
+ nss_ipv4_accel_mode_cfg = i4_accel_mode_cfgp.current_value;
+ up(&i4_accel_mode_cfgp.sem);
+ return -EIO;
+}
+
static struct ctl_table nss_ipv4_table[] = {
{
.procname = "ipv4_conn",
.data = &nss_ipv4_conn_cfg,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &nss_ipv4_conn_cfg_handler,
+ .proc_handler = &nss_ipv4_conn_cfg_handler,
+ },
+ {
+ .procname = "ipv4_accel_mode",
+ .data = &nss_ipv4_accel_mode_cfg,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_ipv4_accel_mode_cfg_handler,
},
{ }
};
@@ -583,9 +691,11 @@
*/
void nss_ipv4_register_sysctl(void)
{
- sema_init(&i4cfgp.sem, 1);
- init_completion(&i4cfgp.complete);
- i4cfgp.current_value = nss_ipv4_conn_cfg;
+ sema_init(&i4_conn_cfgp.sem, 1);
+ init_completion(&i4_conn_cfgp.complete);
+
+ sema_init(&i4_accel_mode_cfgp.sem, 1);
+ init_completion(&i4_accel_mode_cfgp.complete);
/*
* Register sysctl table.