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

Commit e7ba4463 authored by Sean Tranchetti's avatar Sean Tranchetti
Browse files

soc: qcom: dfc: ignore indications during RAT switch



Added support to identify the start and end of RAT switch from
QMI DFC indications. Any additional messages in between will be
ignored. This is to resolve a race condition that could happen
if QMI messages are coming from different transports.

Change-Id: I3bb28a34348509eae54d30958555cf1d207838c7
Acked-by: default avatarWeiyi Chen <weiyic@qti.qualcomm.com>
Signed-off-by: default avatarSean Tranchetti <stranche@codeaurora.org>
parent c8aa8abe
Loading
Loading
Loading
Loading
+22 −9
Original line number Diff line number Diff line
@@ -21,6 +21,11 @@
#define CREATE_TRACE_POINTS
#include <trace/events/dfc.h>

#define DFC_MASK_TCP_BIDIR 0x1
#define DFC_MASK_RAT_SWITCH 0x2
#define DFC_IS_TCP_BIDIR(r) (bool)((r) & DFC_MASK_TCP_BIDIR)
#define DFC_IS_RAT_SWITCH(r) (bool)((r) & DFC_MASK_RAT_SWITCH)

#define DFC_IS_ANCILLARY(type) ((type) != AF_INET && (type) != AF_INET6)

#define DFC_MAX_QOS_ID_V01 2
@@ -852,7 +857,7 @@ static int dfc_bearer_flow_ctl(struct net_device *dev,
			/*
			 * Do not flow disable ancillary q if ancillary is true
			 */
			if (bearer->ancillary && enable == 0 &&
			if (bearer->tcp_bidir && enable == 0 &&
					DFC_IS_ANCILLARY(itm->ip_type))
				continue;

@@ -890,7 +895,7 @@ static int dfc_all_bearer_flow_ctl(struct net_device *dev,
			qmi_rmnet_grant_per(bearer_itm->grant_size);
		bearer_itm->seq = fc_info->seq_num;
		bearer_itm->ack_req = ack_req;
		bearer_itm->ancillary = ancillary;
		bearer_itm->tcp_bidir = DFC_IS_TCP_BIDIR(ancillary);
		bearer_itm->last_grant = fc_info->num_bytes;
		bearer_itm->last_seq = fc_info->seq_num;
	}
@@ -918,24 +923,32 @@ static int dfc_update_fc_map(struct net_device *dev, struct qos_info *qos,
{
	struct rmnet_bearer_map *itm = NULL;
	int rc = 0;
	int action = -1;
	bool action = false;

	itm = qmi_rmnet_get_bearer_map(qos, fc_info->bearer_id);
	if (itm) {
		if (itm->grant_size == 0 && fc_info->num_bytes > 0)
			action = 1;
		else if (itm->grant_size > 0 && fc_info->num_bytes == 0)
			action = 0;
		/* The RAT switch flag indicates the start and end of
		 * the switch. Ignore indications in between.
		 */
		if (DFC_IS_RAT_SWITCH(ancillary))
			itm->rat_switch = !fc_info->num_bytes;
		else
			if (itm->rat_switch)
				return 0;

		if ((itm->grant_size == 0 && fc_info->num_bytes > 0) ||
		    (itm->grant_size > 0 && fc_info->num_bytes == 0))
			action = true;

		itm->grant_size = fc_info->num_bytes;
		itm->grant_thresh = qmi_rmnet_grant_per(itm->grant_size);
		itm->seq = fc_info->seq_num;
		itm->ack_req = ack_req;
		itm->ancillary = ancillary;
		itm->tcp_bidir = DFC_IS_TCP_BIDIR(ancillary);
		itm->last_grant = fc_info->num_bytes;
		itm->last_seq = fc_info->seq_num;

		if (action != -1)
		if (action)
			rc = dfc_bearer_flow_ctl(dev, itm, qos);
	} else {
		pr_debug("grant %u before flow activate", fc_info->num_bytes);
+2 −1
Original line number Diff line number Diff line
@@ -590,7 +590,8 @@ void qmi_rmnet_enable_all_flows(struct net_device *dev)
		bearer->grant_thresh = DEFAULT_GRANT;
		bearer->seq = 0;
		bearer->ack_req = 0;
		bearer->ancillary = 0;
		bearer->tcp_bidir = false;
		bearer->rat_switch = false;
	}

	if (do_wake) {
+2 −1
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ struct rmnet_bearer_map {
	u8  ack_req;
	u32 last_grant;
	u16 last_seq;
	u32 ancillary;
	bool tcp_bidir;
	bool rat_switch;
};

struct svc_info {