Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36e607f5 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan
Browse files

rmnet: egress burst mode qos



Add support for UL burst mode flow control.
Burst mode Data Flow Control (DFC) is handled in kernel.
Flow info is added/deleted to rmnet driver if DFC is supported.
Flow is enabled if grant size is larger than 0 on flow status indication.
Flow is disabled if grant size is 0 or UL data size larger than grant size.

Change-Id: I7f8f9af3252cf4a742eceaae2e9deb1c384c476d
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 8588eafd
Loading
Loading
Loading
Loading
+80 −7
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include "rmnet_vnd.h"
#include "rmnet_private.h"
#include "rmnet_map.h"
#include <soc/qcom/rmnet_qmi.h>
#include <soc/qcom/qmi_rmnet.h>

/* Locking scheme -
 * The shared resource which needs to be protected is realdev->rx_handler_data.
@@ -44,9 +46,10 @@

/* Local Definitions and Declarations */

static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = {
static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 2] = {
	[IFLA_RMNET_MUX_ID]	= { .type = NLA_U16 },
	[IFLA_RMNET_FLAGS]	= { .len = sizeof(struct ifla_rmnet_flags) },
	[IFLA_VLAN_EGRESS_QOS]	= { .len = sizeof(struct tcmsg) },
};

static int rmnet_is_real_dev_registered(const struct net_device *real_dev)
@@ -286,12 +289,15 @@ static int rmnet_rtnl_validate(struct nlattr *tb[], struct nlattr *data[],
{
	u16 mux_id;

	if (!data || !data[IFLA_RMNET_MUX_ID])
	if (!data) {
		return -EINVAL;

	} else {
		if (data[IFLA_RMNET_MUX_ID]) {
			mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]);
			if (mux_id > (RMNET_MAX_LOGICAL_EP - 1))
				return -ERANGE;
		}
	}

	return 0;
}
@@ -334,6 +340,13 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],
		port->data_format = flags->flags & flags->mask;
	}

	if (data[IFLA_VLAN_EGRESS_QOS]) {
		struct tcmsg *tcm;

		tcm = nla_data(data[IFLA_VLAN_EGRESS_QOS]);
		qmi_rmnet_change_link(dev, port, tcm);
	}

	return 0;
}

@@ -343,7 +356,8 @@ static size_t rmnet_get_size(const struct net_device *dev)
		/* IFLA_RMNET_MUX_ID */
		nla_total_size(2) +
		/* IFLA_RMNET_FLAGS */
		nla_total_size(sizeof(struct ifla_rmnet_flags));
		nla_total_size(sizeof(struct ifla_rmnet_flags)) +
		nla_total_size(sizeof(struct tcmsg));
}

static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)
@@ -463,6 +477,65 @@ int rmnet_del_bridge(struct net_device *rmnet_dev,
	return 0;
}

#ifdef CONFIG_QCOM_QMI_DFC
void *rmnet_get_qmi_pt(void *port)
{
	if (port)
		return ((struct rmnet_port *)port)->qmi_info;

	return NULL;
}
EXPORT_SYMBOL(rmnet_get_qmi_pt);

void *rmnet_get_qos_pt(struct net_device *dev)
{
	if (dev)
		return ((struct rmnet_priv *)netdev_priv(dev))->qos_info;

	return NULL;
}
EXPORT_SYMBOL(rmnet_get_qos_pt);

void *rmnet_get_rmnet_port(struct net_device *dev)
{
	struct rmnet_priv *priv;

	if (dev) {
		priv = (struct rmnet_priv *)netdev_priv(dev);
		return (void *)rmnet_get_port(priv->real_dev);
	}

	return NULL;
}
EXPORT_SYMBOL(rmnet_get_rmnet_port);

struct net_device *rmnet_get_rmnet_dev(void *port, uint8_t mux_id)
{
	struct rmnet_endpoint *ep;

	ep = rmnet_get_endpoint((struct rmnet_port *)port, mux_id);
	if (ep)
		return ep->egress_dev;

	return NULL;
}
EXPORT_SYMBOL(rmnet_get_rmnet_dev);

