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