[qca-nss-drv] Add support for 4 N2H DATA QUEUE
Creates 4 interrupt instances to serve NSS RPS to 4
different queues.
Change-Id: Ifb1c577c8cfa7d9a8652e0207b501da80460fc7c
Signed-off-by: Stephen Wang <wstephen@codeaurora.org>
diff --git a/nss_core.c b/nss_core.c
index fdad77b..12fef11 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -321,7 +321,7 @@
*/
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 +329,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;
}
@@ -1473,10 +1481,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 +1493,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..b5b1bb1 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 */
};
@@ -1233,17 +1238,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? */
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) {