[qca-nss-drv] Remove dscp2pri as a special node

The dscp2pri package has been made into a simple helper package
in NSS FW to enable easy re-use. Since it is no longer a standalone
node, the dscp to priority mappings will now be sent through the
user nodes, namely ipv4 and ipv6.

Change-Id: I00330611a3b1378be827bb79fb2dab8794546f01
Signed-off-by: Sakthi Vignesh Radhakrishnan <sradhakr@codeaurora.org>
diff --git a/nss_ipv4.c b/nss_ipv4.c
index c655a35..e6dfe1a 100644
--- a/nss_ipv4.c
+++ b/nss_ipv4.c
@@ -20,18 +20,20 @@
  */
 #include <linux/sysctl.h>
 #include "nss_tx_rx_common.h"
+#include "nss_dscp_map.h"
 
 #define NSS_IPV4_TX_MSG_TIMEOUT 1000	/* 1 sec timeout for IPv4 messages */
 
 /*
- * Private data structure for ipv4 configure messages
+ * Private data structure for ipv4 configuration
  */
-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 */
-};
+struct nss_ipv4_pvt {
+	struct semaphore sem;		/* Semaphore structure */
+	struct completion complete;	/* completion structure */
+	int response;			/* Response from FW */
+	void *cb;			/* Original cb for sync msgs */
+	void *app_data;			/* Original app_data for sync msgs */
+} nss_ipv4_pvt;
 
 /*
  * Private data structure for ipv4 connection information.
@@ -46,7 +48,7 @@
 int nss_ipv4_conn_cfg __read_mostly = NSS_DEFAULT_NUM_CONN;
 int nss_ipv4_accel_mode_cfg __read_mostly = 1;
 
-static struct nss_ipv4_cfg_pvt i4_accel_mode_cfgp;
+static struct nss_dscp_map_entry mapping[NSS_DSCP_MAP_ARRAY_SIZE];
 
 /*
  * Callback for conn_sync_many request message.
@@ -54,45 +56,17 @@
 nss_ipv4_msg_callback_t nss_ipv4_conn_sync_many_msg_cb = NULL;
 
 /*
- * nss_ipv4_max_conn_count()
- *	Return the maximum number of IPv4 connections that the NSS acceleration engine supports.
+ * nss_ipv4_dscp_map_usage()
+ *	Help function shows the usage of the command.
  */
-int nss_ipv4_max_conn_count(void)
+static inline void nss_ipv4_dscp_map_usage(void)
 {
-	return nss_ipv4_conn_cfg;
+	nss_info_always("\nUsage:\n");
+	nss_info_always("echo <dscp> <action> <prio> > /proc/sys/dev/nss/ipv4cfg/ipv4_dscp_map\n\n");
+	nss_info_always("dscp[0-63] action[0-%u] prio[0-%u]:\n\n",
+				NSS_IPV4_DSCP_MAP_ACTION_MAX - 1,
+				NSS_DSCP_MAP_PRIORITY_MAX - 1);
 }
