1/*
2 * Marvell Wireless LAN device driver: generic TX/RX data handling
3 *
4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 *
6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8 * (the "License").  You may use, redistribute and/or modify this File in
9 * accordance with the terms and conditions of the License, a copy of which
10 * is available by writing to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13 *
14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
17 * this warranty disclaimer.
18 */
19
20#include "decl.h"
21#include "ioctl.h"
22#include "util.h"
23#include "fw.h"
24#include "main.h"
25#include "wmm.h"
26
27/*
28 * This function processes the received buffer.
29 *
30 * Main responsibility of this function is to parse the RxPD to
31 * identify the correct interface this packet is headed for and
32 * forwarding it to the associated handling function, where the
33 * packet will be further processed and sent to kernel/upper layer
34 * if required.
35 */
36int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
37			     struct sk_buff *skb)
38{
39	struct mwifiex_private *priv =
40		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
41	struct rxpd *local_rx_pd;
42	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
43	int ret;
44
45	local_rx_pd = (struct rxpd *) (skb->data);
46	/* Get the BSS number from rxpd, get corresponding priv */
47	priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
48				      BSS_NUM_MASK, local_rx_pd->bss_type);
49	if (!priv)
50		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
51
52	if (!priv) {
53		dev_err(adapter->dev, "data: priv not found. Drop RX packet\n");
54		dev_kfree_skb_any(skb);
55		return -1;
56	}
57
58	memset(rx_info, 0, sizeof(*rx_info));
59	rx_info->bss_num = priv->bss_num;
60	rx_info->bss_type = priv->bss_type;
61
62	if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
63		ret = mwifiex_process_uap_rx_packet(priv, skb);
64	else
65		ret = mwifiex_process_sta_rx_packet(priv, skb);
66
67	return ret;
68}
69EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
70
71/*
72 * This function sends a packet to device.
73 *
74 * It processes the packet to add the TxPD, checks condition and
75 * sends the processed packet to firmware for transmission.
76 *
77 * On successful completion, the function calls the completion callback
78 * and logs the time.
79 */
80int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
81		       struct mwifiex_tx_param *tx_param)
82{
83	int hroom, ret = -1;
84	struct mwifiex_adapter *adapter = priv->adapter;
85	u8 *head_ptr;
86	struct txpd *local_tx_pd = NULL;
87
88	hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
89
90	if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
91		head_ptr = mwifiex_process_uap_txpd(priv, skb);
92	else
93		head_ptr = mwifiex_process_sta_txpd(priv, skb);
94
95	if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
96		skb_queue_tail(&adapter->tx_data_q, skb);
97		atomic_inc(&adapter->tx_queued);
98		return 0;
99	}
100
101	if (head_ptr) {
102		if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
103			local_tx_pd = (struct txpd *)(head_ptr + hroom);
104		if (adapter->iface_type == MWIFIEX_USB) {
105			adapter->data_sent = true;
106			ret = adapter->if_ops.host_to_card(adapter,
107							   MWIFIEX_USB_EP_DATA,
108							   skb, NULL);
109		} else {
110			ret = adapter->if_ops.host_to_card(adapter,
111							   MWIFIEX_TYPE_DATA,
112							   skb, tx_param);
113		}
114	}
115
116	switch (ret) {
117	case -ENOSR:
118		dev_dbg(adapter->dev, "data: -ENOSR is returned\n");
119		break;
120	case -EBUSY:
121		if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
122		    (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) {
123				priv->adapter->tx_lock_flag = false;
124				if (local_tx_pd)
125					local_tx_pd->flags = 0;
126		}
127		dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
128		break;
129	case -1:
130		if (adapter->iface_type != MWIFIEX_PCIE)
131			adapter->data_sent = false;
132		dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
133			ret);
134		adapter->dbg.num_tx_host_to_card_failure++;
135		mwifiex_write_data_complete(adapter, skb, 0, ret);
136		break;
137	case -EINPROGRESS:
138		if (adapter->iface_type != MWIFIEX_PCIE)
139			adapter->data_sent = false;
140		break;
141	case 0:
142		mwifiex_write_data_complete(adapter, skb, 0, ret);
143		break;
144	default:
145		break;
146	}
147
148	return ret;
149}
150
151static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
152				struct sk_buff *skb,
153				struct mwifiex_tx_param *tx_param)
154{
155	struct txpd *local_tx_pd = NULL;
156	u8 *head_ptr = skb->data;
157	int ret = 0;
158	struct mwifiex_private *priv;
159	struct mwifiex_txinfo *tx_info;
160
161	tx_info = MWIFIEX_SKB_TXCB(skb);
162	priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
163				      tx_info->bss_type);
164	if (!priv) {
165		dev_err(adapter->dev, "data: priv not found. Drop TX packet\n");
166		adapter->dbg.num_tx_host_to_card_failure++;
167		mwifiex_write_data_complete(adapter, skb, 0, 0);
168		return ret;
169	}
170	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
171		if (adapter->iface_type == MWIFIEX_USB)
172			local_tx_pd = (struct txpd *)head_ptr;
173		else
174			local_tx_pd = (struct txpd *) (head_ptr +
175				INTF_HEADER_LEN);
176	}
177
178	if (adapter->iface_type == MWIFIEX_USB) {
179		adapter->data_sent = true;
180		ret = adapter->if_ops.host_to_card(adapter,
181						   MWIFIEX_USB_EP_DATA,
182						   skb, NULL);
183	} else {
184		ret = adapter->if_ops.host_to_card(adapter,
185						   MWIFIEX_TYPE_DATA,
186						   skb, tx_param);
187	}
188	switch (ret) {
189	case -ENOSR:
190		dev_err(adapter->dev, "data: -ENOSR is returned\n");
191		break;
192	case -EBUSY:
193		if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
194		    (adapter->pps_uapsd_mode) &&
195		    (adapter->tx_lock_flag)) {
196			priv->adapter->tx_lock_flag = false;
197			if (local_tx_pd)
198				local_tx_pd->flags = 0;
199		}
200		skb_queue_head(&adapter->tx_data_q, skb);
201		if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
202			atomic_add(tx_info->aggr_num, &adapter->tx_queued);
203		else
204			atomic_inc(&adapter->tx_queued);
205		dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
206		break;
207	case -1:
208		if (adapter->iface_type != MWIFIEX_PCIE)
209			adapter->data_sent = false;
210		dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
211			ret);
212		adapter->dbg.num_tx_host_to_card_failure++;
213		mwifiex_write_data_complete(adapter, skb, 0, ret);
214		break;
215	case -EINPROGRESS:
216		if (adapter->iface_type != MWIFIEX_PCIE)
217			adapter->data_sent = false;
218		break;
219	case 0:
220		mwifiex_write_data_complete(adapter, skb, 0, ret);
221		break;
222	default:
223		break;
224	}
225	return ret;
226}
227
228static int
229mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter)
230{
231	struct sk_buff *skb, *skb_next;
232	struct mwifiex_txinfo *tx_info;
233	struct mwifiex_tx_param tx_param;
234
235	skb = skb_dequeue(&adapter->tx_data_q);
236	if (!skb)
237		return -1;
238
239	tx_info = MWIFIEX_SKB_TXCB(skb);
240	if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
241		atomic_sub(tx_info->aggr_num, &adapter->tx_queued);
242	else
243		atomic_dec(&adapter->tx_queued);
244
245	if (!skb_queue_empty(&adapter->tx_data_q))
246		skb_next = skb_peek(&adapter->tx_data_q);
247	else
248		skb_next = NULL;
249	tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0);
250	if (!tx_param.next_pkt_len) {
251		if (!mwifiex_wmm_lists_empty(adapter))
252			tx_param.next_pkt_len = 1;
253	}
254	return mwifiex_host_to_card(adapter, skb, &tx_param);
255}
256
257void
258mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
259{
260	do {
261		if (adapter->data_sent || adapter->tx_lock_flag)
262			break;
263		if (mwifiex_dequeue_tx_queue(adapter))
264			break;
265	} while (!skb_queue_empty(&adapter->tx_data_q));
266}
267
268/*
269 * Packet send completion callback handler.
270 *
271 * It either frees the buffer directly or forwards it to another
272 * completion callback which checks conditions, updates statistics,
273 * wakes up stalled traffic queue if required, and then frees the buffer.
274 */
275int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
276				struct sk_buff *skb, int aggr, int status)
277{
278	struct mwifiex_private *priv;
279	struct mwifiex_txinfo *tx_info;
280	struct netdev_queue *txq;
281	int index;
282
283	if (!skb)
284		return 0;
285
286	tx_info = MWIFIEX_SKB_TXCB(skb);
287	priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
288				      tx_info->bss_type);
289	if (!priv)
290		goto done;
291
292	if (adapter->iface_type == MWIFIEX_USB)
293		adapter->data_sent = false;
294
295	mwifiex_set_trans_start(priv->netdev);
296	if (!status) {
297		priv->stats.tx_packets++;
298		priv->stats.tx_bytes += tx_info->pkt_len;
299		if (priv->tx_timeout_cnt)
300			priv->tx_timeout_cnt = 0;
301	} else {
302		priv->stats.tx_errors++;
303	}
304
305	if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
306		atomic_dec_return(&adapter->pending_bridged_pkts);
307		if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
308			goto done;
309	}
310
311	if (aggr)
312		/* For skb_aggr, do not wake up tx queue */
313		goto done;
314
315	atomic_dec(&adapter->tx_pending);
316
317	index = mwifiex_1d_to_wmm_queue[skb->priority];
318	if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) {
319		txq = netdev_get_tx_queue(priv->netdev, index);
320		if (netif_tx_queue_stopped(txq)) {
321			netif_tx_wake_queue(txq);
322			dev_dbg(adapter->dev, "wake queue: %d\n", index);
323		}
324	}
325done:
326	dev_kfree_skb_any(skb);
327
328	return 0;
329}
330EXPORT_SYMBOL_GPL(mwifiex_write_data_complete);
331
332void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
333				   void *event_body)
334{
335	struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
336	struct sk_buff *ack_skb;
337	unsigned long flags;
338	struct mwifiex_txinfo *tx_info;
339
340	if (!tx_status->tx_token_id)
341		return;
342
343	spin_lock_irqsave(&priv->ack_status_lock, flags);
344	ack_skb = idr_find(&priv->ack_status_frames, tx_status->tx_token_id);
345	if (ack_skb)
346		idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
347	spin_unlock_irqrestore(&priv->ack_status_lock, flags);
348
349	if (ack_skb) {
350		tx_info = MWIFIEX_SKB_TXCB(ack_skb);
351
352		if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
353			/* consumes ack_skb */
354			skb_complete_wifi_ack(ack_skb, !tx_status->status);
355		} else {
356			cfg80211_mgmt_tx_status(&priv->wdev, tx_info->cookie,
357						ack_skb->data, ack_skb->len,
358						!tx_status->status, GFP_ATOMIC);
359			dev_kfree_skb_any(ack_skb);
360		}
361	}
362}
363