void rmnet_reset_qmi_pt(void *port)
{
	if (port)
		((struct rmnet_port *)port)->qmi_info = NULL;
}
EXPORT_SYMBOL(rmnet_reset_qmi_pt);

void rmnet_init_qmi_pt(void *port, void *qmi)
{
	if (port)
		((struct rmnet_port *)port)->qmi_info = qmi;
}
EXPORT_SYMBOL(rmnet_init_qmi_pt);
#endif

/* Startup/Shutdown */

static int __init rmnet_init(void)
+3 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ struct rmnet_port {
	struct timespec agg_time;
	struct timespec agg_last;
	struct hrtimer hrtimer;

	void *qmi_info;
};

extern struct rtnl_link_ops rmnet_link_ops;
@@ -85,6 +87,7 @@ struct rmnet_priv {
	struct rmnet_pcpu_stats __percpu *pcpu_stats;
	struct gro_cells gro_cells;
	struct rmnet_priv_stats stats;
	void *qos_info;
};

struct rmnet_port *rmnet_get_port(struct net_device *real_dev);
+9 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include "rmnet_map.h"
#include "rmnet_vnd.h"

#include <soc/qcom/qmi_rmnet.h>

/* RX/TX Fixup */

void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev)
@@ -61,6 +63,7 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
	priv = netdev_priv(dev);
	if (priv->real_dev) {
		rmnet_egress_handler(skb);
		qmi_rmnet_burst_fc_check(dev, skb);
	} else {
		this_cpu_inc(priv->pcpu_stats->stats.tx_drops);
		kfree_skb(skb);
@@ -108,6 +111,11 @@ static void rmnet_vnd_uninit(struct net_device *dev)

	gro_cells_destroy(&priv->gro_cells);
	free_percpu(priv->pcpu_stats);

	qmi_rmnet_qos_exit(dev);
	priv->qos_info = NULL;

	free_netdev(dev);
}

static void rmnet_get_stats64(struct net_device *dev,
@@ -254,6 +262,7 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
		priv = netdev_priv(rmnet_dev);
		priv->mux_id = id;
		priv->real_dev = real_dev;
		priv->qos_info = qmi_rmnet_qos_init(real_dev, id);

		netdev_dbg(rmnet_dev, "rmnet dev created\n");
	}
+20 −0
Original line number Diff line number Diff line
@@ -112,6 +112,26 @@ config QCOM_QMI_HELPERS
	  clients and this helpers provide the common functionality needed for
	  doing this from a kernel driver.

config QCOM_QMI_DFC
	bool "Enable burst mode flow control"
	depends on QCOM_QMI_HELPERS
	depends on RMNET
	help
	  Say y here to enable support for burst mode data flow control.
	  DFC client provides an interface to the modem dfc service and
	  does burst mode flow control. It enables the flow on receiving flow
	  status indication and disables flows while grant size is reached.
	  If unsure or not use burst mode flow control, say 'N'.

config QCOM_QMI_POWER_COLLAPSE
	bool "Enable power collapse feature"
	depends on QCOM_QMI_DFC
	help
	  Say y here to enable support for power collapse.
	  It is to register/unregister the flow status indication callback
	  based on detected flow status.
	  If unsure or not use power collapse feature, say 'N'.

config QCOM_SMEM
	tristate "Qualcomm Shared Memory Manager (SMEM)"
	depends on ARCH_QCOM
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ obj-$(CONFIG_QCOM_PM) += spm.o
obj-$(CONFIG_QCOM_QMI_HELPERS)	+= qmi_helpers.o
qmi_helpers-y += qmi_encdec.o
qmi_helpers-y += qmi_interface.o
obj-$(CONFIG_QCOM_QMI_DFC)	+= qmi_rmnet.o
obj-$(CONFIG_QCOM_QMI_DFC)	+= dfc_qmi.o
obj-$(CONFIG_QCOM_SMD_RPM)	+= smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) +=	smem.o
obj-$(CONFIG_MSM_SPM) += msm-spm.o spm_devices.o
Loading