Example #1
0
/*
 * Add buffer into wmm tx queue and queue work to transmit it.
 */
int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
{
	struct netdev_queue *txq;
	int index = mwifiex_1d_to_wmm_queue[skb->priority];

	if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) {
		txq = netdev_get_tx_queue(priv->netdev, index);
		if (!netif_tx_queue_stopped(txq)) {
			netif_tx_stop_queue(txq);
			mwifiex_dbg(priv->adapter, DATA,
				    "stop queue: %d\n", index);
		}
	}

	if (mwifiex_bypass_tx_queue(priv, skb)) {
		atomic_inc(&priv->adapter->tx_pending);
		atomic_inc(&priv->adapter->bypass_tx_pending);
		mwifiex_wmm_add_buf_bypass_txqueue(priv, skb);
	 } else {
		atomic_inc(&priv->adapter->tx_pending);
		mwifiex_wmm_add_buf_txqueue(priv, skb);
	 }

	mwifiex_queue_main_work(priv->adapter);

	return 0;
}
Example #2
0
static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
{
	unsigned long flags;
	struct sk_buff *skb;
	struct mwifiex_rxinfo *rx_info;

	spin_lock_irqsave(&adapter->rx_proc_lock, flags);
	if (adapter->rx_processing || adapter->rx_locked) {
		spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
		goto exit_rx_proc;
	} else {
		adapter->rx_processing = true;
		spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
	}

	/* Check for Rx data */
	while ((skb = skb_dequeue(&adapter->rx_data_q))) {
		atomic_dec(&adapter->rx_pending);
		if ((adapter->delay_main_work ||
		     adapter->iface_type == MWIFIEX_USB) &&
		    (atomic_read(&adapter->rx_pending) < LOW_RX_PENDING)) {
			if (adapter->if_ops.submit_rem_rx_urbs)
				adapter->if_ops.submit_rem_rx_urbs(adapter);
			adapter->delay_main_work = false;
			mwifiex_queue_main_work(adapter);
		}
		rx_info = MWIFIEX_SKB_RXCB(skb);
		if (rx_info->buf_type == MWIFIEX_TYPE_AGGR_DATA) {
			if (adapter->if_ops.deaggr_pkt)
				adapter->if_ops.deaggr_pkt(adapter, skb);
			dev_kfree_skb_any(skb);
		} else {
			mwifiex_handle_rx_packet(adapter, skb);
		}
	}
	spin_lock_irqsave(&adapter->rx_proc_lock, flags);
	adapter->rx_processing = false;
	spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);

exit_rx_proc:
	return 0;
}
Example #3
0
static void mwifiex_usb_tx_complete(struct urb *urb)
{
	struct urb_context *context = (struct urb_context *)(urb->context);
	struct mwifiex_adapter *adapter = context->adapter;
	struct usb_card_rec *card = adapter->card;
	struct usb_tx_data_port *port;
	int i;

	mwifiex_dbg(adapter, INFO,
		    "%s: status: %d\n", __func__, urb->status);

	if (context->ep == card->tx_cmd_ep) {
		mwifiex_dbg(adapter, CMD,
			    "%s: CMD\n", __func__);
		atomic_dec(&card->tx_cmd_urb_pending);
		adapter->cmd_sent = false;
	} else {
		mwifiex_dbg(adapter, DATA,
			    "%s: DATA\n", __func__);
		mwifiex_write_data_complete(adapter, context->skb, 0,
					    urb->status ? -1 : 0);
		for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
			port = &card->port[i];
			if (context->ep == port->tx_data_ep) {
				atomic_dec(&port->tx_data_urb_pending);
				port->block_status = false;
				break;
			}
		}
		adapter->data_sent = false;
	}

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

	mwifiex_queue_main_work(adapter);

	return;
}
Example #4
0
File: usb.c Project: 19Dan01/linux
static void mwifiex_usb_tx_complete(struct urb *urb)
{
	struct urb_context *context = (struct urb_context *)(urb->context);
	struct mwifiex_adapter *adapter = context->adapter;
	struct usb_card_rec *card = adapter->card;

	dev_dbg(adapter->dev, "%s: status: %d\n", __func__, urb->status);

	if (context->ep == card->tx_cmd_ep) {
		dev_dbg(adapter->dev, "%s: CMD\n", __func__);
		atomic_dec(&card->tx_cmd_urb_pending);
		adapter->cmd_sent = false;
	} else {
		dev_dbg(adapter->dev, "%s: DATA\n", __func__);
		atomic_dec(&card->tx_data_urb_pending);
		mwifiex_write_data_complete(adapter, context->skb, 0,
					    urb->status ? -1 : 0);
	}

	mwifiex_queue_main_work(adapter);

	return;
}
Example #5
0
File: usb.c Project: 19Dan01/linux
static void mwifiex_usb_rx_complete(struct urb *urb)
{
	struct urb_context *context = (struct urb_context *)urb->context;
	struct mwifiex_adapter *adapter = context->adapter;
	struct sk_buff *skb = context->skb;
	struct usb_card_rec *card;
	int recv_length = urb->actual_length;
	int size, status;

	if (!adapter || !adapter->card) {
		pr_err("mwifiex adapter or card structure is not valid\n");
		return;
	}

	card = (struct usb_card_rec *)adapter->card;
	if (card->rx_cmd_ep == context->ep)
		atomic_dec(&card->rx_cmd_urb_pending);
	else
		atomic_dec(&card->rx_data_urb_pending);

	if (recv_length) {
		if (urb->status || (adapter->surprise_removed)) {
			dev_err(adapter->dev,
				"URB status is failed: %d\n", urb->status);
			/* Do not free skb in case of command ep */
			if (card->rx_cmd_ep != context->ep)
				dev_kfree_skb_any(skb);
			goto setup_for_next;
		}
		if (skb->len > recv_length)
			skb_trim(skb, recv_length);
		else
			skb_put(skb, recv_length - skb->len);

		status = mwifiex_usb_recv(adapter, skb, context->ep);

		dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n",
			recv_length, status);
		if (status == -EINPROGRESS) {
			mwifiex_queue_main_work(adapter);

			/* urb for data_ep is re-submitted now;
			 * urb for cmd_ep will be re-submitted in callback
			 * mwifiex_usb_recv_complete
			 */
			if (card->rx_cmd_ep == context->ep)
				return;
		} else {
			if (status == -1)
				dev_err(adapter->dev,
					"received data processing failed!\n");

			/* Do not free skb in case of command ep */
			if (card->rx_cmd_ep != context->ep)
				dev_kfree_skb_any(skb);
		}
	} else if (urb->status) {
		if (!adapter->is_suspended) {
			dev_warn(adapter->dev,
				 "Card is removed: %d\n", urb->status);
			adapter->surprise_removed = true;
		}
		dev_kfree_skb_any(skb);
		return;
	} else {
		/* Do not free skb in case of command ep */
		if (card->rx_cmd_ep != context->ep)
			dev_kfree_skb_any(skb);

		/* fall through setup_for_next */
	}

setup_for_next:
	if (card->rx_cmd_ep == context->ep)
		size = MWIFIEX_RX_CMD_BUF_SIZE;
	else
		size = MWIFIEX_RX_DATA_BUF_SIZE;

	if (card->rx_cmd_ep == context->ep) {
		mwifiex_usb_submit_rx_urb(context, size);
	} else {
		context->skb = NULL;
		if (atomic_read(&adapter->rx_pending) <= HIGH_RX_PENDING)
			mwifiex_usb_submit_rx_urb(context, size);
	}

	return;
}