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