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

Commit 9dd7f49b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: Fix rndis client disconnection gracefully"

parents 46af90d7 1bb10a18
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -699,13 +699,21 @@ static void ecm_ipa_packet_receive_notify
	packet_len = skb->len;
	ECM_IPA_DEBUG("packet RX, len=%d\n", skb->len);

	if (unlikely(ecm_ipa_ctx == NULL)) {
		ECM_IPA_DEBUG("Private context is NULL. Drop SKB.\n");
		dev_kfree_skb_any(skb);
		return;
	}

	if (unlikely(ecm_ipa_ctx->state != ECM_IPA_CONNECTED_AND_UP)) {
		ECM_IPA_DEBUG("Missing pipe connected and/or iface up\n");
		dev_kfree_skb_any(skb);
		return;
	}

	if (evt != IPA_RECEIVE)	{
		ECM_IPA_ERROR("A none IPA_RECEIVE event in ecm_ipa_receive\n");
		dev_kfree_skb_any(skb);
		return;
	}

+11 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1178,6 +1178,12 @@ static void rndis_ipa_packet_receive_notify(
		("packet Rx, len=%d\n",
		skb->len);

	if (unlikely(rndis_ipa_ctx == NULL)) {
		RNDIS_IPA_DEBUG("Private context is NULL. Drop SKB.\n");
		dev_kfree_skb_any(skb);
		return;
	}

	if (unlikely(rndis_ipa_ctx->rx_dump_enable))
		rndis_ipa_dump_skb(skb);

@@ -1185,11 +1191,15 @@ static void rndis_ipa_packet_receive_notify(
		RNDIS_IPA_DEBUG("use connect()/up() before receive()\n");
		RNDIS_IPA_DEBUG("packet dropped (length=%d)\n",
				skb->len);
		rndis_ipa_ctx->rx_dropped++;
		dev_kfree_skb_any(skb);
		return;
	}

	if (evt != IPA_RECEIVE)	{
		RNDIS_IPA_ERROR("a none IPA_RECEIVE event in driver RX\n");
		rndis_ipa_ctx->rx_dropped++;
		dev_kfree_skb_any(skb);
		return;
	}

+5 −0
Original line number Diff line number Diff line
@@ -1429,7 +1429,10 @@ int ipa3_release_gsi_channel(u32 clnt_hdl)
		IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl));

	/* Set the disconnect in progress flag to avoid calling cb.*/
	spin_lock(&ipa3_ctx->disconnect_lock);
	atomic_set(&ep->disconnect_in_progress, 1);
	spin_unlock(&ipa3_ctx->disconnect_lock);


	gsi_res = gsi_dealloc_channel(ep->gsi_chan_hdl);
	if (gsi_res != GSI_STATUS_SUCCESS) {
@@ -1449,7 +1452,9 @@ int ipa3_release_gsi_channel(u32 clnt_hdl)
	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));

	spin_lock(&ipa3_ctx->disconnect_lock);
	memset(&ipa3_ctx->ep[clnt_hdl], 0, sizeof(struct ipa3_ep_context));
	spin_unlock(&ipa3_ctx->disconnect_lock);

	IPADBG("exit\n");
	return 0;
+15 −4
Original line number Diff line number Diff line
@@ -3080,13 +3080,17 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
	unsigned int src_pipe;
	u32 metadata;
	u8 ucp;
	void (*client_notify)(void *client_priv, enum ipa_dp_evt_type evt,
		       unsigned long data);
	void *client_priv;

	ipahal_pkt_status_parse(rx_skb->data, &status);
	src_pipe = status.endp_src_idx;
	metadata = status.metadata;
	ucp = status.ucp;
	ep = &ipa3_ctx->ep[src_pipe];
	if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes)) {
	if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes) ||
		unlikely(atomic_read(&ep->disconnect_in_progress))) {
		IPAERR("drop pipe=%d\n", src_pipe);
		dev_kfree_skb_any(rx_skb);
		return;
@@ -3109,14 +3113,21 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
			metadata, *(u32 *)rx_skb->cb);
	IPADBG_LOW("ucp: %d\n", *(u8 *)(rx_skb->cb + 4));

	spin_lock(&ipa3_ctx->disconnect_lock);
	if (likely((!atomic_read(&ep->disconnect_in_progress)) &&
				ep->valid && ep->client_notify))
		ep->client_notify(ep->priv, IPA_RECEIVE,
				ep->valid && ep->client_notify)) {
		client_notify = ep->client_notify;
		client_priv = ep->priv;
		spin_unlock(&ipa3_ctx->disconnect_lock);
		client_notify(client_priv, IPA_RECEIVE,
				(unsigned long)(rx_skb));
	else
	} else {
		spin_unlock(&ipa3_ctx->disconnect_lock);
		dev_kfree_skb_any(rx_skb);
	}

}

static void ipa3_recycle_rx_wrapper(struct ipa3_rx_pkt_wrapper *rx_pkt)
{
	rx_pkt->data.dma_addr = 0;