Merge "[qca-nss-drv] Set NETIF_F_HIGHDMA flag"
diff --git a/Makefile b/Makefile
index b8c176c..0cdc956 100644
--- a/Makefile
+++ b/Makefile
@@ -65,7 +65,7 @@
ccflags-y += -DNSS_PM_DEBUG_LEVEL=0 -DNSS_PPP_SUPPORT=1
ifneq ($(findstring 3.4, $(KERNELVERSION)),)
-NSS_CCFLAGS = -DNSS_DT_SUPPORT=0 -DNSS_FW_DBG_SUPPORT=1 -DNSS_PM_SUPPORT=1 -DNSS_EMPTY_BUFFER_SIZE=2048
+NSS_CCFLAGS = -DNSS_DT_SUPPORT=0 -DNSS_FW_DBG_SUPPORT=1 -DNSS_PM_SUPPORT=1 -DNSS_EMPTY_BUFFER_SIZE=1984
else
NSS_CCFLAGS = -DNSS_DT_SUPPORT=1 -DNSS_FW_DBG_SUPPORT=0 -DNSS_PM_SUPPORT=0 -DNSS_EMPTY_BUFFER_SIZE=1792
ccflags-y += -I$(obj)
diff --git a/exports/nss_ipv4.h b/exports/nss_ipv4.h
index 62fc18b..3e8d786 100644
--- a/exports/nss_ipv4.h
+++ b/exports/nss_ipv4.h
@@ -58,7 +58,8 @@
/**< Update MTU of connection interfaces */
#define NSS_IPV4_RULE_CREATE_FLAG_ICMP_NO_CME_FLUSH 0x40
/**< Rule for not flushing CME on ICMP pkt */
-#define NSS_IPV4_RULE_CREATE_FLAG_L2_ENCAP 0x80 /**< The L2 payload is not IPv4 but consists of an encapsulating protocol that carries an IPv4 payload within it. */
+#define NSS_IPV4_RULE_CREATE_FLAG_L2_ENCAP 0x80
+ /**< The L2 payload is not IPv4 but consists of an encapsulating protocol that carries an IPv4 payload within it. */
/**
@@ -71,6 +72,7 @@
#define NSS_IPV4_RULE_CREATE_VLAN_VALID 0x10 /**< VLAN fields are valid */
#define NSS_IPV4_RULE_CREATE_DSCP_MARKING_VALID 0x20 /**< DSCP marking fields are valid */
#define NSS_IPV4_RULE_CREATE_VLAN_MARKING_VALID 0x40 /**< VLAN marking fields are valid */
+#define NSS_IPV4_RULE_CREATE_SRC_MAC_VALID 0x80 /**< Src MAC address fields are valid */
/**
* IPv4 multicast command rule flags
@@ -101,6 +103,12 @@
#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_NAT_VALID 0x4 /**< Interface is configured with Source-NAT */
/**
+ * Source MAC address valid flags (to be used with mac_valid_flags field of nss_ipv4_src_mac_rule structure)
+ */
+#define NSS_IPV4_SRC_MAC_FLOW_VALID 0x01 /**< FLOW interface MAC address is valid */
+#define NSS_IPV4_SRC_MAC_RETURN_VALID 0x02 /**< Return interface MAC address is valid */
+
+/**
* Common 5 tuple structure
*/
struct nss_ipv4_5tuple {
@@ -179,6 +187,15 @@
};
/**
+ * Src MAC address rule structure
+ */
+struct nss_ipv4_src_mac_rule {
+ uint32_t mac_valid_flags; /**< MAC address valid flags */
+ uint16_t flow_src_mac[3]; /**< Source MAC address for flow direction */
+ uint16_t return_src_mac[3]; /**< Source MAC address for return direction */
+};
+
+/**
* Error types for ipv4 messages
*/
enum nss_ipv4_error_response_types {
@@ -215,6 +232,7 @@
struct nss_ipv4_dscp_rule dscp_rule; /**< DSCP related accleration parameters */
struct nss_ipv4_vlan_rule vlan_primary_rule; /**< Primary VLAN related accleration parameters */
struct nss_ipv4_vlan_rule vlan_secondary_rule; /**< Secondary VLAN related accleration parameters */
+ struct nss_ipv4_src_mac_rule src_mac_rule; /**< Source MAC address related acceleration parameters */
/* Response */
uint32_t reserved; /**< Reserved field */
diff --git a/exports/nss_ipv6.h b/exports/nss_ipv6.h
index 6f3c190..8f6bbf7 100644
--- a/exports/nss_ipv6.h
+++ b/exports/nss_ipv6.h
@@ -58,7 +58,8 @@
/**< Rule for not flushing CME on ICMP pkt */
#define NSS_IPV6_RULE_UPDATE_FLAG_CHANGE_MTU 0x40
/**< Rule updation for MTU change */
-#define NSS_IPV6_RULE_CREATE_FLAG_L2_ENCAP 0x80 /**< The L2 payload is not IPv6 but consists of an encapsulating protocol that carries an IPv6 payload within it. */
+#define NSS_IPV6_RULE_CREATE_FLAG_L2_ENCAP 0x80
+ /**< The L2 payload is not IPv6 but consists of an encapsulating protocol that carries an IPv6 payload within it. */
/**
@@ -71,6 +72,7 @@
#define NSS_IPV6_RULE_CREATE_VLAN_VALID 0x10 /**< VLAN fields are valid */
#define NSS_IPV6_RULE_CREATE_DSCP_MARKING_VALID 0x20 /**< DSCP marking fields are valid */
#define NSS_IPV6_RULE_CREATE_VLAN_MARKING_VALID 0x40 /**< VLAN marking fields are valid */
+#define NSS_IPV6_RULE_CREATE_SRC_MAC_VALID 0x80 /**< Src MAC address fields are valid */
/**
* IPv6 multicast command rule flags
@@ -94,12 +96,18 @@
#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_LEAVE 0x08 /**< Interface has left the flow */
/**
- * IPv6 multicast connection per-interface valid flags (to be used with valid_flags field of nss_ipv4_mc_if_rule structure)
+ * IPv6 multicast connection per-interface valid flags (to be used with valid_flags field of nss_ipv6_mc_if_rule structure)
*/
#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_VLAN_VALID 0x01 /**< VLAN fields are valid */
#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_PPPOE_VALID 0x02 /**< PPPoE fields are valid */
/**
+ * Source MAC address valid flags (to be used with mac_valid_flags field of nss_ipv6_src_mac_rule structure)
+ */
+#define NSS_IPV6_SRC_MAC_FLOW_VALID 0x01 /**< FLOW interface MAC address is valid */
+#define NSS_IPV6_SRC_MAC_RETURN_VALID 0x02 /**< Return interface MAC address is valid */
+
+/**
* Exception events from IPv6 bridge/route handler
*/
enum exception_events_ipv6 {
@@ -229,6 +237,15 @@
};
/**
+ * Src MAC address rule structure
+ */
+struct nss_ipv6_src_mac_rule {
+ uint32_t mac_valid_flags; /**< MAC address valid flags */
+ uint16_t flow_src_mac[3]; /**< Source MAC address for flow direction */
+ uint16_t return_src_mac[3]; /**< Source MAC address for return direction */
+};
+
+/**
* Error types for ipv6 messages
*/
enum nss_ipv6_error_response_types {
@@ -264,6 +281,7 @@
struct nss_ipv6_dscp_rule dscp_rule; /**< DSCP related accleration parameters */
struct nss_ipv6_vlan_rule vlan_primary_rule; /**< VLAN related accleration parameters */
struct nss_ipv6_vlan_rule vlan_secondary_rule; /**< VLAN related accleration parameters */
+ struct nss_ipv6_src_mac_rule src_mac_rule; /**< Source MAC address related acceleration parameters */
/*
* Response
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index cb20caa..7290c97 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -27,13 +27,17 @@
#ifndef __NSS_N2H_H
#define __NSS_N2H_H
+#define MAX_PAGES_PER_MSG 32
+
/*
* Private data structure for configure general configs
*/
struct nss_n2h_cfg_pvt {
struct semaphore sem; /* Semaphore structure */
struct completion complete; /* completion structure */
- int current_value; /* valid entry */
+ int empty_buf_pool; /* valid entry */
+ int low_water; /* valid entry */
+ int high_water; /* valid entry */
int response; /* Response from FW */
};
@@ -45,6 +49,10 @@
NSS_TX_METADATA_TYPE_N2H_RPS_CFG,
NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS,
+ NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
+ NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
+ NSS_TX_METADATA_TYPE_SET_WATER_MARK,
+ NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
NSS_METADATA_TYPE_N2H_MAX,
};
@@ -52,8 +60,51 @@
uint32_t enable; /* Enable NSS RPS */
};
+struct nss_n2h_mitigation {
+ uint32_t enable; /* Enable NSS MITIGATION */
+};
+
+struct nss_n2h_buf_pool {
+ uint32_t nss_buf_page_size;
+ uint32_t nss_buf_num_pages;
+ void *nss_buf_pool_vaddr[MAX_PAGES_PER_MSG];
+ uint32_t nss_buf_pool_addr[MAX_PAGES_PER_MSG];
+};
+
+/*
+ * Old way of setting number of empty pool buffers (payloads).
+ * NSS FW then sets low water mark to 'n - ring_size' and
+ * high water mark to 'n + ring_size'.
+ */
struct nss_n2h_empty_pool_buf {
- uint32_t pool_size; /* Empty pool buf size */
+ uint32_t pool_size; /* Empty buffer pool size */
+};
+
+/*
+ * New way of setting low and high water marks in the NSS FW.
+ */
+struct nss_n2h_water_mark {
+ /*
+ * Low water mark. Set it to 0 for system to determine automatically.
+ */
+ uint32_t low_water;
+
+ /*
+ * High water mark. Set it to 0 for system to determine automatically.
+ */
+ uint32_t high_water;
+};
+
+struct nss_n2h_payload_info {
+ uint32_t pool_size; /* Empty buffer pool size */
+ /*
+ * Low water mark. Set it to 0 for system to determine automatically.
+ */
+ uint32_t low_water;
+ /*
+ * High water mark. Set it to 0 for system to determine automatically.
+ */
+ uint32_t high_water;
};
struct nss_n2h_flush_payloads {
@@ -64,9 +115,9 @@
* NSS Pbuf mgr stats
*/
struct nss_n2h_pbuf_mgr_stats {
- uint32_t pbuf_alloc_fails; /* Pbuf ocm alloc fail */
- uint32_t pbuf_free_count; /* Pbuf ocm free count */
- uint32_t pbuf_total_count; /* Pbuf ocm total count */
+ uint32_t pbuf_alloc_fails; /* Pbuf alloc fail */
+ uint32_t pbuf_free_count; /* Pbuf free count */
+ uint32_t pbuf_total_count; /* Pbuf total count */
};
/*
@@ -97,6 +148,7 @@
uint32_t h2n_data_bytes; /* Data bytes received from HLOS */
uint32_t n2h_data_pkts; /* Data packets sent to HLOS */
uint32_t n2h_data_bytes; /* Data bytes sent to HLOS */
+ uint32_t tot_payloads; /* Total number of payloads in NSS FW */
};
/*
@@ -111,6 +163,13 @@
/* Message: empty pool buf configuration */
struct nss_n2h_flush_payloads flush_payloads;
/* Message: flush payloads present in NSS */
+ struct nss_n2h_mitigation mitigation_cfg;
+ /* Message: Mitigation configuration */
+ struct nss_n2h_buf_pool buf_pool; /* Message: pbuf coniguration */
+ struct nss_n2h_water_mark wm;
+ /* Message: Sets low and high water marks */
+ struct nss_n2h_payload_info payload_info;
+ /* Message: Gets payload info */
} msg;
};
@@ -132,6 +191,18 @@
extern nss_tx_status_t nss_n2h_rps_cfg(struct nss_ctx_instance *nss_ctx, int enable_rps);
/*
+ * nss_n2h_mitigation_cfg()
+ * API to enable/disable Host MITIGATION support in NSS
+ */
+extern nss_tx_status_t nss_n2h_mitigation_cfg(struct nss_ctx_instance *nss_ctx, int enable_mitigation, nss_core_id_t nss_core);
+
+/*
+ * nss_n2h_buf_pool_cfg()
+ * API to increase the pbufs on NSS using Host memory
+ */
+extern nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx, int nss_pbuf_pool_size, nss_core_id_t nss_core);
+
+/*
* nss_n2h_empty_pool_buf_register_sysctl()
* API to register sysctl for empty pool buffer in n2h.
*/
diff --git a/exports/nss_wifi.h b/exports/nss_wifi.h
index f26b24e..c0e1c1f 100644
--- a/exports/nss_wifi.h
+++ b/exports/nss_wifi.h
@@ -46,6 +46,7 @@
NSS_WIFI_SEND_PEER_MEMORY_REQUEST_MSG,
NSS_WIFI_SEND_RRA_MEMORY_REQUEST_MSG,
NSS_WIFI_FW_STATS_MSG,
+ NSS_WIFI_MONITOR_FILTER_SET_MSG,
NSS_WIFI_MAX_MSG
};
@@ -164,6 +165,13 @@
};
/**
+ * wifi monitor mode set filter message structure
+ */
+struct nss_wifi_monitor_set_filter_msg {
+ uint32_t filter_type; /**< filter type */
+};
+
+/**
* wifi pdev wds peer specific messages
*/
struct nss_wifi_wds_peer_msg {
@@ -240,6 +248,7 @@
struct nss_wifi_peer_freelist_append_msg peer_freelist_append;
struct nss_wifi_rx_reorder_array_freelist_append_msg rx_reorder_array_freelist_append;
struct nss_wifi_fw_stats_msg fwstatsmsg;
+ struct nss_wifi_monitor_set_filter_msg monitor_filter_msg;
} msg;
};
diff --git a/exports/nss_wifi_vdev.h b/exports/nss_wifi_vdev.h
index 62175ef..b0a3726 100644
--- a/exports/nss_wifi_vdev.h
+++ b/exports/nss_wifi_vdev.h
@@ -41,6 +41,7 @@
NSS_WIFI_VDEV_SNOOPLIST_DENY_LIST_DELETE_MSG,
NSS_WIFI_VDEV_SNOOPLIST_DENY_LIST_DUMP_MSG,
NSS_WIFI_VDEV_SNOOPLIST_DUMP_MSG,
+ NSS_WIFI_VDEV_SNOOPLIST_RESET_MSG,
NSS_WIFI_VDEV_MAX_MSG
};
diff --git a/nss_core.h b/nss_core.h
index 89638ed..38c586b 100755
--- a/nss_core.h
+++ b/nss_core.h
@@ -49,6 +49,8 @@
/*
* NSS debug macros
*/
+#define nss_info_always(s, ...) pr_alert(s, ##__VA_ARGS__)
+
#if (NSS_DEBUG_LEVEL < 1)
#define nss_assert(fmt, args...)
#else
@@ -482,6 +484,7 @@
NSS_STATS_N2H_H2N_DATA_BYTES, /* Data bytes received from HLOS */
NSS_STATS_N2H_N2H_DATA_PACKETS, /* Data packets sent to HLOS */
NSS_STATS_N2H_N2H_DATA_BYTES, /* Data bytes sent to HLOS */
+ NSS_STATS_N2H_N2H_TOT_PAYLOADS, /* No. of payloads in NSS */
NSS_STATS_N2H_MAX,
};
@@ -619,8 +622,10 @@
/* Host to NSS descriptor rings */
struct hlos_n2h_desc_ring n2h_desc_ring[15];
/* NSS to Host descriptor rings */
- uint8_t n2h_rps_en; /* N2H Enable Multiple queues for Data Packets */
+ uint16_t n2h_rps_en; /* N2H Enable Multiple queues for Data Packets */
+ uint16_t n2h_mitigate_en; /* N2H mitigation */
uint32_t max_buf_size; /* Maximum buffer size */
+ uint32_t buf_sz_allocated; /* size of bufs allocated from host */
nss_cmn_queue_decongestion_callback_t queue_decongestion_callback[NSS_MAX_CLIENTS];
/* Queue decongestion callbacks */
void *queue_decongestion_ctx[NSS_MAX_CLIENTS];
diff --git a/nss_hal/fsm9010/nss_hal_pvt.c b/nss_hal/fsm9010/nss_hal_pvt.c
index 6c99955..8410373 100644
--- a/nss_hal/fsm9010/nss_hal_pvt.c
+++ b/nss_hal/fsm9010/nss_hal_pvt.c
@@ -436,7 +436,6 @@
#endif
nss_eth_rx_register_handler();
nss_n2h_register_handler();
- nss_virt_if_register_handler();
nss_lag_register_handler();
nss_dynamic_interface_register_handler();
diff --git a/nss_init.c b/nss_init.c
index dbc52dd..a41f463 100755
--- a/nss_init.c
+++ b/nss_init.c
@@ -47,12 +47,18 @@
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
+#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 4) /* 4MB */
+
/*
* Global declarations
*/
int nss_ctl_redirect __read_mostly = 0;
int nss_ctl_debug __read_mostly = 0;
int nss_rps_cfg __read_mostly = 0;
+int nss_core0_mitigation_cfg __read_mostly = 1;
+int nss_core1_mitigation_cfg __read_mostly = 1;
+int nss_core0_add_buf_pool_size __read_mostly = 0;
+int nss_core1_add_buf_pool_size __read_mostly = 0;
int nss_ctl_logbuf __read_mostly = 0;
int nss_jumbo_mru __read_mostly = 0;
int nss_paged_mode __read_mostly = 0;
@@ -433,6 +439,146 @@
}
/*
+ * nss_mitigation_handler()
+ * Enable NSS MITIGATION
+ */
+static int nss_mitigationcfg_core0_handler(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[NSS_CORE_0];
+ int ret;
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret) {
+ return ret;
+ }
+
+ /*
+ * It's a read operation
+ */
+ if (!write) {
+ return ret;
+ }
+
+ if (!nss_core0_mitigation_cfg ) {
+ printk("Disabling NSS MITIGATION\n");
+ nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0);
+ return 0;
+ }
+ printk("Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
+ return -EINVAL;
+}
+
+/*
+ * nss_mitigation_handler()
+ * Enable NSS MITIGATION
+ */
+static int nss_mitigationcfg_core1_handler(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[NSS_CORE_1];
+ int ret;
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret) {
+ return ret;;
+ }
+
+ /*
+ * It's a read operation
+ */
+ if (!write) {
+ return ret;
+ }
+
+ if (!nss_core1_mitigation_cfg ) {
+ printk("Disabling NSS MITIGATION\n");
+ nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1);
+ return 0;
+ }
+ printk("Invalid input value.Valid value is 0, Runtime re-enabling not supported\n");
+ return -EINVAL;
+}
+
+/*
+ * nss_buf_handler()
+ * Add extra NSS bufs from host memory
+ */
+static int nss_buf_cfg_core0_handler(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[NSS_CORE_0];
+ int ret;
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret) {
+ return ret;
+ }
+
+ /*
+ * It's a read operation
+ */
+ if (!write) {
+ return ret;
+ }
+
+ if (nss_ctx->buf_sz_allocated) {
+ nss_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
+ return -EPERM;
+ }
+
+ if ((nss_core0_add_buf_pool_size >= 1) && (nss_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
+ printk("configuring additional NSS pbufs\n");
+ ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_core0_add_buf_pool_size, NSS_CORE_0);
+ nss_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated;
+ printk("additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
+ return ret;;
+ }
+
+ printk("Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
+ return -EINVAL;
+}
+
+/*
+ * nss_buf_handler()
+ * Add extra NSS bufs from host memory
+ */
+static int nss_buf_cfg_core1_handler(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[NSS_CORE_1];
+ int ret;
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret) {
+ return ret;
+ }
+
+ /*
+ * It's a read operation
+ */
+ if (!write) {
+ return ret;
+ }
+
+ if (nss_ctx->buf_sz_allocated) {
+ nss_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
+ return -EPERM;
+ }
+
+ if ((nss_core1_add_buf_pool_size >= 1) && (nss_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) {
+ printk("configuring additional NSS pbufs\n");
+ ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_core1_add_buf_pool_size, NSS_CORE_1);
+ nss_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated;
+ printk("additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated);
+ return ret;
+ }
+
+ printk("Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE);
+ return -EINVAL;
+}
+
+/*
* nss_coredump_handler()
* Send Signal To Coredump NSS Cores
*/
@@ -563,6 +709,34 @@
.proc_handler = &nss_rpscfg_handler,
},
{
+ .procname = "mitigation_core0",
+ .data = &nss_core0_mitigation_cfg,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_mitigationcfg_core0_handler,
+ },
+ {
+ .procname = "mitigation_core1",
+ .data = &nss_core1_mitigation_cfg,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_mitigationcfg_core1_handler,
+ },
+ {
+ .procname = "extra_pbuf_core0",
+ .data = &nss_core0_add_buf_pool_size,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_buf_cfg_core0_handler,
+ },
+ {
+ .procname = "extra_pbuf_core1",
+ .data = &nss_core1_add_buf_pool_size,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_buf_cfg_core1_handler,
+ },
+ {
.procname = "logbuf",
.data = &nss_ctl_logbuf,
.maxlen = sizeof(int),
@@ -641,8 +815,8 @@
*/
cmn = of_find_node_by_name(NULL, "nss-common");
if (!cmn) {
- nss_info("cannot find nss-common node\n");
- return -EFAULT;
+ nss_info_always("qca-nss-drv.ko is loaded for symbol link\n");
+ return 0;
}
if (of_address_to_resource(cmn, 0, &res_nss_fpb_base) != 0) {
@@ -759,6 +933,19 @@
*/
static void __exit nss_cleanup(void)
{
+#if (NSS_DT_SUPPORT == 1)
+ struct device_node *cmn = NULL;
+
+ /*
+ * Get reference to NSS common device node
+ */
+ cmn = of_find_node_by_name(NULL, "nss-common");
+ if (!cmn) {
+ nss_info_always("cannot find nss-common node, maybe just for symbol link\n");
+ return;
+ }
+#endif
+
nss_info("Exit NSS driver");
if (nss_dev_header)
diff --git a/nss_n2h.c b/nss_n2h.c
index ca87dbd..486a41b 100755
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -20,19 +20,14 @@
*/
#include "nss_tx_rx_common.h"
+#include <asm/cacheflush.h>
-#define NSS_CORE_0 0
-#define NSS_CORE_1 1
-/*
- * This number is chosen becuase currently default IPV4 + IPV6
- * connection size is 1024 + 1024 = 2048.
- * FYI: However this doesnt have any impact on n2h/ipv6 connections
- */
-#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 2048
+#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
#define NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ 8192
-int nss_n2h_empty_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ, NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ};
+int nss_n2h_empty_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {-1, -1};
+int nss_n2h_water_mark[NSS_MAX_CORES][2] __read_mostly = {{-1, -1}, {-1, -1} };
struct nss_n2h_registered_data {
nss_n2h_msg_callback_t n2h_callback;
@@ -42,6 +37,8 @@
static struct nss_n2h_cfg_pvt nss_n2h_nepbcfgp[NSS_MAX_CORES];
static struct nss_n2h_registered_data nss_n2h_rd[NSS_MAX_CORES];
static struct nss_n2h_cfg_pvt nss_n2h_rcp;
+static struct nss_n2h_cfg_pvt nss_n2h_mitigationcp[NSS_CORE_MAX];
+static struct nss_n2h_cfg_pvt nss_n2h_bufcp[NSS_CORE_MAX];
/*
* nss_n2h_stats_sync()
@@ -103,6 +100,11 @@
nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_PACKETS] += nnss->n2h_data_pkts;
nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_DATA_BYTES] += nnss->n2h_data_bytes;
+ /*
+ * Payloads related stats
+ */
+ nss_ctx->stats_n2h[NSS_STATS_N2H_N2H_TOT_PAYLOADS] = nnss->tot_payloads;
+
spin_unlock_bh(&nss_top->stats_lock);
}
@@ -132,6 +134,10 @@
nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable);
break;
+ case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG:
+ nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable);
+ break;
+
case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG:
nss_info("%p: empty pool buf cfg response from FW", nss_ctx);
break;
@@ -209,43 +215,157 @@
}
/*
- * nss_n2h_empty_pool_buf_cfg_core1_callback()
- * call back function for the n2h connection configuration handler
+ * nss_n2h_mitigation_cfg_callback()
+ * call back function for mitigation configuration
*/
-static void nss_n2h_empty_pool_buf_cfg_callback(void *app_data,
- struct nss_n2h_msg *nnm)
+static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
{
int core_num = (int)app_data;
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
+
+ if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
+
+ /*
+ * Error, hence we are not updating the nss_n2h_mitigate_en
+ */
+ nss_n2h_mitigationcp[core_num].response = NSS_FAILURE;
+ complete(&nss_n2h_mitigationcp[core_num].complete);
+ nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error);
+ return;
+ }
+
+ nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error);
+
+ nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable;
+ nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS;
+ complete(&nss_n2h_mitigationcp[core_num].complete);
+}
+
+/*
+ * nss_n2h_buf_cfg_callback()
+ * call back function for pbuf configuration
+ */
+static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm)
+{
+ int core_num = (int)app_data;
+ unsigned int allocated_sz;
+
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
+
+ if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
+ nss_n2h_bufcp[core_num].response = NSS_FAILURE;
+ nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error);
+ goto done;
+ }
+
+ nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error);
+
+ allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages;
+ nss_ctx->buf_sz_allocated += allocated_sz;
+
+ nss_n2h_bufcp[core_num].response = NSS_SUCCESS;
+
+done:
+ complete(&nss_n2h_bufcp[core_num].complete);
+}
+
+/*
+ * nss_n2h_payload_stats_callback()
+ * It gets called response to payload accounting.
+ */
+static void nss_n2h_payload_stats_callback(void *app_data,
+ struct nss_n2h_msg *nnm)
+{
+ int core_num = (int)app_data;
+
if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) {
struct nss_n2h_empty_pool_buf *nnepbcm;
nnepbcm = &nnm->msg.empty_pool_buf_cfg;
- /*
- * Error, hence we are not updating the nss_n2h_empty_pool_buf
- * Restore the current_value to its previous state
- */
- nss_warning("Core %d empty pool buf set failure: %d\n", core_num, nnm->cm.error);
+ nss_warning("%d: core empty pool buf set failure: %d\n",
+ core_num, nnm->cm.error);
nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE;
complete(&nss_n2h_nepbcfgp[core_num].complete);
return;
}
- /*
- * Sucess at NSS FW, hence updating nss_n2h_empty_pool_buf, with the valid value
- * saved at the sysctl handler.
- */
- nss_info("Core %d empty pool buf set success: %d\n", core_num, nnm->cm.error);
+ if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO) {
+ nss_n2h_nepbcfgp[core_num].empty_buf_pool =
+ ntohl(nnm->msg.payload_info.pool_size);
+ nss_n2h_nepbcfgp[core_num].low_water =
+ ntohl(nnm->msg.payload_info.low_water);
+ nss_n2h_nepbcfgp[core_num].high_water =
+ ntohl(nnm->msg.payload_info.high_water);
+ }
+
nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS;
complete(&nss_n2h_nepbcfgp[core_num].complete);
}
/*
- * nss_n2h_empty_pool_buf_core1_handler()
- * Sets the number of connections for IPv4
+ * nss_n2h_get_payload_info()
+ * Gets Payload information
*/
-static int nss_n2h_set_empty_pool_buf(ctl_table *ctl, int write, void __user *buffer,
- size_t *lenp, loff_t *ppos,
- int core_num, int *new_val)
+static int nss_n2h_get_payload_info(ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos,
+ int core_num)
+{
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
+ struct nss_n2h_msg nnm;
+ struct nss_n2h_payload_info *nnepbcm;
+ nss_tx_status_t nss_tx_status;
+ int ret = NSS_FAILURE;
+
+ /*
+ * Note that semaphore should be already held.
+ */
+
+ nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
+ NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
+ sizeof(struct nss_n2h_payload_info),
+ nss_n2h_payload_stats_callback,
+ (void *)core_num);
+
+ nnepbcm = &nnm.msg.payload_info;
+ nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
+
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: core %d nss_tx error errorn",
+ nss_ctx, core_num);
+ return NSS_FAILURE;
+ }
+
+ /*
+ * Blocking call, wait till we get ACK for this msg.
+ */
+ ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
+ msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: core %d waiting for ack timed out\n", nss_ctx,
+ core_num);
+ return NSS_FAILURE;
+ }
+
+ if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) {
+ nss_warning("%p: core %d response returned failure\n", nss_ctx,
+ core_num);
+ return NSS_FAILURE;
+ }
+
+ return NSS_SUCCESS;
+}
+
+/*
+ * nss_n2h_set_empty_pool_buf()
+ * Sets empty pool buffer
+ */
+static int nss_n2h_set_empty_pool_buf(ctl_table *ctl, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos,
+ int core_num, int *new_val)
{
struct nss_top_instance *nss_top = &nss_top_main;
struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
@@ -262,23 +382,31 @@
/*
* Take snap shot of current value
*/
- nss_n2h_nepbcfgp[core_num].current_value = *new_val;
+ nss_n2h_nepbcfgp[core_num].empty_buf_pool = *new_val;
- /*
- * Write the variable with user input
- */
+ if (!write) {
+ ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
+ core_num);
+ *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
+ if (ret == NSS_FAILURE) {
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+ return -EBUSY;
+ }
+
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ return ret;
+ }
+
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
- if (ret || (!write)) {
+ if (ret) {
up(&nss_n2h_nepbcfgp[core_num].sem);
return ret;
}
- /*
- * Input for n2h should be atleast 2048 to support defalt connections
- * of 1024 (IPV4) + 1024 (IPV6) connections.
- */
if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
- nss_warning("%p: core %d setting %d is less than minimum number of buffer",
+ nss_warning("%p: core %d setting %d < min number of buffer",
nss_ctx, core_num, *new_val);
goto failure;
}
@@ -289,7 +417,7 @@
nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG,
sizeof(struct nss_n2h_empty_pool_buf),
- nss_n2h_empty_pool_buf_cfg_callback,
+ nss_n2h_payload_stats_callback,
(void *)core_num);
nnepbcm = &nnm.msg.empty_pool_buf_cfg;
@@ -297,7 +425,7 @@
nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
if (nss_tx_status != NSS_TX_SUCCESS) {
- nss_warning("%p: core %d nss_tx error setting empty pool buffer: %d\n",
+ nss_warning("%p: core %d nss_tx error empty pool buffer: %d\n",
nss_ctx, core_num, *new_val);
goto failure;
}
@@ -305,9 +433,11 @@
/*
* Blocking call, wait till we get ACK for this msg.
*/
- ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
+ msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
if (ret == 0) {
- nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx, core_num);
+ nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
+ core_num);
goto failure;
}
@@ -327,7 +457,133 @@
/*
* Restore the current_value to its previous state
*/
- *new_val = nss_n2h_nepbcfgp[core_num].current_value;
+ *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool;
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+ return NSS_FAILURE;
+}
+
+/*
+ * nss_n2h_set_water_mark()
+ * Sets water mark for N2H SOS
+ */
+static int nss_n2h_set_water_mark(ctl_table *ctl, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos,
+ int core_num, int *low, int *high)
+{
+ struct nss_top_instance *nss_top = &nss_top_main;
+ struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num];
+ struct nss_n2h_msg nnm;
+ struct nss_n2h_water_mark *wm;
+ nss_tx_status_t nss_tx_status;
+ int ret = NSS_FAILURE;
+
+ /*
+ * Acquiring semaphore
+ */
+ down(&nss_n2h_nepbcfgp[core_num].sem);
+
+ /*
+ * Take snap shot of current value
+ */
+ nss_n2h_nepbcfgp[core_num].low_water = *low;
+ nss_n2h_nepbcfgp[core_num].high_water = *high;
+
+ if (!write) {
+ ret = nss_n2h_get_payload_info(ctl, write, buffer, lenp, ppos,
+ core_num);
+ *low = nss_n2h_nepbcfgp[core_num].low_water;
+ *high = nss_n2h_nepbcfgp[core_num].high_water;
+
+ if (ret == NSS_FAILURE) {
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+ return -EBUSY;
+ }
+
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ return ret;
+ }
+
+ ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+ if (ret) {
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+ return ret;
+ }
+
+ /*
+ * If either low or high water mark is not set then we do
+ * nothing.
+ */
+ if (*low == -1 || *high == -1)
+ goto failure;
+
+ if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) ||
+ (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) {
+ nss_warning("%p: core %d setting %d, %d < min number of buffer",
+ nss_ctx, core_num, *low, *high);
+ goto failure;
+ }
+
+ if ((*low > (NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ * 2)) ||
+ (*high > (NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ * 2))) {
+ nss_warning("%p: core %d setting %d, %d is > upper limit",
+ nss_ctx, core_num, *low, *high);
+ goto failure;
+ }
+
+ if (*low > *high) {
+ nss_warning("%p: core %d setting low %d is more than high %d",
+ nss_ctx, core_num, *low, *high);
+ goto failure;
+ }
+
+ nss_info("%p: core %d number of low : %d and high : %d\n",
+ nss_ctx, core_num, *low, *high);
+
+ nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
+ NSS_TX_METADATA_TYPE_SET_WATER_MARK,
+ sizeof(struct nss_n2h_water_mark),
+ nss_n2h_payload_stats_callback,
+ (void *)core_num);
+
+ wm = &nnm.msg.wm;
+ wm->low_water = htonl(*low);
+ wm->high_water = htonl(*high);
+ nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
+
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: core %d nss_tx error setting : %d, %d\n",
+ nss_ctx, core_num, *low, *high);
+ goto failure;
+ }
+
+ /*
+ * Blocking call, wait till we get ACK for this msg.
+ */
+ ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete,
+ msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: core %d Waiting for ack timed out\n", nss_ctx,
+ core_num);
+ goto failure;
+ }
+
+ /*
+ * ACK/NACK received from NSS FW
+ */
+ if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response)
+ goto failure;
+
+ up(&nss_n2h_nepbcfgp[core_num].sem);
+ return NSS_SUCCESS;
+
+failure:
+ /*
+ * Restore the current_value to its previous state
+ */
+ *low = nss_n2h_nepbcfgp[core_num].low_water;
+ *high = nss_n2h_nepbcfgp[core_num].high_water;
up(&nss_n2h_nepbcfgp[core_num].sem);
return -EINVAL;
}
@@ -371,11 +627,11 @@
* Sets the number of empty buffer for core 1
*/
static int nss_n2h_empty_pool_buf_cfg_core1_handler(ctl_table *ctl,
- int write, void __user *buffer,
- size_t *lenp, loff_t *ppos)
+ int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
- NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
+ NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]);
}
/*
@@ -383,11 +639,37 @@
* Sets the number of empty buffer for core 0
*/
static int nss_n2h_empty_pool_buf_cfg_core0_handler(ctl_table *ctl,
- int write, void __user *buffer,
- size_t *lenp, loff_t *ppos)
+ int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
return nss_n2h_set_empty_pool_buf(ctl, write, buffer, lenp, ppos,
- NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
+ NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]);
+}
+
+/*
+ * nss_n2h_water_mark_core1_handler()
+ * Sets water mark for core 1
+ */
+static int nss_n2h_water_mark_core1_handler(ctl_table *ctl,
+ int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
+ NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0],
+ &nss_n2h_water_mark[NSS_CORE_1][1]);
+}
+
+/*
+ * nss_n2h_water_mark_core0_handler()
+ * Sets water mark for core 0
+ */
+static int nss_n2h_water_mark_core0_handler(ctl_table *ctl,
+ int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos,
+ NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0],
+ &nss_n2h_water_mark[NSS_CORE_0][1]);
}
/*
@@ -443,20 +725,188 @@
return NSS_SUCCESS;
}
+/*
+ * nss_n2h_mitigation_cfg()
+ * Send Message to NSS to disable MITIGATION.
+ */
+nss_tx_status_t nss_n2h_mitigation_cfg(struct nss_ctx_instance *nss_ctx, int enable_mitigation, nss_core_id_t core_num)
+{
+ struct nss_n2h_msg nnm;
+ struct nss_n2h_mitigation *mitigation_cfg;
+ nss_tx_status_t nss_tx_status;
+ int ret;
+
+ nss_assert(core_num < NSS_CORE_MAX);
+
+ down(&nss_n2h_mitigationcp[core_num].sem);
+ nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG,
+ sizeof(struct nss_n2h_mitigation),
+ nss_n2h_mitigation_cfg_callback,
+ (void *)core_num);
+
+ mitigation_cfg = &nnm.msg.mitigation_cfg;
+ mitigation_cfg->enable = enable_mitigation;
+
+ nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
+
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+ nss_warning("%p: nss_tx error setting mitigation\n", nss_ctx);
+ goto failure;
+ }
+
+ /*
+ * Blocking call, wait till we get ACK for this msg.
+ */
+ ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
+ goto failure;
+ }
+
+ /*
+ * ACK/NACK received from NSS FW
+ */
+ if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) {
+ goto failure;
+ }
+
+ up(&nss_n2h_mitigationcp[core_num].sem);
+ return NSS_SUCCESS;
+
+failure:
+ up(&nss_n2h_mitigationcp[core_num].sem);
+ return NSS_FAILURE;
+}
+
+static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool)
+{
+ int page_count;
+ for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) {
+ kfree(buf_pool->nss_buf_pool_vaddr[page_count]);
+ }
+}
+
+/*
+ * nss_n2h_buf_cfg()
+ * Send Message to NSS to enable pbufs.
+ */
+nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx,
+ int buf_pool_size, nss_core_id_t core_num)
+{
+ static struct nss_n2h_msg nnm;
+ struct nss_n2h_buf_pool *buf_pool;
+ nss_tx_status_t nss_tx_status;
+ int ret;
+ int page_count;
+ int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE;
+
+ nss_assert(core_num < NSS_CORE_MAX);
+
+ nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL,
+ sizeof(struct nss_n2h_buf_pool),
+ nss_n2h_bufs_cfg_callback,
+ (void *)core_num);
+
+ do {
+
+ down(&nss_n2h_bufcp[core_num].sem);
+
+ buf_pool = &nnm.msg.buf_pool;
+ buf_pool->nss_buf_page_size = PAGE_SIZE;
+
+ for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) {
+
+ void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ if (!kern_addr) {
+ BUG_ON(!page_count);
+ break;
+ }
+ BUG_ON((long unsigned int)kern_addr % PAGE_SIZE);
+
+ buf_pool->nss_buf_pool_vaddr[page_count] = kern_addr;
+ buf_pool->nss_buf_pool_addr[page_count] = dma_map_single(NULL, kern_addr, PAGE_SIZE, DMA_TO_DEVICE);
+ }
+
+ buf_pool->nss_buf_num_pages = page_count;
+ nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm);
+ if (nss_tx_status != NSS_TX_SUCCESS) {
+
+ nss_n2h_buf_pool_free(buf_pool);
+ nss_warning("%p: nss_tx error setting pbuf\n", nss_ctx);
+ goto failure;
+ }
+
+ /*
+ * Blocking call, wait till we get ACK for this msg.
+ */
+ ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT));
+ if (ret == 0) {
+ nss_warning("%p: Waiting for ack timed out\n", nss_ctx);
+ goto failure;
+ }
+
+ /*
+ * ACK/NACK received from NSS FW
+ */
+ if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) {
+
+ nss_n2h_buf_pool_free(buf_pool);
+ goto failure;
+ }
+
+ up(&nss_n2h_bufcp[core_num].sem);
+ } while(num_pages);
+
+ return NSS_SUCCESS;
+failure:
+ up(&nss_n2h_bufcp[core_num].sem);
+ return NSS_FAILURE;
+}
+
+
+
static ctl_table nss_n2h_table[] = {
{
- .procname = "n2h_empty_pool_buf_core0",
- .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
+ .procname = "n2h_empty_pool_buf_core0",
+ .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0],
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler,
},
{
- .procname = "n2h_empty_pool_buf_core1",
- .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
+ .procname = "n2h_empty_pool_buf_core1",
+ .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1],
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler,
+ },
+ {
+ .procname = "n2h_low_water_core0",
+ .data = &nss_n2h_water_mark[NSS_CORE_0][0],
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_n2h_water_mark_core0_handler,
+ },
+ {
+ .procname = "n2h_low_water_core1",
+ .data = &nss_n2h_water_mark[NSS_CORE_1][0],
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_n2h_water_mark_core1_handler,
+ },
+ {
+ .procname = "n2h_high_water_core0",
+ .data = &nss_n2h_water_mark[NSS_CORE_0][1],
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_n2h_water_mark_core0_handler,
+ },
+ {
+ .procname = "n2h_high_water_core1",
+ .data = &nss_n2h_water_mark[NSS_CORE_1][1],
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &nss_n2h_water_mark_core1_handler,
},
{ }
@@ -518,14 +968,24 @@
*/
sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1);
init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete);
- nss_n2h_nepbcfgp[NSS_CORE_0].current_value = nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
+ nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool =
+ nss_n2h_empty_pool_buf_cfg[NSS_CORE_0];
+ nss_n2h_nepbcfgp[NSS_CORE_0].low_water =
+ nss_n2h_water_mark[NSS_CORE_0][0];
+ nss_n2h_nepbcfgp[NSS_CORE_0].high_water =
+ nss_n2h_water_mark[NSS_CORE_0][1];
/*
* Core1
*/
sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1);
init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete);
- nss_n2h_nepbcfgp[NSS_CORE_1].current_value = nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
+ nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool =
+ nss_n2h_empty_pool_buf_cfg[NSS_CORE_1];
+ nss_n2h_nepbcfgp[NSS_CORE_1].low_water =
+ nss_n2h_water_mark[NSS_CORE_1][0];
+ nss_n2h_nepbcfgp[NSS_CORE_1].high_water =
+ nss_n2h_water_mark[NSS_CORE_1][1];
}
/*
@@ -636,6 +1096,29 @@
sema_init(&nss_n2h_rcp.sem, 1);
init_completion(&nss_n2h_rcp.complete);
+ /*
+ * MITIGATION sema init for core0
+ */
+ sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1);
+ init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete);
+
+ /*
+ * MITIGATION sema init for core1
+ */
+ sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1);
+ init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete);
+
+ /*
+ * PBUF addition sema init for core0
+ */
+ sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1);
+ init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete);
+
+ /*
+ * PBUF addition sema init for core1
+ */
+ sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1);
+ init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete);
nss_n2h_notify_register(NSS_CORE_0, NULL, NULL);
nss_n2h_notify_register(NSS_CORE_1, NULL, NULL);
diff --git a/nss_phys_if.c b/nss_phys_if.c
index 6da204d..b8af1c2 100644
--- a/nss_phys_if.c
+++ b/nss_phys_if.c
@@ -600,6 +600,13 @@
nss_ctx->max_buf_size = ((mtu_sz + ETH_HLEN + SMP_CACHE_BYTES - 1) & ~(SMP_CACHE_BYTES - 1)) + NSS_NBUF_PAD_EXTRA;
+ /*
+ * max_buf_size should not be lesser than NSS_NBUF_PAYLOAD_SIZE
+ */
+ if (nss_ctx->max_buf_size < NSS_NBUF_PAYLOAD_SIZE) {
+ nss_ctx->max_buf_size = NSS_NBUF_PAYLOAD_SIZE;
+ }
+
nss_info("Current mtu:%u mtu_sz:%u max_buf_size:%d\n", mtu, mtu_sz, nss_ctx->max_buf_size);
if (mtu_sz > nss_ctx->nss_top->prev_mtu_sz) {
diff --git a/nss_pm.h b/nss_pm.h
index 2a2cb8d..1b2d27e 100644
--- a/nss_pm.h
+++ b/nss_pm.h
@@ -115,8 +115,8 @@
{\
.src = MSM_BUS_MASTER_NSS_CRYPTO5_0, \
.dst = MSM_BUS_SLAVE_EBI_CH0, \
- .ab = (_data_bw) * 16 * 1000000ULL, \
- .ib = (_data_bw) * 16 * 1000000ULL, \
+ .ab = 0, \
+ .ib = 0, \
}, \
{ \
.src = MSM_BUS_MASTER_NSS_CRYPTO5_0, \
diff --git a/nss_stats.c b/nss_stats.c
index d5ed3e5..b5f1373 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -150,6 +150,7 @@
"h2n_data_bytes",
"n2h_data_packets",
"n2h_data_bytes",
+ "n2h_tot_payloads",
};
/*
diff --git a/nss_tx_rx_virt_if.c b/nss_tx_rx_virt_if.c
index bd59d4e..87e7e6d 100644
--- a/nss_tx_rx_virt_if.c
+++ b/nss_tx_rx_virt_if.c
@@ -119,7 +119,7 @@
* to the same callback/app_data.
*/
if (ncm->response == NSS_CMM_RESPONSE_NOTIFY) {
- ncm->cb = (uint32_t)nss_ctx->nss_top->virt_if_msg_callback[ncm->interface];
+ ncm->cb = (uint32_t)nss_ctx->nss_top->if_rx_msg_callback[ncm->interface];
ncm->app_data = (uint32_t)nss_ctx->nss_top->subsys_dp_register[ncm->interface].ndev;
}
@@ -180,6 +180,8 @@
nss_top_main.subsys_dp_register[if_num].app_data = NULL;
nss_top_main.subsys_dp_register[if_num].features = (uint32_t)netdev->features;
+ nss_top_main.if_rx_msg_callback[if_num] = NULL;
+
return ctx;
}
diff --git a/nss_virt_if.c b/nss_virt_if.c
index 92b80e8..8a14d63 100644
--- a/nss_virt_if.c
+++ b/nss_virt_if.c
@@ -117,7 +117,7 @@
* to the same callback/app_data.
*/
if (ncm->response == NSS_CMM_RESPONSE_NOTIFY) {
- ncm->cb = (uint32_t)nss_ctx->nss_top->virt_if_msg_callback[ncm->interface];
+ ncm->cb = (uint32_t)nss_ctx->nss_top->if_rx_msg_callback[ncm->interface];
ncm->app_data = (uint32_t)nss_ctx->nss_top->subsys_dp_register[ncm->interface].ndev;
}
@@ -887,6 +887,8 @@
nss_top_main.subsys_dp_register[if_num].cb = data_callback;
nss_top_main.subsys_dp_register[if_num].app_data = NULL;
nss_top_main.subsys_dp_register[if_num].features = (uint32_t)netdev->features;
+
+ nss_top_main.if_rx_msg_callback[if_num] = NULL;
}
EXPORT_SYMBOL(nss_virt_if_register);