-EXPORT_SYMBOL(nss_ipv4_max_conn_count);
-
-/*
- * nss_ipv4_conn_inquiry()
- *	Inquiry if a connection has been established in NSS FW
- */
-nss_tx_status_t nss_ipv4_conn_inquiry(struct nss_ipv4_5tuple *ipv4_5t_p,
-				nss_ipv4_msg_callback_t cb)
-{
-	nss_tx_status_t nss_tx_status;
-	struct nss_ipv4_msg nim;
-	struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
-
-	/*
-	 * Initialize inquiry message structure.
-	 * This is async message and the result will be returned
-	 * to the caller by the msg_callback passed in.
-	 */
-	memset(&nim, 0, sizeof(nim));
-	nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE,
-			NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
-			sizeof(struct nss_ipv4_inquiry_msg),
-			cb, NULL);
-	nim.msg.inquiry.rr.tuple = *ipv4_5t_p;
-	nss_tx_status = nss_ipv4_tx(nss_ctx, &nim);
-	if (nss_tx_status != NSS_TX_SUCCESS) {
-		nss_warning("%p: Send inquiry message failed\n", ipv4_5t_p);
-	}
-
-	return nss_tx_status;
-}
-EXPORT_SYMBOL(nss_ipv4_conn_inquiry);
 
 /*
  * nss_ipv4_driver_conn_sync_update()
@@ -257,6 +231,88 @@
 }
 
 /*
+ * nss_ipv4_tx_sync_callback()
+ *	Callback to handle the completion of synchronous tx messages.
+ */
+static void nss_ipv4_tx_sync_callback(void *app_data, struct nss_ipv4_msg *nim)
+{
+	nss_ipv4_msg_callback_t callback = (nss_ipv4_msg_callback_t)nss_ipv4_pvt.cb;
+	void *data = nss_ipv4_pvt.app_data;
+
+	nss_ipv4_pvt.cb = NULL;
+	nss_ipv4_pvt.app_data = NULL;
+
+	if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
+		nss_warning("ipv4 error response %d\n", nim->cm.response);
+		nss_ipv4_pvt.response = NSS_TX_FAILURE;
+	} else {
+		nss_ipv4_pvt.response = NSS_TX_SUCCESS;
+	}
+
+	if (callback) {
+		callback(data, nim);
+	}
+
+	complete(&nss_ipv4_pvt.complete);
+}
+
+/*
+ * nss_ipv4_dscp_action_get()
+ *	Gets the action mapped to dscp.
+ */
+enum nss_ipv4_dscp_map_actions nss_ipv4_dscp_action_get(uint8_t dscp)
+{
+	if (dscp > NSS_DSCP_MAP_ARRAY_SIZE) {
+		nss_warning("dscp:%u invalid\n", dscp);
+		return NSS_IPV4_DSCP_MAP_ACTION_MAX;
+	}
+
+	return mapping[dscp].action;
+}
+EXPORT_SYMBOL(nss_ipv4_dscp_action_get);
+
+/*
+ * nss_ipv4_max_conn_count()
+ *	Return the maximum number of IPv4 connections that the NSS acceleration engine supports.
+ */
+int nss_ipv4_max_conn_count(void)
+{
+	return nss_ipv4_conn_cfg;
+}
+EXPORT_SYMBOL(nss_ipv4_max_conn_count);
+
+/*
+ * nss_ipv4_conn_inquiry()
+ *	Inquiry if a connection has been established in NSS FW
+ */
+nss_tx_status_t nss_ipv4_conn_inquiry(struct nss_ipv4_5tuple *ipv4_5t_p,
+				nss_ipv4_msg_callback_t cb)
+{
+	nss_tx_status_t nss_tx_status;
+	struct nss_ipv4_msg nim;
+	struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
+
+	/*
+	 * Initialize inquiry message structure.
+	 * This is async message and the result will be returned
+	 * to the caller by the msg_callback passed in.
+	 */
+	memset(&nim, 0, sizeof(nim));
+	nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE,
+			NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
+			sizeof(struct nss_ipv4_inquiry_msg),
+			cb, NULL);
+	nim.msg.inquiry.rr.tuple = *ipv4_5t_p;
+	nss_tx_status = nss_ipv4_tx(nss_ctx, &nim);
+	if (nss_tx_status != NSS_TX_SUCCESS) {
+		nss_warning("%p: Send inquiry message failed\n", ipv4_5t_p);
+	}
+
+	return nss_tx_status;
+}
+EXPORT_SYMBOL(nss_ipv4_conn_inquiry);
+
+/*
  * nss_ipv4_tx_with_size()
  *	Transmit an ipv4 message to the FW with a specified size.
  */
@@ -339,6 +395,41 @@
 EXPORT_SYMBOL(nss_ipv4_tx);
 
 /*
+ * nss_ipv4_tx_sync()
+ *	Transmit a synchronous ipv4 message to the FW.
+ */
+nss_tx_status_t nss_ipv4_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim)
+{
+	nss_tx_status_t status;
+	int ret = 0;
+
+	down(&nss_ipv4_pvt.sem);
+	nss_ipv4_pvt.cb = (void *)nim->cm.cb;
+	nss_ipv4_pvt.app_data = (void *)nim->cm.app_data;
+
+	nim->cm.cb = (nss_ptr_t)nss_ipv4_tx_sync_callback;
+	nim->cm.app_data = (nss_ptr_t)NULL;
+
+	status = nss_ipv4_tx(nss_ctx, nim);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: nss ipv4 msg tx failed\n", nss_ctx);
+		up(&nss_ipv4_pvt.sem);
+		return status;
+	}
+
+	ret = wait_for_completion_timeout(&nss_ipv4_pvt.complete, msecs_to_jiffies(NSS_IPV4_TX_MSG_TIMEOUT));
+	if (!ret) {
+		nss_warning("%p: IPv4 tx sync failed due to timeout\n", nss_ctx);
+		nss_ipv4_pvt.response = NSS_TX_FAILURE;
+	}
+
+	status = nss_ipv4_pvt.response;
+	up(&nss_ipv4_pvt.sem);
+	return status;
+}
+EXPORT_SYMBOL(nss_ipv4_tx_sync);
+
+/*
  **********************************
  Register/Unregister/Miscellaneous APIs
  **********************************
@@ -595,24 +686,6 @@
 }
 
 /*
- * 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_free_conn_tables()
  *	Frees memory allocated for connection tables
  */
