1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#define _RTL871X_XMIT_C_
18
19#include "osdep_service.h"
20#include "drv_types.h"
21#include "wifi.h"
22#include "osdep_intf.h"
23#include "usb_ops.h"
24
25
26static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
27static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
28static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
29static void alloc_hwxmits(struct _adapter *padapter);
30static void free_hwxmits(struct _adapter *padapter);
31
32static void _init_txservq(struct tx_servq *ptxservq)
33{
34 INIT_LIST_HEAD(&ptxservq->tx_pending);
35 _init_queue(&ptxservq->sta_pending);
36 ptxservq->qcnt = 0;
37}
38
39void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
40{
41 memset((unsigned char *)psta_xmitpriv, 0,
42 sizeof(struct sta_xmit_priv));
43 spin_lock_init(&psta_xmitpriv->lock);
44 _init_txservq(&psta_xmitpriv->be_q);
45 _init_txservq(&psta_xmitpriv->bk_q);
46 _init_txservq(&psta_xmitpriv->vi_q);
47 _init_txservq(&psta_xmitpriv->vo_q);
48 INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
49 INIT_LIST_HEAD(&psta_xmitpriv->apsd);
50}
51
52int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
53 struct _adapter *padapter)
54{
55 sint i;
56 struct xmit_buf *pxmitbuf;
57 struct xmit_frame *pxframe;
58
59 memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
60 spin_lock_init(&pxmitpriv->lock);
61
62
63
64 pxmitpriv->adapter = padapter;
65 _init_queue(&pxmitpriv->be_pending);
66 _init_queue(&pxmitpriv->bk_pending);
67 _init_queue(&pxmitpriv->vi_pending);
68 _init_queue(&pxmitpriv->vo_pending);
69 _init_queue(&pxmitpriv->bm_pending);
70 _init_queue(&pxmitpriv->legacy_dz_queue);
71 _init_queue(&pxmitpriv->apsd_queue);
72 _init_queue(&pxmitpriv->free_xmit_queue);
73
74
75
76
77
78 pxmitpriv->pallocated_frame_buf =
79 kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4, GFP_ATOMIC);
80 if (!pxmitpriv->pallocated_frame_buf) {
81 pxmitpriv->pxmit_frame_buf = NULL;
82 return -ENOMEM;
83 }
84 pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
85 ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
86 pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
87 for (i = 0; i < NR_XMITFRAME; i++) {
88 INIT_LIST_HEAD(&(pxframe->list));
89 pxframe->padapter = padapter;
90 pxframe->frame_tag = DATA_FRAMETAG;
91 pxframe->pkt = NULL;
92 pxframe->buf_addr = NULL;
93 pxframe->pxmitbuf = NULL;
94 list_add_tail(&(pxframe->list),
95 &(pxmitpriv->free_xmit_queue.queue));
96 pxframe++;
97 }
98 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
99
100
101
102 _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
103 _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
104 _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
105 _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
106 _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
107 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
108 pxmitpriv->txirp_cnt = 1;
109
110 pxmitpriv->beq_cnt = 0;
111 pxmitpriv->bkq_cnt = 0;
112 pxmitpriv->viq_cnt = 0;
113 pxmitpriv->voq_cnt = 0;
114
115 _init_queue(&pxmitpriv->free_xmitbuf_queue);
116 _init_queue(&pxmitpriv->pending_xmitbuf_queue);
117 pxmitpriv->pallocated_xmitbuf =
118 kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
119 if (!pxmitpriv->pallocated_xmitbuf) {
120 kfree(pxmitpriv->pallocated_frame_buf);
121 pxmitpriv->pallocated_frame_buf = NULL;
122 return -ENOMEM;
123 }
124 pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
125 ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
126 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
127 for (i = 0; i < NR_XMITBUFF; i++) {
128 INIT_LIST_HEAD(&pxmitbuf->list);
129 pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ,
130 GFP_ATOMIC);
131 if (!pxmitbuf->pallocated_buf)
132 return -ENOMEM;
133 pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
134 ((addr_t) (pxmitbuf->pallocated_buf) &
135 (XMITBUF_ALIGN_SZ - 1));
136 if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
137 return -ENOMEM;
138 list_add_tail(&pxmitbuf->list,
139 &(pxmitpriv->free_xmitbuf_queue.queue));
140 pxmitbuf++;
141 }
142 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
143 INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter);
144 alloc_hwxmits(padapter);
145 init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
146 tasklet_init(&pxmitpriv->xmit_tasklet, r8712_xmit_bh,
147 (unsigned long)padapter);
148 return 0;
149}
150
151void _free_xmit_priv(struct xmit_priv *pxmitpriv)
152{
153 int i;
154 struct _adapter *padapter = pxmitpriv->adapter;
155 struct xmit_frame *pxmitframe = (struct xmit_frame *)
156 pxmitpriv->pxmit_frame_buf;
157 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
158
159 if (pxmitpriv->pxmit_frame_buf == NULL)
160 return;
161 for (i = 0; i < NR_XMITFRAME; i++) {
162 r8712_xmit_complete(padapter, pxmitframe);
163 pxmitframe++;
164 }
165 for (i = 0; i < NR_XMITBUFF; i++) {
166 r8712_xmit_resource_free(padapter, pxmitbuf);
167 kfree(pxmitbuf->pallocated_buf);
168 pxmitbuf++;
169 }
170 kfree(pxmitpriv->pallocated_frame_buf);
171 kfree(pxmitpriv->pallocated_xmitbuf);
172 free_hwxmits(padapter);
173}
174
175int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
176 struct pkt_attrib *pattrib)
177{
178 struct pkt_file pktfile;
179 struct sta_info *psta = NULL;
180 struct ethhdr etherhdr;
181
182 struct tx_cmd txdesc;
183
184 bool bmcast;
185 struct sta_priv *pstapriv = &padapter->stapriv;
186 struct security_priv *psecuritypriv = &padapter->securitypriv;
187 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
188 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
189
190 _r8712_open_pktfile(pkt, &pktfile);
191
192 _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN);
193
194 pattrib->ether_type = ntohs(etherhdr.h_proto);
195
196
197
198
199
200 if (pattrib->ether_type == 0x0806) {
201 if (padapter->pwrctrlpriv.pwr_mode !=
202 padapter->registrypriv.power_mgnt) {
203 del_timer_sync(&pmlmepriv->dhcp_timer);
204 r8712_set_ps_mode(padapter,
205 padapter->registrypriv.power_mgnt,
206 padapter->registrypriv.smart_ps);
207 }
208 }
209
210 memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
211 memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
212 pattrib->pctrl = 0;
213 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
214 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
215 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
216 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
217 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
218 memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
219 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
220 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
221 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
222 memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
223 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
224
225 if (pattrib->ether_type != 0x8712)
226 return -EINVAL;
227
228
229
230
231 _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
232 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
233 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
234 pattrib->pctrl = 1;
235 }
236
237 pattrib->pktlen = pktfile.pkt_len;
238 if (pattrib->ether_type == ETH_P_IP) {
239
240
241
242
243 u8 tmp[24];
244
245 _r8712_pktfile_read(&pktfile, &tmp[0], 24);
246 pattrib->dhcp_pkt = 0;
247 if (pktfile.pkt_len > 282) {
248 if (pattrib->ether_type == ETH_P_IP) {
249 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
250 ((tmp[21] == 67) && (tmp[23] == 68))) {
251
252
253
254
255 pattrib->dhcp_pkt = 1;
256 }
257 }
258 }
259 }
260 bmcast = is_multicast_ether_addr(pattrib->ra);
261
262 if (bmcast) {
263 psta = r8712_get_bcmc_stainfo(padapter);
264 pattrib->mac_id = 4;
265 } else {
266 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
267 psta = r8712_get_stainfo(pstapriv,
268 get_bssid(pmlmepriv));
269 pattrib->mac_id = 5;
270 } else {
271 psta = r8712_get_stainfo(pstapriv, pattrib->ra);
272 if (psta == NULL)
273 return -ENOMEM;
274 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
275 pattrib->mac_id = 5;
276 else
277 pattrib->mac_id = psta->mac_id;
278 }
279 }
280
281 if (psta) {
282 pattrib->psta = psta;
283 } else {
284
285 return -ENOMEM;
286 }
287
288 pattrib->ack_policy = 0;
289
290 pattrib->pkt_hdrlen = ETH_HLEN;
291
292 if (pqospriv->qos_option) {
293 r8712_set_qos(&pktfile, pattrib);
294 } else {
295 pattrib->hdrlen = WLAN_HDR_A3_LEN;
296 pattrib->subtype = WIFI_DATA_TYPE;
297 pattrib->priority = 0;
298 }
299 if (psta->ieee8021x_blocked) {
300 pattrib->encrypt = 0;
301 if ((pattrib->ether_type != 0x888e) &&
302 !check_fwstate(pmlmepriv, WIFI_MP_STATE))
303 return -EINVAL;
304 } else {
305 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
306 }
307 switch (pattrib->encrypt) {
308 case _WEP40_:
309 case _WEP104_:
310 pattrib->iv_len = 4;
311 pattrib->icv_len = 4;
312 break;
313 case _TKIP_:
314 pattrib->iv_len = 8;
315 pattrib->icv_len = 4;
316 if (padapter->securitypriv.busetkipkey == _FAIL)
317 return -EINVAL;
318 break;
319 case _AES_:
320 pattrib->iv_len = 8;
321 pattrib->icv_len = 8;
322 break;
323 default:
324 pattrib->iv_len = 0;
325 pattrib->icv_len = 0;
326 break;
327 }
328
329 if (pattrib->encrypt &&
330 (padapter->securitypriv.sw_encrypt ||
331 !psecuritypriv->hw_decrypted))
332 pattrib->bswenc = true;
333 else
334 pattrib->bswenc = false;
335
336
337
338 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
339 pattrib->priority =
340 (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f;
341 return 0;
342}
343
344static int xmitframe_addmic(struct _adapter *padapter,
345 struct xmit_frame *pxmitframe)
346{
347 u32 curfragnum, length;
348 u8 *pframe, *payload, mic[8];
349 struct mic_data micdata;
350 struct sta_info *stainfo;
351 struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
352 struct pkt_attrib *pattrib = &pxmitframe->attrib;
353 struct security_priv *psecuritypriv = &padapter->securitypriv;
354 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
355 u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
356 bool bmcst = is_multicast_ether_addr(pattrib->ra);
357
358 if (pattrib->psta)
359 stainfo = pattrib->psta;
360 else
361 stainfo = r8712_get_stainfo(&padapter->stapriv,
362 &pattrib->ra[0]);
363 if (pattrib->encrypt == _TKIP_) {
364
365 if (stainfo != NULL) {
366 u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
367 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
368 0x0, 0x0};
369 pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
370 if (bmcst) {
371 if (!memcmp(psecuritypriv->XGrptxmickey
372 [psecuritypriv->XGrpKeyid].skey,
373 null_key, 16))
374 return -ENOMEM;
375
376 r8712_secmicsetkey(&micdata,
377 psecuritypriv->
378 XGrptxmickey[psecuritypriv->
379 XGrpKeyid].skey);
380 } else {
381 if (!memcmp(&stainfo->tkiptxmickey.skey[0],
382 null_key, 16))
383 return -ENOMEM;
384
385 r8712_secmicsetkey(&micdata,
386 &stainfo->tkiptxmickey.skey[0]);
387 }
388 if (pframe[1] & 1) {
389 r8712_secmicappend(&micdata,
390 &pframe[16], 6);
391 if (pframe[1] & 2)
392 r8712_secmicappend(&micdata,
393 &pframe[24], 6);
394 else
395 r8712_secmicappend(&micdata,
396 &pframe[10], 6);
397 } else {
398 r8712_secmicappend(&micdata,
399 &pframe[4], 6);
400 if (pframe[1] & 2)
401 r8712_secmicappend(&micdata,
402 &pframe[16], 6);
403 else
404 r8712_secmicappend(&micdata,
405 &pframe[10], 6);
406 }
407 if (pqospriv->qos_option == 1)
408 priority[0] = (u8)pxmitframe->attrib.priority;
409 r8712_secmicappend(&micdata, &priority[0], 4);
410 payload = pframe;
411 for (curfragnum = 0; curfragnum < pattrib->nr_frags;
412 curfragnum++) {
413 payload = (u8 *)RND4((addr_t)(payload));
414 payload += pattrib->hdrlen + pattrib->iv_len;
415 if ((curfragnum + 1) == pattrib->nr_frags) {
416 length = pattrib->last_txcmdsz -
417 pattrib->hdrlen -
418 pattrib->iv_len -
419 ((psecuritypriv->sw_encrypt)
420 ? pattrib->icv_len : 0);
421 r8712_secmicappend(&micdata, payload,
422 length);
423 payload = payload + length;
424 } else {
425 length = pxmitpriv->frag_len -
426 pattrib->hdrlen - pattrib->iv_len -
427 ((psecuritypriv->sw_encrypt) ?
428 pattrib->icv_len : 0);
429 r8712_secmicappend(&micdata, payload,
430 length);
431 payload = payload + length +
432 pattrib->icv_len;
433 }
434 }
435 r8712_secgetmic(&micdata, &(mic[0]));
436
437
438
439 memcpy(payload, &(mic[0]), 8);
440 pattrib->last_txcmdsz += 8;
441 payload = payload - pattrib->last_txcmdsz + 8;
442 }
443 }
444 return 0;
445}
446
447static sint xmitframe_swencrypt(struct _adapter *padapter,
448 struct xmit_frame *pxmitframe)
449{
450 struct pkt_attrib *pattrib = &pxmitframe->attrib;
451
452 if (pattrib->bswenc) {
453 switch (pattrib->encrypt) {
454 case _WEP40_:
455 case _WEP104_:
456 r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
457 break;
458 case _TKIP_:
459 r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
460 break;
461 case _AES_:
462 r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
463 break;
464 default:
465 break;
466 }
467 }
468 return _SUCCESS;
469}
470
471static int make_wlanhdr(struct _adapter *padapter, u8 *hdr,
472 struct pkt_attrib *pattrib)
473{
474 u16 *qc;
475
476 struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
477 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
478 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
479 __le16 *fctrl = &pwlanhdr->frame_ctl;
480
481 memset(hdr, 0, WLANHDR_OFFSET);
482 SetFrameSubType(fctrl, pattrib->subtype);
483 if (pattrib->subtype & WIFI_DATA_TYPE) {
484 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
485
486 SetToDs(fctrl);
487 memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
488 ETH_ALEN);
489 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
490 memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
491 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
492
493 SetFrDs(fctrl);
494 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
495 memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
496 ETH_ALEN);
497 memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
498 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
499 check_fwstate(pmlmepriv,
500 WIFI_ADHOC_MASTER_STATE)) {
501 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
502 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
503 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
504 ETH_ALEN);
505 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
506 memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
507 memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
508 memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
509 ETH_ALEN);
510 } else {
511 return -EINVAL;
512 }
513
514 if (pattrib->encrypt)
515 SetPrivacy(fctrl);
516 if (pqospriv->qos_option) {
517 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
518 if (pattrib->priority)
519 SetPriority(qc, pattrib->priority);
520 SetAckpolicy(qc, pattrib->ack_policy);
521 }
522
523
524 {
525 struct sta_info *psta;
526 bool bmcst = is_multicast_ether_addr(pattrib->ra);
527
528 if (pattrib->psta) {
529 psta = pattrib->psta;
530 } else {
531 if (bmcst)
532 psta = r8712_get_bcmc_stainfo(padapter);
533 else
534 psta =
535 r8712_get_stainfo(&padapter->stapriv,
536 pattrib->ra);
537 }
538 if (psta) {
539 psta->sta_xmitpriv.txseq_tid
540 [pattrib->priority]++;
541 psta->sta_xmitpriv.txseq_tid[pattrib->priority]
542 &= 0xFFF;
543 pattrib->seqnum = psta->sta_xmitpriv.
544 txseq_tid[pattrib->priority];
545 SetSeqNum(hdr, pattrib->seqnum);
546 }
547 }
548 }
549 return 0;
550}
551
552static sint r8712_put_snap(u8 *data, u16 h_proto)
553{
554 struct ieee80211_snap_hdr *snap;
555 const u8 *oui;
556
557 snap = (struct ieee80211_snap_hdr *)data;
558 snap->dsap = 0xaa;
559 snap->ssap = 0xaa;
560 snap->ctrl = 0x03;
561 if (h_proto == 0x8137 || h_proto == 0x80f3)
562 oui = P802_1H_OUI;
563 else
564 oui = RFC1042_OUI;
565 snap->oui[0] = oui[0];
566 snap->oui[1] = oui[1];
567 snap->oui[2] = oui[2];
568 *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
569 return SNAP_SIZE + sizeof(u16);
570}
571
572
573
574
575
576
577
578
579
580
581sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
582 struct xmit_frame *pxmitframe)
583{
584 struct pkt_file pktfile;
585
586 sint frg_len, mpdu_len, llc_sz;
587 u32 mem_sz;
588 u8 frg_inx;
589 addr_t addr;
590 u8 *pframe, *mem_start, *ptxdesc;
591 struct sta_info *psta;
592 struct security_priv *psecuritypriv = &padapter->securitypriv;
593 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
594 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
595 struct pkt_attrib *pattrib = &pxmitframe->attrib;
596 u8 *pbuf_start;
597 bool bmcst = is_multicast_ether_addr(pattrib->ra);
598
599 if (pattrib->psta == NULL)
600 return _FAIL;
601 psta = pattrib->psta;
602 if (pxmitframe->buf_addr == NULL)
603 return _FAIL;
604 pbuf_start = pxmitframe->buf_addr;
605 ptxdesc = pbuf_start;
606 mem_start = pbuf_start + TXDESC_OFFSET;
607 if (make_wlanhdr(padapter, mem_start, pattrib))
608 return _FAIL;
609 _r8712_open_pktfile(pkt, &pktfile);
610 _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
611 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
612
613 if (pattrib->ether_type == 0x8712) {
614
615 _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
616 }
617 }
618 pattrib->pktlen = pktfile.pkt_len;
619 frg_inx = 0;
620 frg_len = pxmitpriv->frag_len - 4;
621 while (1) {
622 llc_sz = 0;
623 mpdu_len = frg_len;
624 pframe = mem_start;
625 SetMFrag(mem_start);
626 pframe += pattrib->hdrlen;
627 mpdu_len -= pattrib->hdrlen;
628
629 if (pattrib->iv_len) {
630 if (psta != NULL) {
631 switch (pattrib->encrypt) {
632 case _WEP40_:
633 case _WEP104_:
634 WEP_IV(pattrib->iv, psta->txpn,
635 (u8)psecuritypriv->
636 PrivacyKeyIndex);
637 break;
638 case _TKIP_:
639 if (bmcst)
640 TKIP_IV(pattrib->iv,
641 psta->txpn,
642 (u8)psecuritypriv->
643 XGrpKeyid);
644 else
645 TKIP_IV(pattrib->iv, psta->txpn,
646 0);
647 break;
648 case _AES_:
649 if (bmcst)
650 AES_IV(pattrib->iv, psta->txpn,
651 (u8)psecuritypriv->
652 XGrpKeyid);
653 else
654 AES_IV(pattrib->iv, psta->txpn,
655 0);
656 break;
657 }
658 }
659 memcpy(pframe, pattrib->iv, pattrib->iv_len);
660 pframe += pattrib->iv_len;
661 mpdu_len -= pattrib->iv_len;
662 }
663 if (frg_inx == 0) {
664 llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
665 pframe += llc_sz;
666 mpdu_len -= llc_sz;
667 }
668 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
669 mpdu_len -= pattrib->icv_len;
670 if (bmcst)
671 mem_sz = _r8712_pktfile_read(&pktfile, pframe,
672 pattrib->pktlen);
673 else
674 mem_sz = _r8712_pktfile_read(&pktfile, pframe,
675 mpdu_len);
676 pframe += mem_sz;
677 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
678 memcpy(pframe, pattrib->icv, pattrib->icv_len);
679 pframe += pattrib->icv_len;
680 }
681 frg_inx++;
682 if (bmcst || r8712_endofpktfile(&pktfile)) {
683 pattrib->nr_frags = frg_inx;
684 pattrib->last_txcmdsz = pattrib->hdrlen +
685 pattrib->iv_len +
686 ((pattrib->nr_frags == 1) ?
687 llc_sz : 0) +
688 ((pattrib->bswenc) ?
689 pattrib->icv_len : 0) + mem_sz;
690 ClearMFrag(mem_start);
691 break;
692 }
693 addr = (addr_t)(pframe);
694 mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
695 memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
696 }
697
698 if (xmitframe_addmic(padapter, pxmitframe))
699 return _FAIL;
700 xmitframe_swencrypt(padapter, pxmitframe);
701 return _SUCCESS;
702}
703
704void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
705{
706 uint protection;
707 u8 *perp;
708 uint erp_len;
709 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
710 struct registry_priv *pregistrypriv = &padapter->registrypriv;
711
712 switch (pxmitpriv->vcs_setting) {
713 case DISABLE_VCS:
714 pxmitpriv->vcs = NONE_VCS;
715 break;
716 case ENABLE_VCS:
717 break;
718 case AUTO_VCS:
719 default:
720 perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
721 if (perp == NULL) {
722 pxmitpriv->vcs = NONE_VCS;
723 } else {
724 protection = (*(perp + 2)) & BIT(1);
725 if (protection) {
726 if (pregistrypriv->vcs_type == RTS_CTS)
727 pxmitpriv->vcs = RTS_CTS;
728 else
729 pxmitpriv->vcs = CTS_TO_SELF;
730 } else {
731 pxmitpriv->vcs = NONE_VCS;
732 }
733 }
734 break;
735 }
736}
737
738struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
739{
740 unsigned long irqL;
741 struct xmit_buf *pxmitbuf;
742 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
743
744 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
745 pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
746 struct xmit_buf, list);
747 if (pxmitbuf) {
748 list_del_init(&pxmitbuf->list);
749 pxmitpriv->free_xmitbuf_cnt--;
750 }
751 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
752 return pxmitbuf;
753}
754
755void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
756{
757 unsigned long irqL;
758 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
759
760 if (pxmitbuf == NULL)
761 return;
762 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
763 list_del_init(&pxmitbuf->list);
764 list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
765 pxmitpriv->free_xmitbuf_cnt++;
766 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
767}
768
769
770
771
772
773
774
775
776
777
778
779
780struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
781{
782
783
784
785
786
787 unsigned long irqL;
788 struct xmit_frame *pxframe;
789 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
790
791 spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
792 pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
793 struct xmit_frame, list);
794 if (pxframe) {
795 list_del_init(&pxframe->list);
796 pxmitpriv->free_xmitframe_cnt--;
797 pxframe->buf_addr = NULL;
798 pxframe->pxmitbuf = NULL;
799 pxframe->attrib.psta = NULL;
800 pxframe->pkt = NULL;
801 }
802 spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
803 return pxframe;
804}
805
806void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
807 struct xmit_frame *pxmitframe)
808{
809 unsigned long irqL;
810 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
811 struct _adapter *padapter = pxmitpriv->adapter;
812
813 if (pxmitframe == NULL)
814 return;
815 spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
816 list_del_init(&pxmitframe->list);
817 if (pxmitframe->pkt)
818 pxmitframe->pkt = NULL;
819 list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
820 pxmitpriv->free_xmitframe_cnt++;
821 spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
822 if (netif_queue_stopped(padapter->pnetdev))
823 netif_wake_queue(padapter->pnetdev);
824}
825
826void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
827 struct xmit_frame *pxmitframe)
828{
829 if (pxmitframe == NULL)
830 return;
831 if (pxmitframe->frame_tag == DATA_FRAMETAG)
832 r8712_free_xmitframe(pxmitpriv, pxmitframe);
833}
834
835void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
836 struct __queue *pframequeue)
837{
838 unsigned long irqL;
839 struct list_head *plist, *phead;
840 struct xmit_frame *pxmitframe;
841
842 spin_lock_irqsave(&(pframequeue->lock), irqL);
843 phead = &pframequeue->queue;
844 plist = phead->next;
845 while (!end_of_queue_search(phead, plist)) {
846 pxmitframe = container_of(plist, struct xmit_frame, list);
847 plist = plist->next;
848 r8712_free_xmitframe(pxmitpriv, pxmitframe);
849 }
850 spin_unlock_irqrestore(&(pframequeue->lock), irqL);
851}
852
853static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
854 struct __queue **ppstapending,
855 struct sta_info *psta, sint up)
856{
857
858 struct tx_servq *ptxservq;
859 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
860
861 switch (up) {
862 case 1:
863 case 2:
864 ptxservq = &(psta->sta_xmitpriv.bk_q);
865 *ppstapending = &padapter->xmitpriv.bk_pending;
866 (phwxmits + 3)->accnt++;
867 break;
868 case 4:
869 case 5:
870 ptxservq = &(psta->sta_xmitpriv.vi_q);
871 *ppstapending = &padapter->xmitpriv.vi_pending;
872 (phwxmits + 1)->accnt++;
873 break;
874 case 6:
875 case 7:
876 ptxservq = &(psta->sta_xmitpriv.vo_q);
877 *ppstapending = &padapter->xmitpriv.vo_pending;
878 (phwxmits + 0)->accnt++;
879 break;
880 case 0:
881 case 3:
882 default:
883 ptxservq = &(psta->sta_xmitpriv.be_q);
884 *ppstapending = &padapter->xmitpriv.be_pending;
885 (phwxmits + 2)->accnt++;
886 break;
887 }
888 return ptxservq;
889}
890
891
892
893
894
895int r8712_xmit_classifier(struct _adapter *padapter,
896 struct xmit_frame *pxmitframe)
897{
898 unsigned long irqL0;
899 struct __queue *pstapending;
900 struct sta_info *psta;
901 struct tx_servq *ptxservq;
902 struct pkt_attrib *pattrib = &pxmitframe->attrib;
903 struct sta_priv *pstapriv = &padapter->stapriv;
904 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
905 bool bmcst = is_multicast_ether_addr(pattrib->ra);
906
907 if (pattrib->psta) {
908 psta = pattrib->psta;
909 } else {
910 if (bmcst) {
911 psta = r8712_get_bcmc_stainfo(padapter);
912 } else {
913 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
914 psta = r8712_get_stainfo(pstapriv,
915 get_bssid(pmlmepriv));
916 else
917 psta = r8712_get_stainfo(pstapriv, pattrib->ra);
918 }
919 }
920 if (psta == NULL)
921 return -EINVAL;
922 ptxservq = get_sta_pending(padapter, &pstapending,
923 psta, pattrib->priority);
924 spin_lock_irqsave(&pstapending->lock, irqL0);
925 if (list_empty(&ptxservq->tx_pending))
926 list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
927 list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
928 ptxservq->qcnt++;
929 spin_unlock_irqrestore(&pstapending->lock, irqL0);
930 return 0;
931}
932
933static void alloc_hwxmits(struct _adapter *padapter)
934{
935 struct hw_xmit *hwxmits;
936 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
937
938 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
939 pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry,
940 sizeof(struct hw_xmit), GFP_ATOMIC);
941 if (!pxmitpriv->hwxmits)
942 return;
943 hwxmits = pxmitpriv->hwxmits;
944 if (pxmitpriv->hwxmit_entry == 5) {
945 pxmitpriv->bmc_txqueue.head = 0;
946 hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
947 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
948 pxmitpriv->vo_txqueue.head = 0;
949 hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
950 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
951 pxmitpriv->vi_txqueue.head = 0;
952 hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
953 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
954 pxmitpriv->bk_txqueue.head = 0;
955 hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
956 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
957 pxmitpriv->be_txqueue.head = 0;
958 hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
959 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
960 } else if (pxmitpriv->hwxmit_entry == 4) {
961 pxmitpriv->vo_txqueue.head = 0;
962 hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
963 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
964 pxmitpriv->vi_txqueue.head = 0;
965 hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
966 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
967 pxmitpriv->be_txqueue.head = 0;
968 hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
969 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
970 pxmitpriv->bk_txqueue.head = 0;
971 hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
972 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
973 }
974}
975
976static void free_hwxmits(struct _adapter *padapter)
977{
978 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
979
980 kfree(pxmitpriv->hwxmits);
981}
982
983static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
984{
985 sint i;
986
987 for (i = 0; i < entry; i++, phwxmit++) {
988 spin_lock_init(&phwxmit->xmit_lock);
989 INIT_LIST_HEAD(&phwxmit->pending);
990 phwxmit->txcmdcnt = 0;
991 phwxmit->accnt = 0;
992 }
993}
994
995void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
996 struct xmit_buf *pxmitbuf)
997{
998
999 pxmitframe->pxmitbuf = pxmitbuf;
1000
1001 pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
1002
1003 pxmitframe->buf_addr = pxmitbuf->pbuf;
1004
1005 pxmitbuf->priv_data = pxmitframe;
1006}
1007
1008
1009
1010
1011
1012
1013
1014
1015int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
1016{
1017 unsigned long irqL;
1018 int ret;
1019 struct xmit_buf *pxmitbuf = NULL;
1020 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1021 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1022
1023 r8712_do_queue_select(padapter, pattrib);
1024 spin_lock_irqsave(&pxmitpriv->lock, irqL);
1025 if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1026 ret = false;
1027 r8712_xmit_enqueue(padapter, pxmitframe);
1028 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1029 return ret;
1030 }
1031 pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
1032 if (pxmitbuf == NULL) {
1033 ret = false;
1034 r8712_xmit_enqueue(padapter, pxmitframe);
1035 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1036 } else {
1037 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1038 ret = true;
1039 xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
1040 r8712_xmit_direct(padapter, pxmitframe);
1041 }
1042 return ret;
1043}
1044