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

Commit 1a7f7cd8 authored by Sean Tranchetti's avatar Sean Tranchetti Committed by Gerrit - the friendly Code Review server
Browse files

soc: qcom: dfc: Ignore grants after powersave



If rmnet receives a grant after going into powersave, the start grant
will be incorrect when coming out of powersave. And if this grant is 0
then data stall will happen.

This change ignores any grant received after rmnet enters powersave.

Change-Id: I45dbfaa28b23806584d5a47738e7a87f76ead889
Acked-by: default avatarWeiyi Chen <weiyic@qti.qualcomm.com>
Signed-off-by: default avatarSean Tranchetti <stranche@codeaurora.org>
parent 11276b2c
Loading
Loading
Loading
Loading
+5 −12
Original line number Diff line number Diff line
@@ -1161,6 +1161,11 @@ static void dfc_do_burst_flow_control(struct dfc_qmi_data *dfc,

		spin_lock_bh(&qos->qos_lock);

		if (qmi_rmnet_ignore_grant(dfc->rmnet_port)) {
			spin_unlock_bh(&qos->qos_lock);
			continue;
		}

		if (unlikely(flow_status->bearer_id == 0xFF))
			dfc_all_bearer_flow_ctl(
				dev, qos, ack_req, ancillary, flow_status);
@@ -1556,18 +1561,6 @@ void dfc_qmi_burst_check(struct net_device *dev, struct qos_info *qos,
	spin_unlock_bh(&qos->qos_lock);
}

void dfc_qmi_wq_flush(struct qmi_info *qmi)
{
	struct dfc_qmi_data *dfc_data;
	int i;

	for (i = 0; i < MAX_CLIENT_NUM; i++) {
		dfc_data = (struct dfc_qmi_data *)(qmi->dfc_clients[i]);
		if (dfc_data)
			flush_workqueue(dfc_data->dfc_wq);
	}
}

void dfc_qmi_query_flow(void *dfc_data)
{
	struct dfc_qmi_data *data = (struct dfc_qmi_data *)dfc_data;
+23 −6
Original line number Diff line number Diff line
@@ -815,11 +815,6 @@ int qmi_rmnet_set_powersave_mode(void *port, uint8_t enable)
		return rc;
	}

	if (enable)
		dfc_qmi_wq_flush(qmi);
	else
		qmi_rmnet_query_flows(qmi);

	return 0;
}
EXPORT_SYMBOL(qmi_rmnet_set_powersave_mode);
@@ -850,6 +845,10 @@ static void qmi_rmnet_check_stats(struct work_struct *work)
		return;

	if (qmi->ps_enabled) {

		/* Ready to accept grant */
		qmi->ps_ignore_grant = false;

		/* Register to get QMI DFC and DL marker */
		if (qmi_rmnet_set_powersave_mode(real_work->port, 0) < 0) {
			/* If this failed need to retry quickly */
@@ -860,10 +859,12 @@ static void qmi_rmnet_check_stats(struct work_struct *work)
		}
		qmi->ps_enabled = false;

		/* Do a query when coming out of powersave */
		qmi_rmnet_query_flows(qmi);

		if (rmnet_get_powersave_notif(real_work->port))
			qmi_rmnet_ps_off_notify(real_work->port);


		goto end;
	}

@@ -892,6 +893,9 @@ static void qmi_rmnet_check_stats(struct work_struct *work)
		}
		qmi->ps_enabled = true;

		/* Ignore grant after going into powersave */
		qmi->ps_ignore_grant = true;

		/* Clear the bit before enabling flow so pending packets
		 * can trigger the work again
		 */
@@ -988,4 +992,17 @@ void qmi_rmnet_flush_ps_wq(void)
	if (rmnet_ps_wq)
		flush_workqueue(rmnet_ps_wq);
}

bool qmi_rmnet_ignore_grant(void *port)
{
	struct qmi_info *qmi;

	qmi = (struct qmi_info *)rmnet_get_qmi_pt(port);
	if (unlikely(!qmi))
		return false;

	return qmi->ps_ignore_grant;
}
EXPORT_SYMBOL(qmi_rmnet_ignore_grant);

#endif
+1 −7
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ struct qmi_info {
	unsigned long ps_work_active;
	bool ps_enabled;
	bool dl_msg_active;
	bool ps_ignore_grant;
};

enum data_ep_type_enum_v01 {
@@ -120,8 +121,6 @@ void dfc_qmi_burst_check(struct net_device *dev, struct qos_info *qos,

int qmi_rmnet_flow_control(struct net_device *dev, u32 tcm_handle, int enable);

void dfc_qmi_wq_flush(struct qmi_info *qmi);

void dfc_qmi_query_flow(void *dfc_data);

int dfc_bearer_flow_ctl(struct net_device *dev,
@@ -158,11 +157,6 @@ dfc_qmi_burst_check(struct net_device *dev, struct qos_info *qos,
{
}

static inline void
dfc_qmi_wq_flush(struct qmi_info *qmi)
{
}

static inline void
dfc_qmi_query_flow(void *dfc_data)
{
+5 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ void qmi_rmnet_work_init(void *port);
void qmi_rmnet_work_exit(void *port);
void qmi_rmnet_work_maybe_restart(void *port);
void qmi_rmnet_set_dl_msg_active(void *port);
bool qmi_rmnet_ignore_grant(void *port);

int qmi_rmnet_ps_ind_register(void *port,
			      struct qmi_rmnet_ps_ind *ps_ind);
@@ -113,6 +114,10 @@ static inline void qmi_rmnet_work_maybe_restart(void *port)
static inline void qmi_rmnet_set_dl_msg_active(void *port)
{
}
static inline bool qmi_rmnet_ignore_grant(void *port)
{
	return false;
}

static inline int qmi_rmnet_ps_ind_register(struct rmnet_port *port,
				     struct qmi_rmnet_ps_ind *ps_ind)