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