Merge "[qca-nss-drv] Register bridge netdev in data plane"
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index 640d7d3..6c1f49a 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014 - 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.
@@ -55,9 +55,26 @@
NSS_TX_METADATA_TYPE_SET_WATER_MARK,
NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
+ NSS_TX_DDR_INFO_VIA_N2H_CFG,
NSS_METADATA_TYPE_N2H_MAX,
};
+/*
+ * n2h errors -- reference only.
+ */
+enum nss_n2h_error_types {
+ N2H_EUNKNOWN = 1,
+ N2H_ALREADY_CFG, /* Already configured */
+ N2H_LOW_WATER_MIN_INVALID, /* Low water's is lower than min */
+ N2H_HIGH_WATER_LESS_THAN_LOW, /* High water is less than low water */
+ N2H_HIGH_WATER_LIMIT_INVALID, /* High water limit is more than allowed */
+ N2H_LOW_WATER_LIMIT_INVALID, /* Low water limit is more than allowed */
+ N2H_WATER_MARK_INVALID, /* High-Low water is not at least in ring size difference */
+ N2H_EMPTY_BUFFER_TOO_HIGH, /* Empty buffer size is more than allowed */
+ N2H_EMPTY_BUFFER_TOO_LOW, /* Empty buffer size is too low */
+ N2H_MMU_ENTRY_IS_INVALID, /* mmu DDR range entry is not ok to change */
+};
+
struct nss_n2h_rps {
uint32_t enable; /* Enable NSS RPS */
};
@@ -162,6 +179,14 @@
};
/*
+ * system DDR memory info needed by FW MMU to set range guardian
+ */
+struct nss_mmu_ddr_info {
+ uint32_t ddr_size; /* total DDR size */
+ uint32_t start_address; /* system DDR start address */
+};
+
+/*
* Message structure to send/receive phys i/f commands
*/
struct nss_n2h_msg {
@@ -182,6 +207,7 @@
/* Message: Gets payload info */
struct nss_n2h_wifi_payloads wp;
/* Message: Sets number of wifi payloads */
+ struct nss_mmu_ddr_info mmu; /* use N2H for carrier, will change later */
} msg;
};
diff --git a/nss_core.c b/nss_core.c
index fdad77b..1f8396d 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -21,6 +21,7 @@
#include "nss_core.h"
#include <linux/module.h>
+#include <linux/of.h>
#include <nss_hal.h>
#include <net/dst.h>
#include <linux/etherdevice.h>
@@ -316,12 +317,86 @@
}
/*
+ * nss_get_ddr_info()
+ * get DDR start address and size from device tree.
+ */
+static void nss_get_ddr_info(struct nss_mmu_ddr_info *mmu, char *name)
+{
+ struct device_node *node = of_find_node_by_name(NULL, name);
+ if (node) {
+ int len;
+ const __be32 *ppp = (int32_t*)of_get_property(node, "reg", &len);
+ if (ppp && len == sizeof(ppp[0]) * 2) {
+ mmu->start_address = be32_to_cpup(ppp);
+ mmu->ddr_size = be32_to_cpup(&ppp[1]);
+ of_node_put(node);
+ nss_info_always("%s: %x %x prop len %d\n", name,
+ mmu->start_address, mmu->ddr_size, len);
+ return;
+ }
+ of_node_put(node);
+ nss_info_always("incorrect memory info %p len %d\n",
+ ppp, len);
+ }
+
+ /*
+ * boilerplate for setting customer values;
+ * start_address = 0 will not change default start address
+ * set in NSS FW (likely 0x4000_0000)
+ */
+ mmu->start_address = 0;
+ mmu->ddr_size = 1 << 30;
+ nss_warning("of_find_node_by_name for %s failed: use default 1GB\n", name);
+}
+
+/*
+ * nss_send_ddr_info()
+ * Send DDR info to NSS
+ */
+static int32_t nss_send_ddr_info(struct nss_ctx_instance *nss_own)
+{
+ struct sk_buff *nbuf;
+ int32_t status;
+ struct nss_n2h_msg *nnm;
+ atomic64_t *stats;
+
+ nss_info("%p: send DDR info\n", nss_own);
+
+ nbuf = dev_alloc_skb(NSS_NBUF_PAYLOAD_SIZE);
+ if (unlikely(!nbuf)) {
+ struct nss_top_instance *nss_top = nss_own->nss_top;
+ stats = &nss_top->stats_drv[NSS_STATS_DRV_NBUF_ALLOC_FAILS];
+
+ NSS_PKT_STATS_INCREMENT(nss_own, stats);
+ nss_warning("%p: Unable to allocate memory for 'tx DDR info'", nss_own);
+ return NSS_CORE_STATUS_FAILURE;
+ }
+
+ nnm = (struct nss_n2h_msg *)skb_put(nbuf, sizeof(struct nss_n2h_msg));
+ nss_cmn_msg_init(&nnm->cm, NSS_N2H_INTERFACE, NSS_TX_DDR_INFO_VIA_N2H_CFG,
+ sizeof(struct nss_mmu_ddr_info), NULL, NULL);
+
+ nss_get_ddr_info(&nnm->msg.mmu, "memory");
+
+ status = nss_core_send_buffer(nss_own, 0, nbuf, NSS_IF_CMD_QUEUE, H2N_BUFFER_CTRL, 0);
+ if (unlikely(status != NSS_CORE_STATUS_SUCCESS)) {
+ dev_kfree_skb_any(nbuf);
+ nss_warning("%p: Unable to enqueue 'tx DDR info'\n", nss_own);
+ return NSS_CORE_STATUS_FAILURE;
+ }
+
+ nss_hal_send_interrupt(nss_own, NSS_H2N_INTR_DATA_COMMAND_QUEUE);
+
+ return NSS_CORE_STATUS_SUCCESS;
+}
+
+/*
* nss_core_cause_to_queue()
* Map interrupt cause to queue id
*/
static inline uint16_t nss_core_cause_to_queue(uint16_t cause)
{
- if (likely(cause == NSS_N2H_INTR_DATA_COMMAND_QUEUE)) {
+ if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_0)) {
return NSS_IF_DATA_QUEUE_0;
}
@@ -329,6 +404,14 @@
return NSS_IF_DATA_QUEUE_1;
}
+ if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_2)) {
+ return NSS_IF_DATA_QUEUE_2;
+ }
+
+ if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_3)) {
+ return NSS_IF_DATA_QUEUE_3;
+ }
+
if (likely(cause == NSS_N2H_INTR_EMPTY_BUFFER_QUEUE)) {
return NSS_IF_EMPTY_BUFFER_QUEUE;
}
@@ -623,6 +706,11 @@
NSS_PKT_STATS_DECREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NSS_SKB_COUNT]);
+ if (interface_num >= NSS_MAX_NET_INTERFACES) {
+ nss_warning("%p: Invalid interface_num: %d", nss_ctx, interface_num);
+ return;
+ }
+
switch (buffer_type) {
case N2H_BUFFER_SHAPER_BOUNCED_INTERFACE:
reg = &nss_top->bounce_interface_registrants[interface_num];
@@ -1250,6 +1338,7 @@
*/
if (unlikely(nss_ctx->state == NSS_CORE_STATE_UNINITIALIZED)) {
nss_core_init_nss(nss_ctx, if_map);
+ nss_send_ddr_info(nss_ctx);
#if (NSS_MAX_CORES > 1)
/*
@@ -1473,10 +1562,10 @@
return NSS_N2H_INTR_TX_UNBLOCKED;
}
- if (cause & NSS_N2H_INTR_DATA_COMMAND_QUEUE) {
+ if (cause & NSS_N2H_INTR_DATA_QUEUE_0) {
*type = NSS_INTR_CAUSE_QUEUE;
*weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT;
- return NSS_N2H_INTR_DATA_COMMAND_QUEUE;
+ return NSS_N2H_INTR_DATA_QUEUE_0;
}
if (cause & NSS_N2H_INTR_DATA_QUEUE_1) {
@@ -1485,6 +1574,18 @@
return NSS_N2H_INTR_DATA_QUEUE_1;
}
+ if (cause & NSS_N2H_INTR_DATA_QUEUE_2) {
+ *type = NSS_INTR_CAUSE_QUEUE;
+ *weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT;
+ return NSS_N2H_INTR_DATA_QUEUE_2;
+ }
+
+ if (cause & NSS_N2H_INTR_DATA_QUEUE_3) {
+ *type = NSS_INTR_CAUSE_QUEUE;
+ *weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT;
+ return NSS_N2H_INTR_DATA_QUEUE_3;
+ }
+
if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE_0) {
printk("NSS core 0 signal COREDUMP COMPLETE %x ", cause);
*type = NSS_INTR_CAUSE_EMERGENCY;
diff --git a/nss_core.h b/nss_core.h
index c7faa01..738f36b 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -123,6 +123,8 @@
#define NSS_IF_EMPTY_BUFFER_QUEUE 0
#define NSS_IF_DATA_QUEUE_0 1
#define NSS_IF_DATA_QUEUE_1 2
+#define NSS_IF_DATA_QUEUE_2 3
+#define NSS_IF_DATA_QUEUE_3 4
#define NSS_IF_CMD_QUEUE 1
/*
@@ -154,12 +156,13 @@
/*
* NSS maximum data queue per core
*/
-#define NSS_MAX_DATA_QUEUE 2
+#define NSS_MAX_DATA_QUEUE 4
/*
- * NSS maximum IRQ per interrupt instance
+ * NSS maximum IRQ per interrupt instance/core
*/
-#define NSS_MAX_IRQ_PER_INSTANCE 5
+#define NSS_MAX_IRQ_PER_INSTANCE 4
+#define NSS_MAX_IRQ_PER_CORE 7
/*
* NSS maximum clients
@@ -822,6 +825,8 @@
/* HLOS IRQ numbers bind to this instance */
uint32_t shift_factor; /* Shift factor for this IRQ queue */
uint32_t cause; /* Interrupt cause carried forward to BH */
+ uint32_t queue_cause; /* Queue cause bind to this interrupt ctx */
+ char irq_name[11]; /* IRQ name bind to this interrupt ctx */
struct net_device *ndev; /* Netdev associated with this interrupt ctx */
struct napi_struct napi; /* NAPI handler */
};
@@ -1166,6 +1171,7 @@
uint32_t average_inst; /* average of inst for nss core */
uint32_t coredump; /* cmd coredump buffer */
};
+extern struct nss_cmd_buffer nss_cmd_buf;
/*
* The scales for NSS
@@ -1233,17 +1239,17 @@
* Platform data per core
*/
struct nss_platform_data {
- uint32_t id; /* NSS core ID */
- uint32_t num_queue; /* No. of queues supported per core */
- uint32_t num_irq; /* No. of irq binded per queue */
- uint32_t irq[5]; /* IRQ numbers per queue */
- void __iomem *nmap; /* Virtual addr of NSS CSM space */
- void __iomem *vmap; /* Virtual addr of NSS virtual register map */
+ uint32_t id; /* NSS core ID */
+ uint32_t num_queue; /* No. of queues supported per core */
+ uint32_t num_irq; /* No. of irq binded per queue */
+ uint32_t irq[NSS_MAX_IRQ_PER_CORE]; /* IRQ numbers per queue */
+ void __iomem *nmap; /* Virtual addr of NSS CSM space */
+ void __iomem *vmap; /* Virtual addr of NSS virtual register map */
void __iomem *qgic_map; /* Virtual addr of QGIC interrupt register */
- uint32_t nphys; /* Physical addr of NSS CSM space */
- uint32_t vphys; /* Physical addr of NSS virtual register map */
- uint32_t qgic_phys; /* Physical addr of QGIC virtual register map */
- uint32_t load_addr; /* Load address of NSS firmware */
+ uint32_t nphys; /* Physical addr of NSS CSM space */
+ uint32_t vphys; /* Physical addr of NSS virtual register map */
+ uint32_t qgic_phys; /* Physical addr of QGIC virtual register map */
+ uint32_t load_addr; /* Load address of NSS firmware */
enum nss_feature_enabled capwap_enabled;
/* Does this core handle capwap? */
@@ -1385,7 +1391,7 @@
/*
* APIs provided by nss_freq.c
*/
-extern void nss_freq_sched_change(nss_freq_scales_t index, bool auto_scale);
+extern bool nss_freq_sched_change(nss_freq_scales_t index, bool auto_scale);
/*
* APIs for PPE
diff --git a/nss_coredump.c b/nss_coredump.c
index 1d870a2..4692d48 100644
--- a/nss_coredump.c
+++ b/nss_coredump.c
@@ -151,11 +151,21 @@
if (nss_ctx != nss_own) {
if (nss_ctx->state & NSS_CORE_STATE_FW_DEAD ||
!nss_ctx->nmap) {
- /*
- * cannot call atomic_notifier_chain_unregister?
- * (&panic_notifier_list, &nss_panic_nb);
- */
- panic("NSS FW coredump: bringing system down\n");
+ if (nss_cmd_buf.coredump & 0xFFFFFFFE) {
+ /*
+ * bit 1 is used for testing coredump. Any other
+ * bit(s) (value other than 0/1) disable panic
+ * in order to use mdump utility: see mdump/src/README
+ * for more info.
+ */
+ nss_info_always("NSS core dump completed and please use mdump to collect dump data\n");
+ } else {
+ /*
+ * cannot call atomic_notifier_chain_unregister?
+ * (&panic_notifier_list, &nss_panic_nb);
+ */
+ panic("NSS FW coredump: bringing system down\n");
+ }
}
nss_warning("notify NSS FW %p for coredump\n",
nss_ctx->nmap);
diff --git a/nss_crypto.c b/nss_crypto.c
index 200deab..cc1808a 100644
--- a/nss_crypto.c
+++ b/nss_crypto.c
@@ -129,12 +129,7 @@
return NSS_TX_FAILURE_NOT_READY;
}
-
- if (NSS_NBUF_PAYLOAD_SIZE < sizeof(struct nss_crypto_msg)) {
- nss_warning("%p: tx message request is too large: %d (desired), %d (requested)", nss_ctx,
- NSS_NBUF_PAYLOAD_SIZE, (int)sizeof(struct nss_crypto_msg));
- return NSS_TX_FAILURE_TOO_LARGE;
- }
+ BUILD_BUG_ON(NSS_NBUF_PAYLOAD_SIZE < sizeof(struct nss_crypto_msg));
if (ncm->interface != NSS_CRYPTO_INTERFACE) {
nss_warning("%p: tx message request for another interface: %d", nss_ctx, ncm->interface);
diff --git a/nss_freq.c b/nss_freq.c
index d5e6fa9..86adbb6 100644
--- a/nss_freq.c
+++ b/nss_freq.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013, 2015-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2015-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.
@@ -24,7 +24,6 @@
#define NSS_ACK_STARTED 0
#define NSS_ACK_FINISHED 1
-extern struct nss_cmd_buffer nss_cmd_buf;
extern struct nss_frequency_statistics nss_freq_stat;
extern struct nss_runtime_sampling nss_runtime_samples;
extern struct workqueue_struct *nss_wq;
@@ -71,7 +70,7 @@
* nss_freq_queue_work()
* Queue Work to the NSS Workqueue based on Current index.
*/
-static int nss_freq_queue_work(void)
+static bool nss_freq_queue_work(void)
{
nss_freq_scales_t index = nss_runtime_samples.freq_scale_index;
@@ -83,9 +82,7 @@
/*
* schedule freq change with autoscale ON
*/
- nss_freq_sched_change(index, true);
-
- return 0;
+ return nss_freq_sched_change(index, true);
}
/*
@@ -171,7 +168,7 @@
* If fail to increase frequency, decrease index
*/
nss_trace("frequency increase to %d inst:%x > maximum:%x\n", nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency, sample, maximum);
- if (nss_freq_queue_work()) {
+ if (!nss_freq_queue_work()) {
nss_runtime_samples.freq_scale_index--;
}
}
@@ -198,7 +195,7 @@
* If fail to decrease frequency, increase index
*/
nss_trace("frequency decrease to %d inst:%x < minumum:%x\n", nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency, nss_runtime_samples.average, minimum);
- if (nss_freq_queue_work()) {
+ if (!nss_freq_queue_work()) {
nss_runtime_samples.freq_scale_index++;
}
}
@@ -282,17 +279,17 @@
* nss_freq_sched_change()
* schedule a frequency work
*/
-void nss_freq_sched_change(nss_freq_scales_t index, bool auto_scale)
+bool nss_freq_sched_change(nss_freq_scales_t index, bool auto_scale)
{
if (index >= NSS_FREQ_MAX_SCALE) {
nss_info("NSS freq scale beyond limit\n");
- return;
+ return false;
}
nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC);
if (!nss_work) {
nss_info("NSS Freq WQ kmalloc fail");
- return;
+ return false;
}
INIT_WORK((struct work_struct *)nss_work, nss_wq_function);
@@ -302,6 +299,8 @@
nss_work->stats_enable = auto_scale;
nss_cmd_buf.current_freq = nss_work->frequency;
queue_work(nss_wq, (struct work_struct *)nss_work);
+
+ return true;
}
/*
diff --git a/nss_hal/include/nss_hal.h b/nss_hal/include/nss_hal.h
index 004dbba..1ac6e20 100644
--- a/nss_hal/include/nss_hal.h
+++ b/nss_hal/include/nss_hal.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-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.
@@ -43,13 +43,12 @@
#endif
#define NSS_HAL_SUPPORTED_INTERRUPTS (NSS_N2H_INTR_EMPTY_BUFFER_QUEUE | \
- NSS_N2H_INTR_DATA_COMMAND_QUEUE | \
+ NSS_N2H_INTR_DATA_QUEUE_0 | \
NSS_N2H_INTR_DATA_QUEUE_1 | \
NSS_N2H_INTR_EMPTY_BUFFERS_SOS | \
NSS_N2H_INTR_TX_UNBLOCKED | \
NSS_N2H_INTR_COREDUMP_COMPLETE_0 | \
NSS_N2H_INTR_COREDUMP_COMPLETE_1)
-#define NSS_MAX_IRQ_PER_QUEUE 5
/*
* nss_hal_read_interrupt_cause()
diff --git a/nss_hal/include/nss_regs.h b/nss_hal/include/nss_regs.h
index b33b0b8..9af9508 100644
--- a/nss_hal/include/nss_regs.h
+++ b/nss_hal/include/nss_regs.h
@@ -60,8 +60,10 @@
* both NSS cores may generate interrupt simultaneously
*/
#define NSS_N2H_INTR_EMPTY_BUFFER_QUEUE (1 << 0)
-#define NSS_N2H_INTR_DATA_COMMAND_QUEUE (1 << 1)
+#define NSS_N2H_INTR_DATA_QUEUE_0 (1 << 1)
#define NSS_N2H_INTR_DATA_QUEUE_1 (1 << 2)
+#define NSS_N2H_INTR_DATA_QUEUE_2 (1 << 3)
+#define NSS_N2H_INTR_DATA_QUEUE_3 (1 << 4)
#define NSS_N2H_INTR_EMPTY_BUFFERS_SOS (1 << 10)
#define NSS_N2H_INTR_TX_UNBLOCKED (1 << 11)
#define NSS_N2H_INTR_COREDUMP_COMPLETE_1 (1 << 13)
diff --git a/nss_hal/ipq807x/nss_hal_pvt.c b/nss_hal/ipq807x/nss_hal_pvt.c
index f082ee6..b03534c 100644
--- a/nss_hal/ipq807x/nss_hal_pvt.c
+++ b/nss_hal/ipq807x/nss_hal_pvt.c
@@ -54,11 +54,11 @@
/*
* nss_hal_handle_data_cmd_irq()
*/
-static irqreturn_t nss_hal_handle_data_cmd_irq(int irq, void *ctx)
+static irqreturn_t nss_hal_handle_data_cmd_queue_irq(int irq, void *ctx)
{
struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx;
- int_ctx->cause |= NSS_N2H_INTR_DATA_COMMAND_QUEUE;
+ int_ctx->cause |= int_ctx->queue_cause;
if (napi_schedule_prep(&int_ctx->napi))
__napi_schedule(&int_ctx->napi);
@@ -97,21 +97,6 @@
}
/*
- * nss_hal_handle_data_queue_one_irq()
- */
-static irqreturn_t nss_hal_handle_data_queue_one_irq(int irq, void *ctx)
-{
- struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx;
-
- int_ctx->cause |= NSS_N2H_INTR_DATA_QUEUE_1;
-
- if (napi_schedule_prep(&int_ctx->napi))
- __napi_schedule(&int_ctx->napi);
-
- return IRQ_HANDLED;
-}
-
-/*
* nss_hal_handle_tx_unblock_irq()
*/
static irqreturn_t nss_hal_handle_tx_unblock_irq(int irq, void *ctx)
@@ -429,15 +414,19 @@
int err;
/*
- * Queue1 use the last (#5) IRQ and queue0 use #1 to #4
+ * Queue0-3 use the IRQ #4 to #7, and are mapped to cause bit 1 to 4
*/
- if (qnum == 1) {
- err = request_irq(npd->irq[4], nss_hal_handle_data_queue_one_irq, 0, "nss_queue1", int_ctx);
- if (err) {
- nss_info_always("%p: IRQ%d request failed", int_ctx, npd->irq[4]);
- return err;
- }
- int_ctx->irq[0] = npd->irq[4];
+ snprintf(int_ctx->irq_name, 11, "nss_queue%d", qnum);
+ int_ctx->queue_cause = (1 << (qnum+1));
+ err = request_irq(npd->irq[qnum+3], nss_hal_handle_data_cmd_queue_irq, 0, int_ctx->irq_name, int_ctx);
+ if (err) {
+ nss_info_always("%p: IRQ%d request failed", int_ctx, npd->irq[qnum+3]);
+ return err;
+ }
+
+ int_ctx->irq[0] = npd->irq[qnum+3];
+
+ if (qnum) {
return 0;
}
@@ -446,28 +435,24 @@
nss_info_always("%p: IRQ%d request failed", int_ctx, npd->irq[0]);
return err;
}
- int_ctx->irq[0] = npd->irq[0];
- err = request_irq(npd->irq[1], nss_hal_handle_data_cmd_irq, 0, "nss_queue0", int_ctx);
+ int_ctx->irq[1] = npd->irq[0];
+
+ err = request_irq(npd->irq[1], nss_hal_handle_empty_buff_queue_irq, 0, "nss_empty_buf_queue", int_ctx);
if (err) {
nss_info_always("%p: IRQ%d request failed", int_ctx, npd->irq[1]);
return err;
}
- int_ctx->irq[1] = npd->irq[1];
- err = request_irq(npd->irq[2], nss_hal_handle_empty_buff_queue_irq, 0, "nss_empty_buf_queue", int_ctx);
+ int_ctx->irq[2] = npd->irq[1];
+
+ err = request_irq(npd->irq[2], nss_hal_handle_tx_unblock_irq, 0, "nss-tx-unblock", int_ctx);
if (err) {
nss_info_always("%p: IRQ%d request failed", int_ctx, npd->irq[2]);
return err;
}
- int_ctx->irq[2] = npd->irq[2];
- err = request_irq(npd->irq[3], nss_hal_handle_tx_unblock_irq, 0, "nss-tx-unblock", int_ctx);
- if (err) {
- nss_info_always("%p: IRQ%d request failed", int_ctx, npd->irq[3]);
- return err;
- }
- int_ctx->irq[3] = npd->irq[3];
+ int_ctx->irq[3] = npd->irq[2];
return 0;
}
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index 537bde1..7970602 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -142,12 +142,17 @@
{
int i;
- for (i = 0; i < NSS_MAX_IRQ_PER_QUEUE; i++) {
+ for (i = 0; i < NSS_MAX_IRQ_PER_INSTANCE; i++) {
if (int_ctx->irq[i]) {
free_irq(int_ctx->irq[i], int_ctx);
int_ctx->irq[i] = 0;
}
}
+
+ if (!int_ctx->ndev) {
+ return;
+ }
+
unregister_netdev(int_ctx->ndev);
free_netdev(int_ctx->ndev);
int_ctx->ndev = NULL;
@@ -196,7 +201,6 @@
err = nss_top->hal_ops->request_irq_for_queue(nss_ctx, npd, qnum);
if (err) {
nss_warning("%p: IRQ request for queue %d failed", nss_ctx, qnum);
- nss_hal_clean_up_netdevice(int_ctx);
return err;
}
@@ -312,26 +316,10 @@
nss_info("%d:ctx=%p, vphys=%x, vmap=%p, nphys=%x, nmap=%p", nss_ctx->id,
nss_ctx, nss_ctx->vphys, nss_ctx->vmap, nss_ctx->nphys, nss_ctx->nmap);
- /*
- * Register netdevice for queue 0
- */
- err = nss_hal_register_netdevice(nss_ctx, npd, 0);
- if (err) {
- goto err_init;
- }
-
- /*
- * Check if second interrupt is supported on this nss core
- */
- if (npd->num_queue > 1) {
- nss_info("%d: This NSS core supports two interrupts", nss_dev->id);
-
- /*
- * Register netdevice for queue 1
- */
- err = nss_hal_register_netdevice(nss_ctx, npd, 1);
+ for (i = 0; i < npd->num_queue; i++) {
+ err = nss_hal_register_netdevice(nss_ctx, npd, i);
if (err) {
- goto err_register_netdev_0;
+ goto err_register_netdevice;
}
}
@@ -523,7 +511,7 @@
*/
err = nss_top->hal_ops->core_reset(nss_dev, nss_ctx->nmap, nss_ctx->load, nss_top->clk_src);
if (err) {
- goto err_register_netdev_1;
+ goto err_register_netdevice;
}
/*
@@ -562,11 +550,10 @@
nss_info("%p: All resources initialized and nss core%d has been brought out of reset", nss_ctx, nss_dev->id);
goto out;
-err_register_netdev_1:
- nss_hal_clean_up_netdevice(&nss_ctx->int_ctx[1]);
-
-err_register_netdev_0:
- nss_hal_clean_up_netdevice(&nss_ctx->int_ctx[0]);
+err_register_netdevice:
+ for (i = 0; i < npd->num_queue; i++) {
+ nss_hal_clean_up_netdevice(&nss_ctx->int_ctx[i]);
+ }
err_init:
if (nss_dev->dev.of_node) {
diff --git a/nss_init.c b/nss_init.c
index f35e793..05314b1 100644
--- a/nss_init.c
+++ b/nss_init.c
@@ -464,7 +464,12 @@
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
if (!ret) {
- if ((write) && (nss_ctl_debug != 0)) {
+ /*
+ * if nss_cmd_buf.coredump is not 0 or 1, panic will be disabled
+ * when NSS FW crashes, so OEM/ODM have a chance to use mdump
+ * to dump crash dump (coredump) and send dump to us for analysis.
+ */
+ if ((write) && (nss_ctl_debug != 0) && nss_cmd_buf.coredump == 1) {
printk("Coredumping to DDR\n");
nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_TRIGGER_COREDUMP);
}
diff --git a/nss_ipsec.c b/nss_ipsec.c
index 0a91a0a..b0b3009 100644
--- a/nss_ipsec.c
+++ b/nss_ipsec.c
@@ -178,11 +178,7 @@
return NSS_TX_FAILURE_NOT_READY;
}
- if (NSS_NBUF_PAYLOAD_SIZE < sizeof(struct nss_ipsec_msg)) {
- nss_ipsec_warning("%p: tx message request is too large: %d (desired), %d (requested)", nss_ctx,
- NSS_NBUF_PAYLOAD_SIZE, (int)sizeof(struct nss_ipsec_msg));
- return NSS_TX_FAILURE_TOO_LARGE;
- }
+ BUILD_BUG_ON(NSS_NBUF_PAYLOAD_SIZE < sizeof(struct nss_ipsec_msg));
if ((ncm->interface != NSS_IPSEC_ENCAP_IF_NUMBER) && (ncm->interface != NSS_IPSEC_DECAP_IF_NUMBER)) {
nss_ipsec_warning("%p: tx message request for another interface: %d", nss_ctx, ncm->interface);
diff --git a/nss_virt_if.c b/nss_virt_if.c
index c476a41..b4eed1f 100644
--- a/nss_virt_if.c
+++ b/nss_virt_if.c
@@ -160,7 +160,7 @@
* Send a message from HLOS to NSS synchronously.
*/
static nss_tx_status_t nss_virt_if_tx_msg_sync(struct nss_virt_if_handle *handle,
- struct nss_virt_if_msg *nvim)
+ struct nss_virt_if_msg *nvim)
{
nss_tx_status_t status;
int ret = 0;
@@ -870,7 +870,7 @@
nss_virt_if_data_callback_t data_callback,
struct net_device *netdev)
{
- struct nss_ctx_instance *nss_ctx = handle->nss_ctx;
+ struct nss_ctx_instance *nss_ctx;
int32_t if_num;
if (!handle) {
@@ -878,6 +878,7 @@
return;
}
+ nss_ctx = handle->nss_ctx;
if_num = handle->if_num;
nss_ctx->subsys_dp_register[if_num].ndev = netdev;
@@ -894,7 +895,7 @@
*/
void nss_virt_if_unregister(struct nss_virt_if_handle *handle)
{
- struct nss_ctx_instance *nss_ctx = handle->nss_ctx;
+ struct nss_ctx_instance *nss_ctx;
int32_t if_num;
if (!handle) {
@@ -902,6 +903,7 @@
return;
}
+ nss_ctx = handle->nss_ctx;
if_num = handle->if_num;
nss_ctx->subsys_dp_register[if_num].ndev = NULL;