[qca-nss-drv] Pass pnode queue config during boot

 Pnode queue configuration is passed to NSS during boottime

Change-Id: Id1e3ce11fa9894706b0c0ee07610a9d145d14eb9
Signed-off-by: ratheesh kannoth <rkannoth@qti.qualcomm.com>
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index 8ebcd07..4ea418b 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -29,6 +29,10 @@
 
 #define MAX_PAGES_PER_MSG 32	/**< Maximum number of pages per message. */
 
+#define NSS_MAX_NUM_PRI 4		/**< Maximum number of pnode ingress priorities. */
+#define NSS_DEFAULT_NUM_PRI 1		/**< Default priority. */
+#define NSS_DEFAULT_QUEUE_LIMIT 256	/**< Default pnode queue limit. */
+
 /**
  * nss_n2h_cfg_pvt
  *	N2H private data configuration.
@@ -60,6 +64,7 @@
 	NSS_TX_METADATA_TYPE_GET_PAYLOAD_INFO,
 	NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG,
 	NSS_TX_DDR_INFO_VIA_N2H_CFG,
+	NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
 	NSS_METADATA_TYPE_N2H_MAX,
 };
 
@@ -110,6 +115,21 @@
 };
 
 /**
+ * nss_n2h_pnode_queue_config
+ *	N2H pnode queue configuration.
+ */
+struct nss_n2h_pnode_queue_config {
+	uint8_t num_pri;	/**< Maximum number of priorities. */
+	uint8_t mq_en;		/**< Enable multiple queues. */
+	uint16_t reserved1;	/**< Reserved for alignment. */
+	uint16_t qlimits[NSS_MAX_NUM_PRI];
+				/**< Limits of each queue. */
+#if (NSS_MAX_NUM_PRI & 1)
+	uint16_t reserved2;
+#endif
+};
+
+/**
  * nss_n2h_empty_pool_buf
  *	Old way of setting the number of empty pool buffers (payloads).
  *
@@ -265,6 +285,8 @@
 				/**< Sets the number of Wi-Fi payloads. */
 		struct nss_mmu_ddr_info mmu;
 				/**< Gets the DDR size and start address to configure the MMU. */
+		struct nss_n2h_pnode_queue_config pn_q_cfg;
+				/**< Pnode queueing configuration. */
 	} msg;			/**< Message payload. */
 };
 
@@ -352,9 +374,21 @@
 			nss_n2h_msg_callback_t cb, void *app_data);
 
 /**
+ * nss_n2h_update_queue_config
+ *	Update pnode queue configuration to NSS.
+ *
+ * @param[in] max_pri  Maximum number of ingress priorities.
+ * @param[in] mq_en    Enable multiple pnode queues.
+ * @param[in] pri_num  Number of ingress priorities.
+ * @param[in] qlimits  Maximum number of packets in each queues.
+ *
+ * @return
+ * Status of the configuration update operation.
+ */
+extern nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int pri_num, int *qlimits);
+
+/**
  * @}
  */
 
 #endif /* __NSS_N2H_H */
-
-
diff --git a/nss_core.c b/nss_core.c
index b4a7f4a..89672a0 100644
--- a/nss_core.c
+++ b/nss_core.c
@@ -56,11 +56,25 @@
 module_param(max_ipv6_conn, int, S_IRUGO);
 MODULE_PARM_DESC(max_ipv6_conn, "Max number of IPv6 connections");
 
+static bool pn_mq_en = false;
+module_param(pn_mq_en, bool, S_IRUGO);
+MODULE_PARM_DESC(pn_mq_en, "Enable pnode ingress Qos");
+
+static int pn_pri_num = NSS_MAX_NUM_PRI;
+module_param(pn_pri_num, int, S_IRUGO);
+MODULE_PARM_DESC(pn_pri_num, "Maximum number of queue priority");
+
+static int pn_qlimits[NSS_MAX_NUM_PRI] = { NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT,
+					       NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT};
+module_param_array(pn_qlimits, int, NULL, 0);
+MODULE_PARM_DESC(pn_qlimits, "Default queue limit");
+
 /*
  * Track IPv4/IPv6 max connection update done
  */
 static int max_ipv4_conn_update_done;
 static int max_ipv6_conn_update_done;
+static int pn_q_update_done;
 
 /*
  * Atomic variables to control jumbo_mru & paged_mode
@@ -1221,6 +1235,7 @@
 	int32_t i;
 	struct nss_top_instance *nss_top;
 	bool is_scheduled = true;
+	int ret;
 
 	/*
 	 * NOTE: A commonly found error is that sizes and start address of per core
@@ -1264,6 +1279,17 @@
 	}
 
 	if (is_scheduled) {
+
+		/*
+		 * Send pnode queue config message
+		 */
+		if (pn_q_update_done == 0) {
+			ret = nss_n2h_update_queue_config(nss_top->num_pri, pn_mq_en, pn_pri_num, pn_qlimits);
+			if (ret == NSS_TX_SUCCESS) {
+				pn_q_update_done = 1;
+			}
+		}
+
 		/*
 		 * Configure the maximum number of IPv4/IPv6
 		 * connections supported by the accelerator.
diff --git a/nss_core.h b/nss_core.h
index 428fb82..b6ba153 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -1517,6 +1517,7 @@
 struct nss_top_instance {
 	uint8_t num_nss;			/* Number of NSS cores supported */
 	uint8_t num_phys_ports;			/* Number of physical ports supported */
