1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
29 #define _RTL871X_XMIT_C_
31 #include "osdep_service.h"
32 #include "drv_types.h"
33 #include "rtl871x_byteorder.h"
35 #include "osdep_intf.h"
39 static const u8 P802_1H_OUI
[P80211_OUI_LEN
] = {0x00, 0x00, 0xf8};
40 static const u8 RFC1042_OUI
[P80211_OUI_LEN
] = {0x00, 0x00, 0x00};
41 static void init_hwxmits(struct hw_xmit
*phwxmit
, sint entry
);
42 static void alloc_hwxmits(struct _adapter
*padapter
);
43 static void free_hwxmits(struct _adapter
*padapter
);
45 static void _init_txservq(struct tx_servq
*ptxservq
)
47 _init_listhead(&ptxservq
->tx_pending
);
48 _init_queue(&ptxservq
->sta_pending
);
52 void _r8712_init_sta_xmit_priv(struct sta_xmit_priv
*psta_xmitpriv
)
54 memset((unsigned char *)psta_xmitpriv
, 0,
55 sizeof(struct sta_xmit_priv
));
56 spin_lock_init(&psta_xmitpriv
->lock
);
57 _init_txservq(&psta_xmitpriv
->be_q
);
58 _init_txservq(&psta_xmitpriv
->bk_q
);
59 _init_txservq(&psta_xmitpriv
->vi_q
);
60 _init_txservq(&psta_xmitpriv
->vo_q
);
61 _init_listhead(&psta_xmitpriv
->legacy_dz
);
62 _init_listhead(&psta_xmitpriv
->apsd
);
65 sint
_r8712_init_xmit_priv(struct xmit_priv
*pxmitpriv
,
66 struct _adapter
*padapter
)
69 struct xmit_buf
*pxmitbuf
;
70 struct xmit_frame
*pxframe
;
72 memset((unsigned char *)pxmitpriv
, 0, sizeof(struct xmit_priv
));
73 spin_lock_init(&pxmitpriv
->lock
);
74 sema_init(&pxmitpriv
->xmit_sema
, 0);
75 sema_init(&pxmitpriv
->terminate_xmitthread_sema
, 0);
77 Please insert all the queue initializaiton using _init_queue below
79 pxmitpriv
->adapter
= padapter
;
80 _init_queue(&pxmitpriv
->be_pending
);
81 _init_queue(&pxmitpriv
->bk_pending
);
82 _init_queue(&pxmitpriv
->vi_pending
);
83 _init_queue(&pxmitpriv
->vo_pending
);
84 _init_queue(&pxmitpriv
->bm_pending
);
85 _init_queue(&pxmitpriv
->legacy_dz_queue
);
86 _init_queue(&pxmitpriv
->apsd_queue
);
87 _init_queue(&pxmitpriv
->free_xmit_queue
);
89 Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
90 and initialize free_xmit_frame below.
91 Please also apply free_txobj to link_up all the xmit_frames...
93 pxmitpriv
->pallocated_frame_buf
= _malloc(NR_XMITFRAME
*
94 sizeof(struct xmit_frame
) + 4);
95 if (pxmitpriv
->pallocated_frame_buf
== NULL
) {
96 pxmitpriv
->pxmit_frame_buf
= NULL
;
99 pxmitpriv
->pxmit_frame_buf
= pxmitpriv
->pallocated_frame_buf
+ 4 -
100 ((addr_t
) (pxmitpriv
->pallocated_frame_buf
) & 3);
101 pxframe
= (struct xmit_frame
*) pxmitpriv
->pxmit_frame_buf
;
102 for (i
= 0; i
< NR_XMITFRAME
; i
++) {
103 _init_listhead(&(pxframe
->list
));
104 pxframe
->padapter
= padapter
;
105 pxframe
->frame_tag
= DATA_FRAMETAG
;
107 pxframe
->buf_addr
= NULL
;
108 pxframe
->pxmitbuf
= NULL
;
109 list_insert_tail(&(pxframe
->list
),
110 &(pxmitpriv
->free_xmit_queue
.queue
));
113 pxmitpriv
->free_xmitframe_cnt
= NR_XMITFRAME
;
117 _r8712_init_hw_txqueue(&pxmitpriv
->be_txqueue
, BE_QUEUE_INX
);
118 _r8712_init_hw_txqueue(&pxmitpriv
->bk_txqueue
, BK_QUEUE_INX
);
119 _r8712_init_hw_txqueue(&pxmitpriv
->vi_txqueue
, VI_QUEUE_INX
);
120 _r8712_init_hw_txqueue(&pxmitpriv
->vo_txqueue
, VO_QUEUE_INX
);
121 _r8712_init_hw_txqueue(&pxmitpriv
->bmc_txqueue
, BMC_QUEUE_INX
);
122 pxmitpriv
->frag_len
= MAX_FRAG_THRESHOLD
;
123 pxmitpriv
->txirp_cnt
= 1;
124 sema_init(&(pxmitpriv
->tx_retevt
), 0);
125 /*per AC pending irp*/
126 pxmitpriv
->beq_cnt
= 0;
127 pxmitpriv
->bkq_cnt
= 0;
128 pxmitpriv
->viq_cnt
= 0;
129 pxmitpriv
->voq_cnt
= 0;
131 _init_queue(&pxmitpriv
->free_xmitbuf_queue
);
132 _init_queue(&pxmitpriv
->pending_xmitbuf_queue
);
133 pxmitpriv
->pallocated_xmitbuf
= _malloc(NR_XMITBUFF
*
134 sizeof(struct xmit_buf
) + 4);
135 if (pxmitpriv
->pallocated_xmitbuf
== NULL
)
137 pxmitpriv
->pxmitbuf
= pxmitpriv
->pallocated_xmitbuf
+ 4 -
138 ((addr_t
)(pxmitpriv
->pallocated_xmitbuf
) & 3);
139 pxmitbuf
= (struct xmit_buf
*)pxmitpriv
->pxmitbuf
;
140 for (i
= 0; i
< NR_XMITBUFF
; i
++) {
141 _init_listhead(&pxmitbuf
->list
);
142 pxmitbuf
->pallocated_buf
= _malloc(MAX_XMITBUF_SZ
+
144 if (pxmitbuf
->pallocated_buf
== NULL
)
146 pxmitbuf
->pbuf
= pxmitbuf
->pallocated_buf
+ XMITBUF_ALIGN_SZ
-
147 ((addr_t
) (pxmitbuf
->pallocated_buf
) &
148 (XMITBUF_ALIGN_SZ
- 1));
149 r8712_xmit_resource_alloc(padapter
, pxmitbuf
);
150 list_insert_tail(&pxmitbuf
->list
,
151 &(pxmitpriv
->free_xmitbuf_queue
.queue
));
154 pxmitpriv
->free_xmitbuf_cnt
= NR_XMITBUFF
;
155 alloc_hwxmits(padapter
);
156 init_hwxmits(pxmitpriv
->hwxmits
, pxmitpriv
->hwxmit_entry
);
157 tasklet_init(&pxmitpriv
->xmit_tasklet
,
158 (void(*)(addr_t
))r8712_xmit_bh
,
163 void _free_xmit_priv(struct xmit_priv
*pxmitpriv
)
166 struct _adapter
*padapter
= pxmitpriv
->adapter
;
167 struct xmit_frame
*pxmitframe
= (struct xmit_frame
*)
168 pxmitpriv
->pxmit_frame_buf
;
169 struct xmit_buf
*pxmitbuf
= (struct xmit_buf
*)pxmitpriv
->pxmitbuf
;
171 if (pxmitpriv
->pxmit_frame_buf
== NULL
)
173 for (i
= 0; i
< NR_XMITFRAME
; i
++) {
174 r8712_xmit_complete(padapter
, pxmitframe
);
177 for (i
= 0; i
< NR_XMITBUFF
; i
++) {
178 r8712_xmit_resource_free(padapter
, pxmitbuf
);
179 kfree(pxmitbuf
->pallocated_buf
);
182 kfree(pxmitpriv
->pallocated_frame_buf
);
183 kfree(pxmitpriv
->pallocated_xmitbuf
);
184 free_hwxmits(padapter
);
187 sint
r8712_update_attrib(struct _adapter
*padapter
, _pkt
*pkt
,
188 struct pkt_attrib
*pattrib
)
191 struct pkt_file pktfile
;
192 struct sta_info
*psta
= NULL
;
193 struct ethhdr etherhdr
;
195 struct tx_cmd txdesc
;
198 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
199 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
200 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
201 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
203 _r8712_open_pktfile(pkt
, &pktfile
);
205 i
= _r8712_pktfile_read(&pktfile
, (unsigned char *)ðerhdr
, ETH_HLEN
);
207 pattrib
->ether_type
= ntohs(etherhdr
.h_proto
);
211 /*If driver xmit ARP packet, driver can set ps mode to initial
212 * setting. It stands for getting DHCP or fix IP.*/
213 if (pattrib
->ether_type
== 0x0806) {
214 if (padapter
->pwrctrlpriv
.pwr_mode
!=
215 padapter
->registrypriv
.power_mgnt
) {
216 _cancel_timer(&(pmlmepriv
->dhcp_timer
), &bool);
217 r8712_set_ps_mode(padapter
, padapter
->registrypriv
.
218 power_mgnt
, padapter
->registrypriv
.smart_ps
);
222 memcpy(pattrib
->dst
, ðerhdr
.h_dest
, ETH_ALEN
);
223 memcpy(pattrib
->src
, ðerhdr
.h_source
, ETH_ALEN
);
225 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true) ||
226 (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) == true)) {
227 memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
228 memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
229 } else if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
230 memcpy(pattrib
->ra
, get_bssid(pmlmepriv
), ETH_ALEN
);
231 memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
232 } else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
233 memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
234 memcpy(pattrib
->ta
, get_bssid(pmlmepriv
), ETH_ALEN
);
235 } else if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true) {
236 /*firstly, filter packet not belongs to mp*/
237 if (pattrib
->ether_type
!= 0x8712)
239 /* for mp storing the txcmd per packet,
240 * according to the info of txcmd to update pattrib */
241 /*get MP_TXDESC_SIZE bytes txcmd per packet*/
242 i
= _r8712_pktfile_read(&pktfile
, (u8
*)&txdesc
, TXDESC_SIZE
);
243 memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
244 memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
247 /* r8712_xmitframe_coalesce() overwrite this!*/
248 pattrib
->pktlen
= pktfile
.pkt_len
;
249 if (ETH_P_IP
== pattrib
->ether_type
) {
250 /* The following is for DHCP and ARP packet, we use cck1M to
251 * tx these packets and let LPS awake some time
252 * to prevent DHCP protocol fail */
254 _r8712_pktfile_read(&pktfile
, &tmp
[0], 24);
255 pattrib
->dhcp_pkt
= 0;
256 if (pktfile
.pkt_len
> 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
257 if (ETH_P_IP
== pattrib
->ether_type
) {/* IP header*/
258 if (((tmp
[21] == 68) && (tmp
[23] == 67)) ||
259 ((tmp
[21] == 67) && (tmp
[23] == 68))) {
260 /* 68 : UDP BOOTP client
261 * 67 : UDP BOOTP server
262 * Use low rate to send DHCP packet.*/
263 pattrib
->dhcp_pkt
= 1;
268 bmcast
= IS_MCAST(pattrib
->ra
);
271 psta
= r8712_get_bcmc_stainfo(padapter
);
274 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true) {
275 psta
= r8712_get_stainfo(pstapriv
,
276 get_bssid(pmlmepriv
));
279 psta
= r8712_get_stainfo(pstapriv
, pattrib
->ra
);
280 if (psta
== NULL
) /* drop the pkt */
282 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
285 pattrib
->mac_id
= psta
->mac_id
;
290 pattrib
->psta
= psta
;
292 /* if we cannot get psta => drrp the pkt */
296 pattrib
->ack_policy
= 0;
297 /* get ether_hdr_len */
298 pattrib
->pkt_hdrlen
= ETH_HLEN
;
300 if (pqospriv
->qos_option
)
301 r8712_set_qos(&pktfile
, pattrib
);
303 pattrib
->hdrlen
= WLAN_HDR_A3_LEN
;
304 pattrib
->subtype
= WIFI_DATA_TYPE
;
305 pattrib
->priority
= 0;
307 if (psta
->ieee8021x_blocked
== true) {
308 pattrib
->encrypt
= 0;
309 if ((pattrib
->ether_type
!= 0x888e) &&
310 (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == false))
313 GET_ENCRY_ALGO(psecuritypriv
, psta
, pattrib
->encrypt
, bmcast
);
314 switch (pattrib
->encrypt
) {
318 pattrib
->icv_len
= 4;
322 pattrib
->icv_len
= 4;
323 if (padapter
->securitypriv
.busetkipkey
== _FAIL
)
328 pattrib
->icv_len
= 8;
332 pattrib
->icv_len
= 0;
336 if (pattrib
->encrypt
&&
337 ((padapter
->securitypriv
.sw_encrypt
== true) ||
338 (psecuritypriv
->hw_decrypted
== false)))
339 pattrib
->bswenc
= true;
341 pattrib
->bswenc
= false;
342 /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
343 * some settings above.*/
344 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true)
345 pattrib
->priority
= (txdesc
.txdw1
>> QSEL_SHT
) & 0x1f;
349 static sint
xmitframe_addmic(struct _adapter
*padapter
,
350 struct xmit_frame
*pxmitframe
)
352 u32 curfragnum
, length
, datalen
;
353 u8
*pframe
, *payload
, mic
[8];
354 struct mic_data micdata
;
355 struct sta_info
*stainfo
;
356 struct qos_priv
*pqospriv
= &(padapter
->mlmepriv
.qospriv
);
357 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
358 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
359 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
360 u8 priority
[4] = {0x0, 0x0, 0x0, 0x0};
361 sint bmcst
= IS_MCAST(pattrib
->ra
);
364 stainfo
= pattrib
->psta
;
366 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
368 if (pattrib
->encrypt
== _TKIP_
) {
370 if (stainfo
!= NULL
) {
371 u8 null_key
[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
372 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
374 datalen
= pattrib
->pktlen
- pattrib
->hdrlen
;
375 pframe
= pxmitframe
->buf_addr
+ TXDESC_OFFSET
;
377 if (!memcmp(psecuritypriv
->XGrptxmickey
378 [psecuritypriv
->XGrpKeyid
].skey
,
381 /*start to calculate the mic code*/
382 r8712_secmicsetkey(&micdata
,
384 XGrptxmickey
[psecuritypriv
->
387 if (!memcmp(&stainfo
->tkiptxmickey
.skey
[0],
390 /* start to calculate the mic code */
391 r8712_secmicsetkey(&micdata
,
392 &stainfo
->tkiptxmickey
.skey
[0]);
394 if (pframe
[1] & 1) { /* ToDS==1 */
395 r8712_secmicappend(&micdata
,
396 &pframe
[16], 6); /*DA*/
397 if (pframe
[1]&2) /* From Ds==1 */
398 r8712_secmicappend(&micdata
,
401 r8712_secmicappend(&micdata
,
403 } else { /* ToDS==0 */
404 r8712_secmicappend(&micdata
,
405 &pframe
[4], 6); /* DA */
406 if (pframe
[1]&2) /* From Ds==1 */
407 r8712_secmicappend(&micdata
,
410 r8712_secmicappend(&micdata
,
413 if (pqospriv
->qos_option
== 1)
414 priority
[0] = (u8
)pxmitframe
->
416 r8712_secmicappend(&micdata
, &priority
[0], 4);
418 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
420 payload
= (u8
*)RND4((addr_t
)(payload
));
421 payload
= payload
+pattrib
->
422 hdrlen
+pattrib
->iv_len
;
423 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
424 length
= pattrib
->last_txcmdsz
-
427 ((psecuritypriv
->sw_encrypt
)
428 ? pattrib
->icv_len
: 0);
429 r8712_secmicappend(&micdata
, payload
,
431 payload
= payload
+length
;
433 length
= pxmitpriv
->frag_len
-
434 pattrib
->hdrlen
-pattrib
->iv_len
-
435 ((psecuritypriv
->sw_encrypt
) ?
436 pattrib
->icv_len
: 0);
437 r8712_secmicappend(&micdata
, payload
,
439 payload
= payload
+ length
+
443 r8712_secgetmic(&micdata
, &(mic
[0]));
444 /* add mic code and add the mic code length in
446 memcpy(payload
, &(mic
[0]), 8);
447 pattrib
->last_txcmdsz
+= 8;
448 payload
= payload
-pattrib
->last_txcmdsz
+ 8;
454 static sint
xmitframe_swencrypt(struct _adapter
*padapter
,
455 struct xmit_frame
*pxmitframe
)
457 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
459 if (pattrib
->bswenc
) {
460 switch (pattrib
->encrypt
) {
463 r8712_wep_encrypt(padapter
, (u8
*)pxmitframe
);
466 r8712_tkip_encrypt(padapter
, (u8
*)pxmitframe
);
469 r8712_aes_encrypt(padapter
, (u8
*)pxmitframe
);
478 static sint
make_wlanhdr(struct _adapter
*padapter
, u8
*hdr
,
479 struct pkt_attrib
*pattrib
)
483 struct ieee80211_hdr
*pwlanhdr
= (struct ieee80211_hdr
*)hdr
;
484 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
485 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
486 u16
*fctrl
= &pwlanhdr
->frame_ctl
;
487 memset(hdr
, 0, WLANHDR_OFFSET
);
488 SetFrameSubType(fctrl
, pattrib
->subtype
);
489 if (pattrib
->subtype
& WIFI_DATA_TYPE
) {
490 if ((check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == true)) {
491 /* to_ds = 1, fr_ds = 0; */
493 memcpy(pwlanhdr
->addr1
, get_bssid(pmlmepriv
),
495 memcpy(pwlanhdr
->addr2
, pattrib
->src
, ETH_ALEN
);
496 memcpy(pwlanhdr
->addr3
, pattrib
->dst
, ETH_ALEN
);
497 } else if ((check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == true)) {
498 /* to_ds = 0, fr_ds = 1; */
500 memcpy(pwlanhdr
->addr1
, pattrib
->dst
, ETH_ALEN
);
501 memcpy(pwlanhdr
->addr2
, get_bssid(pmlmepriv
),
503 memcpy(pwlanhdr
->addr3
, pattrib
->src
, ETH_ALEN
);
504 } else if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true)
505 || (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)
507 memcpy(pwlanhdr
->addr1
, pattrib
->dst
, ETH_ALEN
);
508 memcpy(pwlanhdr
->addr2
, pattrib
->src
, ETH_ALEN
);
509 memcpy(pwlanhdr
->addr3
, get_bssid(pmlmepriv
),
511 } else if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true) {
512 memcpy(pwlanhdr
->addr1
, pattrib
->dst
, ETH_ALEN
);
513 memcpy(pwlanhdr
->addr2
, pattrib
->src
, ETH_ALEN
);
514 memcpy(pwlanhdr
->addr3
, get_bssid(pmlmepriv
),
519 if (pattrib
->encrypt
)
521 if (pqospriv
->qos_option
) {
522 qc
= (unsigned short *)(hdr
+ pattrib
->hdrlen
- 2);
523 if (pattrib
->priority
)
524 SetPriority(qc
, pattrib
->priority
);
525 SetAckpolicy(qc
, pattrib
->ack_policy
);
527 /* TODO: fill HT Control Field */
528 /* Update Seq Num will be handled by f/w */
530 struct sta_info
*psta
;
532 sint bmcst
= IS_MCAST(pattrib
->ra
);
534 psta
= pattrib
->psta
;
537 psta
= r8712_get_bcmc_stainfo(padapter
);
540 r8712_get_stainfo(&padapter
->stapriv
,
544 psta
->sta_xmitpriv
.txseq_tid
545 [pattrib
->priority
]++;
546 psta
->sta_xmitpriv
.txseq_tid
[pattrib
->priority
]
548 pattrib
->seqnum
= psta
->sta_xmitpriv
.
549 txseq_tid
[pattrib
->priority
];
550 SetSeqNum(hdr
, pattrib
->seqnum
);
557 static sint
r8712_put_snap(u8
*data
, u16 h_proto
)
559 struct ieee80211_snap_hdr
*snap
;
562 snap
= (struct ieee80211_snap_hdr
*)data
;
566 if (h_proto
== 0x8137 || h_proto
== 0x80f3)
570 snap
->oui
[0] = oui
[0];
571 snap
->oui
[1] = oui
[1];
572 snap
->oui
[2] = oui
[2];
573 *(u16
*)(data
+ SNAP_SIZE
) = htons(h_proto
);
574 return SNAP_SIZE
+ sizeof(u16
);
578 * This sub-routine will perform all the following:
579 * 1. remove 802.3 header.
580 * 2. create wlan_header, based on the info in pxmitframe
581 * 3. append sta's iv/ext-iv
583 * 5. move frag chunk from pframe to pxmitframe->mem
584 * 6. apply sw-encrypt, if necessary.
586 sint
r8712_xmitframe_coalesce(struct _adapter
*padapter
, _pkt
*pkt
,
587 struct xmit_frame
*pxmitframe
)
589 struct pkt_file pktfile
;
591 sint frg_len
, mpdu_len
, llc_sz
;
595 u8
*pframe
, *mem_start
, *ptxdesc
;
596 struct sta_info
*psta
;
597 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
598 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
599 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
600 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
602 sint bmcst
= IS_MCAST(pattrib
->ra
);
604 if (pattrib
->psta
== NULL
)
606 psta
= pattrib
->psta
;
607 if (pxmitframe
->buf_addr
== NULL
)
609 pbuf_start
= pxmitframe
->buf_addr
;
610 ptxdesc
= pbuf_start
;
611 mem_start
= pbuf_start
+ TXDESC_OFFSET
;
612 if (make_wlanhdr(padapter
, mem_start
, pattrib
) == _FAIL
)
614 _r8712_open_pktfile(pkt
, &pktfile
);
615 _r8712_pktfile_read(&pktfile
, NULL
, pattrib
->pkt_hdrlen
);
616 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true) {
617 /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
618 if (pattrib
->ether_type
== 0x8712) {
619 /* take care - update_txdesc overwrite this */
620 _r8712_pktfile_read(&pktfile
, ptxdesc
, TXDESC_SIZE
);
623 pattrib
->pktlen
= pktfile
.pkt_len
;
625 frg_len
= pxmitpriv
->frag_len
- 4;
631 pframe
+= pattrib
->hdrlen
;
632 mpdu_len
-= pattrib
->hdrlen
;
633 /* adding icv, if necessary...*/
634 if (pattrib
->iv_len
) {
636 switch (pattrib
->encrypt
) {
639 WEP_IV(pattrib
->iv
, psta
->txpn
,
650 TKIP_IV(pattrib
->iv
, psta
->txpn
,
655 AES_IV(pattrib
->iv
, psta
->txpn
,
659 AES_IV(pattrib
->iv
, psta
->txpn
,
664 memcpy(pframe
, pattrib
->iv
, pattrib
->iv_len
);
665 pframe
+= pattrib
->iv_len
;
666 mpdu_len
-= pattrib
->iv_len
;
669 llc_sz
= r8712_put_snap(pframe
, pattrib
->ether_type
);
673 if ((pattrib
->icv_len
> 0) && (pattrib
->bswenc
))
674 mpdu_len
-= pattrib
->icv_len
;
676 mem_sz
= _r8712_pktfile_read(&pktfile
, pframe
,
679 mem_sz
= _r8712_pktfile_read(&pktfile
, pframe
,
682 if ((pattrib
->icv_len
> 0) && (pattrib
->bswenc
)) {
683 memcpy(pframe
, pattrib
->icv
, pattrib
->icv_len
);
684 pframe
+= pattrib
->icv_len
;
687 if (bmcst
|| (r8712_endofpktfile(&pktfile
) == true)) {
688 pattrib
->nr_frags
= frg_inx
;
689 pattrib
->last_txcmdsz
= pattrib
->hdrlen
+
691 ((pattrib
->nr_frags
== 1) ?
694 pattrib
->icv_len
: 0) + mem_sz
;
695 ClearMFrag(mem_start
);
698 addr
= (addr_t
)(pframe
);
699 mem_start
= (unsigned char *)RND4(addr
) + TXDESC_OFFSET
;
700 memcpy(mem_start
, pbuf_start
+ TXDESC_OFFSET
, pattrib
->hdrlen
);
703 if (xmitframe_addmic(padapter
, pxmitframe
) == _FAIL
)
705 xmitframe_swencrypt(padapter
, pxmitframe
);
709 void r8712_update_protection(struct _adapter
*padapter
, u8
*ie
, uint ie_len
)
714 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
715 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
717 switch (pxmitpriv
->vcs_setting
) {
719 pxmitpriv
->vcs
= NONE_VCS
;
725 perp
= r8712_get_ie(ie
, _ERPINFO_IE_
, &erp_len
, ie_len
);
727 pxmitpriv
->vcs
= NONE_VCS
;
729 protection
= (*(perp
+ 2)) & BIT(1);
731 if (pregistrypriv
->vcs_type
== RTS_CTS
)
732 pxmitpriv
->vcs
= RTS_CTS
;
734 pxmitpriv
->vcs
= CTS_TO_SELF
;
736 pxmitpriv
->vcs
= NONE_VCS
;
742 struct xmit_buf
*r8712_alloc_xmitbuf(struct xmit_priv
*pxmitpriv
)
745 struct xmit_buf
*pxmitbuf
= NULL
;
746 struct list_head
*plist
, *phead
;
747 struct __queue
*pfree_xmitbuf_queue
= &pxmitpriv
->free_xmitbuf_queue
;
749 spin_lock_irqsave(&pfree_xmitbuf_queue
->lock
, irqL
);
750 if (_queue_empty(pfree_xmitbuf_queue
) == true)
753 phead
= get_list_head(pfree_xmitbuf_queue
);
754 plist
= get_next(phead
);
755 pxmitbuf
= LIST_CONTAINOR(plist
, struct xmit_buf
, list
);
756 list_delete(&(pxmitbuf
->list
));
758 if (pxmitbuf
!= NULL
)
759 pxmitpriv
->free_xmitbuf_cnt
--;
760 spin_unlock_irqrestore(&pfree_xmitbuf_queue
->lock
, irqL
);
764 int r8712_free_xmitbuf(struct xmit_priv
*pxmitpriv
, struct xmit_buf
*pxmitbuf
)
767 struct __queue
*pfree_xmitbuf_queue
= &pxmitpriv
->free_xmitbuf_queue
;
769 if (pxmitbuf
== NULL
)
771 spin_lock_irqsave(&pfree_xmitbuf_queue
->lock
, irqL
);
772 list_delete(&pxmitbuf
->list
);
773 list_insert_tail(&(pxmitbuf
->list
), get_list_head(pfree_xmitbuf_queue
));
774 pxmitpriv
->free_xmitbuf_cnt
++;
775 spin_unlock_irqrestore(&pfree_xmitbuf_queue
->lock
, irqL
);
782 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
784 If we turn on USE_RXTHREAD, then, no need for critical section.
785 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
787 Must be very very cautious...
791 struct xmit_frame
*r8712_alloc_xmitframe(struct xmit_priv
*pxmitpriv
)
794 Please remember to use all the osdep_service api,
795 and lock/unlock or _enter/_exit critical to protect
799 struct xmit_frame
*pxframe
= NULL
;
800 struct list_head
*plist
, *phead
;
801 struct __queue
*pfree_xmit_queue
= &pxmitpriv
->free_xmit_queue
;
803 spin_lock_irqsave(&pfree_xmit_queue
->lock
, irqL
);
804 if (_queue_empty(pfree_xmit_queue
) == true)
807 phead
= get_list_head(pfree_xmit_queue
);
808 plist
= get_next(phead
);
809 pxframe
= LIST_CONTAINOR(plist
, struct xmit_frame
, list
);
810 list_delete(&(pxframe
->list
));
812 if (pxframe
!= NULL
) {
813 pxmitpriv
->free_xmitframe_cnt
--;
814 pxframe
->buf_addr
= NULL
;
815 pxframe
->pxmitbuf
= NULL
;
816 pxframe
->attrib
.psta
= NULL
;
819 spin_unlock_irqrestore(&pfree_xmit_queue
->lock
, irqL
);
823 void r8712_free_xmitframe(struct xmit_priv
*pxmitpriv
,
824 struct xmit_frame
*pxmitframe
)
827 struct __queue
*pfree_xmit_queue
= &pxmitpriv
->free_xmit_queue
;
828 struct _adapter
*padapter
= pxmitpriv
->adapter
;
830 if (pxmitframe
== NULL
)
833 r8712_xmit_complete(padapter
, pxmitframe
);
834 spin_lock_irqsave(&pfree_xmit_queue
->lock
, irqL
);
835 list_delete(&pxmitframe
->list
);
836 list_insert_tail(&pxmitframe
->list
, get_list_head(pfree_xmit_queue
));
837 pxmitpriv
->free_xmitframe_cnt
++;
838 spin_unlock_irqrestore(&pfree_xmit_queue
->lock
, irqL
);
839 if (netif_queue_stopped(padapter
->pnetdev
))
840 netif_wake_queue(padapter
->pnetdev
);
843 void r8712_free_xmitframe_ex(struct xmit_priv
*pxmitpriv
,
844 struct xmit_frame
*pxmitframe
)
846 if (pxmitframe
== NULL
)
848 if (pxmitframe
->frame_tag
== DATA_FRAMETAG
)
849 r8712_free_xmitframe(pxmitpriv
, pxmitframe
);
852 void r8712_free_xmitframe_queue(struct xmit_priv
*pxmitpriv
,
853 struct __queue
*pframequeue
)
856 struct list_head
*plist
, *phead
;
857 struct xmit_frame
*pxmitframe
;
859 spin_lock_irqsave(&(pframequeue
->lock
), irqL
);
860 phead
= get_list_head(pframequeue
);
861 plist
= get_next(phead
);
862 while (end_of_queue_search(phead
, plist
) == false) {
863 pxmitframe
= LIST_CONTAINOR(plist
, struct xmit_frame
, list
);
864 plist
= get_next(plist
);
865 r8712_free_xmitframe(pxmitpriv
, pxmitframe
);
867 spin_unlock_irqrestore(&(pframequeue
->lock
), irqL
);
870 static inline struct tx_servq
*get_sta_pending(struct _adapter
*padapter
,
871 struct __queue
**ppstapending
,
872 struct sta_info
*psta
, sint up
)
875 struct tx_servq
*ptxservq
;
876 struct hw_xmit
*phwxmits
= padapter
->xmitpriv
.hwxmits
;
881 ptxservq
= &(psta
->sta_xmitpriv
.bk_q
);
882 *ppstapending
= &padapter
->xmitpriv
.bk_pending
;
883 (phwxmits
+3)->accnt
++;
887 ptxservq
= &(psta
->sta_xmitpriv
.vi_q
);
888 *ppstapending
= &padapter
->xmitpriv
.vi_pending
;
889 (phwxmits
+1)->accnt
++;
893 ptxservq
= &(psta
->sta_xmitpriv
.vo_q
);
894 *ppstapending
= &padapter
->xmitpriv
.vo_pending
;
895 (phwxmits
+0)->accnt
++;
900 ptxservq
= &(psta
->sta_xmitpriv
.be_q
);
901 *ppstapending
= &padapter
->xmitpriv
.be_pending
;
902 (phwxmits
+ 2)->accnt
++;
909 * Will enqueue pxmitframe to the proper queue, and indicate it
910 * to xx_pending list.....
912 sint
r8712_xmit_classifier(struct _adapter
*padapter
,
913 struct xmit_frame
*pxmitframe
)
916 struct __queue
*pstapending
;
917 struct sta_info
*psta
;
918 struct tx_servq
*ptxservq
;
919 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
920 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
921 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
922 sint bmcst
= IS_MCAST(pattrib
->ra
);
925 psta
= pattrib
->psta
;
928 psta
= r8712_get_bcmc_stainfo(padapter
);
930 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true)
931 psta
= r8712_get_stainfo(pstapriv
,
932 get_bssid(pmlmepriv
));
934 psta
= r8712_get_stainfo(pstapriv
, pattrib
->ra
);
939 ptxservq
= get_sta_pending(padapter
, &pstapending
,
940 psta
, pattrib
->priority
);
941 spin_lock_irqsave(&pstapending
->lock
, irqL0
);
942 if (is_list_empty(&ptxservq
->tx_pending
))
943 list_insert_tail(&ptxservq
->tx_pending
,
944 get_list_head(pstapending
));
945 list_insert_tail(&pxmitframe
->list
,
946 get_list_head(&ptxservq
->sta_pending
));
948 spin_unlock_irqrestore(&pstapending
->lock
, irqL0
);
952 static void alloc_hwxmits(struct _adapter
*padapter
)
954 struct hw_xmit
*hwxmits
;
955 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
957 pxmitpriv
->hwxmit_entry
= HWXMIT_ENTRY
;
958 pxmitpriv
->hwxmits
= (struct hw_xmit
*)_malloc(sizeof(struct hw_xmit
) *
959 pxmitpriv
->hwxmit_entry
);
960 if (pxmitpriv
->hwxmits
== NULL
)
962 hwxmits
= pxmitpriv
->hwxmits
;
963 if (pxmitpriv
->hwxmit_entry
== 5) {
964 pxmitpriv
->bmc_txqueue
.head
= 0;
965 hwxmits
[0] .phwtxqueue
= &pxmitpriv
->bmc_txqueue
;
966 hwxmits
[0] .sta_queue
= &pxmitpriv
->bm_pending
;
967 pxmitpriv
->vo_txqueue
.head
= 0;
968 hwxmits
[1] .phwtxqueue
= &pxmitpriv
->vo_txqueue
;
969 hwxmits
[1] .sta_queue
= &pxmitpriv
->vo_pending
;
970 pxmitpriv
->vi_txqueue
.head
= 0;
971 hwxmits
[2] .phwtxqueue
= &pxmitpriv
->vi_txqueue
;
972 hwxmits
[2] .sta_queue
= &pxmitpriv
->vi_pending
;
973 pxmitpriv
->bk_txqueue
.head
= 0;
974 hwxmits
[3] .phwtxqueue
= &pxmitpriv
->bk_txqueue
;
975 hwxmits
[3] .sta_queue
= &pxmitpriv
->bk_pending
;
976 pxmitpriv
->be_txqueue
.head
= 0;
977 hwxmits
[4] .phwtxqueue
= &pxmitpriv
->be_txqueue
;
978 hwxmits
[4] .sta_queue
= &pxmitpriv
->be_pending
;
979 } else if (pxmitpriv
->hwxmit_entry
== 4) {
980 pxmitpriv
->vo_txqueue
.head
= 0;
981 hwxmits
[0] .phwtxqueue
= &pxmitpriv
->vo_txqueue
;
982 hwxmits
[0] .sta_queue
= &pxmitpriv
->vo_pending
;
983 pxmitpriv
->vi_txqueue
.head
= 0;
984 hwxmits
[1] .phwtxqueue
= &pxmitpriv
->vi_txqueue
;
985 hwxmits
[1] .sta_queue
= &pxmitpriv
->vi_pending
;
986 pxmitpriv
->be_txqueue
.head
= 0;
987 hwxmits
[2] .phwtxqueue
= &pxmitpriv
->be_txqueue
;
988 hwxmits
[2] .sta_queue
= &pxmitpriv
->be_pending
;
989 pxmitpriv
->bk_txqueue
.head
= 0;
990 hwxmits
[3] .phwtxqueue
= &pxmitpriv
->bk_txqueue
;
991 hwxmits
[3] .sta_queue
= &pxmitpriv
->bk_pending
;
995 static void free_hwxmits(struct _adapter
*padapter
)
997 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
999 kfree(pxmitpriv
->hwxmits
);
1002 static void init_hwxmits(struct hw_xmit
*phwxmit
, sint entry
)
1006 for (i
= 0; i
< entry
; i
++, phwxmit
++) {
1007 spin_lock_init(&phwxmit
->xmit_lock
);
1008 _init_listhead(&phwxmit
->pending
);
1009 phwxmit
->txcmdcnt
= 0;
1015 * tx_action == 0 == no frames to transmit
1016 * tx_action > 0 ==> we have frames to transmit
1017 * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
1018 * to transmit 1 frame.
1021 int r8712_pre_xmit(struct _adapter
*padapter
, struct xmit_frame
*pxmitframe
)
1025 struct xmit_buf
*pxmitbuf
= NULL
;
1026 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1027 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1029 r8712_do_queue_select(padapter
, pattrib
);
1030 spin_lock_irqsave(&pxmitpriv
->lock
, irqL
);
1031 if (r8712_txframes_sta_ac_pending(padapter
, pattrib
) > 0) {
1033 r8712_xmit_enqueue(padapter
, pxmitframe
);
1034 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
1037 pxmitbuf
= r8712_alloc_xmitbuf(pxmitpriv
);
1038 if (pxmitbuf
== NULL
) { /*enqueue packet*/
1040 r8712_xmit_enqueue(padapter
, pxmitframe
);
1041 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
1042 } else { /*dump packet directly*/
1043 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
1045 pxmitframe
->pxmitbuf
= pxmitbuf
;
1046 pxmitframe
->pxmit_urb
[0] = pxmitbuf
->pxmit_urb
[0];
1047 pxmitframe
->buf_addr
= pxmitbuf
->pbuf
;
1048 r8712_xmit_direct(padapter
, pxmitframe
);