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