@@ -642,69 +715,107 @@
 	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);
+	int current_value;
 
 	/*
 	 * Take snap shot of current value
 	 */
-	i4_accel_mode_cfgp.current_value = nss_ipv4_accel_mode_cfg;
+	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);
+		sizeof(struct nss_ipv4_accel_mode_cfg_msg), NULL, NULL);
 
 	nipcm = &nim.msg.accel_mode_cfg;
 	nipcm->mode = htonl(nss_ipv4_accel_mode_cfg);
-	nss_tx_status = nss_ipv4_tx(nss_ctx, &nim);
 
+	nss_tx_status = nss_ipv4_tx_sync(nss_ctx, &nim);
 	if (nss_tx_status != NSS_TX_SUCCESS) {
 		nss_warning("%p: Send acceleration mode message failed\n", nss_ctx);
-		goto fail;
+		nss_ipv4_accel_mode_cfg = current_value;
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/*
+ * nss_ipv4_dscp_map_cfg_handler()
+ *	Sysctl handler for dscp/pri mappings.
+ */
+static int nss_ipv4_dscp_map_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_dscp_map_parse out;
+	struct nss_ipv4_msg nim;
+	struct nss_ipv4_dscp2pri_cfg_msg *nipd2p;
+	nss_tx_status_t status;
+	int ret;
+
+	if (!write) {
+		return nss_dscp_map_print(ctl, buffer, lenp, ppos, mapping);
+	}
+
+	ret = nss_dscp_map_parse(ctl, buffer, lenp, ppos, &out);
+	if (ret) {
+		nss_warning("failed to parse dscp mapping:%d\n", ret);
+		nss_ipv4_dscp_map_usage();
+		return ret;
+	}
+
+	if (out.action >= NSS_IPV4_DSCP_MAP_ACTION_MAX) {
+		nss_warning("invalid action value: %d\n", out.action);
+		nss_ipv4_dscp_map_usage();
+		return -EINVAL;
+	}
+
+	memset(&nim, 0, sizeof(struct nss_ipv4_msg));
+	nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_DSCP2PRI_CFG_MSG,
+		sizeof(struct nss_ipv4_dscp2pri_cfg_msg), NULL, NULL);
+
+	nipd2p = &nim.msg.dscp2pri_cfg;
+	nipd2p->dscp = out.dscp;
+	nipd2p->priority = out.priority;
+
+	status = nss_ipv4_tx_sync(nss_ctx, &nim);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: ipv4 dscp2pri config message failed\n", nss_ctx);
+		return -EFAULT;
 	}
 
 	/*
-	 * Blocking call, wait till we get ACK for this msg.
+	 * NSS firmware acknowleged the configuration, so update the mapping
+	 * table on HOST side as well.
 	 */
-	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;
-	}
+	mapping[out.dscp].action = out.action;
+	mapping[out.dscp].priority = out.priority;
 
-	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_accel_mode",
-		.data			= &nss_ipv4_accel_mode_cfg,
-		.maxlen			= sizeof(int),
-		.mode			= 0644,
-		.proc_handler		= &nss_ipv4_accel_mode_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,
+	},
+	{
+		.procname	= "ipv4_dscp_map",
+		.data		= &mapping[NSS_DSCP_MAP_ARRAY_SIZE],
+		.maxlen		= sizeof(struct nss_dscp_map_entry),
+		.mode		= 0644,
+		.proc_handler	= &nss_ipv4_dscp_map_cfg_handler,
 	},
 	{ }
 };
@@ -744,8 +855,8 @@
  */
 void nss_ipv4_register_sysctl(void)
 {
-	sema_init(&i4_accel_mode_cfgp.sem, 1);
-	init_completion(&i4_accel_mode_cfgp.complete);
+	sema_init(&nss_ipv4_pvt.sem, 1);
+	init_completion(&nss_ipv4_pvt.complete);
 
 	/*
 	 * Register sysctl table.