Merge "[qca-nss-drv] Provision ipv4 and ipv6 to send back create rule responses" into banana_n2h
diff --git a/nss_core.h b/nss_core.h
index 3c944d1..93475f6 100644
--- a/nss_core.h
+++ b/nss_core.h
@@ -326,7 +326,15 @@
 	NSS_STATS_N2H_TOTAL_TICKS,	/* Total clock ticks spend inside the N2H */
 	NSS_STATS_N2H_WORST_CASE_TICKS,	/* Worst case iteration of the exception path in ticks */
 	NSS_STATS_N2H_ITERATIONS,	/* Number of iterations around the N2H */
-	NSS_STATS_N2H_PBUF_ALLOC_FAILS,	/* Number of pbuf allocations that have failed */
+
+	NSS_STATS_N2H_PBUF_OCM_ALLOC_FAILS,	/* Number of pbuf ocm allocations that have failed */
+	NSS_STATS_N2H_PBUF_OCM_FREE_COUNT,	/* Number of pbuf ocm free count */
+	NSS_STATS_N2H_PBUF_OCM_TOTAL_COUNT,	/* Number of pbuf ocm total count */
+
+	NSS_STATS_N2H_PBUF_DEFAULT_ALLOC_FAILS,	/* Number of pbuf default allocations that have failed */
+	NSS_STATS_N2H_PBUF_DEFAULT_FREE_COUNT,	/* Number of pbuf default free count */
+	NSS_STATS_N2H_PBUF_DEFAULT_TOTAL_COUNT,	/* Number of pbuf default total count */
+
 	NSS_STATS_N2H_PAYLOAD_ALLOC_FAILS,
 					/* Number of pbuf allocations that have failed because there were no free payloads */
 	NSS_STATS_N2H_MAX,
diff --git a/nss_hlos_if.h b/nss_hlos_if.h
index 68e706d..1cd8e61 100644
--- a/nss_hlos_if.h
+++ b/nss_hlos_if.h
@@ -120,6 +120,15 @@
 };
 
 /*
+ * 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 */
+};
+
+/*
  * The NSS N2H statistics sync structure.
  */
 struct nss_n2h_stats_sync {
@@ -129,7 +138,10 @@
 	uint32_t total_ticks;		/* Total clock ticks spend inside the PE */
 	uint32_t worst_case_ticks;	/* Worst case iteration of the PE in ticks */
 	uint32_t iterations;		/* Number of iterations around the PE */
-	uint32_t pbuf_alloc_fails;	/* Number of pbuf allocations that have failed */
+
+	struct nss_n2h_pbuf_mgr_stats pbuf_ocm_stats; 		/* Pbuf OCM Stats */
+	struct nss_n2h_pbuf_mgr_stats pbuf_default_stats; 	/* Pbuf Default Stats */
+
 	uint32_t payload_alloc_fails;
 };
 
