0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define _RTL871X_XMIT_C_
0018
0019 #include "osdep_service.h"
0020 #include "drv_types.h"
0021 #include "osdep_intf.h"
0022 #include "usb_ops.h"
0023
0024 #include <linux/ieee80211.h>
0025
0026 static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
0027 static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
0028 static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
0029 static void alloc_hwxmits(struct _adapter *padapter);
0030 static void free_hwxmits(struct _adapter *padapter);
0031
0032 static void _init_txservq(struct tx_servq *ptxservq)
0033 {
0034 INIT_LIST_HEAD(&ptxservq->tx_pending);
0035 _init_queue(&ptxservq->sta_pending);
0036 ptxservq->qcnt = 0;
0037 }
0038
0039 void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
0040 {
0041 memset((unsigned char *)psta_xmitpriv, 0,
0042 sizeof(struct sta_xmit_priv));
0043 spin_lock_init(&psta_xmitpriv->lock);
0044 _init_txservq(&psta_xmitpriv->be_q);
0045 _init_txservq(&psta_xmitpriv->bk_q);
0046 _init_txservq(&psta_xmitpriv->vi_q);
0047 _init_txservq(&psta_xmitpriv->vo_q);
0048 INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
0049 INIT_LIST_HEAD(&psta_xmitpriv->apsd);
0050 }
0051
0052 int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
0053 struct _adapter *padapter)
0054 {
0055 sint i;
0056 struct xmit_buf *pxmitbuf;
0057 struct xmit_frame *pxframe;
0058
0059 memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
0060 spin_lock_init(&pxmitpriv->lock);
0061
0062
0063
0064 pxmitpriv->adapter = padapter;
0065 _init_queue(&pxmitpriv->be_pending);
0066 _init_queue(&pxmitpriv->bk_pending);
0067 _init_queue(&pxmitpriv->vi_pending);
0068 _init_queue(&pxmitpriv->vo_pending);
0069 _init_queue(&pxmitpriv->bm_pending);
0070 _init_queue(&pxmitpriv->legacy_dz_queue);
0071 _init_queue(&pxmitpriv->apsd_queue);
0072 _init_queue(&pxmitpriv->free_xmit_queue);
0073
0074
0075
0076
0077
0078 pxmitpriv->pallocated_frame_buf =
0079 kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4,
0080 GFP_ATOMIC);
0081 if (!pxmitpriv->pallocated_frame_buf) {
0082 pxmitpriv->pxmit_frame_buf = NULL;
0083 return -ENOMEM;
0084 }
0085 pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
0086 ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
0087 pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
0088 for (i = 0; i < NR_XMITFRAME; i++) {
0089 INIT_LIST_HEAD(&(pxframe->list));
0090 pxframe->padapter = padapter;
0091 pxframe->frame_tag = DATA_FRAMETAG;
0092 pxframe->pkt = NULL;
0093 pxframe->buf_addr = NULL;
0094 pxframe->pxmitbuf = NULL;
0095 list_add_tail(&(pxframe->list),
0096 &(pxmitpriv->free_xmit_queue.queue));
0097 pxframe++;
0098 }
0099 pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
0100
0101
0102
0103 _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
0104 _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
0105 _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
0106 _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
0107 _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
0108 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
0109 pxmitpriv->txirp_cnt = 1;
0110
0111 pxmitpriv->beq_cnt = 0;
0112 pxmitpriv->bkq_cnt = 0;
0113 pxmitpriv->viq_cnt = 0;
0114 pxmitpriv->voq_cnt = 0;
0115
0116 _init_queue(&pxmitpriv->free_xmitbuf_queue);
0117 _init_queue(&pxmitpriv->pending_xmitbuf_queue);
0118 pxmitpriv->pallocated_xmitbuf =
0119 kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
0120 if (!pxmitpriv->pallocated_xmitbuf) {
0121 kfree(pxmitpriv->pallocated_frame_buf);
0122 pxmitpriv->pallocated_frame_buf = NULL;
0123 return -ENOMEM;
0124 }
0125 pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
0126 ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
0127 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
0128 for (i = 0; i < NR_XMITBUFF; i++) {
0129 INIT_LIST_HEAD(&pxmitbuf->list);
0130 pxmitbuf->pallocated_buf =
0131 kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
0132 if (!pxmitbuf->pallocated_buf)
0133 return -ENOMEM;
0134 pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
0135 ((addr_t) (pxmitbuf->pallocated_buf) &
0136 (XMITBUF_ALIGN_SZ - 1));
0137 if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
0138 return -ENOMEM;
0139 list_add_tail(&pxmitbuf->list,
0140 &(pxmitpriv->free_xmitbuf_queue.queue));
0141 pxmitbuf++;
0142 }
0143 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
0144 INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter);
0145 alloc_hwxmits(padapter);
0146 init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
0147 tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
0148 return 0;
0149 }
0150
0151 void _free_xmit_priv(struct xmit_priv *pxmitpriv)
0152 {
0153 int i;
0154 struct _adapter *padapter = pxmitpriv->adapter;
0155 struct xmit_frame *pxmitframe = (struct xmit_frame *)
0156 pxmitpriv->pxmit_frame_buf;
0157 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
0158
0159 if (!pxmitpriv->pxmit_frame_buf)
0160 return;
0161 for (i = 0; i < NR_XMITFRAME; i++) {
0162 r8712_xmit_complete(padapter, pxmitframe);
0163 pxmitframe++;
0164 }
0165 for (i = 0; i < NR_XMITBUFF; i++) {
0166 r8712_xmit_resource_free(padapter, pxmitbuf);
0167 kfree(pxmitbuf->pallocated_buf);
0168 pxmitbuf++;
0169 }
0170 kfree(pxmitpriv->pallocated_frame_buf);
0171 kfree(pxmitpriv->pallocated_xmitbuf);
0172 free_hwxmits(padapter);
0173 }
0174
0175 int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
0176 struct pkt_attrib *pattrib)
0177 {
0178 struct pkt_file pktfile;
0179 struct sta_info *psta = NULL;
0180 struct ethhdr etherhdr;
0181
0182 struct tx_cmd txdesc;
0183
0184 bool bmcast;
0185 struct sta_priv *pstapriv = &padapter->stapriv;
0186 struct security_priv *psecuritypriv = &padapter->securitypriv;
0187 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0188 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
0189
0190 _r8712_open_pktfile(pkt, &pktfile);
0191
0192 _r8712_pktfile_read(&pktfile, (unsigned char *)ðerhdr, ETH_HLEN);
0193
0194 pattrib->ether_type = ntohs(etherhdr.h_proto);
0195
0196
0197
0198
0199
0200 if (pattrib->ether_type == 0x0806) {
0201 if (padapter->pwrctrlpriv.pwr_mode !=
0202 padapter->registrypriv.power_mgnt) {
0203 del_timer_sync(&pmlmepriv->dhcp_timer);
0204 r8712_set_ps_mode(padapter,
0205 padapter->registrypriv.power_mgnt,
0206 padapter->registrypriv.smart_ps);
0207 }
0208 }
0209
0210 memcpy(pattrib->dst, ðerhdr.h_dest, ETH_ALEN);
0211 memcpy(pattrib->src, ðerhdr.h_source, ETH_ALEN);
0212 pattrib->pctrl = 0;
0213 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
0214 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
0215 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
0216 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
0217 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
0218 memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
0219 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
0220 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
0221 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
0222 memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
0223 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
0224
0225 if (pattrib->ether_type != 0x8712)
0226 return -EINVAL;
0227
0228
0229
0230
0231 _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
0232 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
0233 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
0234 pattrib->pctrl = 1;
0235 }
0236
0237 pattrib->pktlen = pktfile.pkt_len;
0238 if (pattrib->ether_type == ETH_P_IP) {
0239
0240
0241
0242
0243 u8 tmp[24];
0244
0245 _r8712_pktfile_read(&pktfile, &tmp[0], 24);
0246 pattrib->dhcp_pkt = 0;
0247 if (pktfile.pkt_len > 282) {
0248 if (pattrib->ether_type == ETH_P_IP) {
0249 if (((tmp[21] == 68) && (tmp[23] == 67)) ||
0250 ((tmp[21] == 67) && (tmp[23] == 68))) {
0251
0252
0253
0254
0255 pattrib->dhcp_pkt = 1;
0256 }
0257 }
0258 }
0259 }
0260 bmcast = is_multicast_ether_addr(pattrib->ra);
0261
0262 if (bmcast) {
0263 psta = r8712_get_bcmc_stainfo(padapter);
0264 pattrib->mac_id = 4;
0265 } else {
0266 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
0267 psta = r8712_get_stainfo(pstapriv,
0268 get_bssid(pmlmepriv));
0269 pattrib->mac_id = 5;
0270 } else {
0271 psta = r8712_get_stainfo(pstapriv, pattrib->ra);
0272 if (!psta)
0273 return -ENOMEM;
0274 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
0275 pattrib->mac_id = 5;
0276 else
0277 pattrib->mac_id = psta->mac_id;
0278 }
0279 }
0280
0281 if (psta) {
0282 pattrib->psta = psta;
0283 } else {
0284
0285 return -ENOMEM;
0286 }
0287
0288 pattrib->ack_policy = 0;
0289
0290 pattrib->pkt_hdrlen = ETH_HLEN;
0291
0292 if (pqospriv->qos_option) {
0293 r8712_set_qos(&pktfile, pattrib);
0294 } else {
0295 pattrib->hdrlen = WLAN_HDR_A3_LEN;
0296 pattrib->subtype = IEEE80211_FTYPE_DATA;
0297 pattrib->priority = 0;
0298 }
0299 if (psta->ieee8021x_blocked) {
0300 pattrib->encrypt = 0;
0301 if ((pattrib->ether_type != 0x888e) &&
0302 !check_fwstate(pmlmepriv, WIFI_MP_STATE))
0303 return -EINVAL;
0304 } else {
0305 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
0306 }
0307 switch (pattrib->encrypt) {
0308 case _WEP40_:
0309 case _WEP104_:
0310 pattrib->iv_len = 4;
0311 pattrib->icv_len = 4;
0312 break;
0313 case _TKIP_:
0314 pattrib->iv_len = 8;
0315 pattrib->icv_len = 4;
0316 if (padapter->securitypriv.busetkipkey == _FAIL)
0317 return -EINVAL;
0318 break;
0319 case _AES_:
0320 pattrib->iv_len = 8;
0321 pattrib->icv_len = 8;
0322 break;
0323 default:
0324 pattrib->iv_len = 0;
0325 pattrib->icv_len = 0;
0326 break;
0327 }
0328
0329 if (pattrib->encrypt &&
0330 (padapter->securitypriv.sw_encrypt ||
0331 !psecuritypriv->hw_decrypted))
0332 pattrib->bswenc = true;
0333 else
0334 pattrib->bswenc = false;
0335
0336
0337
0338 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
0339 pattrib->priority =
0340 (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f;
0341 return 0;
0342 }
0343
0344 static int xmitframe_addmic(struct _adapter *padapter,
0345 struct xmit_frame *pxmitframe)
0346 {
0347 u32 curfragnum, length;
0348 u8 *pframe, *payload, mic[8];
0349 struct mic_data micdata;
0350 struct sta_info *stainfo;
0351 struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
0352 struct pkt_attrib *pattrib = &pxmitframe->attrib;
0353 struct security_priv *psecpriv = &padapter->securitypriv;
0354 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
0355 u8 priority[4] = {};
0356 bool bmcst = is_multicast_ether_addr(pattrib->ra);
0357
0358 if (pattrib->psta)
0359 stainfo = pattrib->psta;
0360 else
0361 stainfo = r8712_get_stainfo(&padapter->stapriv,
0362 &pattrib->ra[0]);
0363 if (pattrib->encrypt == _TKIP_) {
0364
0365 if (stainfo) {
0366 u8 null_key[16] = {};
0367
0368 pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
0369 if (bmcst) {
0370 if (!memcmp(psecpriv->XGrptxmickey
0371 [psecpriv->XGrpKeyid].skey,
0372 null_key, 16))
0373 return -ENOMEM;
0374
0375 r8712_secmicsetkey(&micdata,
0376 psecpriv->XGrptxmickey
0377 [psecpriv->XGrpKeyid].skey);
0378 } else {
0379 if (!memcmp(&stainfo->tkiptxmickey.skey[0],
0380 null_key, 16))
0381 return -ENOMEM;
0382
0383 r8712_secmicsetkey(&micdata,
0384 &stainfo->tkiptxmickey.skey[0]);
0385 }
0386 if (pframe[1] & 1) {
0387 r8712_secmicappend(&micdata,
0388 &pframe[16], 6);
0389 if (pframe[1] & 2)
0390 r8712_secmicappend(&micdata,
0391 &pframe[24], 6);
0392 else
0393 r8712_secmicappend(&micdata,
0394 &pframe[10], 6);
0395 } else {
0396 r8712_secmicappend(&micdata,
0397 &pframe[4], 6);
0398 if (pframe[1] & 2)
0399 r8712_secmicappend(&micdata,
0400 &pframe[16], 6);
0401 else
0402 r8712_secmicappend(&micdata,
0403 &pframe[10], 6);
0404 }
0405 if (pqospriv->qos_option == 1)
0406 priority[0] = (u8)pxmitframe->attrib.priority;
0407 r8712_secmicappend(&micdata, &priority[0], 4);
0408 payload = pframe;
0409 for (curfragnum = 0; curfragnum < pattrib->nr_frags;
0410 curfragnum++) {
0411 payload = (u8 *)RND4((addr_t)(payload));
0412 payload += pattrib->hdrlen + pattrib->iv_len;
0413 if ((curfragnum + 1) == pattrib->nr_frags) {
0414 length = pattrib->last_txcmdsz -
0415 pattrib->hdrlen -
0416 pattrib->iv_len -
0417 ((psecpriv->sw_encrypt)
0418 ? pattrib->icv_len : 0);
0419 r8712_secmicappend(&micdata, payload,
0420 length);
0421 payload = payload + length;
0422 } else {
0423 length = pxmitpriv->frag_len -
0424 pattrib->hdrlen - pattrib->iv_len -
0425 ((psecpriv->sw_encrypt) ?
0426 pattrib->icv_len : 0);
0427 r8712_secmicappend(&micdata, payload,
0428 length);
0429 payload = payload + length +
0430 pattrib->icv_len;
0431 }
0432 }
0433 r8712_secgetmic(&micdata, &(mic[0]));
0434
0435
0436
0437 memcpy(payload, &(mic[0]), 8);
0438 pattrib->last_txcmdsz += 8;
0439 payload = payload - pattrib->last_txcmdsz + 8;
0440 }
0441 }
0442 return 0;
0443 }
0444
0445 static sint xmitframe_swencrypt(struct _adapter *padapter,
0446 struct xmit_frame *pxmitframe)
0447 {
0448 struct pkt_attrib *pattrib = &pxmitframe->attrib;
0449
0450 if (pattrib->bswenc) {
0451 switch (pattrib->encrypt) {
0452 case _WEP40_:
0453 case _WEP104_:
0454 r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
0455 break;
0456 case _TKIP_:
0457 r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
0458 break;
0459 case _AES_:
0460 r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
0461 break;
0462 default:
0463 break;
0464 }
0465 }
0466 return _SUCCESS;
0467 }
0468
0469 static int make_wlanhdr(struct _adapter *padapter, u8 *hdr,
0470 struct pkt_attrib *pattrib)
0471 {
0472 u16 *qc;
0473
0474 struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
0475 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0476 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
0477 __le16 *fctrl = &pwlanhdr->frame_control;
0478 u8 *bssid;
0479
0480 memset(hdr, 0, WLANHDR_OFFSET);
0481 SetFrameSubType(fctrl, pattrib->subtype);
0482 if (!(pattrib->subtype & IEEE80211_FTYPE_DATA))
0483 return 0;
0484
0485 bssid = get_bssid(pmlmepriv);
0486
0487 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
0488
0489 SetToDs(fctrl);
0490 ether_addr_copy(pwlanhdr->addr1, bssid);
0491 ether_addr_copy(pwlanhdr->addr2, pattrib->src);
0492 ether_addr_copy(pwlanhdr->addr3, pattrib->dst);
0493 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
0494
0495 SetFrDs(fctrl);
0496 ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
0497 ether_addr_copy(pwlanhdr->addr2, bssid);
0498 ether_addr_copy(pwlanhdr->addr3, pattrib->src);
0499 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
0500 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
0501 ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
0502 ether_addr_copy(pwlanhdr->addr2, pattrib->src);
0503 ether_addr_copy(pwlanhdr->addr3, bssid);
0504 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
0505 ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
0506 ether_addr_copy(pwlanhdr->addr2, pattrib->src);
0507 ether_addr_copy(pwlanhdr->addr3, bssid);
0508 } else {
0509 return -EINVAL;
0510 }
0511
0512 if (pattrib->encrypt)
0513 SetPrivacy(fctrl);
0514 if (pqospriv->qos_option) {
0515 qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
0516 if (pattrib->priority)
0517 SetPriority(qc, pattrib->priority);
0518 SetAckpolicy(qc, pattrib->ack_policy);
0519 }
0520
0521
0522 {
0523 struct sta_info *psta;
0524 bool bmcst = is_multicast_ether_addr(pattrib->ra);
0525
0526 if (pattrib->psta)
0527 psta = pattrib->psta;
0528 else if (bmcst)
0529 psta = r8712_get_bcmc_stainfo(padapter);
0530 else
0531 psta = r8712_get_stainfo(&padapter->stapriv,
0532 pattrib->ra);
0533
0534 if (psta) {
0535 u16 *txtid = psta->sta_xmitpriv.txseq_tid;
0536
0537 txtid[pattrib->priority]++;
0538 txtid[pattrib->priority] &= 0xFFF;
0539 pattrib->seqnum = txtid[pattrib->priority];
0540 SetSeqNum(hdr, pattrib->seqnum);
0541 }
0542 }
0543
0544 return 0;
0545 }
0546
0547 static sint r8712_put_snap(u8 *data, u16 h_proto)
0548 {
0549 struct ieee80211_snap_hdr *snap;
0550 const u8 *oui;
0551
0552 snap = (struct ieee80211_snap_hdr *)data;
0553 snap->dsap = 0xaa;
0554 snap->ssap = 0xaa;
0555 snap->ctrl = 0x03;
0556 if (h_proto == 0x8137 || h_proto == 0x80f3)
0557 oui = P802_1H_OUI;
0558 else
0559 oui = RFC1042_OUI;
0560 snap->oui[0] = oui[0];
0561 snap->oui[1] = oui[1];
0562 snap->oui[2] = oui[2];
0563 *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
0564 return SNAP_SIZE + sizeof(u16);
0565 }
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576 sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
0577 struct xmit_frame *pxmitframe)
0578 {
0579 struct pkt_file pktfile;
0580
0581 sint frg_len, mpdu_len, llc_sz;
0582 u32 mem_sz;
0583 u8 frg_inx;
0584 addr_t addr;
0585 u8 *pframe, *mem_start, *ptxdesc;
0586 struct sta_info *psta;
0587 struct security_priv *psecpriv = &padapter->securitypriv;
0588 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0589 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
0590 struct pkt_attrib *pattrib = &pxmitframe->attrib;
0591 u8 *pbuf_start;
0592 bool bmcst = is_multicast_ether_addr(pattrib->ra);
0593
0594 if (!pattrib->psta)
0595 return _FAIL;
0596 psta = pattrib->psta;
0597 if (!pxmitframe->buf_addr)
0598 return _FAIL;
0599 pbuf_start = pxmitframe->buf_addr;
0600 ptxdesc = pbuf_start;
0601 mem_start = pbuf_start + TXDESC_OFFSET;
0602 if (make_wlanhdr(padapter, mem_start, pattrib))
0603 return _FAIL;
0604 _r8712_open_pktfile(pkt, &pktfile);
0605 _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
0606 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
0607
0608 if (pattrib->ether_type == 0x8712) {
0609
0610 _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
0611 }
0612 }
0613 pattrib->pktlen = pktfile.pkt_len;
0614 frg_inx = 0;
0615 frg_len = pxmitpriv->frag_len - 4;
0616 while (1) {
0617 llc_sz = 0;
0618 mpdu_len = frg_len;
0619 pframe = mem_start;
0620 SetMFrag(mem_start);
0621 pframe += pattrib->hdrlen;
0622 mpdu_len -= pattrib->hdrlen;
0623
0624 if (pattrib->iv_len) {
0625 if (psta) {
0626 switch (pattrib->encrypt) {
0627 case _WEP40_:
0628 case _WEP104_:
0629 WEP_IV(pattrib->iv, psta->txpn,
0630 (u8)psecpriv->PrivacyKeyIndex);
0631 break;
0632 case _TKIP_:
0633 if (bmcst)
0634 TKIP_IV(pattrib->iv,
0635 psta->txpn,
0636 (u8)psecpriv->XGrpKeyid);
0637 else
0638 TKIP_IV(pattrib->iv, psta->txpn,
0639 0);
0640 break;
0641 case _AES_:
0642 if (bmcst)
0643 AES_IV(pattrib->iv, psta->txpn,
0644 (u8)psecpriv->XGrpKeyid);
0645 else
0646 AES_IV(pattrib->iv, psta->txpn,
0647 0);
0648 break;
0649 }
0650 }
0651 memcpy(pframe, pattrib->iv, pattrib->iv_len);
0652 pframe += pattrib->iv_len;
0653 mpdu_len -= pattrib->iv_len;
0654 }
0655 if (frg_inx == 0) {
0656 llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
0657 pframe += llc_sz;
0658 mpdu_len -= llc_sz;
0659 }
0660 if ((pattrib->icv_len > 0) && (pattrib->bswenc))
0661 mpdu_len -= pattrib->icv_len;
0662 if (bmcst)
0663 mem_sz = _r8712_pktfile_read(&pktfile, pframe,
0664 pattrib->pktlen);
0665 else
0666 mem_sz = _r8712_pktfile_read(&pktfile, pframe,
0667 mpdu_len);
0668 pframe += mem_sz;
0669 if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
0670 memcpy(pframe, pattrib->icv, pattrib->icv_len);
0671 pframe += pattrib->icv_len;
0672 }
0673 frg_inx++;
0674 if (bmcst || r8712_endofpktfile(&pktfile)) {
0675 pattrib->nr_frags = frg_inx;
0676 pattrib->last_txcmdsz = pattrib->hdrlen +
0677 pattrib->iv_len +
0678 ((pattrib->nr_frags == 1) ?
0679 llc_sz : 0) +
0680 ((pattrib->bswenc) ?
0681 pattrib->icv_len : 0) + mem_sz;
0682 ClearMFrag(mem_start);
0683 break;
0684 }
0685 addr = (addr_t)(pframe);
0686 mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
0687 memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
0688 }
0689
0690 if (xmitframe_addmic(padapter, pxmitframe))
0691 return _FAIL;
0692 xmitframe_swencrypt(padapter, pxmitframe);
0693 return _SUCCESS;
0694 }
0695
0696 void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
0697 {
0698 uint protection;
0699 u8 *perp;
0700 uint erp_len;
0701 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
0702 struct registry_priv *pregistrypriv = &padapter->registrypriv;
0703
0704 switch (pxmitpriv->vcs_setting) {
0705 case DISABLE_VCS:
0706 pxmitpriv->vcs = NONE_VCS;
0707 break;
0708 case ENABLE_VCS:
0709 break;
0710 case AUTO_VCS:
0711 default:
0712 perp = r8712_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len);
0713 if (!perp) {
0714 pxmitpriv->vcs = NONE_VCS;
0715 } else {
0716 protection = (*(perp + 2)) & BIT(1);
0717 if (protection) {
0718 if (pregistrypriv->vcs_type == RTS_CTS)
0719 pxmitpriv->vcs = RTS_CTS;
0720 else
0721 pxmitpriv->vcs = CTS_TO_SELF;
0722 } else {
0723 pxmitpriv->vcs = NONE_VCS;
0724 }
0725 }
0726 break;
0727 }
0728 }
0729
0730 struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
0731 {
0732 unsigned long irqL;
0733 struct xmit_buf *pxmitbuf;
0734 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
0735
0736 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
0737 pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
0738 struct xmit_buf, list);
0739 if (pxmitbuf) {
0740 list_del_init(&pxmitbuf->list);
0741 pxmitpriv->free_xmitbuf_cnt--;
0742 }
0743 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
0744 return pxmitbuf;
0745 }
0746
0747 void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
0748 {
0749 unsigned long irqL;
0750 struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
0751
0752 if (!pxmitbuf)
0753 return;
0754 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
0755 list_del_init(&pxmitbuf->list);
0756 list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
0757 pxmitpriv->free_xmitbuf_cnt++;
0758 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
0759 }
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772 struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
0773 {
0774
0775
0776
0777
0778
0779 unsigned long irqL;
0780 struct xmit_frame *pxframe;
0781 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
0782
0783 spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
0784 pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
0785 struct xmit_frame, list);
0786 if (pxframe) {
0787 list_del_init(&pxframe->list);
0788 pxmitpriv->free_xmitframe_cnt--;
0789 pxframe->buf_addr = NULL;
0790 pxframe->pxmitbuf = NULL;
0791 pxframe->attrib.psta = NULL;
0792 pxframe->pkt = NULL;
0793 }
0794 spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
0795 return pxframe;
0796 }
0797
0798 void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
0799 struct xmit_frame *pxmitframe)
0800 {
0801 unsigned long irqL;
0802 struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
0803 struct _adapter *padapter = pxmitpriv->adapter;
0804
0805 if (!pxmitframe)
0806 return;
0807 spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
0808 list_del_init(&pxmitframe->list);
0809 if (pxmitframe->pkt)
0810 pxmitframe->pkt = NULL;
0811 list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
0812 pxmitpriv->free_xmitframe_cnt++;
0813 spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
0814 if (netif_queue_stopped(padapter->pnetdev))
0815 netif_wake_queue(padapter->pnetdev);
0816 }
0817
0818 void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
0819 struct xmit_frame *pxmitframe)
0820 {
0821 if (!pxmitframe)
0822 return;
0823 if (pxmitframe->frame_tag == DATA_FRAMETAG)
0824 r8712_free_xmitframe(pxmitpriv, pxmitframe);
0825 }
0826
0827 void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
0828 struct __queue *pframequeue)
0829 {
0830 unsigned long irqL;
0831 struct list_head *plist, *phead;
0832 struct xmit_frame *pxmitframe;
0833
0834 spin_lock_irqsave(&(pframequeue->lock), irqL);
0835 phead = &pframequeue->queue;
0836 plist = phead->next;
0837 while (!end_of_queue_search(phead, plist)) {
0838 pxmitframe = container_of(plist, struct xmit_frame, list);
0839 plist = plist->next;
0840 r8712_free_xmitframe(pxmitpriv, pxmitframe);
0841 }
0842 spin_unlock_irqrestore(&(pframequeue->lock), irqL);
0843 }
0844
0845 static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
0846 struct __queue **ppstapending,
0847 struct sta_info *psta, sint up)
0848 {
0849 struct tx_servq *ptxservq;
0850 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
0851
0852 switch (up) {
0853 case 1:
0854 case 2:
0855 ptxservq = &(psta->sta_xmitpriv.bk_q);
0856 *ppstapending = &padapter->xmitpriv.bk_pending;
0857 (phwxmits + 3)->accnt++;
0858 break;
0859 case 4:
0860 case 5:
0861 ptxservq = &(psta->sta_xmitpriv.vi_q);
0862 *ppstapending = &padapter->xmitpriv.vi_pending;
0863 (phwxmits + 1)->accnt++;
0864 break;
0865 case 6:
0866 case 7:
0867 ptxservq = &(psta->sta_xmitpriv.vo_q);
0868 *ppstapending = &padapter->xmitpriv.vo_pending;
0869 (phwxmits + 0)->accnt++;
0870 break;
0871 case 0:
0872 case 3:
0873 default:
0874 ptxservq = &(psta->sta_xmitpriv.be_q);
0875 *ppstapending = &padapter->xmitpriv.be_pending;
0876 (phwxmits + 2)->accnt++;
0877 break;
0878 }
0879 return ptxservq;
0880 }
0881
0882
0883
0884
0885
0886 int r8712_xmit_classifier(struct _adapter *padapter,
0887 struct xmit_frame *pxmitframe)
0888 {
0889 unsigned long irqL0;
0890 struct __queue *pstapending;
0891 struct sta_info *psta;
0892 struct tx_servq *ptxservq;
0893 struct pkt_attrib *pattrib = &pxmitframe->attrib;
0894 struct sta_priv *pstapriv = &padapter->stapriv;
0895 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0896 bool bmcst = is_multicast_ether_addr(pattrib->ra);
0897
0898 if (pattrib->psta) {
0899 psta = pattrib->psta;
0900 } else {
0901 if (bmcst) {
0902 psta = r8712_get_bcmc_stainfo(padapter);
0903 } else {
0904 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
0905 psta = r8712_get_stainfo(pstapriv,
0906 get_bssid(pmlmepriv));
0907 else
0908 psta = r8712_get_stainfo(pstapriv, pattrib->ra);
0909 }
0910 }
0911 if (!psta)
0912 return -EINVAL;
0913 ptxservq = get_sta_pending(padapter, &pstapending,
0914 psta, pattrib->priority);
0915 spin_lock_irqsave(&pstapending->lock, irqL0);
0916 if (list_empty(&ptxservq->tx_pending))
0917 list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
0918 list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
0919 ptxservq->qcnt++;
0920 spin_unlock_irqrestore(&pstapending->lock, irqL0);
0921 return 0;
0922 }
0923
0924 static void alloc_hwxmits(struct _adapter *padapter)
0925 {
0926 struct hw_xmit *hwxmits;
0927 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
0928
0929 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
0930 pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry,
0931 sizeof(struct hw_xmit), GFP_ATOMIC);
0932 if (!pxmitpriv->hwxmits)
0933 return;
0934 hwxmits = pxmitpriv->hwxmits;
0935 if (pxmitpriv->hwxmit_entry == 5) {
0936 pxmitpriv->bmc_txqueue.head = 0;
0937 hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
0938 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
0939 pxmitpriv->vo_txqueue.head = 0;
0940 hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
0941 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
0942 pxmitpriv->vi_txqueue.head = 0;
0943 hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
0944 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
0945 pxmitpriv->bk_txqueue.head = 0;
0946 hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
0947 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
0948 pxmitpriv->be_txqueue.head = 0;
0949 hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
0950 hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
0951 } else if (pxmitpriv->hwxmit_entry == 4) {
0952 pxmitpriv->vo_txqueue.head = 0;
0953 hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
0954 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
0955 pxmitpriv->vi_txqueue.head = 0;
0956 hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
0957 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
0958 pxmitpriv->be_txqueue.head = 0;
0959 hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
0960 hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
0961 pxmitpriv->bk_txqueue.head = 0;
0962 hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
0963 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
0964 }
0965 }
0966
0967 static void free_hwxmits(struct _adapter *padapter)
0968 {
0969 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
0970
0971 kfree(pxmitpriv->hwxmits);
0972 }
0973
0974 static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
0975 {
0976 sint i;
0977
0978 for (i = 0; i < entry; i++, phwxmit++) {
0979 spin_lock_init(&phwxmit->xmit_lock);
0980 INIT_LIST_HEAD(&phwxmit->pending);
0981 phwxmit->txcmdcnt = 0;
0982 phwxmit->accnt = 0;
0983 }
0984 }
0985
0986 void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
0987 struct xmit_buf *pxmitbuf)
0988 {
0989
0990 pxmitframe->pxmitbuf = pxmitbuf;
0991
0992 pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
0993
0994 pxmitframe->buf_addr = pxmitbuf->pbuf;
0995
0996 pxmitbuf->priv_data = pxmitframe;
0997 }
0998
0999
1000
1001
1002
1003
1004
1005
1006 int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
1007 {
1008 unsigned long irqL;
1009 int ret;
1010 struct xmit_buf *pxmitbuf = NULL;
1011 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1012 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1013
1014 r8712_do_queue_select(padapter, pattrib);
1015 spin_lock_irqsave(&pxmitpriv->lock, irqL);
1016 if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1017 ret = false;
1018 r8712_xmit_enqueue(padapter, pxmitframe);
1019 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1020 return ret;
1021 }
1022 pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
1023 if (!pxmitbuf) {
1024 ret = false;
1025 r8712_xmit_enqueue(padapter, pxmitframe);
1026 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1027 } else {
1028 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1029 ret = true;
1030 xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
1031 r8712_xmit_direct(padapter, pxmitframe);
1032 }
1033 return ret;
1034 }