tc: Add flow control setting on PRIO qdisc

* Enable filter fw, qdiscs prio, and qdisc fifo.
* Add "flow enable|disable" clause for PRIO qdisc
* Now using sanitized kernel headers

Change-Id: I7ccfe9717bf21738c66b33dbafe04b2c3a3a912a
diff --git a/tc/Android.mk b/tc/Android.mk
index f137d3e..e3e4bb8 100644
--- a/tc/Android.mk
+++ b/tc/Android.mk
@@ -7,6 +7,10 @@
                     m_estimator.c tc_filter.c tc_monitor.c tc_stab.c tc_cbq.c \
                     tc_estimator.c f_u32.c m_police.c q_ingress.c m_mirred.c q_htb.c
 
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+LOCAL_SRC_FILES += f_fw.c q_prio.c q_fifo.c
+endif
+
 LOCAL_MODULE := tc
 
 LOCAL_SYSTEM_SHARED_LIBRARIES := \
@@ -14,9 +18,16 @@
 
 LOCAL_SHARED_LIBRARIES += libiprouteutil libnetlink
 
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+LOCAL_C_INCLUDES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += external/iproute2/include
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+LOCAL_CFLAGS := -DFEATURE_PRIO
+else
+LOCAL_C_INCLUDES := $(KERNEL_HEADERS) external/iproute2/include
+endif
 
-LOCAL_CFLAGS := -O2 -g -W -Wall -Wno-pointer-arith -Wno-sign-compare -Werror \
+LOCAL_CFLAGS += -O2 -g -W -Wall -Wno-pointer-arith -Wno-sign-compare -Werror \
     -Wno-unused-parameter \
     -Wno-missing-field-initializers
 
diff --git a/tc/q_prio.c b/tc/q_prio.c
index 79b4fd0..b8e6ab7 100644
--- a/tc/q_prio.c
+++ b/tc/q_prio.c
@@ -25,14 +25,14 @@
 
 static void explain(void)
 {
-	fprintf(stderr, "Usage: ... prio bands NUMBER priomap P1 P2...[multiqueue]\n");
+	fprintf(stderr, "Usage: ... prio bands NUMBER priomap P1 P2...[multiqueue] [flow (enable|disable)]\n");
 }
 
 static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n)
 {
 	int pmap_mode = 0;
 	int idx = 0;
-	struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }};
+	struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },1};
 	struct rtattr *nest;
 	unsigned char mq = 0;
 
@@ -53,6 +53,21 @@
 			pmap_mode = 1;
 		} else if (strcmp(*argv, "multiqueue") == 0) {
 			mq = 1;
+		} else if (strcmp(*argv, "flow") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "enable") == 0)
+			{
+				opt.enable_flow = 1;
+			}
+			else if (strcmp(*argv, "disable") == 0)
+			{
+				opt.enable_flow = 0;
+			}
+			else
+			{
+				explain();
+				return -1;
+			}
 		} else if (strcmp(*argv, "help") == 0) {
 			explain();
 			return -1;
@@ -114,6 +129,9 @@
 		fprintf(f, " multiqueue: %s ",
 			rta_getattr_u8(tb[TCA_PRIO_MQ]) ? "on" : "off");
 
+	if (qu && !strcmp(qu->id, "prio"))
+		fprintf(f, " flow %s", qopt->enable_flow ? "enabled" : "disabled");
+
 	return 0;
 }
 
diff --git a/tc/tc.c b/tc/tc.c
index a261136..f3d3776 100644
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -49,6 +49,12 @@
 extern struct qdisc_util htb_qdisc_util;
 extern struct qdisc_util ingress_qdisc_util;
 extern struct filter_util u32_filter_util;
+#ifdef FEATURE_PRIO
+extern struct filter_util fw_filter_util;
+extern struct qdisc_util prio_qdisc_util;
+extern struct qdisc_util pfifo_fast_qdisc_util;
+extern struct qdisc_util pfifo_qdisc_util;
+#endif
 #endif
 
 static int print_noqopt(struct qdisc_util *qu, FILE *f,
@@ -111,6 +117,14 @@
 		return &htb_qdisc_util;
 	else if (!strcmp(str, "ingress"))
 		return &ingress_qdisc_util;
+#ifdef FEATURE_PRIO
+	else if (!strcmp(str, "pfifo_fast"))
+		return &pfifo_fast_qdisc_util;
+	else if (!strcmp(str, "prio"))
+		return &prio_qdisc_util;
+	else if (!strcmp(str, "pfifo"))
+		return &pfifo_qdisc_util;
+#endif
 	else {
 		fprintf(stderr, "Android does not support qdisc '%s'\n", str);
 		return NULL;
@@ -164,6 +178,10 @@
 #ifdef ANDROID
 	if (!strcmp(str, "u32"))
 		return &u32_filter_util;
+#ifdef FEATURE_PRIO
+	else if (!strcmp(str, "fw"))
+		return &fw_filter_util;
+#endif
 	else {
 		fprintf(stderr, "Android does not support filter '%s'\n", str);
 		return NULL;
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index 3f932a7..5608a65 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -241,11 +241,13 @@
 	if (t->tcm_info != 1) {
 		fprintf(fp, "refcnt %d ", t->tcm_info);
 	}
-	/* pfifo_fast is generic enough to warrant the hardcoding --JHS */
 
+#if 0 /* Suppressed to dinstinguish between prio & pfifo_fast */
+	/* pfifo_fast is generic enough to warrant the hardcoding --JHS */
 	if (0 == strcmp("pfifo_fast", RTA_DATA(tb[TCA_KIND])))
 		q = get_qdisc_kind("prio");
 	else
+#endif
 		q = get_qdisc_kind(RTA_DATA(tb[TCA_KIND]));
 
 	if (tb[TCA_OPTIONS]) {