diff --git a/nss_qdisc.c b/nss_qdisc.c
index aa09966..996f0d3 100644
--- a/nss_qdisc.c
+++ b/nss_qdisc.c
@@ -3506,12 +3506,19 @@
 static int nssbf_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 								 struct Qdisc **old)
 {
+	struct nssbf_sched_data *q = qdisc_priv(sch);
 	struct nssbf_class_data *cl = (struct nssbf_class_data *)arg;
 	struct nss_if_msg nim_detach;
 	struct nss_if_msg nim_attach;
 	struct nssqdisc_qdisc *nq_new = qdisc_priv(new);
 
 	nssqdisc_info("Grafting class %p\n", sch);
+
+	if (cl == &q->root) {
+		nssqdisc_error("%p: Can't graft root class\n", cl);
+		return -EINVAL;
+	}
+
 	if (new == NULL)
 		new = &noop_qdisc;
 
@@ -3620,7 +3627,12 @@
 	qopt.mtu = cl->mtu;
 	qopt.quantum = cl->quantum;
 
-	tcm->tcm_handle |= TC_H_MIN(cl->cl_common.classid);
+	/*
+	 * All bf group nodes are root nodes. i.e. they dont
+	 * have any mode bf groups attached beneath them.
+	 */
+	tcm->tcm_parent = TC_H_ROOT;
+	tcm->tcm_handle = cl->cl_common.classid;
 	tcm->tcm_info = cl->qdisc->handle;
 
 	opts = nla_nest_start(skb, TCA_OPTIONS);
@@ -3689,7 +3701,7 @@
 	if (err < 0)
 		return err;
 
-	q->root.cl_common.classid = sch->handle + 1;
+	q->root.cl_common.classid = sch->handle;
 	q->root.qdisc = &noop_qdisc;
 
 	qdisc_class_hash_insert(&q->clhash, &q->root.cl_common);
@@ -4184,12 +4196,19 @@
 static int nsswrr_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 								 struct Qdisc **old)
 {
+	struct nsswrr_sched_data *q = qdisc_priv(sch);
 	struct nsswrr_class_data *cl = (struct nsswrr_class_data *)arg;
 	struct nss_if_msg nim_detach;
 	struct nss_if_msg nim_attach;
 	struct nssqdisc_qdisc *nq_new = qdisc_priv(new);
 
 	nssqdisc_info("Grafting class %p\n", sch);
+
+	if (cl == &q->root) {
+		nssqdisc_error("%p: Can't graft root class\n", cl);
+		return -EINVAL;
+	}
+
 	if (new == NULL)
 		new = &noop_qdisc;
 
@@ -4295,7 +4314,12 @@
 
 	qopt.quantum = cl->quantum;
 
-	tcm->tcm_handle |= TC_H_MIN(cl->cl_common.classid);
+	/*
+	 * All bf group nodes are root nodes. i.e. they dont
+	 * have any mode bf groups attached beneath them.
+	 */
+	tcm->tcm_parent = TC_H_ROOT;
+	tcm->tcm_handle = cl->cl_common.classid;
 	tcm->tcm_info = cl->qdisc->handle;
 
 	opts = nla_nest_start(skb, TCA_OPTIONS);
@@ -4360,7 +4384,7 @@
 	if (err < 0)
 		return err;
 
-	q->root.cl_common.classid = sch->handle + 1;
+	q->root.cl_common.classid = sch->handle;
 	q->root.qdisc = &noop_qdisc;
 
 	qdisc_class_hash_insert(&q->clhash, &q->root.cl_common);
diff --git a/nss_stats.c b/nss_stats.c
index a751f12..b6dcb1e 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -89,7 +89,12 @@
 	"ticks",
 	"worst_ticks",
 	"iterations",
-	"pbuf_fails",
+	"pbuf_ocm_alloc_fails",
+	"pbuf_ocm_free_count",
+	"pbuf_ocm_total_count",
+	"pbuf_default_alloc_fails",
+	"pbuf_default_free_count",
+	"pbuf_default_total_count",
 	"payload_fails"
 };
 
diff --git a/nss_tx_rx_n2h.c b/nss_tx_rx_n2h.c
index 62a07ba..3ce36f2 100644
--- a/nss_tx_rx_n2h.c
+++ b/nss_tx_rx_n2h.c
@@ -55,9 +55,19 @@
 	nss_ctx->stats_n2h[NSS_STATS_N2H_ITERATIONS] += nnss->iterations;
 
 	/*
-	 * pbuf/payload mgr stats
+	 * pbuf manager ocm and default pool stats
 	 */
-	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_ALLOC_FAILS] += nnss->pbuf_alloc_fails;
+	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_ALLOC_FAILS] += nnss->pbuf_ocm_stats.pbuf_alloc_fails;
+	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_FREE_COUNT] = nnss->pbuf_ocm_stats.pbuf_free_count;
+	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_OCM_TOTAL_COUNT] = nnss->pbuf_ocm_stats.pbuf_total_count;
+
+	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_ALLOC_FAILS] += nnss->pbuf_default_stats.pbuf_alloc_fails;
+	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_FREE_COUNT] = nnss->pbuf_default_stats.pbuf_free_count;
+	nss_ctx->stats_n2h[NSS_STATS_N2H_PBUF_DEFAULT_TOTAL_COUNT] = nnss->pbuf_default_stats.pbuf_total_count;
+
+	/*
+	 * payload mgr stats
+	 */
 	nss_ctx->stats_n2h[NSS_STATS_N2H_PAYLOAD_ALLOC_FAILS] += nnss->payload_alloc_fails;
 
 	spin_unlock_bh(&nss_top->stats_lock);