staging: rtl8188eu: remove all DBG_88E calls from core/rtw_efuse.c
[linux-block.git] / drivers / staging / rtl8188eu / core / rtw_xmit.c
CommitLineData
71e9bd3f 1// SPDX-License-Identifier: GPL-2.0
d6846af6
LF
2/******************************************************************************
3 *
4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 *
d6846af6
LF
6 ******************************************************************************/
7#define _RTW_XMIT_C_
8
9#include <osdep_service.h>
10#include <drv_types.h>
0a0796eb 11#include <mon.h>
d6846af6
LF
12#include <wifi.h>
13#include <osdep_intf.h>
d249db9e 14#include <linux/vmalloc.h>
d6846af6
LF
15
16static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
17static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
18
19static void _init_txservq(struct tx_servq *ptxservq)
20{
aa3f5ccb 21 INIT_LIST_HEAD(&ptxservq->tx_pending);
d6846af6
LF
22 _rtw_init_queue(&ptxservq->sta_pending);
23 ptxservq->qcnt = 0;
d6846af6
LF
24}
25
6da0bda8 26void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
d6846af6 27{
7be921a2 28 memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
f214e521 29 spin_lock_init(&psta_xmitpriv->lock);
d6846af6
LF
30 _init_txservq(&psta_xmitpriv->be_q);
31 _init_txservq(&psta_xmitpriv->bk_q);
32 _init_txservq(&psta_xmitpriv->vi_q);
33 _init_txservq(&psta_xmitpriv->vo_q);
aa3f5ccb 34 INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
35 INIT_LIST_HEAD(&psta_xmitpriv->apsd);
d6846af6
LF
36}
37
6da0bda8 38s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
d6846af6
LF
39{
40 int i;
41 struct xmit_buf *pxmitbuf;
42 struct xmit_frame *pxframe;
6da0bda8 43 int res = _SUCCESS;
d6846af6
LF
44 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
45 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
46
1665c8fd
MK
47 /*
48 * We don't need to memset padapter->XXX to zero because adapter is
49 * allocated by alloc_etherdev_mq, which eventually calls kvzalloc.
50 */
d6846af6 51
f214e521 52 spin_lock_init(&pxmitpriv->lock);
d6846af6
LF
53
54 /*
ee53f6dd
SF
55 * Please insert all the queue initializaiton using _rtw_init_queue below
56 */
d6846af6
LF
57
58 pxmitpriv->adapter = padapter;
59
60 _rtw_init_queue(&pxmitpriv->be_pending);
61 _rtw_init_queue(&pxmitpriv->bk_pending);
62 _rtw_init_queue(&pxmitpriv->vi_pending);
63 _rtw_init_queue(&pxmitpriv->vo_pending);
64 _rtw_init_queue(&pxmitpriv->bm_pending);
65
66 _rtw_init_queue(&pxmitpriv->free_xmit_queue);
67
68 /*
ee53f6dd
SF
69 * Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
70 * and initialize free_xmit_frame below.
71 * Please also apply free_txobj to link_up all the xmit_frames...
72 */
d6846af6 73
2397c6e0 74 pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
d6846af6 75
c39f4bb9 76 if (!pxmitpriv->pallocated_frame_buf) {
d6846af6
LF
77 pxmitpriv->pxmit_frame_buf = NULL;
78 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_frame fail!\n"));
79 res = _FAIL;
80 goto exit;
81 }
fb113408 82 pxmitpriv->pxmit_frame_buf = PTR_ALIGN(pxmitpriv->pallocated_frame_buf, 4);
d6846af6
LF
83
84 pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
85
86 for (i = 0; i < NR_XMITFRAME; i++) {
ceefaace 87 INIT_LIST_HEAD(&pxframe->list);
d6846af6
LF
88
89 pxframe->padapter = padapter;
90 pxframe->frame_tag = NULL_FRAMETAG;
91
92 pxframe->pkt = NULL;
93
94 pxframe->buf_addr = NULL;
95 pxframe->pxmitbuf = NULL;
96
ceefaace 97 list_add_tail(&pxframe->list, &pxmitpriv->free_xmit_queue.queue);
d6846af6
LF
98
99 pxframe++;
100 }
101
102 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
103
104 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
105
106 /* init xmit_buf */
107 _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
108 _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
109
2397c6e0 110 pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
d6846af6 111
c39f4bb9 112 if (!pxmitpriv->pallocated_xmitbuf) {
d6846af6
LF
113 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_buf fail!\n"));
114 res = _FAIL;
115 goto exit;
116 }
117
fb113408 118 pxmitpriv->pxmitbuf = PTR_ALIGN(pxmitpriv->pallocated_xmitbuf, 4);
d6846af6
LF
119
120 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
121
122 for (i = 0; i < NR_XMITBUFF; i++) {
aa3f5ccb 123 INIT_LIST_HEAD(&pxmitbuf->list);
d6846af6
LF
124
125 pxmitbuf->priv_data = NULL;
126 pxmitbuf->padapter = padapter;
127 pxmitbuf->ext_tag = false;
128
129 /* Tx buf allocation may fail sometimes, so sleep and retry. */
69b2e08a 130 res = rtw_os_xmit_resource_alloc(pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
d6846af6 131 if (res == _FAIL) {
0da46e6b 132 msleep(10);
69b2e08a 133 res = rtw_os_xmit_resource_alloc(pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ));
dc0283c7 134 if (res == _FAIL)
d6846af6 135 goto exit;
d6846af6
LF
136 }
137
138 pxmitbuf->flags = XMIT_VO_QUEUE;
139
ceefaace 140 list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmitbuf_queue.queue);
d6846af6
LF
141 pxmitbuf++;
142 }
143
144 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
145
146 /* Init xmit extension buff */
147 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
148
2397c6e0 149 pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
d6846af6 150
c39f4bb9 151 if (!pxmitpriv->pallocated_xmit_extbuf) {
d6846af6
LF
152 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_extbuf fail!\n"));
153 res = _FAIL;
154 goto exit;
155 }
156
fb113408 157 pxmitpriv->pxmit_extbuf = PTR_ALIGN(pxmitpriv->pallocated_xmit_extbuf, 4);
d6846af6
LF
158
159 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
160
161 for (i = 0; i < num_xmit_extbuf; i++) {
aa3f5ccb 162 INIT_LIST_HEAD(&pxmitbuf->list);
d6846af6
LF
163
164 pxmitbuf->priv_data = NULL;
165 pxmitbuf->padapter = padapter;
166 pxmitbuf->ext_tag = true;
167
69b2e08a 168 res = rtw_os_xmit_resource_alloc(pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
d6846af6
LF
169 if (res == _FAIL) {
170 res = _FAIL;
171 goto exit;
172 }
173
ceefaace 174 list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue);
d6846af6
LF
175 pxmitbuf++;
176 }
177
178 pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
179
7671ce0d
AP
180 res = rtw_alloc_hwxmits(padapter);
181 if (res == _FAIL)
182 goto exit;
d6846af6
LF
183 rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
184
185 for (i = 0; i < 4; i++)
186 pxmitpriv->wmm_para_seq[i] = i;
187
188 pxmitpriv->txirp_cnt = 1;
189
d6846af6
LF
190 /* per AC pending irp */
191 pxmitpriv->beq_cnt = 0;
192 pxmitpriv->bkq_cnt = 0;
193 pxmitpriv->viq_cnt = 0;
194 pxmitpriv->voq_cnt = 0;
195
196 pxmitpriv->ack_tx = false;
2ca4ab53 197 mutex_init(&pxmitpriv->ack_tx_mutex);
d6846af6
LF
198 rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
199
200 rtw_hal_init_xmit_priv(padapter);
201
202exit:
d6846af6
LF
203 return res;
204}
205
7be921a2 206void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
d6846af6
LF
207{
208 int i;
209 struct adapter *padapter = pxmitpriv->adapter;
210 struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
211 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
d6846af6
LF
212 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
213
c39f4bb9 214 if (!pxmitpriv->pxmit_frame_buf)
f578b5d3 215 return;
d6846af6
LF
216
217 for (i = 0; i < NR_XMITFRAME; i++) {
218 rtw_os_xmit_complete(padapter, pxmitframe);
219
220 pxmitframe++;
221 }
222
223 for (i = 0; i < NR_XMITBUFF; i++) {
5cd38797 224 rtw_os_xmit_resource_free(pxmitbuf);
d6846af6
LF
225 pxmitbuf++;
226 }
227
da04bf74
BG
228 vfree(pxmitpriv->pallocated_frame_buf);
229 vfree(pxmitpriv->pallocated_xmitbuf);
d6846af6
LF
230
231 /* free xmit extension buff */
d6846af6
LF
232 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
233 for (i = 0; i < num_xmit_extbuf; i++) {
5cd38797 234 rtw_os_xmit_resource_free(pxmitbuf);
d6846af6
LF
235 pxmitbuf++;
236 }
237
f17331eb 238 vfree(pxmitpriv->pallocated_xmit_extbuf);
d6846af6
LF
239
240 rtw_free_hwxmits(padapter);
241
4b33d52a 242 mutex_destroy(&pxmitpriv->ack_tx_mutex);
d6846af6
LF
243}
244
245static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe)
246{
247 u32 sz;
248 struct pkt_attrib *pattrib = &pxmitframe->attrib;
249 struct sta_info *psta = pattrib->psta;
ceefaace
JSB
250 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
251 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
d6846af6
LF
252
253 if (pattrib->nr_frags != 1)
254 sz = padapter->xmitpriv.frag_len;
255 else /* no frag */
256 sz = pattrib->last_txcmdsz;
257
909495c8
MS
258 /* (1) RTS_Threshold is compared to the MPDU, not MSDU.
259 * (2) If there are more than one frag in this MSDU,
260 * only the first frag uses protection frame.
261 * Other fragments are protected by previous fragment.
262 * So we only need to check the length of first fragment.
263 */
d6846af6
LF
264 if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) {
265 if (sz > padapter->registrypriv.rts_thresh) {
266 pattrib->vcs_mode = RTS_CTS;
267 } else {
268 if (psta->rtsen)
269 pattrib->vcs_mode = RTS_CTS;
270 else if (psta->cts2self)
271 pattrib->vcs_mode = CTS_TO_SELF;
272 else
273 pattrib->vcs_mode = NONE_VCS;
274 }
275 } else {
276 while (true) {
277 /* IOT action */
278 if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && pattrib->ampdu_en &&
279 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
280 pattrib->vcs_mode = CTS_TO_SELF;
281 break;
282 }
283
284 /* check ERP protection */
285 if (psta->rtsen || psta->cts2self) {
286 if (psta->rtsen)
287 pattrib->vcs_mode = RTS_CTS;
288 else if (psta->cts2self)
289 pattrib->vcs_mode = CTS_TO_SELF;
290
291 break;
292 }
293
294 /* check HT op mode */
295 if (pattrib->ht_en) {
296 u8 htopmode = pmlmeinfo->HT_protection;
7d2af82c 297
d6846af6
LF
298 if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) ||
299 (!pmlmeext->cur_bwmode && htopmode == 3)) {
300 pattrib->vcs_mode = RTS_CTS;
301 break;
302 }
303 }
304
305 /* check rts */
306 if (sz > padapter->registrypriv.rts_thresh) {
307 pattrib->vcs_mode = RTS_CTS;
308 break;
309 }
310
311 /* to do list: check MIMO power save condition. */
312
313 /* check AMPDU aggregation for TXOP */
314 if (pattrib->ampdu_en) {
315 pattrib->vcs_mode = RTS_CTS;
316 break;
317 }
318
319 pattrib->vcs_mode = NONE_VCS;
320 break;
321 }
322 }
323}
324
325static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta)
326{
d6846af6
LF
327 pattrib->mdata = 0;
328 pattrib->eosp = 0;
329 pattrib->triggered = 0;
330
331 /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
332 pattrib->qos_en = psta->qos_option;
333
334 pattrib->raid = psta->raid;
335 pattrib->ht_en = psta->htpriv.ht_option;
336 pattrib->bwmode = psta->htpriv.bwmode;
337 pattrib->ch_offset = psta->htpriv.ch_offset;
338 pattrib->sgi = psta->htpriv.sgi;
339 pattrib->ampdu_en = false;
340 pattrib->retry_ctrl = false;
341}
342
85255891 343u8 qos_acm(u8 acm_mask, u8 priority)
d6846af6 344{
85255891 345 u8 change_priority = priority;
d6846af6
LF
346
347 switch (priority) {
348 case 0:
349 case 3:
350 if (acm_mask & BIT(1))
351 change_priority = 1;
352 break;
353 case 1:
354 case 2:
355 break;
356 case 4:
357 case 5:
358 if (acm_mask & BIT(2))
359 change_priority = 0;
360 break;
361 case 6:
362 case 7:
363 if (acm_mask & BIT(3))
364 change_priority = 5;
365 break;
366 default:
cac04b1f
MS
367 DBG_88E("%s(): invalid pattrib->priority: %d!!!\n",
368 __func__, priority);
d6846af6
LF
369 break;
370 }
371
372 return change_priority;
373}
374
97212e2b 375static void set_qos(struct sk_buff *skb, struct pkt_attrib *pattrib)
d6846af6 376{
d6846af6 377 if (pattrib->ether_type == 0x0800) {
97212e2b
IS
378 struct iphdr ip_hdr;
379
380 skb_copy_bits(skb, ETH_HLEN, &ip_hdr, sizeof(ip_hdr));
381 pattrib->priority = ip_hdr.tos >> 5;
7b170bac 382 } else if (pattrib->ether_type == ETH_P_PAE) {
909495c8
MS
383 /* When priority processing of data frames is supported,
384 * a STA's SME should send EAPOL-Key frames at the highest
385 * priority.
386 */
97212e2b
IS
387 pattrib->priority = 7;
388 } else {
389 pattrib->priority = 0;
d6846af6
LF
390 }
391
d6846af6
LF
392 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
393 pattrib->subtype = WIFI_QOS_DATA_TYPE;
394}
395
396static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib)
397{
d6846af6
LF
398 struct sta_info *psta = NULL;
399 struct ethhdr etherhdr;
400
2bd827a8 401 bool mcast;
d6846af6
LF
402 struct sta_priv *pstapriv = &padapter->stapriv;
403 struct security_priv *psecuritypriv = &padapter->securitypriv;
404 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
405 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
406 int res = _SUCCESS;
407
ebb2a79d 408 skb_copy_bits(pkt, 0, &etherhdr, ETH_HLEN);
d6846af6
LF
409
410 pattrib->ether_type = ntohs(etherhdr.h_proto);
411
412 memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
413 memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
414
415 pattrib->pctrl = 0;
416
417 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
418 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
419 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
420 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
421 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
422 memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
423 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
424 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
425 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
426 memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
427 }
428
ebb2a79d 429 pattrib->pktlen = pkt->len - ETH_HLEN;
d6846af6 430
7d7be350 431 if (pattrib->ether_type == ETH_P_IP) {
909495c8
MS
432 /* The following is for DHCP and ARP packet, we use
433 * cck1M to tx these packets and let LPS awake some
434 * time to prevent DHCP protocol fail.
435 */
d6846af6 436 u8 tmp[24];
7d2af82c 437
ebb2a79d
IS
438 skb_copy_bits(pkt, ETH_HLEN, tmp, 24);
439
d6846af6 440 pattrib->dhcp_pkt = 0;
ebb2a79d 441 if (pkt->len > ETH_HLEN + 24 + 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
7d7be350 442 if (pattrib->ether_type == ETH_P_IP) {/* IP header */
d6846af6
LF
443 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
444 ((tmp[21] == 67) && (tmp[23] == 68))) {
445 /* 68 : UDP BOOTP client */
446 /* 67 : UDP BOOTP server */
819fa2a0 447 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("====================== %s: get DHCP Packet\n", __func__));
d6846af6
LF
448 /* Use low rate to send DHCP packet. */
449 pattrib->dhcp_pkt = 1;
450 }
451 }
452 }
7b170bac 453 } else if (pattrib->ether_type == ETH_P_PAE) {
d6846af6
LF
454 DBG_88E_LEVEL(_drv_info_, "send eapol packet\n");
455 }
456
7b170bac 457 if ((pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
d6846af6
LF
458 rtw_set_scan_deny(padapter, 3000);
459
460 /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
7b170bac 461 if ((pattrib->ether_type == ETH_P_ARP) || (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1))
d6846af6
LF
462 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
463
2bd827a8 464 mcast = is_multicast_ether_addr(pattrib->ra);
d6846af6
LF
465
466 /* get sta_info */
2bd827a8 467 if (mcast) {
d6846af6
LF
468 psta = rtw_get_bcmc_stainfo(padapter);
469 } else {
470 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7de2258b 471 if (!psta) { /* if we cannot get psta => drrp the pkt */
d6846af6
LF
472 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra: %pM\n", (pattrib->ra)));
473 res = _FAIL;
474 goto exit;
3f95106e
MS
475 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) &&
476 !(psta->state & _FW_LINKED)) {
d6846af6
LF
477 res = _FAIL;
478 goto exit;
479 }
480 }
481
482 if (psta) {
483 pattrib->mac_id = psta->mac_id;
484 /* DBG_88E("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */
485 pattrib->psta = psta;
486 } else {
487 /* if we cannot get psta => drop the pkt */
488 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("\nupdate_attrib => get sta_info fail, ra:%pM\n", (pattrib->ra)));
489 res = _FAIL;
490 goto exit;
491 }
492
493 pattrib->ack_policy = 0;
d6846af6
LF
494
495 pattrib->hdrlen = WLAN_HDR_A3_LEN;
496 pattrib->subtype = WIFI_DATA_TYPE;
497 pattrib->priority = 0;
498
a66ecb24
MS
499 if (check_fwstate(pmlmepriv, WIFI_AP_STATE |
500 WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
d6846af6 501 if (psta->qos_option)
ebb2a79d 502 set_qos(pkt, pattrib);
d6846af6
LF
503 } else {
504 if (pqospriv->qos_option) {
ebb2a79d 505 set_qos(pkt, pattrib);
d6846af6
LF
506
507 if (pmlmepriv->acm_mask != 0)
508 pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
509 }
510 }
511
512 if (psta->ieee8021x_blocked) {
513 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\n psta->ieee8021x_blocked == true\n"));
514
515 pattrib->encrypt = 0;
516
80c96e08 517 if (pattrib->ether_type != ETH_P_PAE) {
7b170bac 518 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != ETH_P_PAE\n", pattrib->ether_type));
d6846af6
LF
519 res = _FAIL;
520 goto exit;
521 }
522 } else {
2bd827a8 523 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, mcast);
d6846af6
LF
524
525 switch (psecuritypriv->dot11AuthAlgrthm) {
526 case dot11AuthAlgrthm_Open:
527 case dot11AuthAlgrthm_Shared:
528 case dot11AuthAlgrthm_Auto:
529 pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
530 break;
531 case dot11AuthAlgrthm_8021X:
2bd827a8 532 if (mcast)
d6846af6
LF
533 pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
534 else
535 pattrib->key_idx = 0;
536 break;
537 default:
538 pattrib->key_idx = 0;
539 break;
540 }
541 }
542
543 switch (pattrib->encrypt) {
544 case _WEP40_:
545 case _WEP104_:
546 pattrib->iv_len = 4;
547 pattrib->icv_len = 4;
548 break;
549 case _TKIP_:
550 pattrib->iv_len = 8;
551 pattrib->icv_len = 4;
552
553 if (padapter->securitypriv.busetkipkey == _FAIL) {
554 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
555 ("\npadapter->securitypriv.busetkipkey(%d) == _FAIL drop packet\n",
556 padapter->securitypriv.busetkipkey));
557 res = _FAIL;
558 goto exit;
559 }
560 break;
561 case _AES_:
562 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("pattrib->encrypt=%d (_AES_)\n", pattrib->encrypt));
563 pattrib->iv_len = 8;
564 pattrib->icv_len = 8;
565 break;
566 default:
567 pattrib->iv_len = 0;
568 pattrib->icv_len = 0;
569 break;
570 }
571
572 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
819fa2a0 573 ("%s: encrypt=%d\n", __func__, pattrib->encrypt));
d6846af6 574
1375baa9 575 if (pattrib->encrypt && !psecuritypriv->hw_decrypted) {
d6846af6
LF
576 pattrib->bswenc = true;
577 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
819fa2a0 578 ("%s: encrypt=%d bswenc = true\n", __func__,
1375baa9 579 pattrib->encrypt));
d6846af6
LF
580 } else {
581 pattrib->bswenc = false;
819fa2a0 582 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s: bswenc = false\n", __func__));
d6846af6
LF
583 }
584
d6846af6
LF
585 update_attrib_phy_info(pattrib, psta);
586
587exit:
d6846af6
LF
588 return res;
589}
590
591static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe)
592{
593 int curfragnum, length;
594 u8 *pframe, *payload, mic[8];
595 struct mic_data micdata;
596 struct sta_info *stainfo;
597 struct pkt_attrib *pattrib = &pxmitframe->attrib;
598 struct security_priv *psecuritypriv = &padapter->securitypriv;
599 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
79ebad32 600 u8 priority[4] = {};
d6846af6 601 u8 hw_hdr_offset = 0;
d6846af6
LF
602
603 if (pattrib->psta)
604 stainfo = pattrib->psta;
605 else
6d9b0f00 606 stainfo = rtw_get_stainfo(&padapter->stapriv, &pattrib->ra[0]);
d6846af6 607
74772fcf 608 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
d6846af6 609
1330c795 610 if (pattrib->encrypt == _TKIP_) {
d6846af6 611 /* encode mic code */
7de2258b 612 if (stainfo) {
79ebad32 613 u8 null_key[16] = {};
d6846af6
LF
614
615 pframe = pxmitframe->buf_addr + hw_hdr_offset;
616
2bd827a8 617 if (is_multicast_ether_addr(pattrib->ra)) {
f42f52aa 618 if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16))
d6846af6
LF
619 return _FAIL;
620 /* start to calculate the mic code */
621 rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
622 } else {
1330c795 623 if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16))
d6846af6 624 return _FAIL;
d6846af6
LF
625 /* start to calculate the mic code */
626 rtw_secmicsetkey(&micdata, &stainfo->dot11tkiptxmickey.skey[0]);
627 }
628
a66ecb24 629 if (pframe[1] & 1) { /* ToDS == 1 */
d6846af6 630 rtw_secmicappend(&micdata, &pframe[16], 6); /* DA */
a66ecb24 631 if (pframe[1] & 2) /* From Ds == 1 */
d6846af6
LF
632 rtw_secmicappend(&micdata, &pframe[24], 6);
633 else
8126c7c1 634 rtw_secmicappend(&micdata, &pframe[10], 6);
d6846af6
LF
635 } else { /* ToDS == 0 */
636 rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */
a66ecb24 637 if (pframe[1] & 2) /* From Ds == 1 */
d6846af6
LF
638 rtw_secmicappend(&micdata, &pframe[16], 6);
639 else
640 rtw_secmicappend(&micdata, &pframe[10], 6);
641 }
642
643 if (pattrib->qos_en)
644 priority[0] = (u8)pxmitframe->attrib.priority;
645
646 rtw_secmicappend(&micdata, &priority[0], 4);
647
648 payload = pframe;
649
650 for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
7be921a2 651 payload = (u8 *)round_up((size_t)(payload), 4);
d6846af6
LF
652 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
653 ("=== curfragnum=%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
a66ecb24
MS
654 curfragnum, *payload, *(payload + 1),
655 *(payload + 2), *(payload + 3),
656 *(payload + 4), *(payload + 5),
657 *(payload + 6), *(payload + 7)));
d6846af6 658
a66ecb24 659 payload += pattrib->hdrlen + pattrib->iv_len;
d6846af6
LF
660 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
661 ("curfragnum=%d pattrib->hdrlen=%d pattrib->iv_len=%d",
662 curfragnum, pattrib->hdrlen, pattrib->iv_len));
a66ecb24
MS
663 if (curfragnum + 1 == pattrib->nr_frags) {
664 length = pattrib->last_txcmdsz -
665 pattrib->hdrlen -
666 pattrib->iv_len -
667 ((pattrib->bswenc) ?
668 pattrib->icv_len : 0);
d6846af6 669 rtw_secmicappend(&micdata, payload, length);
a66ecb24 670 payload += length;
d6846af6 671 } else {
a66ecb24
MS
672 length = pxmitpriv->frag_len -
673 pattrib->hdrlen -
674 pattrib->iv_len -
675 ((pattrib->bswenc) ?
676 pattrib->icv_len : 0);
d6846af6 677 rtw_secmicappend(&micdata, payload, length);
a66ecb24 678 payload += length + pattrib->icv_len;
d6846af6
LF
679 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("curfragnum=%d length=%d pattrib->icv_len=%d", curfragnum, length, pattrib->icv_len));
680 }
681 }
ceefaace 682 rtw_secgetmic(&micdata, &mic[0]);
819fa2a0
SMR
683 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: before add mic code!!!\n", __func__));
684 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: pattrib->last_txcmdsz=%d!!!\n", __func__, pattrib->last_txcmdsz));
685 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: mic[0]=0x%.2x , mic[1]=0x%.2x , mic[2]= 0x%.2x, mic[3]=0x%.2x\n\
d6846af6 686 mic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x , mic[7]= 0x%.2x !!!!\n",
819fa2a0 687 __func__, mic[0], mic[1], mic[2], mic[3], mic[4], mic[5], mic[6], mic[7]));
d6846af6
LF
688 /* add mic code and add the mic code length in last_txcmdsz */
689
ceefaace 690 memcpy(payload, &mic[0], 8);
d6846af6
LF
691 pattrib->last_txcmdsz += 8;
692
693 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("\n ======== last pkt ========\n"));
a66ecb24
MS
694 payload -= pattrib->last_txcmdsz + 8;
695 for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; curfragnum += 8)
67c4b441
JSB
696 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
697 (" %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x, %.2x ",
698 *(payload + curfragnum), *(payload + curfragnum + 1),
699 *(payload + curfragnum + 2), *(payload + curfragnum + 3),
700 *(payload + curfragnum + 4), *(payload + curfragnum + 5),
701 *(payload + curfragnum + 6), *(payload + curfragnum + 7)));
d6846af6 702 } else {
819fa2a0 703 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: rtw_get_stainfo==NULL!!!\n", __func__));
d6846af6
LF
704 }
705 }
706
d6846af6
LF
707 return _SUCCESS;
708}
709
710static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
711{
712 struct pkt_attrib *pattrib = &pxmitframe->attrib;
713
d6846af6 714 if (pattrib->bswenc) {
819fa2a0 715 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, ("### %s\n", __func__));
d6846af6
LF
716 switch (pattrib->encrypt) {
717 case _WEP40_:
718 case _WEP104_:
01713f0d 719 rtw_wep_encrypt(padapter, pxmitframe);
d6846af6
LF
720 break;
721 case _TKIP_:
01713f0d 722 rtw_tkip_encrypt(padapter, pxmitframe);
d6846af6
LF
723 break;
724 case _AES_:
01713f0d 725 rtw_aes_encrypt(padapter, pxmitframe);
d6846af6
LF
726 break;
727 default:
728 break;
729 }
730 } else {
731 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, ("### xmitframe_hwencrypt\n"));
732 }
733
d6846af6
LF
734 return _SUCCESS;
735}
736
7be921a2 737s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib)
d6846af6
LF
738{
739 u16 *qc;
740
d87f574d 741 struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
d6846af6
LF
742 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
743 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
744 u8 qos_option = false;
745
746 int res = _SUCCESS;
d87f574d 747 __le16 *fctrl = &pwlanhdr->frame_control;
d6846af6
LF
748
749 struct sta_info *psta;
750
d6846af6
LF
751 if (pattrib->psta) {
752 psta = pattrib->psta;
753 } else {
2bd827a8 754 if (is_multicast_ether_addr(pattrib->ra))
d6846af6 755 psta = rtw_get_bcmc_stainfo(padapter);
dc0283c7 756 else
d6846af6 757 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
d6846af6
LF
758 }
759
1ce39848 760 memset(hdr, 0, WLANHDR_OFFSET);
d6846af6
LF
761
762 SetFrameSubType(fctrl, pattrib->subtype);
763
764 if (pattrib->subtype & WIFI_DATA_TYPE) {
3f95106e 765 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
d6846af6
LF
766 /* to_ds = 1, fr_ds = 0; */
767 /* Data transfer to AP */
768 SetToDs(fctrl);
769 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
770 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
771 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
772
773 if (pqospriv->qos_option)
774 qos_option = true;
775 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
776 /* to_ds = 0, fr_ds = 1; */
777 SetFrDs(fctrl);
778 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
779 memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
780 memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
781
22824194 782 if (psta && psta->qos_option)
d6846af6
LF
783 qos_option = true;
784 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
785 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
786 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
787 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
788 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
789
22824194 790 if (psta && psta->qos_option)
d6846af6
LF
791 qos_option = true;
792 } else {
793 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv)));
794 res = _FAIL;
795 goto exit;
796 }
797
798 if (pattrib->mdata)
799 SetMData(fctrl);
800
801 if (pattrib->encrypt)
802 SetPrivacy(fctrl);
803
804 if (qos_option) {
805 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
806
807 if (pattrib->priority)
808 SetPriority(qc, pattrib->priority);
809
810 SetEOSP(qc, pattrib->eosp);
811
812 SetAckpolicy(qc, pattrib->ack_policy);
813 }
814
815 /* TODO: fill HT Control Field */
816
817 /* Update Seq Num will be handled by f/w */
818 if (psta) {
819 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
820 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
821
822 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
823
824 SetSeqNum(hdr, pattrib->seqnum);
825
826 /* check if enable ampdu */
827 if (pattrib->ht_en && psta->htpriv.ampdu_enable) {
828 if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
4e0fa71c 829 pattrib->ampdu_en = true;
d6846af6
LF
830 }
831
832 /* re-check if enable ampdu by BA_starting_seqctrl */
833 if (pattrib->ampdu_en) {
834 u16 tx_seq;
835
836 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
837
838 /* check BA_starting_seqctrl */
839 if (SN_LESS(pattrib->seqnum, tx_seq)) {
840 pattrib->ampdu_en = false;/* AGG BK */
841 } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
a66ecb24 842 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq + 1) & 0xfff;
d6846af6
LF
843
844 pattrib->ampdu_en = true;/* AGG EN */
845 } else {
a66ecb24 846 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum + 1) & 0xfff;
d6846af6
LF
847 pattrib->ampdu_en = true;/* AGG EN */
848 }
849 }
850 }
851 }
852exit:
853
d6846af6
LF
854 return res;
855}
856
857s32 rtw_txframes_pending(struct adapter *padapter)
858{
859 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
860
f7091bc6 861 return (!list_empty(&pxmitpriv->be_pending.queue) ||
f996f374
MS
862 !list_empty(&pxmitpriv->bk_pending.queue) ||
863 !list_empty(&pxmitpriv->vi_pending.queue) ||
864 !list_empty(&pxmitpriv->vo_pending.queue));
d6846af6
LF
865}
866
867s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib)
868{
869 struct sta_info *psta;
870 struct tx_servq *ptxservq;
871 int priority = pattrib->priority;
872
873 psta = pattrib->psta;
874
875 switch (priority) {
876 case 1:
877 case 2:
ceefaace 878 ptxservq = &psta->sta_xmitpriv.bk_q;
d6846af6
LF
879 break;
880 case 4:
881 case 5:
ceefaace 882 ptxservq = &psta->sta_xmitpriv.vi_q;
d6846af6
LF
883 break;
884 case 6:
885 case 7:
ceefaace 886 ptxservq = &psta->sta_xmitpriv.vo_q;
d6846af6
LF
887 break;
888 case 0:
889 case 3:
890 default:
ceefaace 891 ptxservq = &psta->sta_xmitpriv.be_q;
d6846af6
LF
892 break;
893 }
894
895 return ptxservq->qcnt;
896}
897
d6846af6 898/*
ee53f6dd
SF
899 *
900 * This sub-routine will perform all the following:
901 *
902 * 1. remove 802.3 header.
903 * 2. create wlan_header, based on the info in pxmitframe
904 * 3. append sta's iv/ext-iv
905 * 4. append LLC
906 * 5. move frag chunk from pframe to pxmitframe->mem
907 * 6. apply sw-encrypt, if necessary.
908 *
909 */
d6846af6
LF
910s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe)
911{
d6846af6
LF
912 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
913 size_t addr;
914 u8 *pframe, *mem_start;
915 u8 hw_hdr_offset;
916 struct sta_info *psta;
917 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
918 struct pkt_attrib *pattrib = &pxmitframe->attrib;
919 u8 *pbuf_start;
2bd827a8 920 bool mcast = is_multicast_ether_addr(pattrib->ra);
d6846af6 921 s32 res = _SUCCESS;
659c8734 922 size_t remainder = pkt->len - ETH_HLEN;
d6846af6
LF
923
924 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
925
7de2258b 926 if (!psta)
d6846af6
LF
927 return _FAIL;
928
c39f4bb9 929 if (!pxmitframe->buf_addr) {
d6846af6
LF
930 DBG_88E("==> %s buf_addr == NULL\n", __func__);
931 return _FAIL;
932 }
933
934 pbuf_start = pxmitframe->buf_addr;
935
936 hw_hdr_offset = TXDESC_SIZE + (pxmitframe->pkt_offset * PACKET_OFFSET_SZ);
937
938 mem_start = pbuf_start + hw_hdr_offset;
939
940 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
819fa2a0
SMR
941 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: rtw_make_wlanhdr fail; drop pkt\n", __func__));
942 DBG_88E("%s: rtw_make_wlanhdr fail; drop pkt\n", __func__);
d6846af6
LF
943 res = _FAIL;
944 goto exit;
945 }
946
d6846af6
LF
947 frg_inx = 0;
948 frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
949
950 while (1) {
951 llc_sz = 0;
952
953 mpdu_len = frg_len;
954
955 pframe = mem_start;
956
957 SetMFrag(mem_start);
958
959 pframe += pattrib->hdrlen;
960 mpdu_len -= pattrib->hdrlen;
961
962 /* adding icv, if necessary... */
963 if (pattrib->iv_len) {
d48037f9 964 switch (pattrib->encrypt) {
4e0fa71c
MB
965 case _WEP40_:
966 case _WEP104_:
967 WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
968 break;
969 case _TKIP_:
2bd827a8 970 if (mcast)
4e0fa71c
MB
971 TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
972 else
973 TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
974 break;
975 case _AES_:
2bd827a8 976 if (mcast)
4e0fa71c
MB
977 AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
978 else
979 AES_IV(pattrib->iv, psta->dot11txpn, 0);
980 break;
d6846af6
LF
981 }
982
983 memcpy(pframe, pattrib->iv, pattrib->iv_len);
984
985 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_,
819fa2a0 986 ("%s: keyid=%d pattrib->iv[3]=%.2x pframe=%.2x %.2x %.2x %.2x\n",
a66ecb24
MS
987 __func__,
988 padapter->securitypriv.dot11PrivacyKeyIndex,
989 pattrib->iv[3], *pframe, *(pframe + 1),
990 *(pframe + 2), *(pframe + 3)));
d6846af6
LF
991
992 pframe += pattrib->iv_len;
993
994 mpdu_len -= pattrib->iv_len;
995 }
996
997 if (frg_inx == 0) {
998 llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
999 pframe += llc_sz;
1000 mpdu_len -= llc_sz;
1001 }
1002
dc0283c7 1003 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
d6846af6 1004 mpdu_len -= pattrib->icv_len;
d6846af6 1005
2bd827a8 1006 mem_sz = min_t(size_t, mcast ? pattrib->pktlen : mpdu_len, remainder);
659c8734
IS
1007 skb_copy_bits(pkt, pkt->len - remainder, pframe, mem_sz);
1008 remainder -= mem_sz;
d6846af6
LF
1009
1010 pframe += mem_sz;
1011
1012 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1013 memcpy(pframe, pattrib->icv, pattrib->icv_len);
1014 pframe += pattrib->icv_len;
1015 }
1016
1017 frg_inx++;
1018
2bd827a8 1019 if (mcast || remainder == 0) {
d6846af6
LF
1020 pattrib->nr_frags = frg_inx;
1021
1022 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz : 0) +
1023 ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
1024
1025 ClearMFrag(mem_start);
1026
1027 break;
d6846af6
LF
1028 }
1029
0b4d1d0d
MS
1030 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: There're still something in packet!\n", __func__));
1031
d6846af6
LF
1032 addr = (size_t)(pframe);
1033
7be921a2 1034 mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset;
d6846af6
LF
1035 memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1036 }
1037
0a0796eb
JS
1038 /* Frame is about to be encrypted. Forward it to the monitor first. */
1039 rtl88eu_mon_xmit_hook(padapter->pmondev, pxmitframe, frg_len);
1040
d6846af6
LF
1041 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
1042 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"));
1043 DBG_88E("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n");
1044 res = _FAIL;
1045 goto exit;
1046 }
1047
1048 xmitframe_swencrypt(padapter, pxmitframe);
1049
2bd827a8 1050 if (!mcast)
d6846af6
LF
1051 update_attrib_vcs_info(padapter, pxmitframe);
1052 else
1053 pattrib->vcs_mode = NONE_VCS;
1054
1055exit:
d6846af6
LF
1056 return res;
1057}
1058
1059/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
1060 * IEEE LLC/SNAP header contains 8 octets
1061 * First 3 octets comprise the LLC portion
1062 * SNAP portion, 5 octets, is divided into two fields:
1063 * Organizationally Unique Identifier(OUI), 3 octets,
1064 * type, defined by that organization, 2 octets.
1065 */
1066s32 rtw_put_snap(u8 *data, u16 h_proto)
1067{
1068 struct ieee80211_snap_hdr *snap;
1069 u8 *oui;
1070
d6846af6
LF
1071 snap = (struct ieee80211_snap_hdr *)data;
1072 snap->dsap = 0xaa;
1073 snap->ssap = 0xaa;
1074 snap->ctrl = 0x03;
1075
1076 if (h_proto == 0x8137 || h_proto == 0x80f3)
1077 oui = P802_1H_OUI;
1078 else
1079 oui = RFC1042_OUI;
1080
1081 snap->oui[0] = oui[0];
1082 snap->oui[1] = oui[1];
1083 snap->oui[2] = oui[2];
1084
1085 *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
1086
d6846af6
LF
1087 return SNAP_SIZE + sizeof(u16);
1088}
1089
1090void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len)
1091{
af27bea4 1092 uint protection, erp_len;
d6846af6 1093 u8 *perp;
d6846af6
LF
1094 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1095 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1096
d6846af6
LF
1097 switch (pxmitpriv->vcs_setting) {
1098 case DISABLE_VCS:
1099 pxmitpriv->vcs = NONE_VCS;
1100 break;
1101 case ENABLE_VCS:
1102 break;
1103 case AUTO_VCS:
1104 default:
75f1df26 1105 perp = rtw_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len);
7de2258b 1106 if (!perp) {
d6846af6
LF
1107 pxmitpriv->vcs = NONE_VCS;
1108 } else {
1109 protection = (*(perp + 2)) & BIT(1);
1110 if (protection) {
1111 if (pregistrypriv->vcs_type == RTS_CTS)
1112 pxmitpriv->vcs = RTS_CTS;
1113 else
1114 pxmitpriv->vcs = CTS_TO_SELF;
1115 } else {
1116 pxmitpriv->vcs = NONE_VCS;
1117 }
1118 }
1119 break;
1120 }
d6846af6
LF
1121}
1122
1123void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz)
1124{
1125 struct sta_info *psta = NULL;
1126 struct stainfo_stats *pstats = NULL;
1127 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1128 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1129
a66ecb24 1130 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
d6846af6
LF
1131 pxmitpriv->tx_bytes += sz;
1132 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pxmitframe->agg_num;
1133
1134 psta = pxmitframe->attrib.psta;
1135 if (psta) {
1136 pstats = &psta->sta_stats;
1137 pstats->tx_pkts += pxmitframe->agg_num;
1138 pstats->tx_bytes += sz;
1139 }
1140 }
1141}
1142
1143struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
1144{
1145 unsigned long irql;
b9f1c275 1146 struct xmit_buf *pxmitbuf;
d6846af6
LF
1147 struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1148
f937886b 1149 spin_lock_irqsave(&pfree_queue->lock, irql);
b9f1c275
GT
1150 pxmitbuf = list_first_entry_or_null(&pfree_queue->queue,
1151 struct xmit_buf, list);
1152 if (pxmitbuf) {
1153 list_del_init(&pxmitbuf->list);
d6846af6 1154 pxmitpriv->free_xmit_extbuf_cnt--;
d6846af6 1155 pxmitbuf->priv_data = NULL;
d6846af6
LF
1156 if (pxmitbuf->sctx) {
1157 DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
1158 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1159 }
1160 }
597794f5 1161 spin_unlock_irqrestore(&pfree_queue->lock, irql);
d6846af6 1162
d6846af6
LF
1163 return pxmitbuf;
1164}
1165
1166s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1167{
1168 unsigned long irql;
1169 struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1170
7de2258b 1171 if (!pxmitbuf)
d6846af6
LF
1172 return _FAIL;
1173
f937886b 1174 spin_lock_irqsave(&pfree_queue->lock, irql);
d6846af6 1175
8d5bdece 1176 list_del_init(&pxmitbuf->list);
d6846af6 1177
ceefaace 1178 list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue));
d6846af6
LF
1179 pxmitpriv->free_xmit_extbuf_cnt++;
1180
597794f5 1181 spin_unlock_irqrestore(&pfree_queue->lock, irql);
d6846af6 1182
d6846af6
LF
1183 return _SUCCESS;
1184}
1185
1186struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
1187{
1188 unsigned long irql;
b9f1c275 1189 struct xmit_buf *pxmitbuf;
d6846af6
LF
1190 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1191
f937886b 1192 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
b9f1c275
GT
1193 pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
1194 struct xmit_buf, list);
1195 if (pxmitbuf) {
1196 list_del_init(&pxmitbuf->list);
d6846af6
LF
1197 pxmitpriv->free_xmitbuf_cnt--;
1198 pxmitbuf->priv_data = NULL;
1199 if (pxmitbuf->sctx) {
1200 DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
1201 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1202 }
1203 }
597794f5 1204 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irql);
d6846af6 1205
d6846af6
LF
1206 return pxmitbuf;
1207}
1208
1209s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1210{
1211 unsigned long irql;
1212 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1213
7de2258b 1214 if (!pxmitbuf)
d6846af6
LF
1215 return _FAIL;
1216
1217 if (pxmitbuf->sctx) {
1218 DBG_88E("%s pxmitbuf->sctx is not NULL\n", __func__);
1219 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
1220 }
1221
1222 if (pxmitbuf->ext_tag) {
1223 rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
1224 } else {
f937886b 1225 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
d6846af6 1226
8d5bdece 1227 list_del_init(&pxmitbuf->list);
d6846af6 1228
ceefaace 1229 list_add_tail(&pxmitbuf->list, get_list_head(pfree_xmitbuf_queue));
d6846af6
LF
1230
1231 pxmitpriv->free_xmitbuf_cnt++;
597794f5 1232 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irql);
d6846af6
LF
1233 }
1234
d6846af6
LF
1235 return _SUCCESS;
1236}
1237
1238/*
ee53f6dd
SF
1239 * Calling context:
1240 * 1. OS_TXENTRY
1241 * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
1242 *
1243 * If we turn on USE_RXTHREAD, then, no need for critical section.
1244 * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
1245 *
b79f45e2 1246 * Must be very, very cautious...
ee53f6dd
SF
1247 *
1248 */
d6846af6 1249
b9f1c275
GT
1250struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)
1251 /* _queue *pfree_xmit_queue) */
d6846af6
LF
1252{
1253 /*
ee53f6dd
SF
1254 * Please remember to use all the osdep_service api,
1255 * and lock/unlock or _enter/_exit critical to protect
1256 * pfree_xmit_queue
1257 */
b9f1c275 1258 struct xmit_frame *pxframe;
d6846af6
LF
1259 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1260
7057dcb3 1261 spin_lock_bh(&pfree_xmit_queue->lock);
b9f1c275
GT
1262 pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
1263 struct xmit_frame, list);
1264 if (!pxframe) {
1265 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1266 ("rtw_alloc_xmitframe:%d\n",
1267 pxmitpriv->free_xmitframe_cnt));
d6846af6 1268 } else {
b9f1c275 1269 list_del_init(&pxframe->list);
d6846af6 1270
b9f1c275 1271 /* default value setting */
d6846af6
LF
1272 pxmitpriv->free_xmitframe_cnt--;
1273
b9f1c275
GT
1274 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1275 ("rtw_alloc_xmitframe():free_xmitframe_cnt=%d\n",
1276 pxmitpriv->free_xmitframe_cnt));
d6846af6
LF
1277
1278 pxframe->buf_addr = NULL;
1279 pxframe->pxmitbuf = NULL;
1280
1ce39848 1281 memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
d6846af6
LF
1282
1283 pxframe->frame_tag = DATA_FRAMETAG;
1284
1285 pxframe->pkt = NULL;
1286 pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */
1287
1288 pxframe->agg_num = 1;
1289 pxframe->ack_report = 0;
1290 }
e02bcf61 1291 spin_unlock_bh(&pfree_xmit_queue->lock);
d6846af6 1292
d6846af6
LF
1293 return pxframe;
1294}
1295
1296s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
1297{
d6846af6
LF
1298 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1299 struct adapter *padapter = pxmitpriv->adapter;
1300 struct sk_buff *pndis_pkt = NULL;
1301
7de2258b 1302 if (!pxmitframe) {
819fa2a0 1303 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("====== %s:pxmitframe == NULL!!!!!!!!!!\n", __func__));
d6846af6
LF
1304 goto exit;
1305 }
1306
7057dcb3 1307 spin_lock_bh(&pfree_xmit_queue->lock);
d6846af6 1308
8d5bdece 1309 list_del_init(&pxmitframe->list);
d6846af6
LF
1310
1311 if (pxmitframe->pkt) {
1312 pndis_pkt = pxmitframe->pkt;
1313 pxmitframe->pkt = NULL;
1314 }
1315
ae6787ad 1316 list_add_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
d6846af6
LF
1317
1318 pxmitpriv->free_xmitframe_cnt++;
819fa2a0 1319 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("%s:free_xmitframe_cnt=%d\n", __func__, pxmitpriv->free_xmitframe_cnt));
d6846af6 1320
e02bcf61 1321 spin_unlock_bh(&pfree_xmit_queue->lock);
d6846af6
LF
1322
1323 if (pndis_pkt)
1324 rtw_os_pkt_complete(padapter, pndis_pkt);
1325
1326exit:
d6846af6
LF
1327 return _SUCCESS;
1328}
1329
1330void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue)
1331{
af39f935
MK
1332 struct list_head *phead;
1333 struct xmit_frame *pxmitframe, *temp;
d6846af6 1334
ceefaace 1335 spin_lock_bh(&pframequeue->lock);
d6846af6
LF
1336
1337 phead = get_list_head(pframequeue);
af39f935 1338 list_for_each_entry_safe(pxmitframe, temp, phead, list)
d6846af6 1339 rtw_free_xmitframe(pxmitpriv, pxmitframe);
af39f935 1340
ceefaace 1341 spin_unlock_bh(&pframequeue->lock);
d6846af6
LF
1342}
1343
1344s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
1345{
1346 if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL) {
1347 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
819fa2a0 1348 ("%s: drop xmit pkt for classifier fail\n", __func__));
d6846af6
LF
1349 return _FAIL;
1350 }
1351
1352 return _SUCCESS;
1353}
1354
1355static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, struct tx_servq *ptxservq, struct __queue *pframe_queue)
1356{
1357 struct list_head *xmitframe_plist, *xmitframe_phead;
1358 struct xmit_frame *pxmitframe = NULL;
1359
1360 xmitframe_phead = get_list_head(pframe_queue);
c44e5e39 1361 xmitframe_plist = xmitframe_phead->next;
d6846af6 1362
84660700 1363 if (xmitframe_phead != xmitframe_plist) {
bea88100 1364 pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
d6846af6 1365
c44e5e39 1366 xmitframe_plist = xmitframe_plist->next;
d6846af6 1367
8d5bdece 1368 list_del_init(&pxmitframe->list);
d6846af6
LF
1369
1370 ptxservq->qcnt--;
d6846af6 1371 }
d6846af6
LF
1372 return pxmitframe;
1373}
1374
1375struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, int entry)
1376{
d6846af6
LF
1377 struct list_head *sta_plist, *sta_phead;
1378 struct hw_xmit *phwxmit;
1379 struct tx_servq *ptxservq = NULL;
1380 struct __queue *pframe_queue = NULL;
1381 struct xmit_frame *pxmitframe = NULL;
1382 struct adapter *padapter = pxmitpriv->adapter;
1383 struct registry_priv *pregpriv = &padapter->registrypriv;
1384 int i, inx[4];
1385
d6846af6
LF
1386 inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
1387
1388 if (pregpriv->wifi_spec == 1) {
1389 int j;
1390
1391 for (j = 0; j < 4; j++)
1392 inx[j] = pxmitpriv->wmm_para_seq[j];
1393 }
1394
7057dcb3 1395 spin_lock_bh(&pxmitpriv->lock);
d6846af6
LF
1396
1397 for (i = 0; i < entry; i++) {
1398 phwxmit = phwxmit_i + inx[i];
1399
1400 sta_phead = get_list_head(phwxmit->sta_queue);
23017c88
GR
1401 list_for_each(sta_plist, sta_phead) {
1402 ptxservq = list_entry(sta_plist, struct tx_servq,
1403 tx_pending);
d6846af6
LF
1404
1405 pframe_queue = &ptxservq->sta_pending;
1406
1407 pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue);
1408
1409 if (pxmitframe) {
1410 phwxmit->accnt--;
1411
1412 /* Remove sta node when there are no pending packets. */
f7091bc6 1413 if (list_empty(&pframe_queue->queue)) /* must be done after get_next and before break */
8d5bdece 1414 list_del_init(&ptxservq->tx_pending);
d6846af6
LF
1415 goto exit;
1416 }
d6846af6
LF
1417 }
1418 }
1419exit:
e02bcf61 1420 spin_unlock_bh(&pxmitpriv->lock);
d6846af6
LF
1421 return pxmitframe;
1422}
1423
d7c25200
MS
1424struct tx_servq *rtw_get_sta_pending(struct adapter *padapter,
1425 struct sta_info *psta, int up, u8 *ac)
d6846af6
LF
1426{
1427 struct tx_servq *ptxservq;
1428
d6846af6
LF
1429 switch (up) {
1430 case 1:
1431 case 2:
ceefaace 1432 ptxservq = &psta->sta_xmitpriv.bk_q;
d6846af6 1433 *(ac) = 3;
d7c25200
MS
1434 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1435 ("%s : BK\n", __func__));
d6846af6
LF
1436 break;
1437 case 4:
1438 case 5:
ceefaace 1439 ptxservq = &psta->sta_xmitpriv.vi_q;
d6846af6 1440 *(ac) = 1;
d7c25200
MS
1441 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1442 ("%s : VI\n", __func__));
d6846af6
LF
1443 break;
1444 case 6:
1445 case 7:
ceefaace 1446 ptxservq = &psta->sta_xmitpriv.vo_q;
d6846af6 1447 *(ac) = 0;
d7c25200
MS
1448 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1449 ("%s : VO\n", __func__));
d6846af6
LF
1450 break;
1451 case 0:
1452 case 3:
1453 default:
ceefaace 1454 ptxservq = &psta->sta_xmitpriv.be_q;
d6846af6 1455 *(ac) = 2;
d7c25200
MS
1456 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
1457 ("%s : BE\n", __func__));
d6846af6
LF
1458 break;
1459 }
1460
d6846af6
LF
1461 return ptxservq;
1462}
1463
1464/*
1465 * Will enqueue pxmitframe to the proper queue,
1466 * and indicate it to xx_pending list.....
1467 */
1468s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
1469{
d6846af6
LF
1470 u8 ac_index;
1471 struct sta_info *psta;
1472 struct tx_servq *ptxservq;
1473 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1474 struct sta_priv *pstapriv = &padapter->stapriv;
1475 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
1476 int res = _SUCCESS;
1477
dc0283c7 1478 if (pattrib->psta)
d6846af6 1479 psta = pattrib->psta;
dc0283c7 1480 else
d6846af6 1481 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
d6846af6 1482
7de2258b 1483 if (!psta) {
d6846af6 1484 res = _FAIL;
819fa2a0
SMR
1485 DBG_88E("%s: psta == NULL\n", __func__);
1486 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("%s: psta == NULL\n", __func__));
d6846af6
LF
1487 goto exit;
1488 }
1489
1490 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
1491
9c4b0e70 1492 if (list_empty(&ptxservq->tx_pending))
ae6787ad 1493 list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
d6846af6 1494
ae6787ad 1495 list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
d6846af6
LF
1496 ptxservq->qcnt++;
1497 phwxmits[ac_index].accnt++;
1498exit:
d6846af6
LF
1499 return res;
1500}
1501
7671ce0d 1502s32 rtw_alloc_hwxmits(struct adapter *padapter)
d6846af6
LF
1503{
1504 struct hw_xmit *hwxmits;
1505 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1506
1507 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
1508
0507a1e5
NSN
1509 pxmitpriv->hwxmits = kcalloc(pxmitpriv->hwxmit_entry,
1510 sizeof(struct hw_xmit), GFP_KERNEL);
7671ce0d
AP
1511 if (!pxmitpriv->hwxmits)
1512 return _FAIL;
d6846af6
LF
1513
1514 hwxmits = pxmitpriv->hwxmits;
1515
c181be7f
MS
1516 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
1517 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
1518 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
1519 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
7671ce0d 1520 return _SUCCESS;
d6846af6
LF
1521}
1522
1523void rtw_free_hwxmits(struct adapter *padapter)
1524{
1525 struct hw_xmit *hwxmits;
1526 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1527
1528 hwxmits = pxmitpriv->hwxmits;
1529 kfree(hwxmits);
1530}
1531
1532void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry)
1533{
1534 int i;
7d2af82c 1535
d6846af6
LF
1536 for (i = 0; i < entry; i++, phwxmit++)
1537 phwxmit->accnt = 0;
d6846af6
LF
1538}
1539
d6846af6
LF
1540u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
1541{
1542 u32 addr;
1543 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1544
1545 switch (pattrib->qsel) {
1546 case 0:
1547 case 3:
1548 addr = BE_QUEUE_INX;
1549 break;
1550 case 1:
1551 case 2:
1552 addr = BK_QUEUE_INX;
1553 break;
1554 case 4:
1555 case 5:
1556 addr = VI_QUEUE_INX;
1557 break;
1558 case 6:
1559 case 7:
1560 addr = VO_QUEUE_INX;
1561 break;
1562 case 0x10:
1563 addr = BCN_QUEUE_INX;
1564 break;
1565 case 0x11:/* BC/MC in PS (HIQ) */
1566 addr = HIGH_QUEUE_INX;
1567 break;
1568 case 0x12:
1569 default:
1570 addr = MGT_QUEUE_INX;
1571 break;
1572 }
1573
1574 return addr;
1575}
1576
d6846af6
LF
1577/*
1578 * The main transmit(tx) entry
1579 *
1580 * Return
1581 * 1 enqueue
1582 * 0 success, hardware will handle this xmit frame(packet)
1583 * <0 fail
1584 */
1585s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
1586{
d6846af6
LF
1587 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1588 struct xmit_frame *pxmitframe = NULL;
d6846af6
LF
1589 s32 res;
1590
1591 pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
7de2258b 1592 if (!pxmitframe) {
819fa2a0 1593 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("%s: no more pxmitframe\n", __func__));
d6846af6
LF
1594 DBG_88E("DBG_TX_DROP_FRAME %s no more pxmitframe\n", __func__);
1595 return -1;
1596 }
1597
d6846af6
LF
1598 res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
1599
1600 if (res == _FAIL) {
819fa2a0 1601 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("%s: update attrib fail\n", __func__));
d6846af6
LF
1602 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1603 return -1;
1604 }
1605 pxmitframe->pkt = *ppkt;
1606
236b3d87 1607 led_control_8188eu(padapter, LED_CTL_TX);
d6846af6 1608
3929667e 1609 pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
d6846af6
LF
1610
1611#ifdef CONFIG_88EU_AP_MODE
7057dcb3 1612 spin_lock_bh(&pxmitpriv->lock);
d6846af6 1613 if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe)) {
e02bcf61 1614 spin_unlock_bh(&pxmitpriv->lock);
d6846af6
LF
1615 return 1;
1616 }
e02bcf61 1617 spin_unlock_bh(&pxmitpriv->lock);
d6846af6
LF
1618#endif
1619
bbf2f71e 1620 if (!rtw_hal_xmit(padapter, pxmitframe))
d6846af6
LF
1621 return 1;
1622
1623 return 0;
1624}
1625
1626#if defined(CONFIG_88EU_AP_MODE)
1627
1628int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe)
1629{
d6846af6
LF
1630 int ret = false;
1631 struct sta_info *psta = NULL;
1632 struct sta_priv *pstapriv = &padapter->stapriv;
1633 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1634 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2bd827a8 1635 bool mcast = is_multicast_ether_addr(pattrib->ra);
d6846af6 1636
bbf2f71e 1637 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
4e0fa71c 1638 return ret;
d6846af6
LF
1639
1640 if (pattrib->psta)
1641 psta = pattrib->psta;
1642 else
1643 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
1644
7de2258b 1645 if (!psta)
d6846af6
LF
1646 return ret;
1647
1648 if (pattrib->triggered == 1) {
2bd827a8 1649 if (mcast)
d6846af6
LF
1650 pattrib->qsel = 0x11;/* HIQ */
1651 return ret;
1652 }
1653
2bd827a8 1654 if (mcast) {
7057dcb3 1655 spin_lock_bh(&psta->sleep_q.lock);
d6846af6
LF
1656
1657 if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */
8d5bdece 1658 list_del_init(&pxmitframe->list);
d6846af6 1659
ae6787ad 1660 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
d6846af6
LF
1661
1662 psta->sleepq_len++;
1663
1664 pstapriv->tim_bitmap |= BIT(0);/* */
1665 pstapriv->sta_dz_bitmap |= BIT(0);
1666
75f1df26 1667 update_beacon(padapter, WLAN_EID_TIM, NULL, false);/* tx bc/mc packets after update bcn */
d6846af6
LF
1668
1669 ret = true;
1670 }
1671
e02bcf61 1672 spin_unlock_bh(&psta->sleep_q.lock);
d6846af6
LF
1673
1674 return ret;
1675 }
1676
7057dcb3 1677 spin_lock_bh(&psta->sleep_q.lock);
d6846af6 1678
a66ecb24 1679 if (psta->state & WIFI_SLEEP_STATE) {
d6846af6
LF
1680 u8 wmmps_ac = 0;
1681
a66ecb24 1682 if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
8d5bdece 1683 list_del_init(&pxmitframe->list);
d6846af6 1684
ae6787ad 1685 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
d6846af6
LF
1686
1687 psta->sleepq_len++;
1688
1689 switch (pattrib->priority) {
1690 case 1:
1691 case 2:
c89e9869 1692 wmmps_ac = psta->uapsd_bk & BIT(0);
d6846af6
LF
1693 break;
1694 case 4:
1695 case 5:
c89e9869 1696 wmmps_ac = psta->uapsd_vi & BIT(0);
d6846af6
LF
1697 break;
1698 case 6:
1699 case 7:
c89e9869 1700 wmmps_ac = psta->uapsd_vo & BIT(0);
d6846af6
LF
1701 break;
1702 case 0:
1703 case 3:
1704 default:
c89e9869 1705 wmmps_ac = psta->uapsd_be & BIT(0);
d6846af6
LF
1706 break;
1707 }
1708
1709 if (wmmps_ac)
1710 psta->sleepq_ac_len++;
1711
1712 if (((psta->has_legacy_ac) && (!wmmps_ac)) ||
1713 ((!psta->has_legacy_ac) && (wmmps_ac))) {
1714 pstapriv->tim_bitmap |= BIT(psta->aid);
1715
1716 if (psta->sleepq_len == 1) {
40a46d8b 1717 /* update BCN for TIM IE */
75f1df26 1718 update_beacon(padapter, WLAN_EID_TIM, NULL, false);
d6846af6
LF
1719 }
1720 }
1721 ret = true;
1722 }
1723 }
1724
e02bcf61 1725 spin_unlock_bh(&psta->sleep_q.lock);
d6846af6
LF
1726
1727 return ret;
1728}
1729
1730static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct __queue *pframequeue)
1731{
e0f489a2 1732 struct list_head *phead;
d6846af6
LF
1733 u8 ac_index;
1734 struct tx_servq *ptxservq;
1735 struct pkt_attrib *pattrib;
e0f489a2 1736 struct xmit_frame *pxmitframe, *n;
d6846af6
LF
1737 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
1738
1739 phead = get_list_head(pframequeue);
e0f489a2 1740 list_for_each_entry_safe(pxmitframe, n, phead, list) {
d6846af6
LF
1741 xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
1742
1743 pattrib = &pxmitframe->attrib;
1744
1745 ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
1746
1747 ptxservq->qcnt--;
1748 phwxmits[ac_index].accnt--;
1749 }
1750}
1751
1752void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
1753{
d6846af6
LF
1754 struct sta_info *psta_bmc;
1755 struct sta_xmit_priv *pstaxmitpriv;
1756 struct sta_priv *pstapriv = &padapter->stapriv;
1757 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1758
1759 pstaxmitpriv = &psta->sta_xmitpriv;
1760
1761 /* for BC/MC Frames */
1762 psta_bmc = rtw_get_bcmc_stainfo(padapter);
1763
7057dcb3 1764 spin_lock_bh(&pxmitpriv->lock);
d6846af6
LF
1765
1766 psta->state |= WIFI_SLEEP_STATE;
1767
1768 pstapriv->sta_dz_bitmap |= BIT(psta->aid);
1769
e0437819
MS
1770 dequeue_xmitframes_to_sleeping_queue(padapter, psta,
1771 &pstaxmitpriv->vo_q.sta_pending);
ceefaace 1772 list_del_init(&pstaxmitpriv->vo_q.tx_pending);
d6846af6 1773
e0437819
MS
1774 dequeue_xmitframes_to_sleeping_queue(padapter, psta,
1775 &pstaxmitpriv->vi_q.sta_pending);
ceefaace 1776 list_del_init(&pstaxmitpriv->vi_q.tx_pending);
d6846af6 1777
e0437819
MS
1778 dequeue_xmitframes_to_sleeping_queue(padapter, psta,
1779 &pstaxmitpriv->be_q.sta_pending);
ceefaace 1780 list_del_init(&pstaxmitpriv->be_q.tx_pending);
d6846af6 1781
e0437819
MS
1782 dequeue_xmitframes_to_sleeping_queue(padapter, psta,
1783 &pstaxmitpriv->bk_q.sta_pending);
ceefaace 1784 list_del_init(&pstaxmitpriv->bk_q.tx_pending);
d6846af6
LF
1785
1786 /* for BC/MC Frames */
1787 pstaxmitpriv = &psta_bmc->sta_xmitpriv;
e0437819
MS
1788 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc,
1789 &pstaxmitpriv->be_q.sta_pending);
ceefaace 1790 list_del_init(&pstaxmitpriv->be_q.tx_pending);
d6846af6 1791
e02bcf61 1792 spin_unlock_bh(&pxmitpriv->lock);
d6846af6
LF
1793}
1794
1795void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
1796{
d6846af6
LF
1797 u8 update_mask = 0, wmmps_ac = 0;
1798 struct sta_info *psta_bmc;
c47bcff9
DC
1799 struct list_head *xmitframe_phead;
1800 struct xmit_frame *pxmitframe, *n;
d6846af6
LF
1801 struct sta_priv *pstapriv = &padapter->stapriv;
1802
7057dcb3 1803 spin_lock_bh(&psta->sleep_q.lock);
d6846af6
LF
1804
1805 xmitframe_phead = get_list_head(&psta->sleep_q);
c47bcff9 1806 list_for_each_entry_safe(pxmitframe, n, xmitframe_phead, list) {
8d5bdece 1807 list_del_init(&pxmitframe->list);
d6846af6
LF
1808
1809 switch (pxmitframe->attrib.priority) {
1810 case 1:
1811 case 2:
c89e9869 1812 wmmps_ac = psta->uapsd_bk & BIT(1);
d6846af6
LF
1813 break;
1814 case 4:
1815 case 5:
c89e9869 1816 wmmps_ac = psta->uapsd_vi & BIT(1);
d6846af6
LF
1817 break;
1818 case 6:
1819 case 7:
c89e9869 1820 wmmps_ac = psta->uapsd_vo & BIT(1);
d6846af6
LF
1821 break;
1822 case 0:
1823 case 3:
1824 default:
c89e9869 1825 wmmps_ac = psta->uapsd_be & BIT(1);
d6846af6
LF
1826 break;
1827 }
1828
1829 psta->sleepq_len--;
1830 if (psta->sleepq_len > 0)
1831 pxmitframe->attrib.mdata = 1;
1832 else
1833 pxmitframe->attrib.mdata = 0;
1834
1835 if (wmmps_ac) {
1836 psta->sleepq_ac_len--;
1837 if (psta->sleepq_ac_len > 0) {
1838 pxmitframe->attrib.mdata = 1;
1839 pxmitframe->attrib.eosp = 0;
1840 } else {
1841 pxmitframe->attrib.mdata = 0;
1842 pxmitframe->attrib.eosp = 1;
1843 }
1844 }
1845
1846 pxmitframe->attrib.triggered = 1;
1847
e02bcf61 1848 spin_unlock_bh(&psta->sleep_q.lock);
d6846af6
LF
1849 if (rtw_hal_xmit(padapter, pxmitframe))
1850 rtw_os_xmit_complete(padapter, pxmitframe);
7057dcb3 1851 spin_lock_bh(&psta->sleep_q.lock);
d6846af6
LF
1852 }
1853
1854 if (psta->sleepq_len == 0) {
1855 pstapriv->tim_bitmap &= ~BIT(psta->aid);
1856
1857 update_mask = BIT(0);
1858
a66ecb24 1859 if (psta->state & WIFI_SLEEP_STATE)
d6846af6
LF
1860 psta->state ^= WIFI_SLEEP_STATE;
1861
1862 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1863 psta->expire_to = pstapriv->expire_to;
1864 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1865 }
1866
1867 pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
1868 }
1869
e02bcf61 1870 spin_unlock_bh(&psta->sleep_q.lock);
d6846af6
LF
1871
1872 /* for BC/MC Frames */
1873 psta_bmc = rtw_get_bcmc_stainfo(padapter);
1874 if (!psta_bmc)
1875 return;
1876
a66ecb24 1877 if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */
7057dcb3 1878 spin_lock_bh(&psta_bmc->sleep_q.lock);
d6846af6
LF
1879
1880 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
c47bcff9 1881 list_for_each_entry_safe(pxmitframe, n, xmitframe_phead, list) {
8d5bdece 1882 list_del_init(&pxmitframe->list);
d6846af6
LF
1883
1884 psta_bmc->sleepq_len--;
1885 if (psta_bmc->sleepq_len > 0)
1886 pxmitframe->attrib.mdata = 1;
1887 else
1888 pxmitframe->attrib.mdata = 0;
1889
1890 pxmitframe->attrib.triggered = 1;
1891
e02bcf61 1892 spin_unlock_bh(&psta_bmc->sleep_q.lock);
d6846af6
LF
1893 if (rtw_hal_xmit(padapter, pxmitframe))
1894 rtw_os_xmit_complete(padapter, pxmitframe);
7057dcb3 1895 spin_lock_bh(&psta_bmc->sleep_q.lock);
d6846af6
LF
1896 }
1897
1898 if (psta_bmc->sleepq_len == 0) {
1899 pstapriv->tim_bitmap &= ~BIT(0);
1900 pstapriv->sta_dz_bitmap &= ~BIT(0);
1901
1902 update_mask |= BIT(1);
1903 }
1904
e02bcf61 1905 spin_unlock_bh(&psta_bmc->sleep_q.lock);
d6846af6
LF
1906 }
1907
1908 if (update_mask)
75f1df26 1909 update_beacon(padapter, WLAN_EID_TIM, NULL, false);
d6846af6
LF
1910}
1911
1912void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta)
1913{
d6846af6 1914 u8 wmmps_ac = 0;
629132b3
DC
1915 struct list_head *xmitframe_phead;
1916 struct xmit_frame *pxmitframe, *n;
d6846af6
LF
1917 struct sta_priv *pstapriv = &padapter->stapriv;
1918
7057dcb3 1919 spin_lock_bh(&psta->sleep_q.lock);
d6846af6
LF
1920
1921 xmitframe_phead = get_list_head(&psta->sleep_q);
629132b3 1922 list_for_each_entry_safe(pxmitframe, n, xmitframe_phead, list) {
d6846af6
LF
1923 switch (pxmitframe->attrib.priority) {
1924 case 1:
1925 case 2:
c89e9869 1926 wmmps_ac = psta->uapsd_bk & BIT(1);
d6846af6
LF
1927 break;
1928 case 4:
1929 case 5:
c89e9869 1930 wmmps_ac = psta->uapsd_vi & BIT(1);
d6846af6
LF
1931 break;
1932 case 6:
1933 case 7:
c89e9869 1934 wmmps_ac = psta->uapsd_vo & BIT(1);
d6846af6
LF
1935 break;
1936 case 0:
1937 case 3:
1938 default:
c89e9869 1939 wmmps_ac = psta->uapsd_be & BIT(1);
d6846af6
LF
1940 break;
1941 }
1942
1943 if (!wmmps_ac)
1944 continue;
1945
8d5bdece 1946 list_del_init(&pxmitframe->list);
d6846af6
LF
1947
1948 psta->sleepq_len--;
1949 psta->sleepq_ac_len--;
1950
1951 if (psta->sleepq_ac_len > 0) {
1952 pxmitframe->attrib.mdata = 1;
1953 pxmitframe->attrib.eosp = 0;
1954 } else {
1955 pxmitframe->attrib.mdata = 0;
1956 pxmitframe->attrib.eosp = 1;
1957 }
1958
1959 pxmitframe->attrib.triggered = 1;
1960
3f95106e 1961 if (rtw_hal_xmit(padapter, pxmitframe))
d6846af6
LF
1962 rtw_os_xmit_complete(padapter, pxmitframe);
1963
1964 if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
1965 pstapriv->tim_bitmap &= ~BIT(psta->aid);
1966
40a46d8b 1967 /* update BCN for TIM IE */
75f1df26 1968 update_beacon(padapter, WLAN_EID_TIM, NULL, false);
d6846af6
LF
1969 }
1970 }
1971
e02bcf61 1972 spin_unlock_bh(&psta->sleep_q.lock);
d6846af6
LF
1973}
1974
1975#endif
1976
1977void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
1978{
1979 sctx->timeout_ms = timeout_ms;
c01fb496 1980 sctx->submit_time = jiffies;
d6846af6
LF
1981 init_completion(&sctx->done);
1982 sctx->status = RTW_SCTX_SUBMITTED;
1983}
1984
1985int rtw_sctx_wait(struct submit_ctx *sctx)
1986{
1987 int ret = _FAIL;
1988 unsigned long expire;
1989 int status = 0;
1990
1991 expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
1992 if (!wait_for_completion_timeout(&sctx->done, expire)) {
1993 /* timeout, do something?? */
1994 status = RTW_SCTX_DONE_TIMEOUT;
1995 DBG_88E("%s timeout\n", __func__);
1996 } else {
1997 status = sctx->status;
1998 }
1999
2000 if (status == RTW_SCTX_DONE_SUCCESS)
2001 ret = _SUCCESS;
2002
2003 return ret;
2004}
2005
f549a60b 2006static bool rtw_sctx_chk_warning_status(int status)
d6846af6
LF
2007{
2008 switch (status) {
2009 case RTW_SCTX_DONE_UNKNOWN:
2010 case RTW_SCTX_DONE_BUF_ALLOC:
2011 case RTW_SCTX_DONE_BUF_FREE:
2012
2013 case RTW_SCTX_DONE_DRV_STOP:
2014 case RTW_SCTX_DONE_DEV_REMOVE:
2015 return true;
2016 default:
2017 return false;
2018 }
2019}
2020
2021void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
2022{
2023 if (*sctx) {
f549a60b 2024 if (rtw_sctx_chk_warning_status(status))
d6846af6
LF
2025 DBG_88E("%s status:%d\n", __func__, status);
2026 (*sctx)->status = status;
2027 complete(&((*sctx)->done));
2028 *sctx = NULL;
2029 }
2030}
2031
d6846af6
LF
2032int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
2033{
2034 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2035
c01fb496 2036 pack_tx_ops->submit_time = jiffies;
d6846af6
LF
2037 pack_tx_ops->timeout_ms = timeout_ms;
2038 pack_tx_ops->status = RTW_SCTX_SUBMITTED;
2039
2040 return rtw_sctx_wait(pack_tx_ops);
2041}
2042
2043void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
2044{
2045 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2046
2047 if (pxmitpriv->ack_tx)
2048 rtw_sctx_done_err(&pack_tx_ops, status);
2049 else
2050 DBG_88E("%s ack_tx not set\n", __func__);
2051}