Merge changes I8533887c,I5b6dc7a6 into msm-3.4
* changes:
msm_rmnet: add ioctl to enable/disable flow on prio qdisc
net: sched: export an api to enable/disable flow on sch
diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c
index fbe8d3c..295c55c 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_bam.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c
@@ -29,6 +29,7 @@
#include <linux/if_arp.h>
#include <linux/msm_rmnet.h>
#include <linux/platform_device.h>
+#include <net/pkt_sched.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
@@ -638,6 +639,16 @@
dev->name);
break;
+ case RMNET_IOCTL_FLOW_ENABLE:
+ tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
+ DBG0("[%s] rmnet_ioctl(): enabled flow", dev->name);
+ break;
+
+ case RMNET_IOCTL_FLOW_DISABLE:
+ tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
+ DBG0("[%s] rmnet_ioctl(): disabled flow", dev->name);
+ break;
+
case RMNET_IOCTL_GET_QOS: /* Get QoS header state */
ifr->ifr_ifru.ifru_data =
(void *)(p->operation_mode & RMNET_MODE_QOS);
diff --git a/include/linux/msm_rmnet.h b/include/linux/msm_rmnet.h
index 9f52464..063a8f1 100644
--- a/include/linux/msm_rmnet.h
+++ b/include/linux/msm_rmnet.h
@@ -40,6 +40,8 @@
RMNET_IOCTL_GET_OPMODE = 0x000089F7, /* Get operation mode */
RMNET_IOCTL_OPEN = 0x000089F8, /* Open transport port */
RMNET_IOCTL_CLOSE = 0x000089F9, /* Close transport port */
+ RMNET_IOCTL_FLOW_ENABLE = 0x000089FA, /* Flow enable */
+ RMNET_IOCTL_FLOW_DISABLE = 0x000089FB, /* Flow disable */
RMNET_IOCTL_MAX
};
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index fffdc60..95ec28b 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -103,7 +103,8 @@
struct tcf_result *res);
extern int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res);
-
+extern void tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle,
+ int flow_enable);
/* Calculate maximal size of packet seen by hard_start_xmit
routine of this device.
*/
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 3d8981f..60e2fa9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1030,6 +1030,35 @@
}
/*
+ * enable/disable flow on qdisc.
+ */
+void
+tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle, int enable_flow)
+{
+ struct Qdisc *q;
+ struct __qdisc_change_req {
+ struct nlattr attr;
+ struct tc_prio_qopt data;
+ } req = {
+ .attr = {sizeof(struct __qdisc_change_req), TCA_OPTIONS},
+ .data = {3, {1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, 1}
+ };
+
+ /* override flow bit */
+ req.data.enable_flow = enable_flow;
+
+ /* look up using tcm handle */
+ q = qdisc_lookup(dev, tcm_handle);
+
+ /* call registered change function */
+ if (q) {
+ if (q->ops->change(q, &(req.attr)) != 0)
+ pr_err("tc_qdisc_flow_control: qdisc change failed");
+ }
+}
+EXPORT_SYMBOL(tc_qdisc_flow_control);
+
+/*
* Create/change qdisc.
*/