rtw_xmit.c revision f2f97035f08a5ea1f0c23e65f6ea9cd2f3cd2586
1/****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 ******************************************************************************/ 15#define _RTW_XMIT_C_ 16 17#include <osdep_service.h> 18#include <drv_types.h> 19#include <wifi.h> 20#include <osdep_intf.h> 21#include <linux/ip.h> 22#include <usb_ops.h> 23#include <rtl8723a_xmit.h> 24 25static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; 26static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; 27 28static void _init_txservq(struct tx_servq *ptxservq) 29{ 30 31 INIT_LIST_HEAD(&ptxservq->tx_pending); 32 _rtw_init_queue23a(&ptxservq->sta_pending); 33 ptxservq->qcnt = 0; 34 35} 36 37void _rtw_init_sta_xmit_priv23a(struct sta_xmit_priv *psta_xmitpriv) 38{ 39 40 spin_lock_init(&psta_xmitpriv->lock); 41 42 /* for (i = 0 ; i < MAX_NUMBLKS; i++) */ 43 /* _init_txservq(&psta_xmitpriv->blk_q[i]); */ 44 45 _init_txservq(&psta_xmitpriv->be_q); 46 _init_txservq(&psta_xmitpriv->bk_q); 47 _init_txservq(&psta_xmitpriv->vi_q); 48 _init_txservq(&psta_xmitpriv->vo_q); 49 INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz); 50 INIT_LIST_HEAD(&psta_xmitpriv->apsd); 51 52} 53 54int _rtw_init_xmit_priv23a(struct xmit_priv *pxmitpriv, 55 struct rtw_adapter *padapter) 56{ 57 int i; 58 struct xmit_buf *pxmitbuf; 59 struct xmit_frame *pxframe; 60 int res = _SUCCESS; 61 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ; 62 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF; 63 64 spin_lock_init(&pxmitpriv->lock); 65 spin_lock_init(&pxmitpriv->lock_sctx); 66 sema_init(&pxmitpriv->xmit_sema, 0); 67 sema_init(&pxmitpriv->terminate_xmitthread_sema, 0); 68 69 pxmitpriv->adapter = padapter; 70 71 _rtw_init_queue23a(&pxmitpriv->be_pending); 72 _rtw_init_queue23a(&pxmitpriv->bk_pending); 73 _rtw_init_queue23a(&pxmitpriv->vi_pending); 74 _rtw_init_queue23a(&pxmitpriv->vo_pending); 75 _rtw_init_queue23a(&pxmitpriv->bm_pending); 76 77 _rtw_init_queue23a(&pxmitpriv->free_xmit_queue); 78 79 for (i = 0; i < NR_XMITFRAME; i++) { 80 pxframe = (struct xmit_frame *) 81 kzalloc(sizeof(struct xmit_frame), GFP_KERNEL); 82 if (!pxframe) 83 break; 84 INIT_LIST_HEAD(&pxframe->list); 85 86 pxframe->padapter = padapter; 87 pxframe->frame_tag = NULL_FRAMETAG; 88 89 list_add_tail(&pxframe->list, 90 &pxmitpriv->free_xmit_queue.queue); 91 } 92 93 pxmitpriv->free_xmitframe_cnt = i; 94 95 pxmitpriv->frag_len = MAX_FRAG_THRESHOLD; 96 97 /* init xmit_buf */ 98 _rtw_init_queue23a(&pxmitpriv->free_xmitbuf_queue); 99 INIT_LIST_HEAD(&pxmitpriv->xmitbuf_list); 100 _rtw_init_queue23a(&pxmitpriv->pending_xmitbuf_queue); 101 102 for (i = 0; i < NR_XMITBUFF; i++) { 103 pxmitbuf = kzalloc(sizeof(struct xmit_buf), GFP_KERNEL); 104 if (!pxmitbuf) 105 goto fail; 106 INIT_LIST_HEAD(&pxmitbuf->list); 107 INIT_LIST_HEAD(&pxmitbuf->list2); 108 109 pxmitbuf->padapter = padapter; 110 111 /* Tx buf allocation may fail sometimes, so sleep and retry. */ 112 res = rtw_os_xmit_resource_alloc23a(padapter, pxmitbuf, 113 (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); 114 if (res == _FAIL) { 115 goto fail; 116 } 117 118 list_add_tail(&pxmitbuf->list, 119 &pxmitpriv->free_xmitbuf_queue.queue); 120 list_add_tail(&pxmitbuf->list2, 121 &pxmitpriv->xmitbuf_list); 122 } 123 124 pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF; 125 126 /* init xframe_ext queue, the same count as extbuf */ 127 _rtw_init_queue23a(&pxmitpriv->free_xframe_ext_queue); 128 129 for (i = 0; i < num_xmit_extbuf; i++) { 130 pxframe = (struct xmit_frame *) 131 kzalloc(sizeof(struct xmit_frame), GFP_KERNEL); 132 if (!pxframe) 133 break; 134 INIT_LIST_HEAD(&pxframe->list); 135 136 pxframe->padapter = padapter; 137 pxframe->frame_tag = NULL_FRAMETAG; 138 139 pxframe->pkt = NULL; 140 141 pxframe->buf_addr = NULL; 142 pxframe->pxmitbuf = NULL; 143 144 pxframe->ext_tag = 1; 145 146 list_add_tail(&pxframe->list, 147 &pxmitpriv->free_xframe_ext_queue.queue); 148 } 149 pxmitpriv->free_xframe_ext_cnt = i; 150 151 /* Init xmit extension buff */ 152 _rtw_init_queue23a(&pxmitpriv->free_xmit_extbuf_queue); 153 INIT_LIST_HEAD(&pxmitpriv->xmitextbuf_list); 154 155 for (i = 0; i < num_xmit_extbuf; i++) { 156 pxmitbuf = kzalloc(sizeof(struct xmit_buf), GFP_KERNEL); 157 if (!pxmitbuf) 158 goto fail; 159 INIT_LIST_HEAD(&pxmitbuf->list); 160 INIT_LIST_HEAD(&pxmitbuf->list2); 161 162 pxmitbuf->padapter = padapter; 163 164 /* Tx buf allocation may fail sometimes, so sleep and retry. */ 165 res = rtw_os_xmit_resource_alloc23a(padapter, pxmitbuf, 166 max_xmit_extbuf_size + XMITBUF_ALIGN_SZ); 167 if (res == _FAIL) { 168 goto exit; 169 } 170 171 list_add_tail(&pxmitbuf->list, 172 &pxmitpriv->free_xmit_extbuf_queue.queue); 173 list_add_tail(&pxmitbuf->list2, 174 &pxmitpriv->xmitextbuf_list); 175 } 176 177 pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; 178 179 rtw_alloc_hwxmits23a(padapter); 180 rtw_init_hwxmits23a(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); 181 182 for (i = 0; i < 4; i ++) 183 pxmitpriv->wmm_para_seq[i] = i; 184 185 pxmitpriv->txirp_cnt = 1; 186 187 sema_init(&pxmitpriv->tx_retevt, 0); 188 189 /* per AC pending irp */ 190 pxmitpriv->beq_cnt = 0; 191 pxmitpriv->bkq_cnt = 0; 192 pxmitpriv->viq_cnt = 0; 193 pxmitpriv->voq_cnt = 0; 194 195 pxmitpriv->ack_tx = false; 196 mutex_init(&pxmitpriv->ack_tx_mutex); 197 rtw_sctx_init23a(&pxmitpriv->ack_tx_ops, 0); 198 tasklet_init(&padapter->xmitpriv.xmit_tasklet, 199 (void(*)(unsigned long))rtl8723au_xmit_tasklet, 200 (unsigned long)padapter); 201 202exit: 203 204 return res; 205fail: 206 goto exit; 207} 208 209void _rtw_free_xmit_priv23a (struct xmit_priv *pxmitpriv) 210{ 211 struct rtw_adapter *padapter = pxmitpriv->adapter; 212 struct xmit_frame *pxframe; 213 struct xmit_buf *pxmitbuf; 214 struct list_head *plist, *ptmp; 215 216 list_for_each_safe(plist, ptmp, &pxmitpriv->free_xmit_queue.queue) { 217 pxframe = container_of(plist, struct xmit_frame, list); 218 list_del_init(&pxframe->list); 219 rtw_os_xmit_complete23a(padapter, pxframe); 220 kfree(pxframe); 221 } 222 223 list_for_each_safe(plist, ptmp, &pxmitpriv->xmitbuf_list) { 224 pxmitbuf = container_of(plist, struct xmit_buf, list2); 225 list_del_init(&pxmitbuf->list2); 226 rtw_os_xmit_resource_free23a(padapter, pxmitbuf); 227 kfree(pxmitbuf); 228 } 229 230 /* free xframe_ext queue, the same count as extbuf */ 231 list_for_each_safe(plist, ptmp, 232 &pxmitpriv->free_xframe_ext_queue.queue) { 233 pxframe = container_of(plist, struct xmit_frame, list); 234 list_del_init(&pxframe->list); 235 rtw_os_xmit_complete23a(padapter, pxframe); 236 kfree(pxframe); 237 } 238 239 /* free xmit extension buff */ 240 list_for_each_safe(plist, ptmp, &pxmitpriv->xmitextbuf_list) { 241 pxmitbuf = container_of(plist, struct xmit_buf, list2); 242 list_del_init(&pxmitbuf->list2); 243 rtw_os_xmit_resource_free23a(padapter, pxmitbuf); 244 kfree(pxmitbuf); 245 } 246 247 rtw_free_hwxmits23a(padapter); 248 mutex_destroy(&pxmitpriv->ack_tx_mutex); 249} 250 251static void update_attrib_vcs_info(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) 252{ 253 u32 sz; 254 struct pkt_attrib *pattrib = &pxmitframe->attrib; 255 struct sta_info *psta = pattrib->psta; 256 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 257 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 258 259 if (pattrib->psta) { 260 psta = pattrib->psta; 261 } else { 262 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 263 psta = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]); 264 } 265 266 if (psta == NULL) { 267 DBG_8723A("%s, psta == NUL\n", __func__); 268 return; 269 } 270 271 if (!(psta->state &_FW_LINKED)) { 272 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); 273 return; 274 } 275 276 if (pattrib->nr_frags != 1) 277 sz = padapter->xmitpriv.frag_len; 278 else /* no frag */ 279 sz = pattrib->last_txcmdsz; 280 281 /* (1) RTS_Threshold is compared to the MPDU, not MSDU. */ 282 /* (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. */ 283 /* Other fragments are protected by previous fragment. */ 284 /* So we only need to check the length of first fragment. */ 285 if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N || padapter->registrypriv.wifi_spec) { 286 if (sz > padapter->registrypriv.rts_thresh) { 287 pattrib->vcs_mode = RTS_CTS; 288 } else { 289 if (psta->rtsen) 290 pattrib->vcs_mode = RTS_CTS; 291 else if (psta->cts2self) 292 pattrib->vcs_mode = CTS_TO_SELF; 293 else 294 pattrib->vcs_mode = NONE_VCS; 295 } 296 } else { 297 while (true) { 298 /* IOT action */ 299 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS && 300 pattrib->ampdu_en && 301 padapter->securitypriv.dot11PrivacyAlgrthm == 302 WLAN_CIPHER_SUITE_CCMP) { 303 pattrib->vcs_mode = CTS_TO_SELF; 304 break; 305 } 306 307 /* check ERP protection */ 308 if (psta->rtsen || psta->cts2self) { 309 if (psta->rtsen) 310 pattrib->vcs_mode = RTS_CTS; 311 else if (psta->cts2self) 312 pattrib->vcs_mode = CTS_TO_SELF; 313 314 break; 315 } 316 317 /* check HT op mode */ 318 if (pattrib->ht_en) { 319 u8 HTOpMode = pmlmeinfo->HT_protection; 320 if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) || 321 (!pmlmeext->cur_bwmode && HTOpMode == 3)) { 322 pattrib->vcs_mode = RTS_CTS; 323 break; 324 } 325 } 326 327 /* check rts */ 328 if (sz > padapter->registrypriv.rts_thresh) { 329 pattrib->vcs_mode = RTS_CTS; 330 break; 331 } 332 333 /* to do list: check MIMO power save condition. */ 334 335 /* check AMPDU aggregation for TXOP */ 336 if (pattrib->ampdu_en) { 337 pattrib->vcs_mode = RTS_CTS; 338 break; 339 } 340 341 pattrib->vcs_mode = NONE_VCS; 342 break; 343 } 344 } 345} 346 347static void update_attrib_phy_info(struct pkt_attrib *pattrib, struct sta_info *psta) 348{ 349 /*if (psta->rtsen) 350 pattrib->vcs_mode = RTS_CTS; 351 else if (psta->cts2self) 352 pattrib->vcs_mode = CTS_TO_SELF; 353 else 354 pattrib->vcs_mode = NONE_VCS;*/ 355 356 pattrib->mdata = 0; 357 pattrib->eosp = 0; 358 pattrib->triggered = 0; 359 360 /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */ 361 pattrib->qos_en = psta->qos_option; 362 363 pattrib->raid = psta->raid; 364 pattrib->ht_en = psta->htpriv.ht_option; 365 pattrib->bwmode = psta->htpriv.bwmode; 366 pattrib->ch_offset = psta->htpriv.ch_offset; 367 pattrib->sgi = psta->htpriv.sgi; 368 pattrib->ampdu_en = false; 369 370 pattrib->retry_ctrl = false; 371} 372 373u8 qos_acm23a(u8 acm_mask, u8 priority) 374{ 375 u8 change_priority = priority; 376 377 switch (priority) { 378 case 0: 379 case 3: 380 if (acm_mask & BIT(1)) 381 change_priority = 1; 382 break; 383 case 1: 384 case 2: 385 break; 386 case 4: 387 case 5: 388 if (acm_mask & BIT(2)) 389 change_priority = 0; 390 break; 391 case 6: 392 case 7: 393 if (acm_mask & BIT(3)) 394 change_priority = 5; 395 break; 396 default: 397 DBG_8723A("qos_acm23a(): invalid pattrib->priority: %d!!!\n", 398 priority); 399 change_priority = 0; 400 break; 401 } 402 403 return change_priority; 404} 405 406static void set_qos(struct sk_buff *skb, struct pkt_attrib *pattrib) 407{ 408 u8 *pframe = skb->data; 409 struct iphdr *ip_hdr; 410 u8 UserPriority = 0; 411 412 /* get UserPriority from IP hdr */ 413 if (pattrib->ether_type == ETH_P_IP) { 414 ip_hdr = (struct iphdr *)(pframe + ETH_HLEN); 415 UserPriority = ip_hdr->tos >> 5; 416 } else if (pattrib->ether_type == ETH_P_PAE) { 417 /* "When priority processing of data frames is supported, */ 418 /* a STA's SME should send EAPOL-Key frames at the highest 419 priority." */ 420 UserPriority = 7; 421 } 422 423 pattrib->priority = UserPriority; 424 pattrib->hdrlen = sizeof(struct ieee80211_qos_hdr); 425 pattrib->type = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA; 426} 427 428static int update_attrib(struct rtw_adapter *padapter, 429 struct sk_buff *skb, struct pkt_attrib *pattrib) 430{ 431 struct sta_info *psta = NULL; 432 int bmcast; 433 struct sta_priv *pstapriv = &padapter->stapriv; 434 struct security_priv *psecuritypriv = &padapter->securitypriv; 435 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 436 int res = _SUCCESS; 437 struct ethhdr *ehdr = (struct ethhdr *) skb->data; 438 439 pattrib->ether_type = ntohs(ehdr->h_proto); 440 441 ether_addr_copy(pattrib->dst, ehdr->h_dest); 442 ether_addr_copy(pattrib->src, ehdr->h_source); 443 444 pattrib->pctrl = 0; 445 446 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || 447 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 448 ether_addr_copy(pattrib->ra, pattrib->dst); 449 ether_addr_copy(pattrib->ta, pattrib->src); 450 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 451 ether_addr_copy(pattrib->ra, get_bssid(pmlmepriv)); 452 ether_addr_copy(pattrib->ta, pattrib->src); 453 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 454 ether_addr_copy(pattrib->ra, pattrib->dst); 455 ether_addr_copy(pattrib->ta, get_bssid(pmlmepriv)); 456 } 457 458 pattrib->pktlen = skb->len - ETH_HLEN; 459 460 if (pattrib->ether_type == ETH_P_IP) { 461 /* The following is for DHCP and ARP packet, we use cck1M 462 to tx these packets and let LPS awake some time */ 463 /* to prevent DHCP protocol fail */ 464 pattrib->dhcp_pkt = 0; 465 /* MINIMUM_DHCP_PACKET_SIZE) { */ 466 if (pattrib->pktlen > 282 + 24) { 467 if (pattrib->ether_type == ETH_P_IP) {/* IP header */ 468 u8 *pframe = skb->data; 469 pframe += ETH_HLEN; 470 471 if ((pframe[21] == 68 && pframe[23] == 67) || 472 (pframe[21] == 67 && pframe[23] == 68)) { 473 /* 68 : UDP BOOTP client */ 474 /* 67 : UDP BOOTP server */ 475 RT_TRACE(_module_rtl871x_xmit_c_, 476 _drv_err_, 477 ("======================" 478 "update_attrib: get DHCP " 479 "Packet\n")); 480 pattrib->dhcp_pkt = 1; 481 } 482 } 483 } 484 } else if (pattrib->ether_type == ETH_P_PAE) { 485 DBG_8723A_LEVEL(_drv_always_, "send eapol packet\n"); 486 } 487 488 if ((pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1)) { 489 rtw_set_scan_deny(padapter, 3000); 490 } 491 492 /* If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */ 493 if ((pattrib->ether_type == ETH_P_ARP) || 494 (pattrib->ether_type == ETH_P_PAE) || (pattrib->dhcp_pkt == 1)) { 495 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_SPECIAL_PACKET, 1); 496 } 497 498 bmcast = is_multicast_ether_addr(pattrib->ra); 499 500 /* get sta_info */ 501 if (bmcast) { 502 psta = rtw_get_bcmc_stainfo23a(padapter); 503 } else { 504 psta = rtw_get_stainfo23a(pstapriv, pattrib->ra); 505 if (psta == NULL) { /* if we cannot get psta => drrp the pkt */ 506 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, 507 ("\nupdate_attrib => get sta_info fail, ra:" 508 MAC_FMT"\n", MAC_ARG(pattrib->ra))); 509 res = _FAIL; 510 goto exit; 511 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && 512 (!(psta->state & _FW_LINKED))) { 513 res = _FAIL; 514 goto exit; 515 } 516 } 517 518 if (psta) { 519 pattrib->mac_id = psta->mac_id; 520 /* DBG_8723A("%s ==> mac_id(%d)\n", __func__, pattrib->mac_id); */ 521 pattrib->psta = psta; 522 } else { 523 /* if we cannot get psta => drop the pkt */ 524 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, 525 ("\nupdate_attrib => get sta_info fail, ra:" MAC_FMT 526 "\n", MAC_ARG(pattrib->ra))); 527 res = _FAIL; 528 goto exit; 529 } 530 531 pattrib->ack_policy = 0; 532 /* get ether_hdr_len */ 533 534 /* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */ 535 pattrib->pkt_hdrlen = ETH_HLEN; 536 537 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 538 pattrib->type = IEEE80211_FTYPE_DATA; 539 pattrib->priority = 0; 540 541 if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | 542 WIFI_ADHOC_MASTER_STATE)) { 543 if (psta->qos_option) 544 set_qos(skb, pattrib); 545 } else { 546 if (pmlmepriv->qos_option) { 547 set_qos(skb, pattrib); 548 549 if (pmlmepriv->acm_mask != 0) { 550 pattrib->priority = qos_acm23a(pmlmepriv->acm_mask, 551 pattrib->priority); 552 } 553 } 554 } 555 556 if (psta->ieee8021x_blocked == true) { 557 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 558 ("\n psta->ieee8021x_blocked == true\n")); 559 560 pattrib->encrypt = 0; 561 562 if ((pattrib->ether_type != ETH_P_PAE) && 563 (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)) { 564 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 565 ("\npsta->ieee8021x_blocked == true, " 566 "pattrib->ether_type(%.4x) != 0x888e\n", 567 pattrib->ether_type)); 568 res = _FAIL; 569 goto exit; 570 } 571 } else { 572 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast); 573 574 switch (psecuritypriv->dot11AuthAlgrthm) { 575 case dot11AuthAlgrthm_Open: 576 case dot11AuthAlgrthm_Shared: 577 case dot11AuthAlgrthm_Auto: 578 pattrib->key_idx = 579 (u8)psecuritypriv->dot11PrivacyKeyIndex; 580 break; 581 case dot11AuthAlgrthm_8021X: 582 if (bmcast) 583 pattrib->key_idx = 584 (u8)psecuritypriv->dot118021XGrpKeyid; 585 else 586 pattrib->key_idx = 0; 587 break; 588 default: 589 pattrib->key_idx = 0; 590 break; 591 } 592 593 } 594 595 switch (pattrib->encrypt) { 596 case WLAN_CIPHER_SUITE_WEP40: 597 case WLAN_CIPHER_SUITE_WEP104: 598 pattrib->iv_len = IEEE80211_WEP_IV_LEN; 599 pattrib->icv_len = IEEE80211_WEP_ICV_LEN; 600 break; 601 602 case WLAN_CIPHER_SUITE_TKIP: 603 pattrib->iv_len = IEEE80211_TKIP_IV_LEN; 604 pattrib->icv_len = IEEE80211_TKIP_ICV_LEN; 605 606 if (!padapter->securitypriv.busetkipkey) { 607 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 608 ("\npadapter->securitypriv.busetkip" 609 "key(%d) == false drop packet\n", 610 padapter->securitypriv.busetkipkey)); 611 res = _FAIL; 612 goto exit; 613 } 614 615 break; 616 case WLAN_CIPHER_SUITE_CCMP: 617 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 618 ("pattrib->encrypt =%d (WLAN_CIPHER_SUITE_CCMP)\n", 619 pattrib->encrypt)); 620 pattrib->iv_len = IEEE80211_CCMP_HDR_LEN; 621 pattrib->icv_len = IEEE80211_CCMP_MIC_LEN; 622 break; 623 624 default: 625 pattrib->iv_len = 0; 626 pattrib->icv_len = 0; 627 break; 628 } 629 630 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 631 ("update_attrib: encrypt =%d\n", pattrib->encrypt)); 632 633 if (pattrib->encrypt && !psecuritypriv->hw_decrypted) { 634 pattrib->bswenc = true; 635 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 636 ("update_attrib: encrypt =%d bswenc = true\n", 637 pattrib->encrypt)); 638 } else { 639 pattrib->bswenc = false; 640 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 641 ("update_attrib: bswenc = false\n")); 642 } 643 update_attrib_phy_info(pattrib, psta); 644 645exit: 646 647 return res; 648} 649 650static int xmitframe_addmic(struct rtw_adapter *padapter, 651 struct xmit_frame *pxmitframe) { 652 struct mic_data micdata; 653 struct sta_info *stainfo; 654 struct pkt_attrib *pattrib = &pxmitframe->attrib; 655 struct security_priv *psecuritypriv = &padapter->securitypriv; 656 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 657 int curfragnum, length; 658 u8 *pframe, *payload, mic[8]; 659 u8 priority[4]= {0x0, 0x0, 0x0, 0x0}; 660 u8 hw_hdr_offset = 0; 661 int bmcst = is_multicast_ether_addr(pattrib->ra); 662 663 if (pattrib->psta) { 664 stainfo = pattrib->psta; 665 } else { 666 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 667 stainfo = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]); 668 } 669 670 if (!stainfo) { 671 DBG_8723A("%s, psta == NUL\n", __func__); 672 return _FAIL; 673 } 674 675 if (!(stainfo->state &_FW_LINKED)) { 676 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", 677 __func__, stainfo->state); 678 return _FAIL; 679 } 680 681 hw_hdr_offset = TXDESC_OFFSET; 682 683 if (pattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) { 684 /* encode mic code */ 685 if (stainfo) { 686 u8 null_key[16]={0x0, 0x0, 0x0, 0x0, 687 0x0, 0x0, 0x0, 0x0, 688 0x0, 0x0, 0x0, 0x0, 689 0x0, 0x0, 0x0, 0x0}; 690 691 pframe = pxmitframe->buf_addr + hw_hdr_offset; 692 693 if (bmcst) { 694 if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16)) { 695 return _FAIL; 696 } 697 /* start to calculate the mic code */ 698 rtw_secmicsetkey23a(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey); 699 } else { 700 if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], 701 null_key, 16)) { 702 return _FAIL; 703 } 704 /* start to calculate the mic code */ 705 rtw_secmicsetkey23a(&micdata, &stainfo->dot11tkiptxmickey.skey[0]); 706 } 707 708 if (pframe[1] & 1) { /* ToDS == 1 */ 709 /* DA */ 710 rtw_secmicappend23a(&micdata, &pframe[16], 6); 711 if (pframe[1] & 2) /* From Ds == 1 */ 712 rtw_secmicappend23a(&micdata, 713 &pframe[24], 6); 714 else 715 rtw_secmicappend23a(&micdata, 716 &pframe[10], 6); 717 } else { /* ToDS == 0 */ 718 /* DA */ 719 rtw_secmicappend23a(&micdata, &pframe[4], 6); 720 if (pframe[1] & 2) /* From Ds == 1 */ 721 rtw_secmicappend23a(&micdata, 722 &pframe[16], 6); 723 else 724 rtw_secmicappend23a(&micdata, 725 &pframe[10], 6); 726 } 727 728 /* if (pmlmepriv->qos_option == 1) */ 729 if (pattrib->qos_en) 730 priority[0] = (u8)pxmitframe->attrib.priority; 731 732 rtw_secmicappend23a(&micdata, &priority[0], 4); 733 734 payload = pframe; 735 736 for (curfragnum = 0; curfragnum < pattrib->nr_frags; 737 curfragnum++) { 738 payload = PTR_ALIGN(payload, 4); 739 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 740 ("=== curfragnum =%d, pframe = 0x%.2x, " 741 "0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x" 742 "%.2x, 0x%.2x, 0x%.2x,!!!\n", 743 curfragnum, *payload, *(payload + 1), 744 *(payload + 2), *(payload + 3), 745 *(payload + 4), *(payload + 5), 746 *(payload + 6), *(payload + 7))); 747 748 payload = payload + pattrib->hdrlen + 749 pattrib->iv_len; 750 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 751 ("curfragnum =%d pattrib->hdrlen =%d " 752 "pattrib->iv_len =%d", curfragnum, 753 pattrib->hdrlen, pattrib->iv_len)); 754 if ((curfragnum + 1) == pattrib->nr_frags) { 755 length = pattrib->last_txcmdsz - 756 pattrib->hdrlen - 757 pattrib->iv_len - 758 ((pattrib->bswenc) ? 759 pattrib->icv_len : 0); 760 rtw_secmicappend23a(&micdata, payload, 761 length); 762 payload = payload + length; 763 } else { 764 length = pxmitpriv->frag_len - 765 pattrib->hdrlen - 766 pattrib->iv_len - 767 ((pattrib->bswenc) ? 768 pattrib->icv_len : 0); 769 rtw_secmicappend23a(&micdata, payload, 770 length); 771 payload = payload + length + 772 pattrib->icv_len; 773 RT_TRACE(_module_rtl871x_xmit_c_, 774 _drv_err_, 775 ("curfragnum =%d length =%d " 776 "pattrib->icv_len =%d", 777 curfragnum, length, 778 pattrib->icv_len)); 779 } 780 } 781 rtw_secgetmic23a(&micdata, &mic[0]); 782 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 783 ("xmitframe_addmic: before add mic code!!\n")); 784 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 785 ("xmitframe_addmic: pattrib->last_txcmdsz =" 786 "%d!!!\n", pattrib->last_txcmdsz)); 787 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 788 ("xmitframe_addmic: mic[0]= 0x%.2x , mic[1]=" 789 "0x%.2x , mic[2]= 0x%.2x , mic[3]= 0x%.2x\n" 790 "mic[4]= 0x%.2x , mic[5]= 0x%.2x , mic[6]= 0x%.2x " 791 ", mic[7]= 0x%.2x !!!!\n", mic[0], mic[1], 792 mic[2], mic[3], mic[4], mic[5], mic[6], 793 mic[7])); 794 /* add mic code and add the mic code length 795 in last_txcmdsz */ 796 797 memcpy(payload, &mic[0], 8); 798 pattrib->last_txcmdsz += 8; 799 800 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 801 ("\n ======== last pkt ========\n")); 802 payload = payload - pattrib->last_txcmdsz + 8; 803 for (curfragnum = 0; curfragnum < pattrib->last_txcmdsz; 804 curfragnum = curfragnum + 8) 805 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 806 (" %.2x, %.2x, %.2x, %.2x, %.2x, " 807 " %.2x, %.2x, %.2x ", 808 *(payload + curfragnum), 809 *(payload + curfragnum + 1), 810 *(payload + curfragnum + 2), 811 *(payload + curfragnum + 3), 812 *(payload + curfragnum + 4), 813 *(payload + curfragnum + 5), 814 *(payload + curfragnum + 6), 815 *(payload + curfragnum + 7))); 816 } else { 817 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 818 ("xmitframe_addmic: rtw_get_stainfo23a ==" 819 "NULL!!!\n")); 820 } 821 } 822 823 return _SUCCESS; 824} 825 826static int xmitframe_swencrypt(struct rtw_adapter *padapter, 827 struct xmit_frame *pxmitframe) 828{ 829 struct pkt_attrib *pattrib = &pxmitframe->attrib; 830 831 /* if ((psecuritypriv->sw_encrypt)||(pattrib->bswenc)) */ 832 if (pattrib->bswenc) { 833 /* DBG_8723A("start xmitframe_swencrypt\n"); */ 834 RT_TRACE(_module_rtl871x_xmit_c_, _drv_alert_, 835 ("### xmitframe_swencrypt\n")); 836 switch (pattrib->encrypt) { 837 case WLAN_CIPHER_SUITE_WEP40: 838 case WLAN_CIPHER_SUITE_WEP104: 839 rtw_wep_encrypt23a(padapter, pxmitframe); 840 break; 841 case WLAN_CIPHER_SUITE_TKIP: 842 rtw_tkip_encrypt23a(padapter, pxmitframe); 843 break; 844 case WLAN_CIPHER_SUITE_CCMP: 845 rtw_aes_encrypt23a(padapter, pxmitframe); 846 break; 847 default: 848 break; 849 } 850 851 } else { 852 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, 853 ("### xmitframe_hwencrypt\n")); 854 } 855 856 return _SUCCESS; 857} 858 859static int rtw_make_wlanhdr(struct rtw_adapter *padapter, u8 *hdr, 860 struct pkt_attrib *pattrib) 861{ 862 struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr; 863 struct ieee80211_qos_hdr *qoshdr; 864 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 865 u8 qos_option = false; 866 int res = _SUCCESS; 867 868 struct sta_info *psta; 869 870 int bmcst = is_multicast_ether_addr(pattrib->ra); 871 872 if (pattrib->psta) { 873 psta = pattrib->psta; 874 } else { 875 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 876 if (bmcst) { 877 psta = rtw_get_bcmc_stainfo23a(padapter); 878 } else { 879 psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra); 880 } 881 } 882 883 if (psta == NULL) { 884 DBG_8723A("%s, psta == NUL\n", __func__); 885 return _FAIL; 886 } 887 888 if (!(psta->state &_FW_LINKED)) { 889 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state); 890 return _FAIL; 891 } 892 893 memset(hdr, 0, WLANHDR_OFFSET); 894 895 pwlanhdr->frame_control = cpu_to_le16(pattrib->type); 896 897 if (pattrib->type & IEEE80211_FTYPE_DATA) { 898 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 899 /* to_ds = 1, fr_ds = 0; */ 900 /* Data transfer to AP */ 901 pwlanhdr->frame_control |= 902 cpu_to_le16(IEEE80211_FCTL_TODS); 903 ether_addr_copy(pwlanhdr->addr1, get_bssid(pmlmepriv)); 904 ether_addr_copy(pwlanhdr->addr2, pattrib->src); 905 ether_addr_copy(pwlanhdr->addr3, pattrib->dst); 906 907 if (pmlmepriv->qos_option) 908 qos_option = true; 909 910 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 911 /* to_ds = 0, fr_ds = 1; */ 912 pwlanhdr->frame_control |= 913 cpu_to_le16(IEEE80211_FCTL_FROMDS); 914 ether_addr_copy(pwlanhdr->addr1, pattrib->dst); 915 ether_addr_copy(pwlanhdr->addr2, get_bssid(pmlmepriv)); 916 ether_addr_copy(pwlanhdr->addr3, pattrib->src); 917 918 if (psta->qos_option) 919 qos_option = true; 920 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || 921 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 922 ether_addr_copy(pwlanhdr->addr1, pattrib->dst); 923 ether_addr_copy(pwlanhdr->addr2, pattrib->src); 924 ether_addr_copy(pwlanhdr->addr3, get_bssid(pmlmepriv)); 925 926 if (psta->qos_option) 927 qos_option = true; 928 } 929 else { 930 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("fw_state:%x is not allowed to xmit frame\n", get_fwstate(pmlmepriv))); 931 res = _FAIL; 932 goto exit; 933 } 934 if (pattrib->mdata) 935 pwlanhdr->frame_control |= 936 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 937 if (pattrib->encrypt) 938 pwlanhdr->frame_control |= 939 cpu_to_le16(IEEE80211_FCTL_PROTECTED); 940 if (qos_option) { 941 qoshdr = (struct ieee80211_qos_hdr *)hdr; 942 943 qoshdr->qos_ctrl = cpu_to_le16( 944 pattrib->priority & IEEE80211_QOS_CTL_TID_MASK); 945 946 qoshdr->qos_ctrl |= cpu_to_le16( 947 (pattrib->ack_policy << 5) & 948 IEEE80211_QOS_CTL_ACK_POLICY_MASK); 949 950 if (pattrib->eosp) 951 qoshdr->qos_ctrl |= 952 cpu_to_le16(IEEE80211_QOS_CTL_EOSP); 953 } 954 /* TODO: fill HT Control Field */ 955 956 /* Update Seq Num will be handled by f/w */ 957 if (psta) { 958 psta->sta_xmitpriv.txseq_tid[pattrib->priority]++; 959 psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF; 960 pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority]; 961 /* We dont need to worry about frag bits here */ 962 pwlanhdr->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ( 963 pattrib->seqnum)); 964 /* check if enable ampdu */ 965 if (pattrib->ht_en && psta->htpriv.ampdu_enable) { 966 if (pattrib->priority >= 16) 967 printk(KERN_WARNING "%s: Invalid " 968 "pattrib->priority %i\n", 969 __func__, pattrib->priority); 970 if (psta->htpriv.agg_enable_bitmap & 971 BIT(pattrib->priority)) 972 pattrib->ampdu_en = true; 973 } 974 /* re-check if enable ampdu by BA_starting_seqctrl */ 975 if (pattrib->ampdu_en) { 976 u16 tx_seq; 977 978 tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f]; 979 980 /* check BA_starting_seqctrl */ 981 if (SN_LESS(pattrib->seqnum, tx_seq)) { 982 /* DBG_8723A("tx ampdu seqnum(%d) < tx_seq(%d)\n", pattrib->seqnum, tx_seq); */ 983 pattrib->ampdu_en = false;/* AGG BK */ 984 } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) { 985 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff; 986 pattrib->ampdu_en = true;/* AGG EN */ 987 } else { 988 /* DBG_8723A("tx ampdu over run\n"); */ 989 psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff; 990 pattrib->ampdu_en = true;/* AGG EN */ 991 } 992 } 993 } 994 } 995exit: 996 return res; 997} 998 999s32 rtw_txframes_pending23a(struct rtw_adapter *padapter) 1000{ 1001 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1002 1003 return (!list_empty(&pxmitpriv->be_pending.queue)) || 1004 (!list_empty(&pxmitpriv->bk_pending.queue)) || 1005 (!list_empty(&pxmitpriv->vi_pending.queue)) || 1006 (!list_empty(&pxmitpriv->vo_pending.queue)); 1007} 1008 1009s32 rtw_txframes_sta_ac_pending23a(struct rtw_adapter *padapter, 1010 struct pkt_attrib *pattrib) 1011{ 1012 struct sta_info *psta; 1013 struct tx_servq *ptxservq; 1014 int priority = pattrib->priority; 1015 1016 if (pattrib->psta) { 1017 psta = pattrib->psta; 1018 } else { 1019 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 1020 psta = rtw_get_stainfo23a(&padapter->stapriv, &pattrib->ra[0]); 1021 } 1022 if (psta == NULL) { 1023 DBG_8723A("%s, psta == NUL\n", __func__); 1024 return 0; 1025 } 1026 if (!(psta->state &_FW_LINKED)) { 1027 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, 1028 psta->state); 1029 return 0; 1030 } 1031 switch (priority) { 1032 case 1: 1033 case 2: 1034 ptxservq = &psta->sta_xmitpriv.bk_q; 1035 break; 1036 case 4: 1037 case 5: 1038 ptxservq = &psta->sta_xmitpriv.vi_q; 1039 break; 1040 case 6: 1041 case 7: 1042 ptxservq = &psta->sta_xmitpriv.vo_q; 1043 break; 1044 case 0: 1045 case 3: 1046 default: 1047 ptxservq = &psta->sta_xmitpriv.be_q; 1048 break; 1049 } 1050 return ptxservq->qcnt; 1051} 1052 1053/* 1054 * Calculate wlan 802.11 packet MAX size from pkt_attrib 1055 * This function doesn't consider fragment case 1056 */ 1057u32 rtw_calculate_wlan_pkt_size_by_attribue23a(struct pkt_attrib *pattrib) 1058{ 1059 u32 len = 0; 1060 1061 len = pattrib->hdrlen + pattrib->iv_len; /* WLAN Header and IV */ 1062 len += SNAP_SIZE + sizeof(u16); /* LLC */ 1063 len += pattrib->pktlen; 1064 if (pattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) len += 8; /* MIC */ 1065 len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /* ICV */ 1066 1067 return len; 1068} 1069 1070/* 1071 1072This sub-routine will perform all the following: 1073 10741. remove 802.3 header. 10752. create wlan_header, based on the info in pxmitframe 10763. append sta's iv/ext-iv 10774. append LLC 10785. move frag chunk from pframe to pxmitframe->mem 10796. apply sw-encrypt, if necessary. 1080 1081*/ 1082int rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *skb, 1083 struct xmit_frame *pxmitframe) 1084{ 1085 struct sta_info *psta; 1086 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1087 struct pkt_attrib *pattrib = &pxmitframe->attrib; 1088 struct ieee80211_hdr *hdr; 1089 s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz; 1090 u8 *pframe, *mem_start; 1091 u8 hw_hdr_offset; 1092 u8 *pbuf_start; 1093 u8 *pdata = skb->data; 1094 int data_len = skb->len; 1095 s32 bmcst = is_multicast_ether_addr(pattrib->ra); 1096 int res = _SUCCESS; 1097 1098 if (pattrib->psta) 1099 psta = pattrib->psta; 1100 else { 1101 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 1102 psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra); 1103 } 1104 1105 if (!psta) { 1106 DBG_8723A("%s, psta == NUL\n", __func__); 1107 return _FAIL; 1108 } 1109 1110 if (!(psta->state &_FW_LINKED)) { 1111 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", 1112 __func__, psta->state); 1113 return _FAIL; 1114 } 1115 1116 if (!pxmitframe->buf_addr) { 1117 DBG_8723A("==> %s buf_addr == NULL\n", __func__); 1118 return _FAIL; 1119 } 1120 1121 pbuf_start = pxmitframe->buf_addr; 1122 1123 hw_hdr_offset = TXDESC_OFFSET; 1124 1125 mem_start = pbuf_start + hw_hdr_offset; 1126 1127 if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) { 1128 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 1129 ("%s: rtw_make_wlanhdr fail; drop pkt\n", __func__)); 1130 res = _FAIL; 1131 goto exit; 1132 } 1133 1134 pdata += pattrib->pkt_hdrlen; 1135 data_len -= pattrib->pkt_hdrlen; 1136 1137 frg_inx = 0; 1138 frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */ 1139 1140 while (1) { 1141 llc_sz = 0; 1142 1143 mpdu_len = frg_len; 1144 1145 pframe = mem_start; 1146 hdr = (struct ieee80211_hdr *)mem_start; 1147 1148 pframe += pattrib->hdrlen; 1149 mpdu_len -= pattrib->hdrlen; 1150 1151 /* adding icv, if necessary... */ 1152 if (pattrib->iv_len) { 1153 if (psta) { 1154 switch (pattrib->encrypt) { 1155 case WLAN_CIPHER_SUITE_WEP40: 1156 case WLAN_CIPHER_SUITE_WEP104: 1157 WEP_IV(pattrib->iv, psta->dot11txpn, 1158 pattrib->key_idx); 1159 break; 1160 case WLAN_CIPHER_SUITE_TKIP: 1161 if (bmcst) 1162 TKIP_IV(pattrib->iv, 1163 psta->dot11txpn, 1164 pattrib->key_idx); 1165 else 1166 TKIP_IV(pattrib->iv, 1167 psta->dot11txpn, 0); 1168 break; 1169 case WLAN_CIPHER_SUITE_CCMP: 1170 if (bmcst) 1171 AES_IV(pattrib->iv, 1172 psta->dot11txpn, 1173 pattrib->key_idx); 1174 else 1175 AES_IV(pattrib->iv, 1176 psta->dot11txpn, 0); 1177 break; 1178 } 1179 } 1180 1181 memcpy(pframe, pattrib->iv, pattrib->iv_len); 1182 1183 RT_TRACE(_module_rtl871x_xmit_c_, _drv_notice_, 1184 ("rtw_xmiaframe_coalesce23a: keyid =%d pattrib" 1185 "->iv[3]=%.2x pframe =%.2x %.2x %.2x %.2x\n", 1186 padapter->securitypriv.dot11PrivacyKeyIndex, 1187 pattrib->iv[3], *pframe, *(pframe+1), 1188 *(pframe+2), *(pframe+3))); 1189 pframe += pattrib->iv_len; 1190 mpdu_len -= pattrib->iv_len; 1191 } 1192 if (frg_inx == 0) { 1193 llc_sz = rtw_put_snap23a(pframe, pattrib->ether_type); 1194 pframe += llc_sz; 1195 mpdu_len -= llc_sz; 1196 } 1197 1198 if (pattrib->icv_len > 0 && pattrib->bswenc) 1199 mpdu_len -= pattrib->icv_len; 1200 1201 if (bmcst) 1202 /* don't do fragment to broadcat/multicast packets */ 1203 mem_sz = min_t(s32, data_len, pattrib->pktlen); 1204 else 1205 mem_sz = min_t(s32, data_len, mpdu_len); 1206 1207 memcpy(pframe, pdata, mem_sz); 1208 1209 pframe += mem_sz; 1210 pdata += mem_sz; 1211 data_len -= mem_sz; 1212 1213 if ((pattrib->icv_len >0) && (pattrib->bswenc)) { 1214 memcpy(pframe, pattrib->icv, pattrib->icv_len); 1215 pframe += pattrib->icv_len; 1216 } 1217 1218 frg_inx++; 1219 1220 if (bmcst || data_len <= 0) { 1221 pattrib->nr_frags = frg_inx; 1222 1223 pattrib->last_txcmdsz = pattrib->hdrlen + 1224 pattrib->iv_len + 1225 ((pattrib->nr_frags == 1) ? 1226 llc_sz : 0) + 1227 ((pattrib->bswenc) ? 1228 pattrib->icv_len : 0) + mem_sz; 1229 hdr->frame_control &= 1230 ~cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); 1231 1232 break; 1233 } else { 1234 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 1235 ("%s: There're still something in packet!\n", 1236 __func__)); 1237 } 1238 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); 1239 1240 mem_start = PTR_ALIGN(pframe, 4) + hw_hdr_offset; 1241 memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); 1242 } 1243 1244 if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) { 1245 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 1246 ("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n")); 1247 DBG_8723A("xmitframe_addmic(padapter, pxmitframe) == _FAIL\n"); 1248 res = _FAIL; 1249 goto exit; 1250 } 1251 1252 xmitframe_swencrypt(padapter, pxmitframe); 1253 1254 if (bmcst == false) 1255 update_attrib_vcs_info(padapter, pxmitframe); 1256 else 1257 pattrib->vcs_mode = NONE_VCS; 1258 1259exit: 1260 return res; 1261} 1262 1263/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header 1264 * IEEE LLC/SNAP header contains 8 octets 1265 * First 3 octets comprise the LLC portion 1266 * SNAP portion, 5 octets, is divided into two fields: 1267 * Organizationally Unique Identifier(OUI), 3 octets, 1268 * type, defined by that organization, 2 octets. 1269 */ 1270s32 rtw_put_snap23a(u8 *data, u16 h_proto) 1271{ 1272 struct ieee80211_snap_hdr *snap; 1273 u8 *oui; 1274 1275 snap = (struct ieee80211_snap_hdr *)data; 1276 snap->dsap = 0xaa; 1277 snap->ssap = 0xaa; 1278 snap->ctrl = 0x03; 1279 1280 if (h_proto == 0x8137 || h_proto == 0x80f3) 1281 oui = P802_1H_OUI; 1282 else 1283 oui = RFC1042_OUI; 1284 snap->oui[0] = oui[0]; 1285 snap->oui[1] = oui[1]; 1286 snap->oui[2] = oui[2]; 1287 *(u16 *)(data + SNAP_SIZE) = htons(h_proto); 1288 return SNAP_SIZE + sizeof(u16); 1289} 1290 1291void rtw_update_protection23a(struct rtw_adapter *padapter, u8 *ie, uint ie_len) 1292{ 1293 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1294 struct registry_priv *pregistrypriv = &padapter->registrypriv; 1295 uint protection; 1296 const u8 *p; 1297 1298 switch (pxmitpriv->vcs_setting) { 1299 case DISABLE_VCS: 1300 pxmitpriv->vcs = NONE_VCS; 1301 break; 1302 case ENABLE_VCS: 1303 break; 1304 case AUTO_VCS: 1305 default: 1306 p = cfg80211_find_ie(WLAN_EID_ERP_INFO, ie, ie_len); 1307 if (!p) 1308 pxmitpriv->vcs = NONE_VCS; 1309 else { 1310 protection = (*(p + 2)) & BIT(1); 1311 if (protection) { 1312 if (pregistrypriv->vcs_type == RTS_CTS) 1313 pxmitpriv->vcs = RTS_CTS; 1314 else 1315 pxmitpriv->vcs = CTS_TO_SELF; 1316 } else { 1317 pxmitpriv->vcs = NONE_VCS; 1318 } 1319 } 1320 break; 1321 } 1322} 1323 1324void rtw_count_tx_stats23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe, int sz) 1325{ 1326 struct sta_info *psta = NULL; 1327 struct stainfo_stats *pstats = NULL; 1328 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1329 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1330 1331 if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { 1332 pxmitpriv->tx_bytes += sz; 1333 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod++; 1334 1335 psta = pxmitframe->attrib.psta; 1336 if (psta) { 1337 pstats = &psta->sta_stats; 1338 pstats->tx_pkts++; 1339 pstats->tx_bytes += sz; 1340 } 1341 } 1342} 1343 1344struct xmit_buf *rtw_alloc_xmitbuf23a_ext(struct xmit_priv *pxmitpriv) 1345{ 1346 unsigned long irqL; 1347 struct xmit_buf *pxmitbuf = NULL; 1348 struct list_head *phead; 1349 struct rtw_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; 1350 1351 spin_lock_irqsave(&pfree_queue->lock, irqL); 1352 1353 phead = get_list_head(pfree_queue); 1354 1355 if (!list_empty(phead)) { 1356 pxmitbuf = list_first_entry(phead, struct xmit_buf, list); 1357 1358 list_del_init(&pxmitbuf->list); 1359 1360 pxmitpriv->free_xmit_extbuf_cnt--; 1361 pxmitbuf->priv_data = NULL; 1362 pxmitbuf->ext_tag = true; 1363 1364 if (pxmitbuf->sctx) { 1365 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__); 1366 rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); 1367 } 1368 } 1369 1370 spin_unlock_irqrestore(&pfree_queue->lock, irqL); 1371 1372 return pxmitbuf; 1373} 1374 1375int rtw_free_xmitbuf_ext23a(struct xmit_priv *pxmitpriv, 1376 struct xmit_buf *pxmitbuf) 1377{ 1378 unsigned long irqL; 1379 struct rtw_queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue; 1380 1381 if (pxmitbuf == NULL) 1382 return _FAIL; 1383 1384 spin_lock_irqsave(&pfree_queue->lock, irqL); 1385 1386 list_del_init(&pxmitbuf->list); 1387 1388 list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue)); 1389 pxmitpriv->free_xmit_extbuf_cnt++; 1390 1391 spin_unlock_irqrestore(&pfree_queue->lock, irqL); 1392 1393 return _SUCCESS; 1394} 1395 1396struct xmit_buf *rtw_alloc_xmitbuf23a(struct xmit_priv *pxmitpriv) 1397{ 1398 unsigned long irqL; 1399 struct xmit_buf *pxmitbuf = NULL; 1400 struct list_head *phead; 1401 struct rtw_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; 1402 1403 /* DBG_8723A("+rtw_alloc_xmitbuf23a\n"); */ 1404 1405 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); 1406 1407 phead = get_list_head(pfree_xmitbuf_queue); 1408 1409 if (!list_empty(phead)) { 1410 pxmitbuf = list_first_entry(phead, struct xmit_buf, list); 1411 1412 list_del_init(&pxmitbuf->list); 1413 1414 pxmitpriv->free_xmitbuf_cnt--; 1415 pxmitbuf->priv_data = NULL; 1416 pxmitbuf->ext_tag = false; 1417 pxmitbuf->flags = XMIT_VO_QUEUE; 1418 1419 if (pxmitbuf->sctx) { 1420 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__); 1421 rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC); 1422 } 1423 } 1424 1425 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); 1426 1427 return pxmitbuf; 1428} 1429 1430int rtw_free_xmitbuf23a(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) 1431{ 1432 unsigned long irqL; 1433 struct rtw_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue; 1434 1435 /* DBG_8723A("+rtw_free_xmitbuf23a\n"); */ 1436 1437 if (pxmitbuf == NULL) 1438 return _FAIL; 1439 1440 if (pxmitbuf->sctx) { 1441 DBG_8723A("%s pxmitbuf->sctx is not NULL\n", __func__); 1442 rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE); 1443 } 1444 1445 if (pxmitbuf->ext_tag) { 1446 rtw_free_xmitbuf_ext23a(pxmitpriv, pxmitbuf); 1447 } else { 1448 spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL); 1449 1450 list_del_init(&pxmitbuf->list); 1451 1452 list_add_tail(&pxmitbuf->list, 1453 get_list_head(pfree_xmitbuf_queue)); 1454 1455 pxmitpriv->free_xmitbuf_cnt++; 1456 spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL); 1457 } 1458 1459 return _SUCCESS; 1460} 1461 1462static void rtw_init_xmitframe(struct xmit_frame *pxframe) 1463{ 1464 if (pxframe != NULL) { 1465 /* default value setting */ 1466 pxframe->buf_addr = NULL; 1467 pxframe->pxmitbuf = NULL; 1468 1469 memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib)); 1470 /* pxframe->attrib.psta = NULL; */ 1471 1472 pxframe->frame_tag = DATA_FRAMETAG; 1473 1474 pxframe->pkt = NULL; 1475 pxframe->pkt_offset = 1;/* default use pkt_offset to fill tx desc */ 1476 1477 pxframe->ack_report = 0; 1478 } 1479} 1480 1481/* 1482Calling context: 14831. OS_TXENTRY 14842. RXENTRY (rx_thread or RX_ISR/RX_CallBack) 1485 1486If we turn on USE_RXTHREAD, then, no need for critical section. 1487Otherwise, we must use _enter/_exit critical to protect free_xmit_queue... 1488 1489Must be very very cautious... 1490 1491*/ 1492static struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv) 1493{ 1494 struct xmit_frame *pxframe = NULL; 1495 struct list_head *plist, *phead; 1496 struct rtw_queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue; 1497 1498 spin_lock_bh(&pfree_xmit_queue->lock); 1499 1500 if (list_empty(&pfree_xmit_queue->queue)) { 1501 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 1502 ("rtw_alloc_xmitframe:%d\n", 1503 pxmitpriv->free_xmitframe_cnt)); 1504 pxframe = NULL; 1505 } else { 1506 phead = get_list_head(pfree_xmit_queue); 1507 1508 plist = phead->next; 1509 1510 pxframe = container_of(plist, struct xmit_frame, list); 1511 1512 list_del_init(&pxframe->list); 1513 pxmitpriv->free_xmitframe_cnt--; 1514 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 1515 ("rtw_alloc_xmitframe():free_xmitframe_cnt =%d\n", 1516 pxmitpriv->free_xmitframe_cnt)); 1517 } 1518 1519 spin_unlock_bh(&pfree_xmit_queue->lock); 1520 1521 rtw_init_xmitframe(pxframe); 1522 1523 return pxframe; 1524} 1525 1526struct xmit_frame *rtw_alloc_xmitframe23a_ext(struct xmit_priv *pxmitpriv) 1527{ 1528 struct xmit_frame *pxframe = NULL; 1529 struct list_head *plist, *phead; 1530 struct rtw_queue *queue = &pxmitpriv->free_xframe_ext_queue; 1531 1532 spin_lock_bh(&queue->lock); 1533 1534 if (list_empty(&queue->queue)) { 1535 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe23a_ext:%d\n", pxmitpriv->free_xframe_ext_cnt)); 1536 pxframe = NULL; 1537 } else { 1538 phead = get_list_head(queue); 1539 plist = phead->next; 1540 pxframe = container_of(plist, struct xmit_frame, list); 1541 1542 list_del_init(&pxframe->list); 1543 pxmitpriv->free_xframe_ext_cnt--; 1544 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe23a_ext():free_xmitframe_cnt =%d\n", pxmitpriv->free_xframe_ext_cnt)); 1545 } 1546 1547 spin_unlock_bh(&queue->lock); 1548 1549 rtw_init_xmitframe(pxframe); 1550 1551 return pxframe; 1552} 1553 1554s32 rtw_free_xmitframe23a(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe) 1555{ 1556 struct rtw_queue *queue = NULL; 1557 struct rtw_adapter *padapter = pxmitpriv->adapter; 1558 struct sk_buff *pndis_pkt = NULL; 1559 1560 if (pxmitframe == NULL) { 1561 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("====== rtw_free_xmitframe23a():pxmitframe == NULL!!!!!!!!!!\n")); 1562 goto exit; 1563 } 1564 1565 if (pxmitframe->pkt) { 1566 pndis_pkt = pxmitframe->pkt; 1567 pxmitframe->pkt = NULL; 1568 } 1569 1570 if (pxmitframe->ext_tag == 0) 1571 queue = &pxmitpriv->free_xmit_queue; 1572 else if (pxmitframe->ext_tag == 1) 1573 queue = &pxmitpriv->free_xframe_ext_queue; 1574 1575 if (!queue) 1576 goto check_pkt_complete; 1577 spin_lock_bh(&queue->lock); 1578 1579 list_del_init(&pxmitframe->list); 1580 list_add_tail(&pxmitframe->list, get_list_head(queue)); 1581 if (pxmitframe->ext_tag == 0) { 1582 pxmitpriv->free_xmitframe_cnt++; 1583 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe23a():free_xmitframe_cnt =%d\n", pxmitpriv->free_xmitframe_cnt)); 1584 } else if (pxmitframe->ext_tag == 1) { 1585 pxmitpriv->free_xframe_ext_cnt++; 1586 RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe23a():free_xframe_ext_cnt =%d\n", pxmitpriv->free_xframe_ext_cnt)); 1587 } 1588 1589 spin_unlock_bh(&queue->lock); 1590 1591check_pkt_complete: 1592 1593 if (pndis_pkt) 1594 rtw_os_pkt_complete23a(padapter, pndis_pkt); 1595 1596exit: 1597 1598 return _SUCCESS; 1599} 1600 1601void rtw_free_xmitframe_queue23a(struct xmit_priv *pxmitpriv, 1602 struct rtw_queue *pframequeue) 1603{ 1604 struct list_head *plist, *phead, *ptmp; 1605 struct xmit_frame *pxmitframe; 1606 1607 spin_lock_bh(&pframequeue->lock); 1608 1609 phead = get_list_head(pframequeue); 1610 1611 list_for_each_safe(plist, ptmp, phead) { 1612 pxmitframe = container_of(plist, struct xmit_frame, list); 1613 1614 rtw_free_xmitframe23a(pxmitpriv, pxmitframe); 1615 } 1616 spin_unlock_bh(&pframequeue->lock); 1617 1618} 1619 1620int rtw_xmitframe_enqueue23a(struct rtw_adapter *padapter, 1621 struct xmit_frame *pxmitframe) 1622{ 1623 if (rtw_xmit23a_classifier(padapter, pxmitframe) == _FAIL) { 1624 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 1625 ("rtw_xmitframe_enqueue23a: drop xmit pkt for " 1626 "classifier fail\n")); 1627 return _FAIL; 1628 } 1629 1630 return _SUCCESS; 1631} 1632 1633static struct xmit_frame * 1634dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit, 1635 struct tx_servq *ptxservq, struct rtw_queue *pframe_queue) 1636{ 1637 struct list_head *phead; 1638 struct xmit_frame *pxmitframe = NULL; 1639 1640 phead = get_list_head(pframe_queue); 1641 1642 if (!list_empty(phead)) { 1643 pxmitframe = list_first_entry(phead, struct xmit_frame, list); 1644 list_del_init(&pxmitframe->list); 1645 ptxservq->qcnt--; 1646 } 1647 return pxmitframe; 1648} 1649 1650struct xmit_frame * 1651rtw_dequeue_xframe23a(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, 1652 int entry) 1653{ 1654 struct list_head *sta_plist, *sta_phead, *ptmp; 1655 struct hw_xmit *phwxmit; 1656 struct tx_servq *ptxservq = NULL; 1657 struct rtw_queue *pframe_queue = NULL; 1658 struct xmit_frame *pxmitframe = NULL; 1659 struct rtw_adapter *padapter = pxmitpriv->adapter; 1660 struct registry_priv *pregpriv = &padapter->registrypriv; 1661 int i, inx[4]; 1662 1663 inx[0] = 0; 1664 inx[1] = 1; 1665 inx[2] = 2; 1666 inx[3] = 3; 1667 if (pregpriv->wifi_spec == 1) { 1668 int j; 1669 1670 for (j = 0; j < 4; j++) 1671 inx[j] = pxmitpriv->wmm_para_seq[j]; 1672 } 1673 1674 spin_lock_bh(&pxmitpriv->lock); 1675 1676 for (i = 0; i < entry; i++) { 1677 phwxmit = phwxmit_i + inx[i]; 1678 1679 sta_phead = get_list_head(phwxmit->sta_queue); 1680 1681 list_for_each_safe(sta_plist, ptmp, sta_phead) { 1682 ptxservq = container_of(sta_plist, struct tx_servq, 1683 tx_pending); 1684 1685 pframe_queue = &ptxservq->sta_pending; 1686 1687 pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit, ptxservq, pframe_queue); 1688 1689 if (pxmitframe) { 1690 phwxmit->accnt--; 1691 1692 /* Remove sta node when there is no pending packets. */ 1693 /* must be done after get_next and 1694 before break */ 1695 if (list_empty(&pframe_queue->queue)) 1696 list_del_init(&ptxservq->tx_pending); 1697 goto exit; 1698 } 1699 } 1700 } 1701exit: 1702 spin_unlock_bh(&pxmitpriv->lock); 1703 return pxmitframe; 1704} 1705 1706struct tx_servq *rtw_get_sta_pending23a(struct rtw_adapter *padapter, struct sta_info *psta, int up, u8 *ac) 1707{ 1708 struct tx_servq *ptxservq = NULL; 1709 1710 switch (up) { 1711 case 1: 1712 case 2: 1713 ptxservq = &psta->sta_xmitpriv.bk_q; 1714 *(ac) = 3; 1715 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : BK\n")); 1716 break; 1717 case 4: 1718 case 5: 1719 ptxservq = &psta->sta_xmitpriv.vi_q; 1720 *(ac) = 1; 1721 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : VI\n")); 1722 break; 1723 case 6: 1724 case 7: 1725 ptxservq = &psta->sta_xmitpriv.vo_q; 1726 *(ac) = 0; 1727 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : VO\n")); 1728 break; 1729 case 0: 1730 case 3: 1731 default: 1732 ptxservq = &psta->sta_xmitpriv.be_q; 1733 *(ac) = 2; 1734 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_get_sta_pending23a : BE\n")); 1735 break; 1736 } 1737 return ptxservq; 1738} 1739 1740/* 1741 * Will enqueue pxmitframe to the proper queue, 1742 * and indicate it to xx_pending list..... 1743 */ 1744int rtw_xmit23a_classifier(struct rtw_adapter *padapter, 1745 struct xmit_frame *pxmitframe) 1746{ 1747 struct sta_info *psta; 1748 struct tx_servq *ptxservq; 1749 struct pkt_attrib *pattrib = &pxmitframe->attrib; 1750 struct sta_priv *pstapriv = &padapter->stapriv; 1751 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; 1752 u8 ac_index; 1753 int res = _SUCCESS; 1754 1755 if (pattrib->psta) { 1756 psta = pattrib->psta; 1757 } else { 1758 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 1759 psta = rtw_get_stainfo23a(pstapriv, pattrib->ra); 1760 } 1761 if (psta == NULL) { 1762 res = _FAIL; 1763 DBG_8723A("rtw_xmit23a_classifier: psta == NULL\n"); 1764 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, 1765 ("rtw_xmit23a_classifier: psta == NULL\n")); 1766 goto exit; 1767 } 1768 if (!(psta->state & _FW_LINKED)) { 1769 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, 1770 psta->state); 1771 return _FAIL; 1772 } 1773 ptxservq = rtw_get_sta_pending23a(padapter, psta, pattrib->priority, 1774 (u8 *)(&ac_index)); 1775 1776 if (list_empty(&ptxservq->tx_pending)) { 1777 list_add_tail(&ptxservq->tx_pending, 1778 get_list_head(phwxmits[ac_index].sta_queue)); 1779 } 1780 1781 list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); 1782 ptxservq->qcnt++; 1783 phwxmits[ac_index].accnt++; 1784exit: 1785 return res; 1786} 1787 1788void rtw_alloc_hwxmits23a(struct rtw_adapter *padapter) 1789{ 1790 struct hw_xmit *hwxmits; 1791 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1792 int size; 1793 1794 pxmitpriv->hwxmit_entry = HWXMIT_ENTRY; 1795 1796 size = sizeof(struct hw_xmit) * (pxmitpriv->hwxmit_entry + 1); 1797 pxmitpriv->hwxmits = kzalloc(size, GFP_KERNEL); 1798 1799 hwxmits = pxmitpriv->hwxmits; 1800 1801 if (pxmitpriv->hwxmit_entry == 5) { 1802 /* pxmitpriv->bmc_txqueue.head = 0; */ 1803 /* hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue; */ 1804 hwxmits[0] .sta_queue = &pxmitpriv->bm_pending; 1805 1806 /* pxmitpriv->vo_txqueue.head = 0; */ 1807 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue; */ 1808 hwxmits[1] .sta_queue = &pxmitpriv->vo_pending; 1809 1810 /* pxmitpriv->vi_txqueue.head = 0; */ 1811 /* hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue; */ 1812 hwxmits[2] .sta_queue = &pxmitpriv->vi_pending; 1813 1814 /* pxmitpriv->bk_txqueue.head = 0; */ 1815 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ 1816 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; 1817 1818 /* pxmitpriv->be_txqueue.head = 0; */ 1819 /* hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue; */ 1820 hwxmits[4] .sta_queue = &pxmitpriv->be_pending; 1821 1822 } else if (pxmitpriv->hwxmit_entry == 4) { 1823 1824 /* pxmitpriv->vo_txqueue.head = 0; */ 1825 /* hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue; */ 1826 hwxmits[0] .sta_queue = &pxmitpriv->vo_pending; 1827 1828 /* pxmitpriv->vi_txqueue.head = 0; */ 1829 /* hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue; */ 1830 hwxmits[1] .sta_queue = &pxmitpriv->vi_pending; 1831 1832 /* pxmitpriv->be_txqueue.head = 0; */ 1833 /* hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue; */ 1834 hwxmits[2] .sta_queue = &pxmitpriv->be_pending; 1835 1836 /* pxmitpriv->bk_txqueue.head = 0; */ 1837 /* hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue; */ 1838 hwxmits[3] .sta_queue = &pxmitpriv->bk_pending; 1839 } else { 1840 1841 } 1842} 1843 1844void rtw_free_hwxmits23a(struct rtw_adapter *padapter) 1845{ 1846 struct hw_xmit *hwxmits; 1847 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1848 1849 hwxmits = pxmitpriv->hwxmits; 1850 kfree(hwxmits); 1851} 1852 1853void rtw_init_hwxmits23a(struct hw_xmit *phwxmit, int entry) 1854{ 1855 int i; 1856 1857 for (i = 0; i < entry; i++, phwxmit++) 1858 phwxmit->accnt = 0; 1859} 1860 1861u32 rtw_get_ff_hwaddr23a(struct xmit_frame *pxmitframe) 1862{ 1863 u32 addr; 1864 struct pkt_attrib *pattrib = &pxmitframe->attrib; 1865 1866 switch (pattrib->qsel) { 1867 case 0: 1868 case 3: 1869 addr = BE_QUEUE_INX; 1870 break; 1871 case 1: 1872 case 2: 1873 addr = BK_QUEUE_INX; 1874 break; 1875 case 4: 1876 case 5: 1877 addr = VI_QUEUE_INX; 1878 break; 1879 case 6: 1880 case 7: 1881 addr = VO_QUEUE_INX; 1882 break; 1883 case 0x10: 1884 addr = BCN_QUEUE_INX; 1885 break; 1886 case 0x11:/* BC/MC in PS (HIQ) */ 1887 addr = HIGH_QUEUE_INX; 1888 break; 1889 case 0x12: 1890 default: 1891 addr = MGT_QUEUE_INX; 1892 break; 1893 } 1894 1895 return addr; 1896} 1897 1898static void do_queue_select(struct rtw_adapter *padapter, struct pkt_attrib *pattrib) 1899{ 1900 u8 qsel; 1901 1902 qsel = pattrib->priority; 1903 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, 1904 ("### do_queue_select priority =%d , qsel = %d\n", 1905 pattrib->priority, qsel)); 1906 1907 pattrib->qsel = qsel; 1908} 1909 1910/* 1911 * The main transmit(tx) entry 1912 * 1913 * Return 1914 * 1 enqueue 1915 * 0 success, hardware will handle this xmit frame(packet) 1916 * <0 fail 1917 */ 1918int rtw_xmit23a(struct rtw_adapter *padapter, struct sk_buff *skb) 1919{ 1920 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1921 struct xmit_frame *pxmitframe = NULL; 1922 int res; 1923 1924 pxmitframe = rtw_alloc_xmitframe(pxmitpriv); 1925 1926 if (pxmitframe == NULL) { 1927 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, 1928 ("rtw_xmit23a: no more pxmitframe\n")); 1929 return -1; 1930 } 1931 1932 res = update_attrib(padapter, skb, &pxmitframe->attrib); 1933 1934 if (res == _FAIL) { 1935 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit23a: update attrib fail\n")); 1936 rtw_free_xmitframe23a(pxmitpriv, pxmitframe); 1937 return -1; 1938 } 1939 pxmitframe->pkt = skb; 1940 1941 rtw_led_control(padapter, LED_CTL_TX); 1942 1943 do_queue_select(padapter, &pxmitframe->attrib); 1944 1945#ifdef CONFIG_8723AU_AP_MODE 1946 spin_lock_bh(&pxmitpriv->lock); 1947 if (xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe)) { 1948 spin_unlock_bh(&pxmitpriv->lock); 1949 return 1; 1950 } 1951 spin_unlock_bh(&pxmitpriv->lock); 1952#endif 1953 1954 if (rtl8723au_hal_xmit(padapter, pxmitframe) == false) 1955 return 1; 1956 1957 return 0; 1958} 1959 1960#if defined(CONFIG_8723AU_AP_MODE) 1961 1962int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter *padapter, struct xmit_frame *pxmitframe) 1963{ 1964 int ret = false; 1965 struct sta_info *psta = NULL; 1966 struct sta_priv *pstapriv = &padapter->stapriv; 1967 struct pkt_attrib *pattrib = &pxmitframe->attrib; 1968 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1969 int bmcst = is_multicast_ether_addr(pattrib->ra); 1970 1971 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false) 1972 return ret; 1973 1974 if (pattrib->psta) { 1975 psta = pattrib->psta; 1976 } else { 1977 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__); 1978 psta = rtw_get_stainfo23a(pstapriv, pattrib->ra); 1979 } 1980 1981 if (psta == NULL) { 1982 DBG_8723A("%s, psta == NUL\n", __func__); 1983 return false; 1984 } 1985 1986 if (!(psta->state & _FW_LINKED)) { 1987 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, 1988 psta->state); 1989 return false; 1990 } 1991 1992 if (pattrib->triggered == 1) { 1993 if (bmcst) 1994 pattrib->qsel = 0x11;/* HIQ */ 1995 return ret; 1996 } 1997 1998 if (bmcst) { 1999 spin_lock_bh(&psta->sleep_q.lock); 2000 2001 if (pstapriv->sta_dz_bitmap) { 2002 /* if anyone sta is in ps mode */ 2003 list_del_init(&pxmitframe->list); 2004 2005 /* spin_lock_bh(&psta->sleep_q.lock); */ 2006 2007 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); 2008 2009 psta->sleepq_len++; 2010 2011 pstapriv->tim_bitmap |= BIT(0);/* */ 2012 pstapriv->sta_dz_bitmap |= BIT(0); 2013 2014 /* DBG_8723A("enqueue, sq_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */ 2015 2016 /* tx bc/mc packets after upate bcn */ 2017 update_beacon23a(padapter, WLAN_EID_TIM, NULL, false); 2018 2019 /* spin_unlock_bh(&psta->sleep_q.lock); */ 2020 2021 ret = true; 2022 2023 } 2024 2025 spin_unlock_bh(&psta->sleep_q.lock); 2026 2027 return ret; 2028 2029 } 2030 2031 spin_lock_bh(&psta->sleep_q.lock); 2032 2033 if (psta->state&WIFI_SLEEP_STATE) { 2034 u8 wmmps_ac = 0; 2035 2036 if (pstapriv->sta_dz_bitmap & CHKBIT(psta->aid)) { 2037 list_del_init(&pxmitframe->list); 2038 2039 /* spin_lock_bh(&psta->sleep_q.lock); */ 2040 2041 list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q)); 2042 2043 psta->sleepq_len++; 2044 2045 switch (pattrib->priority) { 2046 case 1: 2047 case 2: 2048 wmmps_ac = psta->uapsd_bk & BIT(0); 2049 break; 2050 case 4: 2051 case 5: 2052 wmmps_ac = psta->uapsd_vi & BIT(0); 2053 break; 2054 case 6: 2055 case 7: 2056 wmmps_ac = psta->uapsd_vo & BIT(0); 2057 break; 2058 case 0: 2059 case 3: 2060 default: 2061 wmmps_ac = psta->uapsd_be & BIT(0); 2062 break; 2063 } 2064 2065 if (wmmps_ac) 2066 psta->sleepq_ac_len++; 2067 2068 if (((psta->has_legacy_ac) && (!wmmps_ac)) || 2069 ((!psta->has_legacy_ac) && (wmmps_ac))) { 2070 pstapriv->tim_bitmap |= CHKBIT(psta->aid); 2071 2072 if (psta->sleepq_len == 1) { 2073 /* upate BCN for TIM IE */ 2074 update_beacon23a(padapter, WLAN_EID_TIM, 2075 NULL, false); 2076 } 2077 } 2078 2079 /* spin_unlock_bh(&psta->sleep_q.lock); */ 2080 2081 /* if (psta->sleepq_len > (NR_XMITFRAME>>3)) */ 2082 /* */ 2083 /* wakeup_sta_to_xmit23a(padapter, psta); */ 2084 /* */ 2085 2086 ret = true; 2087 2088 } 2089 2090 } 2091 2092 spin_unlock_bh(&psta->sleep_q.lock); 2093 2094 return ret; 2095} 2096 2097static void 2098dequeue_xmitframes_to_sleeping_queue(struct rtw_adapter *padapter, 2099 struct sta_info *psta, 2100 struct rtw_queue *pframequeue) 2101{ 2102 int ret; 2103 struct list_head *plist, *phead, *ptmp; 2104 u8 ac_index; 2105 struct tx_servq *ptxservq; 2106 struct pkt_attrib *pattrib; 2107 struct xmit_frame *pxmitframe; 2108 struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; 2109 2110 phead = get_list_head(pframequeue); 2111 2112 list_for_each_safe(plist, ptmp, phead) { 2113 pxmitframe = container_of(plist, struct xmit_frame, list); 2114 2115 ret = xmitframe_enqueue_for_sleeping_sta23a(padapter, pxmitframe); 2116 2117 if (ret == true) { 2118 pattrib = &pxmitframe->attrib; 2119 2120 ptxservq = rtw_get_sta_pending23a(padapter, psta, pattrib->priority, (u8 *)(&ac_index)); 2121 2122 ptxservq->qcnt--; 2123 phwxmits[ac_index].accnt--; 2124 } else { 2125 /* DBG_8723A("xmitframe_enqueue_for_sleeping_sta23a return false\n"); */ 2126 } 2127 } 2128} 2129 2130void stop_sta_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta) 2131{ 2132 struct sta_info *psta_bmc; 2133 struct sta_xmit_priv *pstaxmitpriv; 2134 struct sta_priv *pstapriv = &padapter->stapriv; 2135 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2136 2137 pstaxmitpriv = &psta->sta_xmitpriv; 2138 2139 /* for BC/MC Frames */ 2140 psta_bmc = rtw_get_bcmc_stainfo23a(padapter); 2141 2142 spin_lock_bh(&pxmitpriv->lock); 2143 2144 psta->state |= WIFI_SLEEP_STATE; 2145 2146 pstapriv->sta_dz_bitmap |= CHKBIT(psta->aid); 2147 2148 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending); 2149 list_del_init(&pstaxmitpriv->vo_q.tx_pending); 2150 2151 dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending); 2152 list_del_init(&pstaxmitpriv->vi_q.tx_pending); 2153 2154 dequeue_xmitframes_to_sleeping_queue(padapter, psta, 2155 &pstaxmitpriv->be_q.sta_pending); 2156 list_del_init(&pstaxmitpriv->be_q.tx_pending); 2157 2158 dequeue_xmitframes_to_sleeping_queue(padapter, psta, 2159 &pstaxmitpriv->bk_q.sta_pending); 2160 list_del_init(&pstaxmitpriv->bk_q.tx_pending); 2161 2162 /* for BC/MC Frames */ 2163 pstaxmitpriv = &psta_bmc->sta_xmitpriv; 2164 dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, 2165 &pstaxmitpriv->be_q.sta_pending); 2166 list_del_init(&pstaxmitpriv->be_q.tx_pending); 2167 2168 spin_unlock_bh(&pxmitpriv->lock); 2169} 2170 2171void wakeup_sta_to_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta) 2172{ 2173 u8 update_mask = 0, wmmps_ac = 0; 2174 struct sta_info *psta_bmc; 2175 struct list_head *plist, *phead, *ptmp; 2176 struct xmit_frame *pxmitframe = NULL; 2177 struct sta_priv *pstapriv = &padapter->stapriv; 2178 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2179 2180 spin_lock_bh(&pxmitpriv->lock); 2181 2182 phead = get_list_head(&psta->sleep_q); 2183 2184 list_for_each_safe(plist, ptmp, phead) { 2185 pxmitframe = container_of(plist, struct xmit_frame, list); 2186 list_del_init(&pxmitframe->list); 2187 2188 switch (pxmitframe->attrib.priority) { 2189 case 1: 2190 case 2: 2191 wmmps_ac = psta->uapsd_bk & BIT(1); 2192 break; 2193 case 4: 2194 case 5: 2195 wmmps_ac = psta->uapsd_vi & BIT(1); 2196 break; 2197 case 6: 2198 case 7: 2199 wmmps_ac = psta->uapsd_vo & BIT(1); 2200 break; 2201 case 0: 2202 case 3: 2203 default: 2204 wmmps_ac = psta->uapsd_be & BIT(1); 2205 break; 2206 } 2207 2208 psta->sleepq_len--; 2209 if (psta->sleepq_len > 0) 2210 pxmitframe->attrib.mdata = 1; 2211 else 2212 pxmitframe->attrib.mdata = 0; 2213 2214 if (wmmps_ac) { 2215 psta->sleepq_ac_len--; 2216 if (psta->sleepq_ac_len > 0) { 2217 pxmitframe->attrib.mdata = 1; 2218 pxmitframe->attrib.eosp = 0; 2219 } else { 2220 pxmitframe->attrib.mdata = 0; 2221 pxmitframe->attrib.eosp = 1; 2222 } 2223 } 2224 2225 pxmitframe->attrib.triggered = 1; 2226 rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe); 2227 } 2228 2229 if (psta->sleepq_len == 0) { 2230 pstapriv->tim_bitmap &= ~CHKBIT(psta->aid); 2231 2232 /* upate BCN for TIM IE */ 2233 update_mask = BIT(0); 2234 2235 if (psta->state&WIFI_SLEEP_STATE) 2236 psta->state ^= WIFI_SLEEP_STATE; 2237 2238 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { 2239 psta->expire_to = pstapriv->expire_to; 2240 psta->state ^= WIFI_STA_ALIVE_CHK_STATE; 2241 } 2242 2243 pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid); 2244 } 2245 2246 /* spin_unlock_bh(&psta->sleep_q.lock); */ 2247 spin_unlock_bh(&pxmitpriv->lock); 2248 2249 /* for BC/MC Frames */ 2250 psta_bmc = rtw_get_bcmc_stainfo23a(padapter); 2251 if (!psta_bmc) 2252 return; 2253 2254 if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) { 2255 /* no any sta in ps mode */ 2256 spin_lock_bh(&pxmitpriv->lock); 2257 2258 phead = get_list_head(&psta_bmc->sleep_q); 2259 2260 list_for_each_safe(plist, ptmp, phead) { 2261 pxmitframe = container_of(plist, struct xmit_frame, 2262 list); 2263 2264 list_del_init(&pxmitframe->list); 2265 2266 psta_bmc->sleepq_len--; 2267 if (psta_bmc->sleepq_len > 0) 2268 pxmitframe->attrib.mdata = 1; 2269 else 2270 pxmitframe->attrib.mdata = 0; 2271 2272 pxmitframe->attrib.triggered = 1; 2273 rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe); 2274 } 2275 if (psta_bmc->sleepq_len == 0) { 2276 pstapriv->tim_bitmap &= ~BIT(0); 2277 pstapriv->sta_dz_bitmap &= ~BIT(0); 2278 2279 /* upate BCN for TIM IE */ 2280 /* update_BCNTIM(padapter); */ 2281 update_mask |= BIT(1); 2282 } 2283 2284 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */ 2285 spin_unlock_bh(&pxmitpriv->lock); 2286 } 2287 2288 if (update_mask) 2289 update_beacon23a(padapter, WLAN_EID_TIM, NULL, false); 2290} 2291 2292void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter, 2293 struct sta_info *psta) 2294{ 2295 u8 wmmps_ac = 0; 2296 struct list_head *plist, *phead, *ptmp; 2297 struct xmit_frame *pxmitframe; 2298 struct sta_priv *pstapriv = &padapter->stapriv; 2299 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2300 2301 /* spin_lock_bh(&psta->sleep_q.lock); */ 2302 spin_lock_bh(&pxmitpriv->lock); 2303 2304 phead = get_list_head(&psta->sleep_q); 2305 2306 list_for_each_safe(plist, ptmp, phead) { 2307 pxmitframe = container_of(plist, struct xmit_frame, list); 2308 2309 switch (pxmitframe->attrib.priority) { 2310 case 1: 2311 case 2: 2312 wmmps_ac = psta->uapsd_bk & BIT(1); 2313 break; 2314 case 4: 2315 case 5: 2316 wmmps_ac = psta->uapsd_vi & BIT(1); 2317 break; 2318 case 6: 2319 case 7: 2320 wmmps_ac = psta->uapsd_vo & BIT(1); 2321 break; 2322 case 0: 2323 case 3: 2324 default: 2325 wmmps_ac = psta->uapsd_be & BIT(1); 2326 break; 2327 } 2328 2329 if (!wmmps_ac) 2330 continue; 2331 2332 list_del_init(&pxmitframe->list); 2333 2334 psta->sleepq_len--; 2335 psta->sleepq_ac_len--; 2336 2337 if (psta->sleepq_ac_len > 0) { 2338 pxmitframe->attrib.mdata = 1; 2339 pxmitframe->attrib.eosp = 0; 2340 } else { 2341 pxmitframe->attrib.mdata = 0; 2342 pxmitframe->attrib.eosp = 1; 2343 } 2344 2345 pxmitframe->attrib.triggered = 1; 2346 2347 rtl8723au_hal_xmitframe_enqueue(padapter, pxmitframe); 2348 2349 if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && 2350 (wmmps_ac)) { 2351 pstapriv->tim_bitmap &= ~CHKBIT(psta->aid); 2352 2353 /* upate BCN for TIM IE */ 2354 update_beacon23a(padapter, WLAN_EID_TIM, NULL, false); 2355 } 2356 } 2357 spin_unlock_bh(&pxmitpriv->lock); 2358} 2359 2360#endif 2361 2362void rtw_sctx_init23a(struct submit_ctx *sctx, int timeout_ms) 2363{ 2364 sctx->timeout_ms = timeout_ms; 2365 init_completion(&sctx->done); 2366 sctx->status = RTW_SCTX_SUBMITTED; 2367} 2368 2369int rtw_sctx_wait23a(struct submit_ctx *sctx) 2370{ 2371 int ret = _FAIL; 2372 unsigned long expire; 2373 int status = 0; 2374 2375 expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : 2376 MAX_SCHEDULE_TIMEOUT; 2377 if (!wait_for_completion_timeout(&sctx->done, expire)) { 2378 /* timeout, do something?? */ 2379 status = RTW_SCTX_DONE_TIMEOUT; 2380 DBG_8723A("%s timeout\n", __func__); 2381 } else { 2382 status = sctx->status; 2383 } 2384 2385 if (status == RTW_SCTX_DONE_SUCCESS) 2386 ret = _SUCCESS; 2387 2388 return ret; 2389} 2390 2391static bool rtw_sctx_chk_waring_status(int status) 2392{ 2393 switch (status) { 2394 case RTW_SCTX_DONE_UNKNOWN: 2395 case RTW_SCTX_DONE_BUF_ALLOC: 2396 case RTW_SCTX_DONE_BUF_FREE: 2397 case RTW_SCTX_DONE_DRV_STOP: 2398 case RTW_SCTX_DONE_DEV_REMOVE: 2399 return true; 2400 default: 2401 return false; 2402 } 2403} 2404 2405void rtw23a_sctx_done_err(struct submit_ctx **sctx, int status) 2406{ 2407 if (*sctx) { 2408 if (rtw_sctx_chk_waring_status(status)) 2409 DBG_8723A("%s status:%d\n", __func__, status); 2410 (*sctx)->status = status; 2411 complete(&(*sctx)->done); 2412 *sctx = NULL; 2413 } 2414} 2415 2416void rtw_sctx_done23a(struct submit_ctx **sctx) 2417{ 2418 rtw23a_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS); 2419} 2420 2421int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms) 2422{ 2423 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; 2424 2425 pack_tx_ops->timeout_ms = timeout_ms; 2426 pack_tx_ops->status = RTW_SCTX_SUBMITTED; 2427 2428 return rtw_sctx_wait23a(pack_tx_ops); 2429} 2430 2431void rtw_ack_tx_done23a(struct xmit_priv *pxmitpriv, int status) 2432{ 2433 struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops; 2434 2435 if (pxmitpriv->ack_tx) 2436 rtw23a_sctx_done_err(&pack_tx_ops, status); 2437 else 2438 DBG_8723A("%s ack_tx not set\n", __func__); 2439} 2440