]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/rtl8712/rtl871x_xmit.c
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"
34 #include "osdep_intf.h"
38 static const u8 P802_1H_OUI
[P80211_OUI_LEN
] = {0x00, 0x00, 0xf8};
39 static const u8 RFC1042_OUI
[P80211_OUI_LEN
] = {0x00, 0x00, 0x00};
40 static void init_hwxmits(struct hw_xmit
*phwxmit
, sint entry
);
41 static void alloc_hwxmits(struct _adapter
*padapter
);
42 static void free_hwxmits(struct _adapter
*padapter
);
44 static void _init_txservq(struct tx_servq
*ptxservq
)
46 INIT_LIST_HEAD(&ptxservq
->tx_pending
);
47 _init_queue(&ptxservq
->sta_pending
);
51 void _r8712_init_sta_xmit_priv(struct sta_xmit_priv
*psta_xmitpriv
)
53 memset((unsigned char *)psta_xmitpriv
, 0,
54 sizeof(struct sta_xmit_priv
));
55 spin_lock_init(&psta_xmitpriv
->lock
);
56 _init_txservq(&psta_xmitpriv
->be_q
);
57 _init_txservq(&psta_xmitpriv
->bk_q
);
58 _init_txservq(&psta_xmitpriv
->vi_q
);
59 _init_txservq(&psta_xmitpriv
->vo_q
);
60 INIT_LIST_HEAD(&psta_xmitpriv
->legacy_dz
);
61 INIT_LIST_HEAD(&psta_xmitpriv
->apsd
);
64 sint
_r8712_init_xmit_priv(struct xmit_priv
*pxmitpriv
,
65 struct _adapter
*padapter
)
68 struct xmit_buf
*pxmitbuf
;
69 struct xmit_frame
*pxframe
;
71 memset((unsigned char *)pxmitpriv
, 0, sizeof(struct xmit_priv
));
72 spin_lock_init(&pxmitpriv
->lock
);
74 Please insert all the queue initialization using _init_queue below
76 pxmitpriv
->adapter
= padapter
;
77 _init_queue(&pxmitpriv
->be_pending
);
78 _init_queue(&pxmitpriv
->bk_pending
);
79 _init_queue(&pxmitpriv
->vi_pending
);
80 _init_queue(&pxmitpriv
->vo_pending
);
81 _init_queue(&pxmitpriv
->bm_pending
);
82 _init_queue(&pxmitpriv
->legacy_dz_queue
);
83 _init_queue(&pxmitpriv
->apsd_queue
);
84 _init_queue(&pxmitpriv
->free_xmit_queue
);
86 Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
87 and initialize free_xmit_frame below.
88 Please also apply free_txobj to link_up all the xmit_frames...
90 pxmitpriv
->pallocated_frame_buf
= kmalloc(NR_XMITFRAME
* sizeof(struct xmit_frame
) + 4,
92 if (pxmitpriv
->pallocated_frame_buf
== NULL
) {
93 pxmitpriv
->pxmit_frame_buf
= NULL
;
96 pxmitpriv
->pxmit_frame_buf
= pxmitpriv
->pallocated_frame_buf
+ 4 -
97 ((addr_t
) (pxmitpriv
->pallocated_frame_buf
) & 3);
98 pxframe
= (struct xmit_frame
*) pxmitpriv
->pxmit_frame_buf
;
99 for (i
= 0; i
< NR_XMITFRAME
; i
++) {
100 INIT_LIST_HEAD(&(pxframe
->list
));
101 pxframe
->padapter
= padapter
;
102 pxframe
->frame_tag
= DATA_FRAMETAG
;
104 pxframe
->buf_addr
= NULL
;
105 pxframe
->pxmitbuf
= NULL
;
106 list_add_tail(&(pxframe
->list
),
107 &(pxmitpriv
->free_xmit_queue
.queue
));
110 pxmitpriv
->free_xmitframe_cnt
= NR_XMITFRAME
;
114 _r8712_init_hw_txqueue(&pxmitpriv
->be_txqueue
, BE_QUEUE_INX
);
115 _r8712_init_hw_txqueue(&pxmitpriv
->bk_txqueue
, BK_QUEUE_INX
);
116 _r8712_init_hw_txqueue(&pxmitpriv
->vi_txqueue
, VI_QUEUE_INX
);
117 _r8712_init_hw_txqueue(&pxmitpriv
->vo_txqueue
, VO_QUEUE_INX
);
118 _r8712_init_hw_txqueue(&pxmitpriv
->bmc_txqueue
, BMC_QUEUE_INX
);
119 pxmitpriv
->frag_len
= MAX_FRAG_THRESHOLD
;
120 pxmitpriv
->txirp_cnt
= 1;
121 /*per AC pending irp*/
122 pxmitpriv
->beq_cnt
= 0;
123 pxmitpriv
->bkq_cnt
= 0;
124 pxmitpriv
->viq_cnt
= 0;
125 pxmitpriv
->voq_cnt
= 0;
127 _init_queue(&pxmitpriv
->free_xmitbuf_queue
);
128 _init_queue(&pxmitpriv
->pending_xmitbuf_queue
);
129 pxmitpriv
->pallocated_xmitbuf
= kmalloc(NR_XMITBUFF
* sizeof(struct xmit_buf
) + 4,
131 if (pxmitpriv
->pallocated_xmitbuf
== NULL
)
133 pxmitpriv
->pxmitbuf
= pxmitpriv
->pallocated_xmitbuf
+ 4 -
134 ((addr_t
)(pxmitpriv
->pallocated_xmitbuf
) & 3);
135 pxmitbuf
= (struct xmit_buf
*)pxmitpriv
->pxmitbuf
;
136 for (i
= 0; i
< NR_XMITBUFF
; i
++) {
137 INIT_LIST_HEAD(&pxmitbuf
->list
);
138 pxmitbuf
->pallocated_buf
= kmalloc(MAX_XMITBUF_SZ
+ XMITBUF_ALIGN_SZ
,
140 if (pxmitbuf
->pallocated_buf
== NULL
)
142 pxmitbuf
->pbuf
= pxmitbuf
->pallocated_buf
+ XMITBUF_ALIGN_SZ
-
143 ((addr_t
) (pxmitbuf
->pallocated_buf
) &
144 (XMITBUF_ALIGN_SZ
- 1));
145 r8712_xmit_resource_alloc(padapter
, pxmitbuf
);
146 list_add_tail(&pxmitbuf
->list
,
147 &(pxmitpriv
->free_xmitbuf_queue
.queue
));
150 pxmitpriv
->free_xmitbuf_cnt
= NR_XMITBUFF
;
151 INIT_WORK(&padapter
->wkFilterRxFF0
, r8712_SetFilter
);
152 alloc_hwxmits(padapter
);
153 init_hwxmits(pxmitpriv
->hwxmits
, pxmitpriv
->hwxmit_entry
);
154 tasklet_init(&pxmitpriv
->xmit_tasklet
,
155 (void(*)(unsigned long))r8712_xmit_bh
,
156 (unsigned long)padapter
);
160 void _free_xmit_priv(struct xmit_priv
*pxmitpriv
)
163 struct _adapter
*padapter
= pxmitpriv
->adapter
;
164 struct xmit_frame
*pxmitframe
= (struct xmit_frame
*)
165 pxmitpriv
->pxmit_frame_buf
;
166 struct xmit_buf
*pxmitbuf
= (struct xmit_buf
*)pxmitpriv
->pxmitbuf
;
168 if (pxmitpriv
->pxmit_frame_buf
== NULL
)
170 for (i
= 0; i
< NR_XMITFRAME
; i
++) {
171 r8712_xmit_complete(padapter
, pxmitframe
);
174 for (i
= 0; i
< NR_XMITBUFF
; i
++) {
175 r8712_xmit_resource_free(padapter
, pxmitbuf
);
176 kfree(pxmitbuf
->pallocated_buf
);
179 kfree(pxmitpriv
->pallocated_frame_buf
);
180 kfree(pxmitpriv
->pallocated_xmitbuf
);
181 free_hwxmits(padapter
);
184 sint
r8712_update_attrib(struct _adapter
*padapter
, _pkt
*pkt
,
185 struct pkt_attrib
*pattrib
)
187 struct pkt_file pktfile
;
188 struct sta_info
*psta
= NULL
;
189 struct ethhdr etherhdr
;
191 struct tx_cmd txdesc
;
194 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
195 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
196 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
197 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
199 _r8712_open_pktfile(pkt
, &pktfile
);
201 _r8712_pktfile_read(&pktfile
, (unsigned char *)ðerhdr
, ETH_HLEN
);
203 pattrib
->ether_type
= ntohs(etherhdr
.h_proto
);
206 /*If driver xmit ARP packet, driver can set ps mode to initial
207 * setting. It stands for getting DHCP or fix IP.*/
208 if (pattrib
->ether_type
== 0x0806) {
209 if (padapter
->pwrctrlpriv
.pwr_mode
!=
210 padapter
->registrypriv
.power_mgnt
) {
211 del_timer_sync(&pmlmepriv
->dhcp_timer
);
212 r8712_set_ps_mode(padapter
, padapter
->registrypriv
.
213 power_mgnt
, padapter
->registrypriv
.smart_ps
);
217 memcpy(pattrib
->dst
, ðerhdr
.h_dest
, ETH_ALEN
);
218 memcpy(pattrib
->src
, ðerhdr
.h_source
, ETH_ALEN
);
220 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) ||
221 check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
)) {
222 memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
223 memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
224 } else if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
225 memcpy(pattrib
->ra
, get_bssid(pmlmepriv
), ETH_ALEN
);
226 memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
227 } else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
228 memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
229 memcpy(pattrib
->ta
, get_bssid(pmlmepriv
), ETH_ALEN
);
230 } else if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) {
231 /*firstly, filter packet not belongs to mp*/
232 if (pattrib
->ether_type
!= 0x8712)
234 /* for mp storing the txcmd per packet,
235 * according to the info of txcmd to update pattrib */
236 /*get MP_TXDESC_SIZE bytes txcmd per packet*/
237 _r8712_pktfile_read(&pktfile
, (u8
*)&txdesc
, TXDESC_SIZE
);
238 memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
239 memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
242 /* r8712_xmitframe_coalesce() overwrite this!*/
243 pattrib
->pktlen
= pktfile
.pkt_len
;
244 if (ETH_P_IP
== pattrib
->ether_type
) {
245 /* The following is for DHCP and ARP packet, we use cck1M to
246 * tx these packets and let LPS awake some time
247 * to prevent DHCP protocol fail */
250 _r8712_pktfile_read(&pktfile
, &tmp
[0], 24);
251 pattrib
->dhcp_pkt
= 0;
252 if (pktfile
.pkt_len
> 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
253 if (ETH_P_IP
== pattrib
->ether_type
) {/* IP header*/
254 if (((tmp
[21] == 68) && (tmp
[23] == 67)) ||
255 ((tmp
[21] == 67) && (tmp
[23] == 68))) {
256 /* 68 : UDP BOOTP client
257 * 67 : UDP BOOTP server
258 * Use low rate to send DHCP packet.*/
259 pattrib
->dhcp_pkt
= 1;
264 bmcast
= IS_MCAST(pattrib
->ra
);
267 psta
= r8712_get_bcmc_stainfo(padapter
);
270 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) {
271 psta
= r8712_get_stainfo(pstapriv
,
272 get_bssid(pmlmepriv
));
275 psta
= r8712_get_stainfo(pstapriv
, pattrib
->ra
);
276 if (psta
== NULL
) /* drop the pkt */
278 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
281 pattrib
->mac_id
= psta
->mac_id
;
286 pattrib
->psta
= psta
;
288 /* if we cannot get psta => drrp the pkt */
292 pattrib
->ack_policy
= 0;
293 /* get ether_hdr_len */
294 pattrib
->pkt_hdrlen
= ETH_HLEN
;
296 if (pqospriv
->qos_option
) {
297 r8712_set_qos(&pktfile
, pattrib
);
299 pattrib
->hdrlen
= WLAN_HDR_A3_LEN
;
300 pattrib
->subtype
= WIFI_DATA_TYPE
;
301 pattrib
->priority
= 0;
303 if (psta
->ieee8021x_blocked
) {
304 pattrib
->encrypt
= 0;
305 if ((pattrib
->ether_type
!= 0x888e) &&
306 !check_fwstate(pmlmepriv
, WIFI_MP_STATE
))
309 GET_ENCRY_ALGO(psecuritypriv
, psta
, pattrib
->encrypt
, bmcast
);
311 switch (pattrib
->encrypt
) {
315 pattrib
->icv_len
= 4;
319 pattrib
->icv_len
= 4;
320 if (padapter
->securitypriv
.busetkipkey
== _FAIL
)
325 pattrib
->icv_len
= 8;
329 pattrib
->icv_len
= 0;
333 if (pattrib
->encrypt
&&
334 (padapter
->securitypriv
.sw_encrypt
||
335 !psecuritypriv
->hw_decrypted
))
336 pattrib
->bswenc
= true;
338 pattrib
->bswenc
= false;
339 /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
340 * some settings above.*/
341 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
))
342 pattrib
->priority
= (txdesc
.txdw1
>> QSEL_SHT
) & 0x1f;
346 static sint
xmitframe_addmic(struct _adapter
*padapter
,
347 struct xmit_frame
*pxmitframe
)
349 u32 curfragnum
, length
;
350 u8
*pframe
, *payload
, mic
[8];
351 struct mic_data micdata
;
352 struct sta_info
*stainfo
;
353 struct qos_priv
*pqospriv
= &(padapter
->mlmepriv
.qospriv
);
354 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
355 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
356 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
357 u8 priority
[4] = {0x0, 0x0, 0x0, 0x0};
358 sint bmcst
= IS_MCAST(pattrib
->ra
);
361 stainfo
= pattrib
->psta
;
363 stainfo
= r8712_get_stainfo(&padapter
->stapriv
,
365 if (pattrib
->encrypt
== _TKIP_
) {
367 if (stainfo
!= NULL
) {
368 u8 null_key
[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
369 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
371 pframe
= pxmitframe
->buf_addr
+ TXDESC_OFFSET
;
373 if (!memcmp(psecuritypriv
->XGrptxmickey
374 [psecuritypriv
->XGrpKeyid
].skey
,
377 /*start to calculate the mic code*/
378 r8712_secmicsetkey(&micdata
,
380 XGrptxmickey
[psecuritypriv
->
383 if (!memcmp(&stainfo
->tkiptxmickey
.skey
[0],
386 /* start to calculate the mic code */
387 r8712_secmicsetkey(&micdata
,
388 &stainfo
->tkiptxmickey
.skey
[0]);
390 if (pframe
[1] & 1) { /* ToDS==1 */
391 r8712_secmicappend(&micdata
,
392 &pframe
[16], 6); /*DA*/
393 if (pframe
[1] & 2) /* From Ds==1 */
394 r8712_secmicappend(&micdata
,
397 r8712_secmicappend(&micdata
,
399 } else { /* ToDS==0 */
400 r8712_secmicappend(&micdata
,
401 &pframe
[4], 6); /* DA */
402 if (pframe
[1] & 2) /* From Ds==1 */
403 r8712_secmicappend(&micdata
,
406 r8712_secmicappend(&micdata
,
409 if (pqospriv
->qos_option
== 1)
410 priority
[0] = (u8
)pxmitframe
->
412 r8712_secmicappend(&micdata
, &priority
[0], 4);
414 for (curfragnum
= 0; curfragnum
< pattrib
->nr_frags
;
416 payload
= (u8
*)RND4((addr_t
)(payload
));
417 payload
= payload
+ pattrib
->
418 hdrlen
+ pattrib
->iv_len
;
419 if ((curfragnum
+ 1) == pattrib
->nr_frags
) {
420 length
= pattrib
->last_txcmdsz
-
423 ((psecuritypriv
->sw_encrypt
)
424 ? pattrib
->icv_len
: 0);
425 r8712_secmicappend(&micdata
, payload
,
427 payload
= payload
+ length
;
429 length
= pxmitpriv
->frag_len
-
430 pattrib
->hdrlen
- pattrib
->iv_len
-
431 ((psecuritypriv
->sw_encrypt
) ?
432 pattrib
->icv_len
: 0);
433 r8712_secmicappend(&micdata
, payload
,
435 payload
= payload
+ length
+
439 r8712_secgetmic(&micdata
, &(mic
[0]));
440 /* add mic code and add the mic code length in
442 memcpy(payload
, &(mic
[0]), 8);
443 pattrib
->last_txcmdsz
+= 8;
444 payload
= payload
- pattrib
->last_txcmdsz
+ 8;
450 static sint
xmitframe_swencrypt(struct _adapter
*padapter
,
451 struct xmit_frame
*pxmitframe
)
453 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
455 if (pattrib
->bswenc
) {
456 switch (pattrib
->encrypt
) {
459 r8712_wep_encrypt(padapter
, (u8
*)pxmitframe
);
462 r8712_tkip_encrypt(padapter
, (u8
*)pxmitframe
);
465 r8712_aes_encrypt(padapter
, (u8
*)pxmitframe
);
474 static sint
make_wlanhdr(struct _adapter
*padapter
, u8
*hdr
,
475 struct pkt_attrib
*pattrib
)
479 struct ieee80211_hdr
*pwlanhdr
= (struct ieee80211_hdr
*)hdr
;
480 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
481 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
482 u16
*fctrl
= &pwlanhdr
->frame_ctl
;
484 memset(hdr
, 0, WLANHDR_OFFSET
);
485 SetFrameSubType(fctrl
, pattrib
->subtype
);
486 if (pattrib
->subtype
& WIFI_DATA_TYPE
) {
487 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
)) {
488 /* to_ds = 1, fr_ds = 0; */
490 memcpy(pwlanhdr
->addr1
, get_bssid(pmlmepriv
),
492 memcpy(pwlanhdr
->addr2
, pattrib
->src
, ETH_ALEN
);
493 memcpy(pwlanhdr
->addr3
, pattrib
->dst
, ETH_ALEN
);
494 } else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
495 /* to_ds = 0, fr_ds = 1; */
497 memcpy(pwlanhdr
->addr1
, pattrib
->dst
, ETH_ALEN
);
498 memcpy(pwlanhdr
->addr2
, get_bssid(pmlmepriv
),
500 memcpy(pwlanhdr
->addr3
, pattrib
->src
, ETH_ALEN
);
501 } else if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) ||
502 check_fwstate(pmlmepriv
,
503 WIFI_ADHOC_MASTER_STATE
)) {
504 memcpy(pwlanhdr
->addr1
, pattrib
->dst
, ETH_ALEN
);
505 memcpy(pwlanhdr
->addr2
, pattrib
->src
, ETH_ALEN
);
506 memcpy(pwlanhdr
->addr3
, get_bssid(pmlmepriv
),
508 } else if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) {
509 memcpy(pwlanhdr
->addr1
, pattrib
->dst
, ETH_ALEN
);
510 memcpy(pwlanhdr
->addr2
, pattrib
->src
, ETH_ALEN
);
511 memcpy(pwlanhdr
->addr3
, get_bssid(pmlmepriv
),
517 if (pattrib
->encrypt
)
519 if (pqospriv
->qos_option
) {
520 qc
= (unsigned short *)(hdr
+ pattrib
->hdrlen
- 2);
521 if (pattrib
->priority
)
522 SetPriority(qc
, pattrib
->priority
);
523 SetAckpolicy(qc
, pattrib
->ack_policy
);
525 /* TODO: fill HT Control Field */
526 /* Update Seq Num will be handled by f/w */
528 struct sta_info
*psta
;
529 sint bmcst
= IS_MCAST(pattrib
->ra
);
532 psta
= pattrib
->psta
;
535 psta
= r8712_get_bcmc_stainfo(padapter
);
538 r8712_get_stainfo(&padapter
->stapriv
,
542 psta
->sta_xmitpriv
.txseq_tid
543 [pattrib
->priority
]++;
544 psta
->sta_xmitpriv
.txseq_tid
[pattrib
->priority
]
546 pattrib
->seqnum
= psta
->sta_xmitpriv
.
547 txseq_tid
[pattrib
->priority
];
548 SetSeqNum(hdr
, pattrib
->seqnum
);
555 static sint
r8712_put_snap(u8
*data
, u16 h_proto
)
557 struct ieee80211_snap_hdr
*snap
;
560 snap
= (struct ieee80211_snap_hdr
*)data
;
564 if (h_proto
== 0x8137 || h_proto
== 0x80f3)
568 snap
->oui
[0] = oui
[0];
569 snap
->oui
[1] = oui
[1];
570 snap
->oui
[2] = oui
[2];
571 *(u16
*)(data
+ SNAP_SIZE
) = htons(h_proto
);
572 return SNAP_SIZE
+ sizeof(u16
);
576 * This sub-routine will perform all the following:
577 * 1. remove 802.3 header.
578 * 2. create wlan_header, based on the info in pxmitframe
579 * 3. append sta's iv/ext-iv
581 * 5. move frag chunk from pframe to pxmitframe->mem
582 * 6. apply sw-encrypt, if necessary.
584 sint
r8712_xmitframe_coalesce(struct _adapter
*padapter
, _pkt
*pkt
,
585 struct xmit_frame
*pxmitframe
)
587 struct pkt_file pktfile
;
589 sint frg_len
, mpdu_len
, llc_sz
;
593 u8
*pframe
, *mem_start
, *ptxdesc
;
594 struct sta_info
*psta
;
595 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
596 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
597 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
598 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
600 sint bmcst
= IS_MCAST(pattrib
->ra
);
602 if (pattrib
->psta
== NULL
)
604 psta
= pattrib
->psta
;
605 if (pxmitframe
->buf_addr
== NULL
)
607 pbuf_start
= pxmitframe
->buf_addr
;
608 ptxdesc
= pbuf_start
;
609 mem_start
= pbuf_start
+ TXDESC_OFFSET
;
610 if (make_wlanhdr(padapter
, mem_start
, pattrib
) == _FAIL
)
612 _r8712_open_pktfile(pkt
, &pktfile
);
613 _r8712_pktfile_read(&pktfile
, NULL
, (uint
) pattrib
->pkt_hdrlen
);
614 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) {
615 /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
616 if (pattrib
->ether_type
== 0x8712) {
617 /* take care - update_txdesc overwrite this */
618 _r8712_pktfile_read(&pktfile
, ptxdesc
, TXDESC_SIZE
);
621 pattrib
->pktlen
= pktfile
.pkt_len
;
623 frg_len
= pxmitpriv
->frag_len
- 4;
629 pframe
+= pattrib
->hdrlen
;
630 mpdu_len
-= pattrib
->hdrlen
;
631 /* adding icv, if necessary...*/
632 if (pattrib
->iv_len
) {
634 switch (pattrib
->encrypt
) {
637 WEP_IV(pattrib
->iv
, psta
->txpn
,
648 TKIP_IV(pattrib
->iv
, psta
->txpn
,
653 AES_IV(pattrib
->iv
, psta
->txpn
,
657 AES_IV(pattrib
->iv
, psta
->txpn
,
662 memcpy(pframe
, pattrib
->iv
, pattrib
->iv_len
);
663 pframe
+= pattrib
->iv_len
;
664 mpdu_len
-= pattrib
->iv_len
;
667 llc_sz
= r8712_put_snap(pframe
, pattrib
->ether_type
);
671 if ((pattrib
->icv_len
> 0) && (pattrib
->bswenc
))
672 mpdu_len
-= pattrib
->icv_len
;
674 mem_sz
= _r8712_pktfile_read(&pktfile
, pframe
,
677 mem_sz
= _r8712_pktfile_read(&pktfile
, pframe
,
680 if ((pattrib
->icv_len
> 0) && (pattrib
->bswenc
)) {
681 memcpy(pframe
, pattrib
->icv
, pattrib
->icv_len
);
682 pframe
+= pattrib
->icv_len
;
685 if (bmcst
|| r8712_endofpktfile(&pktfile
)) {
686 pattrib
->nr_frags
= frg_inx
;
687 pattrib
->last_txcmdsz
= pattrib
->hdrlen
+
689 ((pattrib
->nr_frags
== 1) ?
692 pattrib
->icv_len
: 0) + mem_sz
;
693 ClearMFrag(mem_start
);
696 addr
= (addr_t
)(pframe
);
697 mem_start
= (unsigned char *)RND4(addr
) + TXDESC_OFFSET
;
698 memcpy(mem_start
, pbuf_start
+ TXDESC_OFFSET
, pattrib
->hdrlen
);
701 if (xmitframe_addmic(padapter
, pxmitframe
) == _FAIL
)
703 xmitframe_swencrypt(padapter
, pxmitframe
);
707 void r8712_update_protection(struct _adapter
*padapter
, u8
*ie
, uint ie_len
)
712 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
713 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
715 switch (pxmitpriv
->vcs_setting
) {
717 pxmitpriv
->vcs
= NONE_VCS
;
723 perp
= r8712_get_ie(ie
, _ERPINFO_IE_
, &erp_len
, ie_len
);
725 pxmitpriv
->vcs
= NONE_VCS
;
727 protection
= (*(perp
+ 2)) & BIT(1);
729 if (pregistrypriv
->vcs_type
== RTS_CTS
)
730 pxmitpriv
->vcs
= RTS_CTS
;
732 pxmitpriv
->vcs
= CTS_TO_SELF
;
734 pxmitpriv
->vcs
= NONE_VCS
;
741 struct xmit_buf
*r8712_alloc_xmitbuf(struct xmit_priv
*pxmitpriv
)
744 struct xmit_buf
*pxmitbuf
= NULL
;
745 struct list_head
*plist
, *phead
;
746 struct __queue
*pfree_xmitbuf_queue
= &pxmitpriv
->free_xmitbuf_queue
;
748 spin_lock_irqsave(&pfree_xmitbuf_queue
->lock
, irqL
);
749 if (list_empty(&pfree_xmitbuf_queue
->queue
)) {
752 phead
= &pfree_xmitbuf_queue
->queue
;
754 pxmitbuf
= LIST_CONTAINOR(plist
, struct xmit_buf
, list
);
755 list_del_init(&(pxmitbuf
->list
));
757 if (pxmitbuf
!= NULL
)
758 pxmitpriv
->free_xmitbuf_cnt
--;
759 spin_unlock_irqrestore(&pfree_xmitbuf_queue
->lock
, irqL
);
763 int r8712_free_xmitbuf(struct xmit_priv
*pxmitpriv
, struct xmit_buf
*pxmitbuf
)
766 struct __queue
*pfree_xmitbuf_queue
= &pxmitpriv
->free_xmitbuf_queue
;
768 if (pxmitbuf
== NULL
)
770 spin_lock_irqsave(&pfree_xmitbuf_queue
->lock
, irqL
);
771 list_del_init(&pxmitbuf
->list
);
772 list_add_tail(&(pxmitbuf
->list
), &pfree_xmitbuf_queue
->queue
);
773 pxmitpriv
->free_xmitbuf_cnt
++;
774 spin_unlock_irqrestore(&pfree_xmitbuf_queue
->lock
, irqL
);
781 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
783 If we turn on USE_RXTHREAD, then, no need for critical section.
784 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
786 Must be very very cautious...
790 struct xmit_frame
*r8712_alloc_xmitframe(struct xmit_priv
*pxmitpriv
)
793 Please remember to use all the osdep_service api,
794 and lock/unlock or _enter/_exit critical to protect
798 struct xmit_frame
*pxframe
= NULL
;
799 struct list_head
*plist
, *phead
;
800 struct __queue
*pfree_xmit_queue
= &pxmitpriv
->free_xmit_queue
;
802 spin_lock_irqsave(&pfree_xmit_queue
->lock
, irqL
);
803 if (list_empty(&pfree_xmit_queue
->queue
)) {
806 phead
= &pfree_xmit_queue
->queue
;
808 pxframe
= LIST_CONTAINOR(plist
, struct xmit_frame
, list
);
809 list_del_init(&(pxframe
->list
));
811 if (pxframe
!= NULL
) {
812 pxmitpriv
->free_xmitframe_cnt
--;
813 pxframe
->buf_addr
= NULL
;
814 pxframe
->pxmitbuf
= NULL
;
815 pxframe
->attrib
.psta
= NULL
;
818 spin_unlock_irqrestore(&pfree_xmit_queue
->lock
, irqL
);
822 void r8712_free_xmitframe(struct xmit_priv
*pxmitpriv
,
823 struct xmit_frame
*pxmitframe
)
826 struct __queue
*pfree_xmit_queue
= &pxmitpriv
->free_xmit_queue
;
827 struct _adapter
*padapter
= pxmitpriv
->adapter
;
829 if (pxmitframe
== NULL
)
831 spin_lock_irqsave(&pfree_xmit_queue
->lock
, irqL
);
832 list_del_init(&pxmitframe
->list
);
834 pxmitframe
->pkt
= NULL
;
835 list_add_tail(&pxmitframe
->list
, &pfree_xmit_queue
->queue
);
836 pxmitpriv
->free_xmitframe_cnt
++;
837 spin_unlock_irqrestore(&pfree_xmit_queue
->lock
, irqL
);
838 if (netif_queue_stopped(padapter
->pnetdev
))
839 netif_wake_queue(padapter
->pnetdev
);
842 void r8712_free_xmitframe_ex(struct xmit_priv
*pxmitpriv
,
843 struct xmit_frame
*pxmitframe
)
845 if (pxmitframe
== NULL
)
847 if (pxmitframe
->frame_tag
== DATA_FRAMETAG
)
848 r8712_free_xmitframe(pxmitpriv
, pxmitframe
);
851 void r8712_free_xmitframe_queue(struct xmit_priv
*pxmitpriv
,
852 struct __queue
*pframequeue
)
855 struct list_head
*plist
, *phead
;
856 struct xmit_frame
*pxmitframe
;
858 spin_lock_irqsave(&(pframequeue
->lock
), irqL
);
859 phead
= &pframequeue
->queue
;
861 while (!end_of_queue_search(phead
, plist
)) {
862 pxmitframe
= LIST_CONTAINOR(plist
, struct xmit_frame
, list
);
864 r8712_free_xmitframe(pxmitpriv
, pxmitframe
);
866 spin_unlock_irqrestore(&(pframequeue
->lock
), irqL
);
869 static inline struct tx_servq
*get_sta_pending(struct _adapter
*padapter
,
870 struct __queue
**ppstapending
,
871 struct sta_info
*psta
, sint up
)
874 struct tx_servq
*ptxservq
;
875 struct hw_xmit
*phwxmits
= padapter
->xmitpriv
.hwxmits
;
880 ptxservq
= &(psta
->sta_xmitpriv
.bk_q
);
881 *ppstapending
= &padapter
->xmitpriv
.bk_pending
;
882 (phwxmits
+ 3)->accnt
++;
886 ptxservq
= &(psta
->sta_xmitpriv
.vi_q
);
887 *ppstapending
= &padapter
->xmitpriv
.vi_pending
;
888 (phwxmits
+ 1)->accnt
++;
892 ptxservq
= &(psta
->sta_xmitpriv
.vo_q
);
893 *ppstapending
= &padapter
->xmitpriv
.vo_pending
;
894 (phwxmits
+ 0)->accnt
++;
899 ptxservq
= &(psta
->sta_xmitpriv
.be_q
);
900 *ppstapending
= &padapter
->xmitpriv
.be_pending
;
901 (phwxmits
+ 2)->accnt
++;
908 * Will enqueue pxmitframe to the proper queue, and indicate it
909 * to xx_pending list.....
911 sint
r8712_xmit_classifier(struct _adapter
*padapter
,
912 struct xmit_frame
*pxmitframe
)
915 struct __queue
*pstapending
;
916 struct sta_info
*psta
;
917 struct tx_servq
*ptxservq
;
918 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
919 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
920 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
921 sint bmcst
= IS_MCAST(pattrib
->ra
);
924 psta
= pattrib
->psta
;
927 psta
= r8712_get_bcmc_stainfo(padapter
);
929 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
))
930 psta
= r8712_get_stainfo(pstapriv
,
931 get_bssid(pmlmepriv
));
933 psta
= r8712_get_stainfo(pstapriv
, pattrib
->ra
);
938 ptxservq
= get_sta_pending(padapter
, &pstapending
,
939 psta
, pattrib
->priority
);
940 spin_lock_irqsave(&pstapending
->lock
, irqL0
);
941 if (list_empty(&ptxservq
->tx_pending
))
942 list_add_tail(&ptxservq
->tx_pending
, &pstapending
->queue
);
943 list_add_tail(&pxmitframe
->list
, &ptxservq
->sta_pending
.queue
);
945 spin_unlock_irqrestore(&pstapending
->lock
, irqL0
);
949 static void alloc_hwxmits(struct _adapter
*padapter
)
951 struct hw_xmit
*hwxmits
;
952 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
954 pxmitpriv
->hwxmit_entry
= HWXMIT_ENTRY
;
955 pxmitpriv
->hwxmits
= kmalloc_array(pxmitpriv
->hwxmit_entry
,
956 sizeof(struct hw_xmit
), GFP_ATOMIC
);
957 if (pxmitpriv
->hwxmits
== NULL
)
959 hwxmits
= pxmitpriv
->hwxmits
;
960 if (pxmitpriv
->hwxmit_entry
== 5) {
961 pxmitpriv
->bmc_txqueue
.head
= 0;
962 hwxmits
[0] .phwtxqueue
= &pxmitpriv
->bmc_txqueue
;
963 hwxmits
[0] .sta_queue
= &pxmitpriv
->bm_pending
;
964 pxmitpriv
->vo_txqueue
.head
= 0;
965 hwxmits
[1] .phwtxqueue
= &pxmitpriv
->vo_txqueue
;
966 hwxmits
[1] .sta_queue
= &pxmitpriv
->vo_pending
;
967 pxmitpriv
->vi_txqueue
.head
= 0;
968 hwxmits
[2] .phwtxqueue
= &pxmitpriv
->vi_txqueue
;
969 hwxmits
[2] .sta_queue
= &pxmitpriv
->vi_pending
;
970 pxmitpriv
->bk_txqueue
.head
= 0;
971 hwxmits
[3] .phwtxqueue
= &pxmitpriv
->bk_txqueue
;
972 hwxmits
[3] .sta_queue
= &pxmitpriv
->bk_pending
;
973 pxmitpriv
->be_txqueue
.head
= 0;
974 hwxmits
[4] .phwtxqueue
= &pxmitpriv
->be_txqueue
;
975 hwxmits
[4] .sta_queue
= &pxmitpriv
->be_pending
;
976 } else if (pxmitpriv
->hwxmit_entry
== 4) {
977 pxmitpriv
->vo_txqueue
.head
= 0;
978 hwxmits
[0] .phwtxqueue
= &pxmitpriv
->vo_txqueue
;
979 hwxmits
[0] .sta_queue
= &pxmitpriv
->vo_pending
;
980 pxmitpriv
->vi_txqueue
.head
= 0;
981 hwxmits
[1] .phwtxqueue
= &pxmitpriv
->vi_txqueue
;
982 hwxmits
[1] .sta_queue
= &pxmitpriv
->vi_pending
;
983 pxmitpriv
->be_txqueue
.head
= 0;
984 hwxmits
[2] .phwtxqueue
= &pxmitpriv
->be_txqueue
;
985 hwxmits
[2] .sta_queue
= &pxmitpriv
->be_pending
;
986 pxmitpriv
->bk_txqueue
.head
= 0;
987 hwxmits
[3] .phwtxqueue
= &pxmitpriv
->bk_txqueue
;
988 hwxmits
[3] .sta_queue
= &pxmitpriv
->bk_pending
;
992 static void free_hwxmits(struct _adapter
*padapter
)
994 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
996 kfree(pxmitpriv
->hwxmits
);
999 static void init_hwxmits(struct hw_xmit
*phwxmit
, sint entry
)
1003 for (i
= 0; i
< entry
; i
++, phwxmit
++) {
1004 spin_lock_init(&phwxmit
->xmit_lock
);
1005 INIT_LIST_HEAD(&phwxmit
->pending
);
1006 phwxmit
->txcmdcnt
= 0;
1011 void xmitframe_xmitbuf_attach(struct xmit_frame
*pxmitframe
,
1012 struct xmit_buf
*pxmitbuf
)
1014 /* pxmitbuf attach to pxmitframe */
1015 pxmitframe
->pxmitbuf
= pxmitbuf
;
1016 /* urb and irp connection */
1017 pxmitframe
->pxmit_urb
[0] = pxmitbuf
->pxmit_urb
[0];
1018 /* buffer addr assoc */
1019 pxmitframe
->buf_addr
= pxmitbuf
->pbuf
;
1020 /* pxmitframe attach to pxmitbuf */
1021 pxmitbuf
->priv_data
= pxmitframe
;
1025 * tx_action == 0 == no frames to transmit
1026 * tx_action > 0 ==> we have frames to transmit
1027 * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
1028 * to transmit 1 frame.
1031 int r8712_pre_xmit(struct _adapter
*padapter
, struct xmit_frame
*pxmitframe
)
1035 struct xmit_buf
*pxmitbuf
= NULL
;
1036 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1037 struct pkt_attrib
*pattrib
= &pxmitframe
->attrib
;
1039 r8712_do_queue_select(padapter
, pattrib
);
1040 spin_lock_irqsave(&pxmitpriv
->lock
, irqL
);
1041 if (r8712_txframes_sta_ac_pending(padapter
, pattrib
) > 0) {
1043 r8712_xmit_enqueue(padapter
, pxmitframe
);
1044 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
1047 pxmitbuf
= r8712_alloc_xmitbuf(pxmitpriv
);
1048 if (pxmitbuf
== NULL
) { /*enqueue packet*/
1050 r8712_xmit_enqueue(padapter
, pxmitframe
);
1051 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
1052 } else { /*dump packet directly*/
1053 spin_unlock_irqrestore(&pxmitpriv
->lock
, irqL
);
1055 xmitframe_xmitbuf_attach(pxmitframe
, pxmitbuf
);
1056 r8712_xmit_direct(padapter
, pxmitframe
);