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

Commit 7e4e5d2c authored by Zhaoyang Liu's avatar Zhaoyang Liu Committed by Kalle Valo
Browse files

mwifiex: add usb multi endpoints resync support



This patch add support for usb multi endpoints resync.
Once multi channel event is received from firmware,
update usb_mc_setp flag to block TX data until setup is over.
And available data endpoint will be attached to BSS interface.

Signed-off-by: default avatarZhaoyang Liu <liuzy@marvell.com>
Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 308fe29e
Loading
Loading
Loading
Loading
+50 −4
Original line number Diff line number Diff line
@@ -294,9 +294,15 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
			/* We have tried to wakeup the card already */
			if (adapter->pm_wakeup_fw_try)
				break;
			if (adapter->ps_state != PS_STATE_AWAKE ||
			    adapter->tx_lock_flag)
			if (adapter->ps_state != PS_STATE_AWAKE)
				break;
			if (adapter->tx_lock_flag) {
				if (adapter->iface_type == MWIFIEX_USB) {
					if (!adapter->usb_mc_setup)
						break;
				} else
					break;
			}

			if ((!adapter->scan_chan_gap_enabled &&
			     adapter->scan_processing) || adapter->data_sent ||
@@ -345,8 +351,15 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
		 */
		if ((adapter->ps_state == PS_STATE_SLEEP) ||
		    (adapter->ps_state == PS_STATE_PRE_SLEEP) ||
		    (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
		    adapter->tx_lock_flag){
		    (adapter->ps_state == PS_STATE_SLEEP_CFM)) {
			continue;
		}

		if (adapter->tx_lock_flag) {
			if (adapter->iface_type == MWIFIEX_USB) {
				if (!adapter->usb_mc_setup)
					continue;
			} else
				continue;
		}

@@ -359,6 +372,13 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
			}
		}

		/** If USB Multi channel setup ongoing,
		 *  wait for ready to tx data.
		 */
		if (adapter->iface_type == MWIFIEX_USB &&
		    adapter->usb_mc_setup)
			continue;

		if ((adapter->scan_chan_gap_enabled ||
		     !adapter->scan_processing) &&
		    !adapter->data_sent &&
@@ -928,6 +948,32 @@ mwifiex_tx_timeout(struct net_device *dev)
	}
}

void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter)
{
	struct usb_card_rec *card = adapter->card;
	struct mwifiex_private *priv;
	u16 tx_buf_size;
	int i, ret;

	card->mc_resync_flag = true;
	for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
		if (atomic_read(&card->port[i].tx_data_urb_pending)) {
			mwifiex_dbg(adapter, WARN, "pending data urb in sys\n");
			return;
		}
	}

	card->mc_resync_flag = false;
	tx_buf_size = 0xffff;
	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
	ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
			       HostCmd_ACT_GEN_SET, 0, &tx_buf_size, false);
	if (ret)
		mwifiex_dbg(adapter, ERROR,
			    "send reconfig tx buf size cmd err\n");
}
EXPORT_SYMBOL_GPL(mwifiex_multi_chan_resync);

void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
{
	void *p;
+3 −0
Original line number Diff line number Diff line
@@ -816,6 +816,7 @@ struct mwifiex_if_ops {
	void (*iface_work)(struct work_struct *work);
	void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
	void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
	void (*multi_port_resync)(struct mwifiex_adapter *);
};

struct mwifiex_adapter {
@@ -991,6 +992,7 @@ struct mwifiex_adapter {
	bool drcs_enabled;
	u8 active_scan_triggered;
	bool usb_mc_status;
	bool usb_mc_setup;
};

void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
@@ -1564,6 +1566,7 @@ void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
				    struct sk_buff *event);
void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
				      struct sk_buff *event_skb);
void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter);

#ifdef CONFIG_DEBUG_FS
void mwifiex_debugfs_init(void);
+11 −0
Original line number Diff line number Diff line
@@ -1128,6 +1128,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
		ret = mwifiex_ret_11n_addba_resp(priv, resp);
		break;
	case HostCmd_CMD_RECONFIGURE_TX_BUFF:
		if (0xffff == (u16)le16_to_cpu(resp->params.tx_buf.buff_size)) {
			if (adapter->iface_type == MWIFIEX_USB &&
			    adapter->usb_mc_setup) {
				if (adapter->if_ops.multi_port_resync)
					adapter->if_ops.
						multi_port_resync(adapter);
				adapter->usb_mc_setup = false;
				adapter->tx_lock_flag = false;
			}
			break;
		}
		adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
							     tx_buf.buff_size);
		adapter->tx_buf_size = (adapter->tx_buf_size
+5 −0
Original line number Diff line number Diff line
@@ -381,6 +381,11 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
			       sizeof(struct mwifiex_ie_types_header));
	}

	if (adapter->iface_type == MWIFIEX_USB) {
		adapter->tx_lock_flag = true;
		adapter->usb_mc_setup = true;
		mwifiex_multi_chan_resync(adapter);
	}
}

void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
+56 −0
Original line number Diff line number Diff line
@@ -290,6 +290,9 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
					    urb->status ? -1 : 0);
	}

	if (card->mc_resync_flag)
		mwifiex_multi_chan_resync(adapter);

	mwifiex_queue_main_work(adapter);

	return;
@@ -671,6 +674,10 @@ static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
		if (!port->tx_data_ep)
			continue;
		port->tx_data_ix = 0;
		if (port->tx_data_ep == MWIFIEX_USB_EP_DATA)
			port->block_status = false;
		else
			port->block_status = true;
		for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
			port->tx_data_list[j].adapter = adapter;
			port->tx_data_list[j].ep = port->tx_data_ep;
@@ -769,6 +776,53 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
	return ret;
}

static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter)
{
	struct usb_card_rec *card = adapter->card;
	u8 active_port = MWIFIEX_USB_EP_DATA;
	struct mwifiex_private *priv = NULL;
	int i;

	if (adapter->usb_mc_status) {
		for (i = 0; i < adapter->priv_num; i++) {
			priv = adapter->priv[i];
			if (!priv)
				continue;
			if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&
			     !priv->bss_started) ||
			    (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&
			     !priv->media_connected))
				priv->usb_port = MWIFIEX_USB_EP_DATA;
		}
		for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)
			card->port[i].block_status = false;
	} else {
		for (i = 0; i < adapter->priv_num; i++) {
			priv = adapter->priv[i];
			if (!priv)
				continue;
			if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&
			     priv->bss_started) ||
			    (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&
			     priv->media_connected)) {
				active_port = priv->usb_port;
				break;
			}
		}
		for (i = 0; i < adapter->priv_num; i++) {
			priv = adapter->priv[i];
			if (priv)
				priv->usb_port = active_port;
		}
		for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
			if (active_port == card->port[i].tx_data_ep)
				card->port[i].block_status = false;
			else
				card->port[i].block_status = true;
		}
	}
}

/* This function write a command/data packet to card. */
static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
				    struct sk_buff *skb,
@@ -903,6 +957,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
	}

	adapter->usb_mc_status = false;
	adapter->usb_mc_setup = false;

	return 0;
}
@@ -1133,6 +1188,7 @@ static struct mwifiex_if_ops usb_ops = {
	.event_complete =	mwifiex_usb_cmd_event_complete,
	.host_to_card =		mwifiex_usb_host_to_card,
	.submit_rem_rx_urbs =	mwifiex_usb_submit_rem_rx_urbs,
	.multi_port_resync =	mwifiex_usb_port_resync,
};

/* This function initializes the USB driver module.
Loading