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

Commit 816259ab authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "f_qc_rndis: Fix issue with bus resume while using Linux Host"

parents 53e6e12c 35d3ad1b
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -827,6 +827,14 @@ static void rndis_qc_suspend(struct usb_function *f)
	if (remote_wakeup_allowed) {
		bam_data_suspend(RNDIS_QC_ACTIVE_PORT);
	} else {
		/* This is required as Linux host side RNDIS driver doesn't
		 * send RNDIS_MESSAGE_PACKET_FILTER before suspending USB bus.
		 * Hence we perform same operations explicitly here for Linux
		 * host case. In case of windows, this RNDIS state machine is
		 * already updated due to receiving of PACKET_FILTER.
		 */
		rndis_flow_control(rndis->config, true);

		/*
		 * When remote wakeup is disabled, IPA BAM is disconnected
		 * because it cannot send new data until the USB bus is resumed.
@@ -874,6 +882,14 @@ static void rndis_qc_resume(struct usb_function *f)
		rndis->bam_port.in->desc  = rndis->in_ep_desc_backup;
		rndis->bam_port.out->desc = rndis->out_ep_desc_backup;
		rndis_qc_bam_connect(rndis);
		/*
		 * Linux Host doesn't sends RNDIS_MSG_INIT or non-zero value
		 * set with RNDIS_MESSAGE_PACKET_FILTER after performing bus
		 * resume. Hence trigger USB IPA transfer functionality
		 * explicitly here. For Windows host case is also being
		 * handle with RNDIS state machine.
		 */
		rndis_flow_control(rndis->config, false);
	}

	pr_debug("%s: RNDIS resume completed\n", __func__);
+39 −17
Original line number Diff line number Diff line
@@ -544,24 +544,11 @@ static int gen_ndis_set_resp(u8 configNr, u32 OID, u8 *buf, u32 buf_len,
		 */
		retval = 0;
		if (*params->filter) {
			if (!is_rndis_ipa_supported()) {
				netif_carrier_on(params->dev);
				if (netif_running(params->dev))
					netif_wake_queue(params->dev);
			pr_debug("%s(): disable flow control\n", __func__);
			rndis_flow_control(configNr, false);
		} else {
				if (params->state != RNDIS_DATA_INITIALIZED)
					u_bam_data_start_rndis_ipa();
			}
			params->state = RNDIS_DATA_INITIALIZED;
		} else {
			if (!is_rndis_ipa_supported()) {
				netif_carrier_off(params->dev);
				netif_stop_queue(params->dev);
			} else {
				if (params->state == RNDIS_DATA_INITIALIZED)
					u_bam_data_stop_rndis_ipa();
			}
			params->state = RNDIS_INITIALIZED;
			pr_debug("%s(): enable flow control\n", __func__);
			rndis_flow_control(configNr, true);
		}
		break;

@@ -1013,6 +1000,41 @@ void rndis_set_pkt_alignment_factor(u8 configNr, u8 pkt_alignment_factor)
	rndis_per_dev_params[configNr].pkt_alignment_factor =
					pkt_alignment_factor;
}
/**
 * rndis_flow_control: enable/disable flow control with USB RNDIS interface
 * confignr - RNDIS network interface number
 * enable_flow_control - true: perform flow control, false: disable flow control
 *
 * In BAM2BAM IPA mode, this function triggers functionality to start/stop
 * endless transfers, otherwise it enables/disables RNDIS network interface.
 */
void rndis_flow_control(u8 confignr, bool enable_flow_control)
{
	struct rndis_params *params;

	params = &rndis_per_dev_params[confignr];
	pr_debug("%s(): params->state:%x\n", __func__, params->state);
	if (enable_flow_control) {
		if (is_rndis_ipa_supported() &&
			params->state == RNDIS_DATA_INITIALIZED) {
			u_bam_data_stop_rndis_ipa();
		} else {
			netif_carrier_off(params->dev);
			netif_stop_queue(params->dev);
		}
		params->state = RNDIS_INITIALIZED;
	} else {
		if (is_rndis_ipa_supported() &&
			params->state != RNDIS_DATA_INITIALIZED) {
			u_bam_data_start_rndis_ipa();
		} else {
			netif_carrier_on(params->dev);
			if (netif_running(params->dev))
				netif_wake_queue(params->dev);
		}
		params->state = RNDIS_DATA_INITIALIZED;
	}
}

void rndis_add_hdr(struct sk_buff *skb)
{
+1 −1
Original line number Diff line number Diff line
@@ -228,5 +228,5 @@ extern void rndis_set_host_mac (int configNr, const u8 *addr);
extern bool is_rndis_ipa_supported(void);
int rndis_init(void);
void rndis_exit (void);

void rndis_flow_control(u8 confignr, bool enable_flow_control);
#endif  /* _LINUX_RNDIS_H */