mmc: mxs-mmc: Fix additional cycles after transmission stop
[pandora-kernel.git] / drivers / staging / rtl8712 / rtl871x_xmit.c
1 /******************************************************************************
2  * rtl871x_xmit.c
3  *
4  * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5  * Linux device driver for RTL8192SU
6  *
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.
10  *
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
14  * more details.
15  *
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
19  *
20  * Modifications for inclusion into the Linux staging tree are
21  * Copyright(c) 2010 Larry Finger. All rights reserved.
22  *
23  * Contact information:
24  * WLAN FAE <wlanfae@realtek.com>
25  * Larry Finger <Larry.Finger@lwfinger.net>
26  *
27  ******************************************************************************/
28
29 #define _RTL871X_XMIT_C_
30
31 #include "osdep_service.h"
32 #include "drv_types.h"
33 #include "rtl871x_byteorder.h"
34 #include "wifi.h"
35 #include "osdep_intf.h"
36 #include "usb_ops.h"
37
38
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);
44
45 static void _init_txservq(struct tx_servq *ptxservq)
46 {
47         _init_listhead(&ptxservq->tx_pending);
48         _init_queue(&ptxservq->sta_pending);
49         ptxservq->qcnt = 0;
50 }
51
52 void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
53 {
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);
63 }
64
65 sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
66                            struct _adapter *padapter)
67 {
68         sint i;
69         struct xmit_buf *pxmitbuf;
70         struct xmit_frame *pxframe;
71
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);
76         /*
77         Please insert all the queue initializaiton using _init_queue below
78         */
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);
88         /*
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...
92         */
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;
97                 return _FAIL;
98         }
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;
106                 pxframe->pkt = NULL;
107                 pxframe->buf_addr = NULL;
108                 pxframe->pxmitbuf = NULL;
109                 list_insert_tail(&(pxframe->list),
110                                  &(pxmitpriv->free_xmit_queue.queue));
111                 pxframe++;
112         }
113         pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
114         /*
115                 init xmit hw_txqueue
116         */
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;
130         /*init xmit_buf*/
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)
136                 return _FAIL;
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 +
143                                            XMITBUF_ALIGN_SZ);
144                 if (pxmitbuf->pallocated_buf == NULL)
145                         return _FAIL;
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));
152                 pxmitbuf++;
153         }
154         pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
155         _init_workitem(&padapter->wkFilterRxFF0, r8712_SetFilter, padapter);
156         alloc_hwxmits(padapter);
157         init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
158         tasklet_init(&pxmitpriv->xmit_tasklet,
159                 (void(*)(unsigned long))r8712_xmit_bh,
160                 (unsigned long)padapter);
161         return _SUCCESS;
162 }
163
164 void _free_xmit_priv(struct xmit_priv *pxmitpriv)
165 {
166         int i;
167         struct _adapter *padapter = pxmitpriv->adapter;
168         struct xmit_frame *pxmitframe = (struct xmit_frame *)
169                                         pxmitpriv->pxmit_frame_buf;
170         struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
171
172         if (pxmitpriv->pxmit_frame_buf == NULL)
173                 return;
174         for (i = 0; i < NR_XMITFRAME; i++) {
175                 r8712_xmit_complete(padapter, pxmitframe);
176                 pxmitframe++;
177         }
178         for (i = 0; i < NR_XMITBUFF; i++) {
179                 r8712_xmit_resource_free(padapter, pxmitbuf);
180                 kfree(pxmitbuf->pallocated_buf);
181                 pxmitbuf++;
182         }
183         kfree(pxmitpriv->pallocated_frame_buf);
184         kfree(pxmitpriv->pallocated_xmitbuf);
185         free_hwxmits(padapter);
186 }
187
188 sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
189                    struct pkt_attrib *pattrib)
190 {
191         uint i;
192         struct pkt_file pktfile;
193         struct sta_info *psta = NULL;
194         struct ethhdr etherhdr;
195
196         struct tx_cmd txdesc;
197
198         sint bmcast;
199         struct sta_priv         *pstapriv = &padapter->stapriv;
200         struct security_priv    *psecuritypriv = &padapter->securitypriv;
201         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
202         struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
203
204         _r8712_open_pktfile(pkt, &pktfile);
205
206         i = _r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);
207
208         pattrib->ether_type = ntohs(etherhdr.h_proto);
209
210 {
211         u8 bool;
212         /*If driver xmit ARP packet, driver can set ps mode to initial
213          * setting. It stands for getting DHCP or fix IP.*/
214         if (pattrib->ether_type == 0x0806) {
215                 if (padapter->pwrctrlpriv.pwr_mode !=
216                     padapter->registrypriv.power_mgnt) {
217                         _cancel_timer(&(pmlmepriv->dhcp_timer), &bool);
218                         r8712_set_ps_mode(padapter, padapter->registrypriv.
219                                 power_mgnt, padapter->registrypriv.smart_ps);
220                 }
221         }
222 }
223         memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
224         memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
225         pattrib->pctrl = 0;
226         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
227             (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
228                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
229                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
230         } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
231                 memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
232                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
233         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
234                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
235                 memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
236         } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
237                 /*firstly, filter packet not belongs to mp*/
238                 if (pattrib->ether_type != 0x8712)
239                         return _FAIL;
240                 /* for mp storing the txcmd per packet,
241                  * according to the info of txcmd to update pattrib */
242                 /*get MP_TXDESC_SIZE bytes txcmd per packet*/
243                 i = _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
244                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
245                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
246                 pattrib->pctrl = 1;
247         }
248         /* r8712_xmitframe_coalesce() overwrite this!*/
249         pattrib->pktlen = pktfile.pkt_len;
250         if (ETH_P_IP == pattrib->ether_type) {
251                 /* The following is for DHCP and ARP packet, we use cck1M to
252                  * tx these packets and let LPS awake some time
253                  * to prevent DHCP protocol fail */
254                 u8 tmp[24];
255                 _r8712_pktfile_read(&pktfile, &tmp[0], 24);
256                 pattrib->dhcp_pkt = 0;
257                 if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
258                         if (ETH_P_IP == pattrib->ether_type) {/* IP header*/
259                                 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
260                                         ((tmp[21] == 67) && (tmp[23] == 68))) {
261                                         /* 68 : UDP BOOTP client
262                                          * 67 : UDP BOOTP server
263                                          * Use low rate to send DHCP packet.*/
264                                         pattrib->dhcp_pkt = 1;
265                                 }
266                         }
267                 }
268         }
269         bmcast = IS_MCAST(pattrib->ra);
270         /* get sta_info*/
271         if (bmcast) {
272                 psta = r8712_get_bcmc_stainfo(padapter);
273                 pattrib->mac_id = 4;
274         } else {
275                 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
276                         psta = r8712_get_stainfo(pstapriv,
277                                                  get_bssid(pmlmepriv));
278                         pattrib->mac_id = 5;
279                 } else {
280                         psta = r8712_get_stainfo(pstapriv, pattrib->ra);
281                         if (psta == NULL)  /* drop the pkt */
282                                 return _FAIL;
283                         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
284                                 pattrib->mac_id = 5;
285                         else
286                                 pattrib->mac_id = psta->mac_id;
287                 }
288         }
289
290         if (psta) {
291                 pattrib->psta = psta;
292         } else {
293                 /* if we cannot get psta => drrp the pkt */
294                 return _FAIL;
295         }
296
297         pattrib->ack_policy = 0;
298         /* get ether_hdr_len */
299         pattrib->pkt_hdrlen = ETH_HLEN;
300
301         if (pqospriv->qos_option)
302                 r8712_set_qos(&pktfile, pattrib);
303         else {
304                 pattrib->hdrlen = WLAN_HDR_A3_LEN;
305                 pattrib->subtype = WIFI_DATA_TYPE;
306                 pattrib->priority = 0;
307         }
308         if (psta->ieee8021x_blocked == true) {
309                 pattrib->encrypt = 0;
310                 if ((pattrib->ether_type != 0x888e) &&
311                     (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false))
312                         return _FAIL;
313         } else
314                 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
315         switch (pattrib->encrypt) {
316         case _WEP40_:
317         case _WEP104_:
318                 pattrib->iv_len = 4;
319                 pattrib->icv_len = 4;
320                 break;
321         case _TKIP_:
322                 pattrib->iv_len = 8;
323                 pattrib->icv_len = 4;
324                 if (padapter->securitypriv.busetkipkey == _FAIL)
325                         return _FAIL;
326                 break;
327         case _AES_:
328                 pattrib->iv_len = 8;
329                 pattrib->icv_len = 8;
330                 break;
331         default:
332                 pattrib->iv_len = 0;
333                 pattrib->icv_len = 0;
334                 break;
335         }
336
337         if (pattrib->encrypt &&
338             ((padapter->securitypriv.sw_encrypt == true) ||
339              (psecuritypriv->hw_decrypted == false)))
340                 pattrib->bswenc = true;
341         else
342                 pattrib->bswenc = false;
343         /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
344          * some settings above.*/
345         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
346                 pattrib->priority = (txdesc.txdw1 >> QSEL_SHT) & 0x1f;
347         return _SUCCESS;
348 }
349
350 static sint xmitframe_addmic(struct _adapter *padapter,
351                              struct xmit_frame *pxmitframe)
352 {
353         u32     curfragnum, length, datalen;
354         u8      *pframe, *payload, mic[8];
355         struct  mic_data micdata;
356         struct  sta_info *stainfo;
357         struct  qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
358         struct  pkt_attrib  *pattrib = &pxmitframe->attrib;
359         struct  security_priv *psecuritypriv = &padapter->securitypriv;
360         struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
361         u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
362         sint bmcst = IS_MCAST(pattrib->ra);
363
364         if (pattrib->psta)
365                 stainfo = pattrib->psta;
366         else
367                 stainfo = r8712_get_stainfo(&padapter->stapriv,
368                                             &pattrib->ra[0]);
369         if (pattrib->encrypt == _TKIP_) {
370                 /*encode mic code*/
371                 if (stainfo != NULL) {
372                         u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
373                                            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
374                                            0x0, 0x0};
375                         datalen = pattrib->pktlen - pattrib->hdrlen;
376                         pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
377                         if (bmcst) {
378                                 if (!memcmp(psecuritypriv->XGrptxmickey
379                                    [psecuritypriv->XGrpKeyid].skey,
380                                    null_key, 16))
381                                         return _FAIL;
382                                 /*start to calculate the mic code*/
383                                 r8712_secmicsetkey(&micdata,
384                                          psecuritypriv->
385                                          XGrptxmickey[psecuritypriv->
386                                         XGrpKeyid].skey);
387                         } else {
388                                 if (!memcmp(&stainfo->tkiptxmickey.skey[0],
389                                             null_key, 16))
390                                         return _FAIL;
391                                 /* start to calculate the mic code */
392                                 r8712_secmicsetkey(&micdata,
393                                              &stainfo->tkiptxmickey.skey[0]);
394                         }
395                         if (pframe[1] & 1) {   /* ToDS==1 */
396                                 r8712_secmicappend(&micdata,
397                                                    &pframe[16], 6); /*DA*/
398                                 if (pframe[1]&2)  /* From Ds==1 */
399                                         r8712_secmicappend(&micdata,
400                                                            &pframe[24], 6);
401                                 else
402                                         r8712_secmicappend(&micdata,
403                                                            &pframe[10], 6);
404                         } else {        /* ToDS==0 */
405                                 r8712_secmicappend(&micdata,
406                                                    &pframe[4], 6); /* DA */
407                                 if (pframe[1]&2)  /* From Ds==1 */
408                                         r8712_secmicappend(&micdata,
409                                                            &pframe[16], 6);
410                                 else
411                                         r8712_secmicappend(&micdata,
412                                                            &pframe[10], 6);
413                         }
414                         if (pqospriv->qos_option == 1)
415                                         priority[0] = (u8)pxmitframe->
416                                                       attrib.priority;
417                         r8712_secmicappend(&micdata, &priority[0], 4);
418                         payload = pframe;
419                         for (curfragnum = 0; curfragnum < pattrib->nr_frags;
420                              curfragnum++) {
421                                 payload = (u8 *)RND4((addr_t)(payload));
422                                 payload = payload+pattrib->
423                                           hdrlen+pattrib->iv_len;
424                                 if ((curfragnum + 1) == pattrib->nr_frags) {
425                                         length = pattrib->last_txcmdsz -
426                                                   pattrib->hdrlen -
427                                                   pattrib->iv_len -
428                                                   ((psecuritypriv->sw_encrypt)
429                                                   ? pattrib->icv_len : 0);
430                                         r8712_secmicappend(&micdata, payload,
431                                                            length);
432                                         payload = payload+length;
433                                 } else{
434                                         length = pxmitpriv->frag_len -
435                                             pattrib->hdrlen-pattrib->iv_len -
436                                             ((psecuritypriv->sw_encrypt) ?
437                                             pattrib->icv_len : 0);
438                                         r8712_secmicappend(&micdata, payload,
439                                                            length);
440                                         payload = payload + length +
441                                                   pattrib->icv_len;
442                                 }
443                         }
444                         r8712_secgetmic(&micdata, &(mic[0]));
445                         /* add mic code  and add the mic code length in
446                          * last_txcmdsz */
447                         memcpy(payload, &(mic[0]), 8);
448                         pattrib->last_txcmdsz += 8;
449                         payload = payload-pattrib->last_txcmdsz + 8;
450                 }
451         }
452         return _SUCCESS;
453 }
454
455 static sint xmitframe_swencrypt(struct _adapter *padapter,
456                                 struct xmit_frame *pxmitframe)
457 {
458         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
459
460         if (pattrib->bswenc) {
461                 switch (pattrib->encrypt) {
462                 case _WEP40_:
463                 case _WEP104_:
464                         r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
465                         break;
466                 case _TKIP_:
467                         r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
468                         break;
469                 case _AES_:
470                         r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
471                         break;
472                 default:
473                                 break;
474                 }
475         }
476         return _SUCCESS;
477 }
478
479 static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr,
480                          struct pkt_attrib *pattrib)
481 {
482         u16 *qc;
483
484         struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
485         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
486         struct qos_priv *pqospriv = &pmlmepriv->qospriv;
487         u16 *fctrl = &pwlanhdr->frame_ctl;
488         memset(hdr, 0, WLANHDR_OFFSET);
489         SetFrameSubType(fctrl, pattrib->subtype);
490         if (pattrib->subtype & WIFI_DATA_TYPE) {
491                 if ((check_fwstate(pmlmepriv,  WIFI_STATION_STATE) == true)) {
492                         /* to_ds = 1, fr_ds = 0; */
493                         SetToDs(fctrl);
494                         memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
495                                 ETH_ALEN);
496                         memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
497                         memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
498                 } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)) {
499                         /* to_ds = 0, fr_ds = 1; */
500                         SetFrDs(fctrl);
501                         memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
502                         memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
503                                 ETH_ALEN);
504                         memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
505                 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
506                            || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
507                            == true)) {
508                         memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
509                         memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
510                         memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
511                                 ETH_ALEN);
512                 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
513                         memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
514                         memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
515                         memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
516                                 ETH_ALEN);
517                 } else
518                         return _FAIL;
519
520                 if (pattrib->encrypt)
521                         SetPrivacy(fctrl);
522                 if (pqospriv->qos_option) {
523                         qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
524                         if (pattrib->priority)
525                                 SetPriority(qc, pattrib->priority);
526                         SetAckpolicy(qc, pattrib->ack_policy);
527                 }
528                 /* TODO: fill HT Control Field */
529                 /* Update Seq Num will be handled by f/w */
530                 {
531                         struct sta_info *psta;
532
533                         sint bmcst = IS_MCAST(pattrib->ra);
534                         if (pattrib->psta)
535                                 psta = pattrib->psta;
536                         else {
537                                 if (bmcst)
538                                         psta = r8712_get_bcmc_stainfo(padapter);
539                                 else
540                                         psta =
541                                          r8712_get_stainfo(&padapter->stapriv,
542                                          pattrib->ra);
543                         }
544                         if (psta) {
545                                 psta->sta_xmitpriv.txseq_tid
546                                                   [pattrib->priority]++;
547                                 psta->sta_xmitpriv.txseq_tid[pattrib->priority]
548                                                    &= 0xFFF;
549                                 pattrib->seqnum = psta->sta_xmitpriv.
550                                                   txseq_tid[pattrib->priority];
551                                 SetSeqNum(hdr, pattrib->seqnum);
552                         }
553                 }
554         }
555         return _SUCCESS;
556 }
557
558 static sint r8712_put_snap(u8 *data, u16 h_proto)
559 {
560         struct ieee80211_snap_hdr *snap;
561         const u8 *oui;
562
563         snap = (struct ieee80211_snap_hdr *)data;
564         snap->dsap = 0xaa;
565         snap->ssap = 0xaa;
566         snap->ctrl = 0x03;
567         if (h_proto == 0x8137 || h_proto == 0x80f3)
568                 oui = P802_1H_OUI;
569         else
570                 oui = RFC1042_OUI;
571         snap->oui[0] = oui[0];
572         snap->oui[1] = oui[1];
573         snap->oui[2] = oui[2];
574         *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
575         return SNAP_SIZE + sizeof(u16);
576 }
577
578 /*
579  * This sub-routine will perform all the following:
580  * 1. remove 802.3 header.
581  * 2. create wlan_header, based on the info in pxmitframe
582  * 3. append sta's iv/ext-iv
583  * 4. append LLC
584  * 5. move frag chunk from pframe to pxmitframe->mem
585  * 6. apply sw-encrypt, if necessary.
586  */
587 sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
588                         struct xmit_frame *pxmitframe)
589 {
590         struct pkt_file pktfile;
591
592         sint    frg_len, mpdu_len, llc_sz;
593         u32     mem_sz;
594         u8      frg_inx;
595         addr_t addr;
596         u8 *pframe, *mem_start, *ptxdesc;
597         struct sta_info         *psta;
598         struct security_priv    *psecuritypriv = &padapter->securitypriv;
599         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
600         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
601         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
602         u8 *pbuf_start;
603         sint bmcst = IS_MCAST(pattrib->ra);
604
605         if (pattrib->psta == NULL)
606                 return _FAIL;
607         psta = pattrib->psta;
608         if (pxmitframe->buf_addr == NULL)
609                 return _FAIL;
610         pbuf_start = pxmitframe->buf_addr;
611         ptxdesc = pbuf_start;
612         mem_start = pbuf_start + TXDESC_OFFSET;
613         if (make_wlanhdr(padapter, mem_start, pattrib) == _FAIL)
614                 return _FAIL;
615         _r8712_open_pktfile(pkt, &pktfile);
616         _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
617         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
618                 /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
619                 if (pattrib->ether_type == 0x8712) {
620                         /* take care -  update_txdesc overwrite this */
621                         _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
622                 }
623         }
624         pattrib->pktlen = pktfile.pkt_len;
625         frg_inx = 0;
626         frg_len = pxmitpriv->frag_len - 4;
627         while (1) {
628                 llc_sz = 0;
629                 mpdu_len = frg_len;
630                 pframe = mem_start;
631                 SetMFrag(mem_start);
632                 pframe += pattrib->hdrlen;
633                 mpdu_len -= pattrib->hdrlen;
634                 /* adding icv, if necessary...*/
635                 if (pattrib->iv_len) {
636                         if (psta != NULL) {
637                                 switch (pattrib->encrypt) {
638                                 case _WEP40_:
639                                 case _WEP104_:
640                                         WEP_IV(pattrib->iv, psta->txpn,
641                                                (u8)psecuritypriv->
642                                                PrivacyKeyIndex);
643                                         break;
644                                 case _TKIP_:
645                                         if (bmcst)
646                                                 TKIP_IV(pattrib->iv,
647                                                     psta->txpn,
648                                                     (u8)psecuritypriv->
649                                                     XGrpKeyid);
650                                         else
651                                                 TKIP_IV(pattrib->iv, psta->txpn,
652                                                         0);
653                                         break;
654                                 case _AES_:
655                                         if (bmcst)
656                                                 AES_IV(pattrib->iv, psta->txpn,
657                                                     (u8)psecuritypriv->
658                                                     XGrpKeyid);
659                                         else
660                                                 AES_IV(pattrib->iv, psta->txpn,
661                                                        0);
662                                         break;
663                                 }
664                         }
665                         memcpy(pframe, pattrib->iv, pattrib->iv_len);
666                         pframe += pattrib->iv_len;
667                         mpdu_len -= pattrib->iv_len;
668                 }
669                 if (frg_inx == 0) {
670                         llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
671                         pframe += llc_sz;
672                         mpdu_len -= llc_sz;
673                 }
674                 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
675                         mpdu_len -= pattrib->icv_len;
676                 if (bmcst)
677                         mem_sz = _r8712_pktfile_read(&pktfile, pframe,
678                                  pattrib->pktlen);
679                 else
680                         mem_sz = _r8712_pktfile_read(&pktfile, pframe,
681                                  mpdu_len);
682                 pframe += mem_sz;
683                 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
684                         memcpy(pframe, pattrib->icv, pattrib->icv_len);
685                         pframe += pattrib->icv_len;
686                 }
687                 frg_inx++;
688                 if (bmcst || (r8712_endofpktfile(&pktfile) == true)) {
689                         pattrib->nr_frags = frg_inx;
690                         pattrib->last_txcmdsz = pattrib->hdrlen +
691                                                 pattrib->iv_len +
692                                                 ((pattrib->nr_frags == 1) ?
693                                                 llc_sz : 0) +
694                                                 ((pattrib->bswenc) ?
695                                                 pattrib->icv_len : 0) + mem_sz;
696                         ClearMFrag(mem_start);
697                         break;
698                 }
699                 addr = (addr_t)(pframe);
700                 mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
701                 memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
702         }
703
704         if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
705                 return _FAIL;
706         xmitframe_swencrypt(padapter, pxmitframe);
707         return _SUCCESS;
708 }
709
710 void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
711 {
712         uint    protection;
713         u8      *perp;
714         sint     erp_len;
715         struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
716         struct  registry_priv *pregistrypriv = &padapter->registrypriv;
717
718         switch (pxmitpriv->vcs_setting) {
719         case DISABLE_VCS:
720                 pxmitpriv->vcs = NONE_VCS;
721                 break;
722         case ENABLE_VCS:
723                 break;
724         case AUTO_VCS:
725         default:
726                 perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
727                 if (perp == NULL)
728                         pxmitpriv->vcs = NONE_VCS;
729                 else {
730                         protection = (*(perp + 2)) & BIT(1);
731                         if (protection) {
732                                 if (pregistrypriv->vcs_type == RTS_CTS)
733                                         pxmitpriv->vcs = RTS_CTS;
734                                 else
735                                         pxmitpriv->vcs = CTS_TO_SELF;
736                         } else
737                                 pxmitpriv->vcs = NONE_VCS;
738                 }
739                 break;
740         }
741 }
742
743 struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
744 {
745         unsigned long irqL;
746         struct xmit_buf *pxmitbuf =  NULL;
747         struct list_head *plist, *phead;
748         struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
749
750         spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
751         if (_queue_empty(pfree_xmitbuf_queue) == true)
752                 pxmitbuf = NULL;
753         else {
754                 phead = get_list_head(pfree_xmitbuf_queue);
755                 plist = get_next(phead);
756                 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
757                 list_delete(&(pxmitbuf->list));
758         }
759         if (pxmitbuf !=  NULL)
760                 pxmitpriv->free_xmitbuf_cnt--;
761         spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
762         return pxmitbuf;
763 }
764
765 int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
766 {
767         unsigned long irqL;
768         struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
769
770         if (pxmitbuf == NULL)
771                 return _FAIL;
772         spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
773         list_delete(&pxmitbuf->list);
774         list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
775         pxmitpriv->free_xmitbuf_cnt++;
776         spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
777         return _SUCCESS;
778 }
779
780 /*
781 Calling context:
782 1. OS_TXENTRY
783 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
784
785 If we turn on USE_RXTHREAD, then, no need for critical section.
786 Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
787
788 Must be very very cautious...
789
790 */
791
792 struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
793 {
794         /*
795                 Please remember to use all the osdep_service api,
796                 and lock/unlock or _enter/_exit critical to protect
797                 pfree_xmit_queue
798         */
799         unsigned long irqL;
800         struct xmit_frame *pxframe = NULL;
801         struct list_head *plist, *phead;
802         struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
803
804         spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
805         if (_queue_empty(pfree_xmit_queue) == true)
806                 pxframe =  NULL;
807         else {
808                 phead = get_list_head(pfree_xmit_queue);
809                 plist = get_next(phead);
810                 pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
811                 list_delete(&(pxframe->list));
812         }
813         if (pxframe !=  NULL) {
814                 pxmitpriv->free_xmitframe_cnt--;
815                 pxframe->buf_addr = NULL;
816                 pxframe->pxmitbuf = NULL;
817                 pxframe->attrib.psta = NULL;
818                 pxframe->pkt = NULL;
819         }
820         spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
821         return pxframe;
822 }
823
824 void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
825                           struct xmit_frame *pxmitframe)
826 {
827         unsigned long irqL;
828         struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
829         struct _adapter *padapter = pxmitpriv->adapter;
830         struct sk_buff *pndis_pkt = NULL;
831
832         if (pxmitframe == NULL)
833                 return;
834         spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
835         list_delete(&pxmitframe->list);
836         if (pxmitframe->pkt) {
837                 pndis_pkt = pxmitframe->pkt;
838                 pxmitframe->pkt = NULL;
839         }
840         list_insert_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
841         pxmitpriv->free_xmitframe_cnt++;
842         spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
843         if (netif_queue_stopped(padapter->pnetdev))
844                 netif_wake_queue(padapter->pnetdev);
845 }
846
847 void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
848                       struct xmit_frame *pxmitframe)
849 {
850         if (pxmitframe == NULL)
851                 return;
852         if (pxmitframe->frame_tag == DATA_FRAMETAG)
853                 r8712_free_xmitframe(pxmitpriv, pxmitframe);
854 }
855
856 void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
857                                 struct  __queue *pframequeue)
858 {
859         unsigned long irqL;
860         struct list_head *plist, *phead;
861         struct  xmit_frame      *pxmitframe;
862
863         spin_lock_irqsave(&(pframequeue->lock), irqL);
864         phead = get_list_head(pframequeue);
865         plist = get_next(phead);
866         while (end_of_queue_search(phead, plist) == false) {
867                 pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
868                 plist = get_next(plist);
869                 r8712_free_xmitframe(pxmitpriv, pxmitframe);
870         }
871         spin_unlock_irqrestore(&(pframequeue->lock), irqL);
872 }
873
874 static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
875                                                struct  __queue **ppstapending,
876                                                struct sta_info *psta, sint up)
877 {
878
879         struct tx_servq *ptxservq;
880         struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
881
882         switch (up) {
883         case 1:
884         case 2:
885                 ptxservq = &(psta->sta_xmitpriv.bk_q);
886                 *ppstapending = &padapter->xmitpriv.bk_pending;
887                 (phwxmits+3)->accnt++;
888                 break;
889         case 4:
890         case 5:
891                 ptxservq = &(psta->sta_xmitpriv.vi_q);
892                 *ppstapending = &padapter->xmitpriv.vi_pending;
893                 (phwxmits+1)->accnt++;
894                 break;
895         case 6:
896         case 7:
897                 ptxservq = &(psta->sta_xmitpriv.vo_q);
898                 *ppstapending = &padapter->xmitpriv.vo_pending;
899                 (phwxmits+0)->accnt++;
900                 break;
901         case 0:
902         case 3:
903         default:
904                 ptxservq = &(psta->sta_xmitpriv.be_q);
905                 *ppstapending = &padapter->xmitpriv.be_pending;
906                 (phwxmits + 2)->accnt++;
907                 break;
908         }
909         return ptxservq;
910 }
911
912 /*
913  * Will enqueue pxmitframe to the proper queue, and indicate it
914  * to xx_pending list.....
915  */
916 sint r8712_xmit_classifier(struct _adapter *padapter,
917                            struct xmit_frame *pxmitframe)
918 {
919         unsigned long irqL0;
920         struct  __queue *pstapending;
921         struct sta_info *psta;
922         struct tx_servq *ptxservq;
923         struct pkt_attrib *pattrib = &pxmitframe->attrib;
924         struct sta_priv *pstapriv = &padapter->stapriv;
925         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
926         sint bmcst = IS_MCAST(pattrib->ra);
927
928         if (pattrib->psta)
929                 psta = pattrib->psta;
930         else {
931                 if (bmcst)
932                         psta = r8712_get_bcmc_stainfo(padapter);
933                 else {
934                         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
935                                 psta = r8712_get_stainfo(pstapriv,
936                                        get_bssid(pmlmepriv));
937                         else
938                                 psta = r8712_get_stainfo(pstapriv, pattrib->ra);
939                 }
940         }
941         if (psta == NULL)
942                 return _FAIL;
943         ptxservq = get_sta_pending(padapter, &pstapending,
944                    psta, pattrib->priority);
945         spin_lock_irqsave(&pstapending->lock, irqL0);
946         if (is_list_empty(&ptxservq->tx_pending))
947                 list_insert_tail(&ptxservq->tx_pending,
948                                  get_list_head(pstapending));
949         list_insert_tail(&pxmitframe->list,
950                          get_list_head(&ptxservq->sta_pending));
951         ptxservq->qcnt++;
952         spin_unlock_irqrestore(&pstapending->lock, irqL0);
953         return _SUCCESS;
954 }
955
956 static void alloc_hwxmits(struct _adapter *padapter)
957 {
958         struct hw_xmit *hwxmits;
959         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
960
961         pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
962         pxmitpriv->hwxmits = (struct hw_xmit *)_malloc(sizeof(struct hw_xmit) *
963                              pxmitpriv->hwxmit_entry);
964         if (pxmitpriv->hwxmits == NULL)
965                 return;
966         hwxmits = pxmitpriv->hwxmits;
967         if (pxmitpriv->hwxmit_entry == 5) {
968                 pxmitpriv->bmc_txqueue.head = 0;
969                 hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
970                 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
971                 pxmitpriv->vo_txqueue.head = 0;
972                 hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
973                 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
974         pxmitpriv->vi_txqueue.head = 0;
975                 hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
976                 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
977                 pxmitpriv->bk_txqueue.head = 0;
978                 hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
979                 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
980                 pxmitpriv->be_txqueue.head = 0;
981                 hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
982                 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
983         } else if (pxmitpriv->hwxmit_entry == 4) {
984                 pxmitpriv->vo_txqueue.head = 0;
985                 hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
986                 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
987                 pxmitpriv->vi_txqueue.head = 0;
988                 hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
989                 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
990                 pxmitpriv->be_txqueue.head = 0;
991                 hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
992                 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
993                 pxmitpriv->bk_txqueue.head = 0;
994                 hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
995                 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
996         }
997 }
998
999 static void free_hwxmits(struct _adapter *padapter)
1000 {
1001         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1002
1003         kfree(pxmitpriv->hwxmits);
1004 }
1005
1006 static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
1007 {
1008         sint i;
1009
1010         for (i = 0; i < entry; i++, phwxmit++) {
1011                 spin_lock_init(&phwxmit->xmit_lock);
1012                 _init_listhead(&phwxmit->pending);
1013                 phwxmit->txcmdcnt = 0;
1014                 phwxmit->accnt = 0;
1015         }
1016 }
1017
1018 void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
1019                         struct xmit_buf *pxmitbuf)
1020 {
1021         /* pxmitbuf attach to pxmitframe */
1022         pxmitframe->pxmitbuf = pxmitbuf;
1023         /* urb and irp connection */
1024         pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
1025         /* buffer addr assoc */
1026         pxmitframe->buf_addr = pxmitbuf->pbuf;
1027         /* pxmitframe attach to pxmitbuf */
1028         pxmitbuf->priv_data = pxmitframe;
1029 }
1030
1031 /*
1032  * tx_action == 0 == no frames to transmit
1033  * tx_action > 0 ==> we have frames to transmit
1034  * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
1035  *                                               to transmit 1 frame.
1036  */
1037
1038 int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
1039 {
1040         unsigned long irqL;
1041         int ret;
1042         struct xmit_buf *pxmitbuf = NULL;
1043         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1044         struct pkt_attrib *pattrib = &pxmitframe->attrib;
1045
1046         r8712_do_queue_select(padapter, pattrib);
1047         spin_lock_irqsave(&pxmitpriv->lock, irqL);
1048         if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1049                 ret = false;
1050                 r8712_xmit_enqueue(padapter, pxmitframe);
1051                 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1052                 return ret;
1053         }
1054         pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
1055         if (pxmitbuf == NULL) { /*enqueue packet*/
1056                 ret = false;
1057                 r8712_xmit_enqueue(padapter, pxmitframe);
1058                 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1059         } else { /*dump packet directly*/
1060                 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1061                 ret = true;
1062                 xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
1063                 r8712_xmit_direct(padapter, pxmitframe);
1064         }
1065         return ret;
1066 }