+	uint8_t num_pri;			/* Maximum number of priority */
 	uint32_t clk_src;			/* Clock source: default/alternate */
 	spinlock_t lock;			/* Big lock for NSS driver */
 	spinlock_t stats_lock;			/* Statistics lock */
@@ -1838,6 +1839,7 @@
 	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 */
+	uint8_t num_pri;			/* Maximum number of priority supported. */
 	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 */
diff --git a/nss_hal/fsm9010/nss_hal_pvt.c b/nss_hal/fsm9010/nss_hal_pvt.c
index acb80e2..8b16ed6 100644
--- a/nss_hal/fsm9010/nss_hal_pvt.c
+++ b/nss_hal/fsm9010/nss_hal_pvt.c
@@ -104,6 +104,10 @@
 		npd->num_irq = nss_hal_get_num_irqs(np);
 	}
 
+	if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+		npd->num_pri = NSS_DEFAULT_NUM_PRI;
+	}
+
 	if (npd->num_irq < npd->num_queue) {
 		pr_err("%s: not enough interrupts configured for all the queues\n", np->name);
 		goto out;
diff --git a/nss_hal/ipq806x/nss_hal_pvt.c b/nss_hal/ipq806x/nss_hal_pvt.c
index d325e53..beaa398 100644
--- a/nss_hal/ipq806x/nss_hal_pvt.c
+++ b/nss_hal/ipq806x/nss_hal_pvt.c
@@ -301,6 +301,10 @@
 		goto out;
 	}
 
+	if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+		npd->num_pri = NSS_DEFAULT_NUM_PRI;
+	}
+
 	/*
 	 * Read frequencies. If failure, load default values.
 	 */
diff --git a/nss_hal/ipq807x/nss_hal_pvt.c b/nss_hal/ipq807x/nss_hal_pvt.c
index bb683bd..7689e9b 100644
--- a/nss_hal/ipq807x/nss_hal_pvt.c
+++ b/nss_hal/ipq807x/nss_hal_pvt.c
@@ -132,6 +132,10 @@
 		goto out;
 	}
 
+	if (of_property_read_u8(np, "qcom,num-pri", &npd->num_pri)) {
+		npd->num_pri = NSS_DEFAULT_NUM_PRI;
+	}
+
 	/*
 	 * Read frequencies. If failure, load default values.
 	 */
@@ -625,4 +629,3 @@
 	.clear_interrupt_cause = __nss_hal_clear_interrupt_cause,
 	.read_interrupt_cause = __nss_hal_read_interrupt_cause,
 };
-
diff --git a/nss_hal/nss_hal.c b/nss_hal/nss_hal.c
index 05a4fd8..13d4de5 100644
--- a/nss_hal/nss_hal.c
+++ b/nss_hal/nss_hal.c
@@ -326,6 +326,8 @@
 	}
 	spin_lock_bh(&(nss_top->lock));
 
+	nss_top->num_pri = npd->num_pri;
+
 	/*
 	 * Features that will always be enabled on both cores
 	 */
diff --git a/nss_n2h.c b/nss_n2h.c
index 7981a01..f7a2717 100644
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -777,6 +777,58 @@
 }
 
 /*
+ * nss_n2h_update_queue_config()
+ *	Updates pnode queue configuration and limits
+ */
+nss_tx_status_t nss_n2h_update_queue_config(int max_pri, bool mq_en, int num_pri, int *qlimits)
+{
+	struct nss_n2h_msg nnm;
+	struct nss_n2h_pnode_queue_config *cfg;
+	nss_tx_status_t status;
+	struct nss_top_instance *nss_top = &nss_top_main;
+	struct nss_ctx_instance *nss_ctx = &nss_top->nss[0];
+	int i;
+
+	if (!mq_en) {
+		return NSS_TX_SUCCESS;
+	}
+
+	if (num_pri <= 0) {
+		nss_warning("%p: nss_tx error in pnode queue config param", nss_ctx);
+		return NSS_TX_FAILURE_BAD_PARAM;
+	}
+
+	if (max_pri < num_pri) {
+		nss_warning("%p: nss_tx error in pnode queue config param, maximum supported priority is %d", nss_ctx, max_pri);
+		return NSS_TX_FAILURE_BAD_PARAM;
+	}
+
+	cfg = &nnm.msg.pn_q_cfg;
+	cfg->num_pri = num_pri;
+	for (i = 0; i < num_pri; i++) {
+		cfg->qlimits[i] = qlimits[i];
+	}
+	cfg->mq_en = true;
+
+	/*
+	 * Create message for FW
+	 */
+	nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE,
+			 NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG,
+			 sizeof(struct nss_n2h_pnode_queue_config), NULL, 0);
+
+	status = nss_n2h_tx_msg(nss_ctx, &nnm);
+	if (status != NSS_TX_SUCCESS) {
+		nss_warning("%p: nss_tx error to send pnode queue config\n", nss_ctx);
+		return status;
+	}
+
+	return NSS_TX_SUCCESS;
+
+}
+EXPORT_SYMBOL(nss_n2h_update_queue_config);
+
+/*
  * nss_n2h_rps_cfg()
  *	Send Message to NSS to enable RPS.
  */
@@ -1235,7 +1287,6 @@
 	{ }
 };
 
-
 static struct ctl_table nss_n2h_root_dir[] = {
 	{
 		.procname		= "nss",
@@ -1334,7 +1385,6 @@
 		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]);