[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/Makefile b/Makefile
index 4cab556..e74d3fd 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,6 @@
nss_cmn.o \
nss_core.o \
nss_coredump.o \
- nss_dscp2pri.o \
nss_dtls.o \
nss_dynamic_interface.o \
nss_edma.o \
diff --git a/Makefile.fsm b/Makefile.fsm
index 3256ce7..241fa7d 100644
--- a/Makefile.fsm
+++ b/Makefile.fsm
@@ -13,7 +13,6 @@
nss_core.o \
nss_coredump.o \
nss_crypto.o \
- nss_dscp2pri.o \
nss_dtls.o \
nss_dynamic_interface.o \
nss_edma.o \
diff --git a/exports/nss_api_if.h b/exports/nss_api_if.h
index 5330f2d..74ec181 100644
--- a/exports/nss_api_if.h
+++ b/exports/nss_api_if.h
@@ -65,7 +65,6 @@
#include "nss_trustsec_tx.h"
#include "nss_vlan.h"
#include "nss_wifili_if.h"
-#include "nss_dscp2pri.h"
#include "nss_project.h"
#endif
@@ -201,9 +200,7 @@
/**< Special interface number for GRE. */
#define NSS_WIFILI_INTERFACE (NSS_SPECIAL_IF_START + 47)
/**< Special interface number for WIFILI. */
-#define NSS_DSCP2PRI_INTERFACE (NSS_SPECIAL_IF_START + 48)
- /**< Special interface number for dscp2pri. */
-#define NSS_PROJECT_INTERFACE (NSS_SPECIAL_IF_START + 49)
+#define NSS_PROJECT_INTERFACE (NSS_SPECIAL_IF_START + 48)
/**< Special interface number for project node. */
/**
diff --git a/exports/nss_dscp2pri.h b/exports/nss_dscp2pri.h
deleted file mode 100644
index 115f5b8..0000000
--- a/exports/nss_dscp2pri.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- **************************************************************************
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all copies.
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- **************************************************************************
- */
-
-/**
- * @file nss_dscp2pri.h
- * NSS DSCP to Priority mapping interface definitions.
- */
-
-#ifndef __NSS_DSCP2PRI_H
-#define __NSS_DSCP2PRI_H
-
-/**
- * @addtogroup nss_dscp2pri_subsystem
- * @{
- */
-
-/**
- * nss_dscp2pri_priority
- * Priority types mapped from DSCP values.
- */
-enum nss_dscp2pri_priority {
- NSS_DSCP2PRI_PRIORITY_VO = 0,
- NSS_DSCP2PRI_PRIORITY_VI,
- NSS_DSCP2PRI_PRIORITY_BE,
- NSS_DSCP2PRI_PRIORITY_BK,
- NSS_DSCP2PRI_PRIORITY_MAX,
-};
-
-/**
- * nss_dscp2pri_action
- * Action types mapped from DSCP values.
- */
-enum nss_dscp2pri_action {
- NSS_DSCP2PRI_ACTION_NOT_ACCEL = 0,
- NSS_DSCP2PRI_ACTION_ACCEL,
- NSS_DSCP2PRI_ACTION_MAX,
-};
-
-/**
- * nss_dscp2pri_metadata_types
- * Message types for dscp2pri requests.
- */
-enum nss_dscp2pri_metadata_types {
- NSS_DSCP2PRI_METADATA_TYPE_CONFIGURE_MAPPING,
- NSS_DSCP2PRI_METADATA_TYPE_MAX,
-};
-
-/**
- * nss_dscp2pri_configure_mapping
- * Send DSCP to Priority mapping message.
- */
-struct nss_dscp2pri_configure_mapping {
- uint8_t dscp; /**< Dscp value. */
- uint8_t priority; /**< Priority value. */
- uint8_t opaque; /**< Opaque value which is never used by NSS firmware. */
-};
-
-/**
- * nss_dscp2pri_msg
- * Data for sending dscp2pri messages.
- */
-struct nss_dscp2pri_msg {
- struct nss_cmn_msg cm; /**< Common message header. */
-
- /**
- * Payload of a dscp2pri message.
- */
- union {
- struct nss_dscp2pri_configure_mapping configure_mapping;
- /**< DSCP to Priority mapping configuration. */
- } msg; /**< Message payload. */
-};
-
-/**
- * Callback function for receiving dscp2pri messages.
- *
- * @datatypes
- * nss_dscp2pri_msg
- *
- * @param[in] app_data Pointer to the application context of the message.
- * @param[in] msg Pointer to the dscp2pri message.
- */
-typedef void (*nss_dscp2pri_msg_callback_t)(void *app_data, struct nss_dscp2pri_msg *msg);
-
-/**
- * nss_dscp2pri_get_action
- * Gets the action value of the DSCP.
- *
- * @param[in] dscp Value of the DSCP field.
- *
- * @return
- * Action value of the DSCP field.
- */
-enum nss_dscp2pri_action nss_dscp2pri_get_action(uint8_t dscp);
-
-/**
- * nss_dscp2pri_register_sysctl
- * Registers the dscp2pri sysctl entry to the sysctl tree.
- *
- * @return
- * None.
- */
-void nss_dscp2pri_register_sysctl(void);
-
-/**
- * nss_dscp2pri_unregister_sysctl
- * Deregisters the dscp2pri sysctl entry from the sysctl tree.
- *
- * @return
- * None.
- *
- * @dependencies
- * The system control must have been previously registered.
- */
-void nss_dscp2pri_unregister_sysctl(void);
-
-/**
- * nss_dscp2pri_register_handler
- * Registers the dscp2pri message handler.
- *
- * @return
- * None.
- */
-void nss_dscp2pri_register_handler(void);
-
-/**
- * @}
- */
-
-#endif
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index 11ca415..10880fa 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -45,9 +45,20 @@
NSS_IPV4_TX_ACCEL_MODE_CFG_MSG,
NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG,
NSS_IPV4_TX_CONN_TABLE_SIZE_MSG,
+ NSS_IPV4_TX_DSCP2PRI_CFG_MSG,
NSS_IPV4_MAX_MSG_TYPES,
};
+/**
+ * nss_ipv4_dscp_map_actions
+ * Action types mapped to DSCP values.
+ */
+enum nss_ipv4_dscp_map_actions {
+ NSS_IPV4_DSCP_MAP_ACTION_ACCEL,
+ NSS_IPV4_DSCP_MAP_ACTION_DONT_ACCEL,
+ NSS_IPV4_DSCP_MAP_ACTION_MAX,
+};
+
/*
* NSS IPv4 rule creation & rule update flags.
*/
@@ -540,6 +551,15 @@
};
/**
+ * nss_ipv4_dscp2pri_cfg_msg
+ * IPv4 dscp2pri configuration msg.
+ */
+struct nss_ipv4_dscp2pri_cfg_msg {
+ uint8_t dscp; /**< Value of DSCP. */
+ uint8_t priority; /**< Corresponding priority. */
+};
+
+/**
* exception_events_ipv4
* Exception events from the bridge or route handler.
*/
@@ -711,6 +731,8 @@
/**< Acceleration mode. */
struct nss_ipv4_inquiry_msg inquiry;
/**< Inquiry if a connection has created. */
+ struct nss_ipv4_dscp2pri_cfg_msg dscp2pri_cfg;
+ /**< Configure dscp2pri mapping. */
} msg; /**< Message payload. */
};
@@ -911,6 +933,17 @@
*/
extern void nss_ipv4_free_conn_tables(void);
+/**
+ * nss_ipv4_dscp_action_get
+ * Gets the action value of the DSCP.
+ *
+ * @param[in] dscp Value of the DSCP field.
+ *
+ * @return
+ * Action value of the DSCP field.
+ */
+enum nss_ipv4_dscp_map_actions nss_ipv4_dscp_action_get(uint8_t dscp);
+
/*
* Logger APIs
*/
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index 4b3598b..70ae39a 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -45,9 +45,20 @@
NSS_IPV6_TX_ACCEL_MODE_CFG_MSG,
NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
NSS_IPV6_TX_CONN_TABLE_SIZE_MSG,
+ NSS_IPV6_TX_DSCP2PRI_CFG_MSG,
NSS_IPV6_MAX_MSG_TYPES,
};
+/**
+ * nss_ipv6_dscp_map_actions
+ * Action types mapped to DSCP values.
+ */
+enum nss_ipv6_dscp_map_actions {
+ NSS_IPV6_DSCP_MAP_ACTION_ACCEL,
+ NSS_IPV6_DSCP_MAP_ACTION_DONT_ACCEL,
+ NSS_IPV6_DSCP_MAP_ACTION_MAX,
+};
+
/*
* NSS IPv6 rule creation flags.
*/
@@ -591,6 +602,15 @@
};
/**
+ * nss_ipv6_dscp2pri_cfg_msg
+ * IPv6 dscp2pri configuration msg.
+ */
+struct nss_ipv6_dscp2pri_cfg_msg {
+ uint8_t dscp; /**< Value of DSCP. */
+ uint8_t priority; /**< Corresponding priority. */
+};
+
+/**
* nss_ipv6_node_sync
* IPv6 node synchronization statistics.
*/
@@ -675,6 +695,8 @@
/**< Configure acceleration mode. */
struct nss_ipv6_inquiry_msg inquiry;
/**< Inquiry if a connection has been created. */
+ struct nss_ipv6_dscp2pri_cfg_msg dscp2pri_cfg;
+ /**< Configure dscp2pri mapping. */
} msg; /**< Message payload. */
};
@@ -875,6 +897,17 @@
*/
void nss_ipv6_free_conn_tables(void);
+/**
+ * nss_ipv6_dscp_action_get
+ * Gets the action value of the DSCP.
+ *
+ * @param[in] dscp Value of the DSCP field.
+ *
+ * @return
+ * Action value of the DSCP field.
+ */
+enum nss_ipv6_dscp_map_actions nss_ipv6_dscp_action_get(uint8_t dscp);
+
/*
* Logger APIs
*/
diff --git a/nss_dscp2pri.c b/nss_dscp2pri.c
deleted file mode 100644
index 92a42ed..0000000
--- a/nss_dscp2pri.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- **************************************************************************
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- * Permission to use, copy, modify, and/or distribute this software for
- * any purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all copies.
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- **************************************************************************
- */
-
-/*
- * nss_dscp2pri.c
- * NSS dscp2pri node APIs
- */
-
-#include "nss_tx_rx_common.h"
-
-#define NSS_DSCP2PRI_PARAM_FIELD_COUNT 3
-#define NSS_DSCP2PRI_ARRAY_SIZE 64
-
-/*
- * dscp2pri mapping structure.
- */
-struct nss_dscp2pri_map {
- uint8_t action; /* Action associated with the DSCP value.*/
- uint8_t priority; /* Priority associated with the DSCP value. */
-};
-
-struct nss_dscp2pri_map mapping[NSS_DSCP2PRI_ARRAY_SIZE];
-
-/*
- * Private data structure
- */
-static struct nss_dscp2pri_pvt {
- struct semaphore sem;
- struct completion complete;
- int response;
- void *cb;
- void *app_data;
-} dscp2pri_pvt;
-
-/*
- * nss_dscp2pri_usage()
- * Help function shows the usage of the command.
- */
-static void nss_dscp2pri_usage(void)
-{
- nss_info_always("\nUsage:\n");
- nss_info_always("echo <dscp> <action> <prio> > /proc/sys/dev/nss/dscp2pri/map\n\n");
- nss_info_always("dscp[0-63] action[0-1] prio[0-3]:\n\n");
-}
-
-/*
- * nss_dscp2pri_msg_init()
- * Initialize dscp2pri message.
- */
-static void nss_dscp2pri_msg_init(struct nss_dscp2pri_msg *ndm, uint16_t if_num, uint32_t type,
- uint32_t len, nss_dscp2pri_msg_callback_t cb, void *app_data)
-{
- nss_cmn_msg_init(&ndm->cm, if_num, type, len, (void *)cb, app_data);
-}
-
-/*
- * nss_dscp2pri_tx_msg()
- * TX message function.
- */
-static nss_tx_status_t nss_dscp2pri_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_dscp2pri_msg *ndm)
-{
- struct nss_dscp2pri_msg *ndm2;
- struct nss_cmn_msg *ncm = &ndm->cm;
- struct sk_buff *nbuf;
- nss_tx_status_t status;
-
- NSS_VERIFY_CTX_MAGIC(nss_ctx);
- if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) {
- return NSS_TX_FAILURE_NOT_READY;
- }
-
- /*
- * Sanity check the message
- */
- if (ncm->interface != NSS_DSCP2PRI_INTERFACE) {
- nss_warning("%p: tx request for another interface: %d", nss_ctx, ncm->interface);
- return NSS_TX_FAILURE;
- }
-
- if (ncm->type >= NSS_DSCP2PRI_METADATA_TYPE_MAX) {
- nss_warning("%p: message type out of range: %d", nss_ctx, ncm->type);
- return NSS_TX_FAILURE;
- }
-
- if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_dscp2pri_msg)) {
- nss_warning("%p: tx request for another interface: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
- return NSS_TX_FAILURE;
- }
-
- nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
- if (unlikely(!nbuf)) {
- NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS]);
- return NSS_TX_FAILURE;
- }
-
- /*
- * Copy the message to our skb.
- */
- ndm2 = (struct nss_dscp2pri_msg *)skb_put(nbuf, sizeof(struct nss_dscp2pri_msg));
- memcpy(ndm2, ndm, sizeof(struct nss_dscp2pri_msg));
- status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
- if (status != NSS_CORE_STATUS_SUCCESS) {
- dev_kfree_skb_any(nbuf);
- nss_info("%p: unable to send dscp2pri message\n", nss_ctx);
- return NSS_TX_FAILURE;
- }
-
- nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
- NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_TX_CMD_REQ]);
- return NSS_TX_SUCCESS;
-}
-
-/*
- * nss_dscp2pri_configure_mapping_callback_async()
- * Callback function for async messages.
- */
-static void nss_dscp2pri_configure_mapping_callback_async(void *app_data, struct nss_dscp2pri_msg *ndm)
-{
- if (ndm->cm.response != NSS_CMN_RESPONSE_ACK) {
- nss_warning("%p: nss dscp2pri configure mapping tx async failed: %d\n",
- &dscp2pri_pvt, ndm->cm.error);
- return;
- }
-
- nss_info("%p: nss dscp2pri configure mapping tx async succeeded\n", &dscp2pri_pvt);
-
- /*
- * NSS firmware acknowleged the configuration, so update the mapping table on HOST side as well.
- * Note that action value was sent to NSS firmware as opaque, because action is not needed in
- * NSS firmware. It is only used in HOST code.
- */
- mapping[ndm->msg.configure_mapping.dscp].action = ndm->msg.configure_mapping.opaque;
- mapping[ndm->msg.configure_mapping.dscp].priority = ndm->msg.configure_mapping.priority;
-}
-
-/*
- * nss_dscp2pri_configure_mapping_callback_sync()
- * Callback function for sync messages.
- */
-static void nss_dscp2pri_configure_mapping_callback_sync(void *app_data, struct nss_dscp2pri_msg *ndm)
-{
- nss_dscp2pri_msg_callback_t callback = (nss_dscp2pri_msg_callback_t)dscp2pri_pvt.cb;
- void *data = (void *)dscp2pri_pvt.app_data;
-
- dscp2pri_pvt.cb = NULL;
- dscp2pri_pvt.app_data = NULL;
-
- if (ndm->cm.response != NSS_CMN_RESPONSE_ACK) {
- dscp2pri_pvt.response = NSS_FAILURE;
- complete(&dscp2pri_pvt.complete);
- nss_warning("%p: nss dscp2pri configure mapping tx sync failed: %d\n",
- &dscp2pri_pvt, ndm->cm.error);
- return;
- }
-
- nss_info("%p: nss dscp2pri configure mapping tx sync succeeded\n",
- &dscp2pri_pvt);
-
- dscp2pri_pvt.response = NSS_SUCCESS;
-
- if (callback) {
- callback(data, ndm);
- }
-
- complete(&dscp2pri_pvt.complete);
-}
-
-/*
- * nss_dscp2pri_configure_mapping_async()
- * Async implementation for sending message to NSS.
- */
-static nss_tx_status_t nss_dscp2pri_configure_mapping_async(struct nss_dscp2pri_msg *ndm)
-{
- struct nss_top_instance *nss_top = &nss_top_main;
- struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
-
- nss_tx_status_t status = nss_dscp2pri_tx_msg(nss_ctx, ndm);
- if (status != NSS_TX_SUCCESS) {
- nss_warning("nss_dscp2pri tx error to send configure mapping message\n");
- return status;
- }
-
- return NSS_TX_SUCCESS;
-}
-
-/*
- * nss_dscp2pri_configure_mapping_sync()
- * Sync implementation for sending message to NSS.
- */
-static nss_tx_status_t nss_dscp2pri_configure_mapping_sync(struct nss_dscp2pri_msg *ndm)
-{
- nss_tx_status_t status;
- int ret;
-
- down(&dscp2pri_pvt.sem);
- dscp2pri_pvt.response = NSS_FAILURE;
-
- dscp2pri_pvt.cb = (void *)ndm->cm.cb;
- dscp2pri_pvt.app_data = (void *)ndm->cm.app_data;
-
- ndm->cm.cb = (nss_ptr_t)nss_dscp2pri_configure_mapping_callback_sync;
- ndm->cm.app_data = (nss_ptr_t)ndm;
-
- status = nss_dscp2pri_configure_mapping_async(ndm);
- if (status != NSS_TX_SUCCESS) {
- goto failure;
- }
-
- /*
- * Blocking call, wait till we get ACK for this msg.
- */
- ret = wait_for_completion_timeout(&dscp2pri_pvt.complete,
- msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
- if (!ret) {
- nss_warning("Waiting for ack time out for configure mapping message\n");
- goto failure;
- }
-
- up(&dscp2pri_pvt.sem);
- return dscp2pri_pvt.response;
-
-failure:
- dscp2pri_pvt.response = NSS_TX_FAILURE;
- up(&dscp2pri_pvt.sem);
- return NSS_TX_FAILURE;
-}
-
-/*
- * nss_dscp2pri_sysctl_map_handler()
- * Sysctl handler for dscp/pri mappings.
- */
-static int nss_dscp2pri_sysctl_map_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- int count;
- size_t cp_bytes = 0;
- char w_buf[7];
- loff_t w_offset = 0;
- char *str;
- char *tokens[NSS_DSCP2PRI_PARAM_FIELD_COUNT];
- unsigned int dscp, priority, action;
- struct nss_dscp2pri_configure_mapping *cfg;
- struct nss_dscp2pri_msg ndm;
- nss_tx_status_t status;
- int ret;
-
- /*
- * It's a read operation
- */
- if (!write) {
- /*
- * (64 * 8) + 22 bytes for the buffer size is sufficient to write
- * the table including the spaces and new line characters.
- */
- char r_buf[(NSS_DSCP2PRI_ARRAY_SIZE * 8) + 22] = {0};
- int i, len;
-
- /*
- * Write the priority values to the first line of the output.
- */
- len = scnprintf(r_buf + cp_bytes, 11, "%s: ", "priority");
- cp_bytes += len;
- for (i = 0; i < NSS_DSCP2PRI_ARRAY_SIZE; i++) {
- len = scnprintf(r_buf + cp_bytes, 4, "%d ", mapping[i].priority);
- if (!len) {
- nss_warning("failed to read from buffer %d\n", mapping[i].priority);
- return -EFAULT;
- }
- cp_bytes += len;
- }
-
- /*
- * Add new line character at the end.
- */
- len = scnprintf(r_buf + cp_bytes, 4, "\n");
- cp_bytes += len;
-
- /*
- * Write the action values to the second line of the output.
- */
- len = scnprintf(r_buf + cp_bytes, 11, "%s: ", "action");
- cp_bytes += len;
- for (i = 0; i < NSS_DSCP2PRI_ARRAY_SIZE; i++) {
- len = scnprintf(r_buf + cp_bytes, 4, "%d ", mapping[i].action);
- if (!len) {
- nss_warning("failed to read from buffer %d\n", mapping[i].action);
- return -EFAULT;
- }
- cp_bytes += len;
- }
-
- /*
- * Add new line character at the end.
- */
- len = scnprintf(r_buf + cp_bytes, 4, "\n");
- cp_bytes += len;
-
- cp_bytes = simple_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes);
- *lenp = cp_bytes;
- return 0;
- }
-
- /*
- * Buffer length cannot be more than 7 and less than 6.
- */
- if (*lenp < 6 || *lenp > 7) {
- nss_warning("Buffer is not correct. Invalid lenght: %d\n", (int)*lenp);
- nss_dscp2pri_usage();
- return 0;
- }
-
- /*
- * It's a write operation
- */
- cp_bytes = simple_write_to_buffer(w_buf, *lenp, &w_offset, buffer, 7);
- if (cp_bytes != *lenp) {
- nss_warning("failed to write to buffer\n");
- return -EFAULT;
- }
-
- count = 0;
- str = w_buf;
- tokens[count] = strsep(&str, " ");
- while (tokens[count] != NULL) {
- count++;
- if (count == NSS_DSCP2PRI_PARAM_FIELD_COUNT) {
- nss_warning("maximum allowed field count is %d\n", NSS_DSCP2PRI_PARAM_FIELD_COUNT);
- break;
- }
- tokens[count] = strsep(&str, " ");
- }
-
- /*
- * Did we read enough number of parameters from the command line.
- * There must be 2 parameters.
- */
- if (count != NSS_DSCP2PRI_PARAM_FIELD_COUNT) {
- nss_warning("param fields are less than expected: %d\n", count);
- nss_dscp2pri_usage();
- return 0;
- }
-
- /*
- * Write the tokens to integers.
- */
- ret = sscanf(tokens[0], "%u", &dscp);
- if (ret != 1) {
- nss_warning("failed to write the dscp token to integer\n");
- return -EFAULT;
- }
-
- ret = sscanf(tokens[1], "%u", &action);
- if (ret != 1) {
- nss_warning("failed to write the action token to integer\n");
- return -EFAULT;
- }
-
- ret = sscanf(tokens[2], "%u", &priority);
- if (ret != 1) {
- nss_warning("failed to write the priority token to integer\n");
- return -EFAULT;
- }
-
- /*
- * dscp value cannot be higher than 63.
- */
- if (dscp >= NSS_DSCP2PRI_ARRAY_SIZE) {
- nss_warning("invalid dscp value: %d\n", dscp);
- nss_dscp2pri_usage();
- return 0;
- }
-
- /*
- * Action can be 0 or 1.
- * 0: NSS_DSCP2PRI_ACTION_NOT_ACCEL
- * 1: NSS_DSCP2PRI_ACTION_ACCEL
- */
- if (action >= NSS_DSCP2PRI_ACTION_MAX) {
- nss_warning("invalid action value: %d\n", action);
- nss_dscp2pri_usage();
- return 0;
- }
-
- /*
- * Priority must be less than NSS_DSCP2PRI_PRIORITY_MAX which is 4.
- */
- if (priority >= NSS_DSCP2PRI_PRIORITY_MAX) {
- nss_warning("invalid priority value: %d\n", priority);
- nss_dscp2pri_usage();
- return 0;
- }
-
- nss_info("dscp: %d action: %d priority: %d\n", dscp, action, priority);
-
- /*
- * Write the dscp, priority and opaque values to the message fields.
- * Opaque is set to action value and when the message is acknowledged
- * by NSS firmware it is used to set the action value in the mapping table.
- */
- cfg = &ndm.msg.configure_mapping;
- cfg->dscp = (uint8_t)dscp;
- cfg->opaque = (uint8_t)action;
- cfg->priority = (uint8_t)priority;
-
- /*
- * Initialize message.
- */
- nss_dscp2pri_msg_init(&ndm, NSS_DSCP2PRI_INTERFACE,
- NSS_DSCP2PRI_METADATA_TYPE_CONFIGURE_MAPPING,
- sizeof(struct nss_dscp2pri_configure_mapping),
- nss_dscp2pri_configure_mapping_callback_async,
- (void *)&ndm);
-
- /*
- * Send the message to the NSS.
- */
- status = nss_dscp2pri_configure_mapping_sync(&ndm);
- if (status != NSS_TX_SUCCESS) {
- return -EFAULT;
- }
-
- return 0;
-}
-
-/*
- * nss_dscp2pri_configure_handler()
- * Handles NSS -> HLOS messages for dscp2pri node.
- */
-static void nss_dscp2pri_configure_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
-{
- struct nss_dscp2pri_msg *ndm = (struct nss_dscp2pri_msg *)ncm;
- nss_dscp2pri_msg_callback_t cb;
-
- BUG_ON(ncm->interface != NSS_DSCP2PRI_INTERFACE);
-
- /*
- * Is this a valid request/response packet?
- */
- if (ncm->type >= NSS_DSCP2PRI_METADATA_TYPE_MAX) {
- nss_warning("%p: received invalid message %d for dscp2pri interface", nss_ctx, ncm->type);
- return;
- }
-
- if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_dscp2pri_msg)) {
- nss_warning("%p: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
- return;
- }
-
- nss_core_log_msg_failures(nss_ctx, ncm);
-
- /*
- * Do we have a callback
- */
- if (!ncm->cb) {
- nss_trace("%p: cb is null for interface %d", nss_ctx, ncm->interface);
- return;
- }
-
- cb = (nss_dscp2pri_msg_callback_t)ncm->cb;
- cb((void *)ncm->app_data, ndm);
-}
-
-static struct ctl_table nss_dscp2pri_table[] = {
- {
- .procname = "map",
- .data = &mapping[NSS_DSCP2PRI_ARRAY_SIZE],
- .maxlen = sizeof(struct nss_dscp2pri_map),
- .mode = 0644,
- .proc_handler = &nss_dscp2pri_sysctl_map_handler,
- },
-
- { }
-};
-
-static struct ctl_table nss_dscp2pri_dir[] = {
- {
- .procname = "dscp2pri",
- .mode = 0555,
- .child = nss_dscp2pri_table,
- },
- { }
-};
-
-
-static struct ctl_table nss_dscp2pri_root_dir[] = {
- {
- .procname = "nss",
- .mode = 0555,
- .child = nss_dscp2pri_dir,
- },
- { }
-};
-
-static struct ctl_table nss_dscp2pri_root[] = {
- {
- .procname = "dev",
- .mode = 0555,
- .child = nss_dscp2pri_root_dir,
- },
- { }
-};
-
-static struct ctl_table_header *nss_dscp2pri_header;
-
-/*
- * nss_dscp2pri_get_action()
- * Gets the action value of the dscp.
- */
-enum nss_dscp2pri_action nss_dscp2pri_get_action(uint8_t dscp)
-{
- return mapping[dscp].action;
-}
-EXPORT_SYMBOL(nss_dscp2pri_get_action);
-
-/*
- * nss_dscp2pri_register_sysctl()
- */
-void nss_dscp2pri_register_sysctl(void)
-{
- /*
- * Register sysctl table.
- */
- nss_dscp2pri_header = register_sysctl_table(nss_dscp2pri_root);
-}
-
-/*
- * nss_dscp2pri_unregister_sysctl()
- * Unregister sysctl specific to n2h
- */
-void nss_dscp2pri_unregister_sysctl(void)
-{
- /*
- * Unregister sysctl table.
- */
- if (nss_dscp2pri_header) {
- unregister_sysctl_table(nss_dscp2pri_header);
- }
-}
-
-/*
- * nss_dscp2pri_register_handler()
- * Registering handler for receiving notify msg from dscp2pri node on NSS.
- */
-void nss_dscp2pri_register_handler(void)
-{
- struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0];
- int i;
-
- /*
- * Initialize the mapping table with the default values.
- */
- for (i = 0; i < NSS_DSCP2PRI_ARRAY_SIZE; i++) {
- mapping[i].priority = NSS_DSCP2PRI_PRIORITY_BE;
- mapping[i].action = NSS_DSCP2PRI_ACTION_ACCEL;
- }
-
- nss_core_register_handler(nss_ctx, NSS_DSCP2PRI_INTERFACE, nss_dscp2pri_configure_handler, NULL);
-
- /*
- * dscp2pri sema init.
- */
- sema_init(&dscp2pri_pvt.sem, 1);
- init_completion(&dscp2pri_pvt.complete);
-}
diff --git a/nss_dscp_map.h b/nss_dscp_map.h
new file mode 100644
index 0000000..276d08b
--- /dev/null
+++ b/nss_dscp_map.h
@@ -0,0 +1,209 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+/*
+ * nss_dscp_map.h
+ * NSS dscp map parse APIs
+ */
+
+#include "nss_tx_rx_common.h"
+
+#define NSS_DSCP_MAP_PARAM_FIELD_COUNT 3
+#define NSS_DSCP_MAP_ARRAY_SIZE 64
+#define NSS_DSCP_MAP_PRIORITY_MAX NSS_MAX_NUM_PRI
+
+/*
+ * nss dscp map entry structure.
+ */
+struct nss_dscp_map_entry {
+ uint8_t action; /* Action associated with the DSCP value.*/
+ uint8_t priority; /* Priority associated with the DSCP value. */
+};
+
+/*
+ * nss dscp map parse output.
+ */
+struct nss_dscp_map_parse {
+ uint8_t dscp; /* Parsed dscp value */
+ uint8_t action; /* Parsed action value */
+ uint8_t priority; /* Parsed priority value */
+};
+
+/*
+ * nss_dscp_map_print()
+ * Sysctl handler for printing dscp/pri mapping.
+ */
+static int nss_dscp_map_print(struct ctl_table *ctl, void __user *buffer, size_t *lenp,
+ loff_t *ppos, struct nss_dscp_map_entry *mapping)
+{
+ char *r_buf;
+ int i, len;
+ size_t cp_bytes = 0;
+
+ /*
+ * (64 * 8) + 22 bytes for the buffer size is sufficient to write
+ * the table including the spaces and new line characters.
+ */
+ r_buf = kzalloc(((NSS_DSCP_MAP_ARRAY_SIZE * 8) + 22) * sizeof(char), GFP_KERNEL);
+ if (!r_buf) {
+ nss_warning("Failed to alloc buffer to print dscp map table\n");
+ return -EFAULT;
+ }
+
+ /*
+ * Write the priority values to the first line of the output.
+ */
+ len = scnprintf(r_buf + cp_bytes, 11, "%s: ", "priority");
+ cp_bytes += len;
+ for (i = 0; i < NSS_DSCP_MAP_ARRAY_SIZE; i++) {
+ len = scnprintf(r_buf + cp_bytes, 4, "%d ", mapping[i].priority);
+ if (!len) {
+ nss_warning("failed to read from buffer %d\n", mapping[i].priority);
+ return -EFAULT;
+ }
+ cp_bytes += len;
+ }
+
+ /*
+ * Add new line character at the end.
+ */
+ len = scnprintf(r_buf + cp_bytes, 4, "\n");
+ cp_bytes += len;
+
+ /*
+ * Write the action values to the second line of the output.
+ */
+ len = scnprintf(r_buf + cp_bytes, 11, "%s: ", "action");
+ cp_bytes += len;
+ for (i = 0; i < NSS_DSCP_MAP_ARRAY_SIZE; i++) {
+ len = scnprintf(r_buf + cp_bytes, 4, "%d ", mapping[i].action);
+ if (!len) {
+ nss_warning("failed to read from buffer %d\n", mapping[i].action);
+ return -EFAULT;
+ }
+ cp_bytes += len;
+ }
+
+ /*
+ * Add new line character at the end.
+ */
+ len = scnprintf(r_buf + cp_bytes, 4, "\n");
+ cp_bytes += len;
+
+ cp_bytes = simple_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes);
+ *lenp = cp_bytes;
+ return 0;
+}
+
+/*
+ * nss_dscp_map_parse()
+ * Sysctl handler for dscp/pri mappings.
+ */
+static int nss_dscp_map_parse(struct ctl_table *ctl, void __user *buffer, size_t *lenp,
+ loff_t *ppos, struct nss_dscp_map_parse *out)
+{
+ int count;
+ size_t cp_bytes = 0;
+ char w_buf[7];
+ loff_t w_offset = 0;
+ char *str;
+ char *tokens[NSS_DSCP_MAP_PARAM_FIELD_COUNT];
+ unsigned int dscp, priority, action;
+ int ret;
+
+ /*
+ * Buffer length cannot be more than 7 and less than 6.
+ */
+ if (*lenp < 6 || *lenp > 7) {
+ nss_warning("Buffer is not correct. Invalid lenght: %d\n", (int)*lenp);
+ return -EINVAL;
+ }
+
+ /*
+ * It's a write operation
+ */
+ cp_bytes = simple_write_to_buffer(w_buf, *lenp, &w_offset, buffer, 7);
+ if (cp_bytes != *lenp) {
+ nss_warning("failed to write to buffer\n");
+ return -EFAULT;
+ }
+
+ count = 0;
+ str = w_buf;
+ tokens[count] = strsep(&str, " ");
+ while (tokens[count] != NULL) {
+ count++;
+ if (count == NSS_DSCP_MAP_PARAM_FIELD_COUNT) {
+ nss_warning("maximum allowed field count is %d\n", NSS_DSCP_MAP_PARAM_FIELD_COUNT);
+ break;
+ }
+ tokens[count] = strsep(&str, " ");
+ }
+
+ /*
+ * Did we read enough number of parameters from the command line.
+ * There must be 2 parameters.
+ */
+ if (count != NSS_DSCP_MAP_PARAM_FIELD_COUNT) {
+ nss_warning("param fields are less than expected: %d\n", count);
+ return -EINVAL;
+ }
+
+ /*
+ * Write the tokens to integers.
+ */
+ ret = sscanf(tokens[0], "%u", &dscp);
+ if (ret != 1) {
+ nss_warning("failed to write the dscp token to integer\n");
+ return -EFAULT;
+ }
+
+ ret = sscanf(tokens[1], "%u", &action);
+ if (ret != 1) {
+ nss_warning("failed to write the action token to integer\n");
+ return -EFAULT;
+ }
+
+ ret = sscanf(tokens[2], "%u", &priority);
+ if (ret != 1) {
+ nss_warning("failed to write the priority token to integer\n");
+ return -EFAULT;
+ }
+
+ /*
+ * dscp value cannot be higher than 63.
+ */
+ if (dscp >= NSS_DSCP_MAP_ARRAY_SIZE) {
+ nss_warning("invalid dscp value: %d\n", dscp);
+ return -EINVAL;
+ }
+
+ /*
+ * Priority must be less than NSS_DSCP_MAP_PRIORITY_MAX which is 4.
+ */
+ if (priority >= NSS_DSCP_MAP_PRIORITY_MAX) {
+ nss_warning("invalid priority value: %d\n", priority);
+ return -EINVAL;
+ }
+
+ nss_info("dscp: %d action: %d priority: %d\n", dscp, action, priority);
+
+ out->dscp = dscp;
+ out->action = action;
+ out->priority = priority;
+
+ return 0;
+}
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index d0959e9..14ecf1d 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -360,8 +360,6 @@
}
nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_802_3_REDIR] = nss_dev->id;
-
- nss_dscp2pri_register_handler();
}
if (npd->capwap_enabled == NSS_FEATURE_ENABLED) {
diff --git a/nss_init.c b/nss_init.c
index 82dbbf4..fbaae7d 100644
--- a/nss_init.c
+++ b/nss_init.c
@@ -641,11 +641,6 @@
nss_n2h_register_sysctl();
/*
- * Registering sysctl for dscp2pri specific config.
- */
- nss_dscp2pri_register_sysctl();
-
- /*
* Register sysctl for project config
*/
nss_project_register_sysctl();
@@ -742,7 +737,6 @@
nss_ipv4_free_conn_tables();
nss_ipv6_free_conn_tables();
- nss_dscp2pri_unregister_sysctl();
nss_project_unregister_sysctl();
nss_data_plane_destroy_delay_work();
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.
diff --git a/nss_ipv6.c b/nss_ipv6.c
index 5273dca..ae83ea2 100644
--- a/nss_ipv6.c
+++ b/nss_ipv6.c
@@ -19,21 +19,23 @@
* NSS IPv6 APIs
*/
#include "nss_tx_rx_common.h"
+#include "nss_dscp_map.h"
-#define NSS_IPV6_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv4 messages */
+#define NSS_IPV6_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv6 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 */
-};
+ 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_ipv6_pvt;
/*
- * Private data structure for ipv4 connection information.
+ * Private data structure for ipv6 connection information.
*/
struct nss_ipv6_conn_table_info {
uint32_t ce_table_size; /* Size of connection entry table in NSS FW */
@@ -45,7 +47,7 @@
int nss_ipv6_conn_cfg = NSS_DEFAULT_NUM_CONN;
int nss_ipv6_accel_mode_cfg __read_mostly = 1;
-static struct nss_ipv6_cfg_pvt i6_accel_mode_cfgp;
+static struct nss_dscp_map_entry mapping[NSS_DSCP_MAP_ARRAY_SIZE];
/*
* Callback for conn_sync_many request message.
@@ -53,45 +55,17 @@
nss_ipv6_msg_callback_t nss_ipv6_conn_sync_many_msg_cb = NULL;
/*
- * nss_ipv6_max_conn_count()
- * Return the maximum number of IPv6 connections that the NSS acceleration engine supports.
+ * nss_ipv6_dscp_map_usage()
+ * Help function shows the usage of the command.
*/
-int nss_ipv6_max_conn_count(void)
+static inline void nss_ipv6_dscp_map_usage(void)
{
- return nss_ipv6_conn_cfg;
+ nss_info_always("\nUsage:\n");
+ nss_info_always("echo <dscp> <action> <prio> > /proc/sys/dev/nss/ipv6cfg/ipv6_dscp_map\n\n");
+ nss_info_always("dscp[0-63] action[0-%u] prio[0-%u]:\n\n",
+ NSS_IPV6_DSCP_MAP_ACTION_MAX - 1,
+ NSS_DSCP_MAP_PRIORITY_MAX - 1);
}
-EXPORT_SYMBOL(nss_ipv6_max_conn_count);
-
-/*
- * nss_ipv6_conn_inquiry()
- * Inquiry if a connection has been established in NSS FW
- */
-nss_tx_status_t nss_ipv6_conn_inquiry(struct nss_ipv6_5tuple *ipv6_5t_p,
- nss_ipv6_msg_callback_t cb)
-{
- nss_tx_status_t nss_tx_status;
- struct nss_ipv6_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_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE,
- NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
- sizeof(struct nss_ipv6_inquiry_msg),
- cb, NULL);
- nim.msg.inquiry.rr.tuple = *ipv6_5t_p;
- nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
- if (nss_tx_status != NSS_TX_SUCCESS) {
- nss_warning("%p: Send inquiry message failed\n", ipv6_5t_p);
- }
-
- return nss_tx_status;
-}
-EXPORT_SYMBOL(nss_ipv6_conn_inquiry);
/*
* nss_ipv6_driver_conn_sync_update()
@@ -260,6 +234,88 @@
}
/*
+ * nss_ipv6_tx_sync_callback()
+ * Callback to handle the completion of synchronous tx messages.
+ */
+static void nss_ipv6_tx_sync_callback(void *app_data, struct nss_ipv6_msg *nim)
+{
+ nss_ipv6_msg_callback_t callback = (nss_ipv6_msg_callback_t)nss_ipv6_pvt.cb;
+ void *data = nss_ipv6_pvt.app_data;
+
+ nss_ipv6_pvt.cb = NULL;
+ nss_ipv6_pvt.app_data = NULL;
+
+ if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_warning("ipv6 error response %d\n", nim->cm.response);
+ nss_ipv6_pvt.response = NSS_TX_FAILURE;
+ } else {
+ nss_ipv6_pvt.response = NSS_TX_SUCCESS;
+ }
+
+ if (callback) {
+ callback(data, nim);
+ }
+
+ complete(&nss_ipv6_pvt.complete);
+}
+
+/*
+ * nss_ipv6_dscp_action_get()
+ * Gets the action mapped to dscp.
+ */
+enum nss_ipv6_dscp_map_actions nss_ipv6_dscp_action_get(uint8_t dscp)
+{
+ if (dscp > NSS_DSCP_MAP_ARRAY_SIZE) {
+ nss_warning("dscp:%u invalid\n", dscp);
+ return NSS_IPV6_DSCP_MAP_ACTION_MAX;
+ }
+
+ return mapping[dscp].action;
+}
+EXPORT_SYMBOL(nss_ipv6_dscp_action_get);
+
+/*
+ * nss_ipv6_max_conn_count()
+ * Return the maximum number of IPv6 connections that the NSS acceleration engine supports.
+ */
+int nss_ipv6_max_conn_count(void)
+{
+ return nss_ipv6_conn_cfg;
+}
+EXPORT_SYMBOL(nss_ipv6_max_conn_count);
+
+/*
+ * nss_ipv6_conn_inquiry()
+ * Inquiry if a connection has been established in NSS FW
+ */
+nss_tx_status_t nss_ipv6_conn_inquiry(struct nss_ipv6_5tuple *ipv6_5t_p,
+ nss_ipv6_msg_callback_t cb)
+{
+ nss_tx_status_t nss_tx_status;
+ struct nss_ipv6_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_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE,
+ NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG,
+ sizeof(struct nss_ipv6_inquiry_msg),
+ cb, NULL);
+ nim.msg.inquiry.rr.tuple = *ipv6_5t_p;
+ nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: Send inquiry message failed\n", ipv6_5t_p);
+ }
+
+ return nss_tx_status;
+}
+EXPORT_SYMBOL(nss_ipv6_conn_inquiry);
+
+/*
* nss_ipv6_tx_with_size()
* Transmit an ipv6 message to the FW with a specified size.
*/
@@ -342,6 +398,41 @@
EXPORT_SYMBOL(nss_ipv6_tx);
/*
+ * nss_ipv6_tx_sync()
+ * Transmit a synchronous ipv6 message to the FW.
+ */
+nss_tx_status_t nss_ipv6_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim)
+{
+ nss_tx_status_t status;
+ int ret = 0;
+
+ down(&nss_ipv6_pvt.sem);
+ nss_ipv6_pvt.cb = (void *)nim->cm.cb;
+ nss_ipv6_pvt.app_data = (void *)nim->cm.app_data;
+
+ nim->cm.cb = (nss_ptr_t)nss_ipv6_tx_sync_callback;
+ nim->cm.app_data = (nss_ptr_t)NULL;
+
+ status = nss_ipv6_tx(nss_ctx, nim);
+ if (status != NSS_TX_SUCCESS) {
+ nss_warning("%p: nss ipv6 msg tx failed\n", nss_ctx);
+ up(&nss_ipv6_pvt.sem);
+ return status;
+ }
+
+ ret = wait_for_completion_timeout(&nss_ipv6_pvt.complete, msecs_to_jiffies(NSS_IPV6_TX_MSG_TIMEOUT));
+ if (!ret) {
+ nss_warning("%p: IPv6 tx sync failed due to timeout\n", nss_ctx);
+ nss_ipv6_pvt.response = NSS_TX_FAILURE;
+ }
+
+ status = nss_ipv6_pvt.response;
+ up(&nss_ipv6_pvt.sem);
+ return status;
+}
+EXPORT_SYMBOL(nss_ipv6_tx_sync);
+
+/*
**********************************
Register/Unregister/Miscellaneous APIs
**********************************
@@ -623,24 +714,6 @@
}
/*
- * 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
*/
@@ -652,60 +725,90 @@
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);
+ int current_value;
/*
* Take snap shot of current value
*/
- i6_accel_mode_cfgp.current_value = nss_ipv6_accel_mode_cfg;
+ 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);
+ sizeof(struct nss_ipv6_accel_mode_cfg_msg), NULL, NULL);
nipcm = &nim.msg.accel_mode_cfg;
nipcm->mode = htonl(nss_ipv6_accel_mode_cfg);
- nss_tx_status = nss_ipv6_tx(nss_ctx, &nim);
+ nss_tx_status = nss_ipv6_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_ipv6_accel_mode_cfg = current_value;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * nss_ipv6_dscp_map_cfg_handler()
+ * Sysctl handler for dscp/pri mappings.
+ */
+static int nss_ipv6_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_ipv6_msg nim;
+ struct nss_ipv6_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);
+ return ret;
+ }
+
+ if (out.action >= NSS_IPV6_DSCP_MAP_ACTION_MAX) {
+ nss_warning("invalid action value: %d\n", out.action);
+ nss_ipv6_dscp_map_usage();
+ return -EINVAL;
+ }
+
+ memset(&nim, 0, sizeof(struct nss_ipv6_msg));
+ nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_DSCP2PRI_CFG_MSG,
+ sizeof(struct nss_ipv6_dscp2pri_cfg_msg), NULL, NULL);
+
+ nipd2p = &nim.msg.dscp2pri_cfg;
+ nipd2p->dscp = out.dscp;
+ nipd2p->priority = out.priority;
+
+ status = nss_ipv6_tx_sync(nss_ctx, &nim);
+ if (status != NSS_TX_SUCCESS) {
+ nss_warning("%p: ipv6 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(&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;
- }
+ mapping[out.dscp].action = out.action;
+ mapping[out.dscp].priority = out.priority;
- 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[] = {
@@ -716,6 +819,13 @@
.mode = 0644,
.proc_handler = &nss_ipv6_accel_mode_cfg_handler,
},
+ {
+ .procname = "ipv6_dscp_map",
+ .data = &mapping[NSS_DSCP_MAP_ARRAY_SIZE],
+ .maxlen = sizeof(struct nss_dscp_map_entry),
+ .mode = 0644,
+ .proc_handler = &nss_ipv6_dscp_map_cfg_handler,
+ },
{ }
};
@@ -754,8 +864,8 @@
*/
void nss_ipv6_register_sysctl(void)
{
- sema_init(&i6_accel_mode_cfgp.sem, 1);
- init_completion(&i6_accel_mode_cfgp.complete);
+ sema_init(&nss_ipv6_pvt.sem, 1);
+ init_completion(&nss_ipv6_pvt.complete);
/*
* Register sysctl table.