1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 8 #include <drv_types.h> 9 #include <rtw_debug.h> 10 #include <rtl8723b_hal.h> 11 12 static u8 rtw_sdio_wait_enough_TxOQT_space(struct adapter *padapter, u8 agg_num) 13 { 14 u32 n = 0; 15 struct hal_com_data *pHalData = GET_HAL_DATA(padapter); 16 17 while (pHalData->SdioTxOQTFreeSpace < agg_num) { 18 if ( 19 (padapter->bSurpriseRemoved) || 20 (padapter->bDriverStopped) 21 ) 22 return false; 23 24 HalQueryTxOQTBufferStatus8723BSdio(padapter); 25 26 if ((++n % 60) == 0) { 27 msleep(1); 28 /* yield(); */ 29 } 30 } 31 32 pHalData->SdioTxOQTFreeSpace -= agg_num; 33 34 return true; 35 } 36 37 static s32 rtl8723_dequeue_writeport(struct adapter *padapter) 38 { 39 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 40 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 41 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 42 struct xmit_buf *pxmitbuf; 43 struct adapter *pri_padapter = padapter; 44 s32 ret = 0; 45 u8 PageIdx = 0; 46 u32 deviceId; 47 u8 bUpdatePageNum = false; 48 49 ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY); 50 51 if (ret) 52 pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv); 53 else 54 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv); 55 56 if (!pxmitbuf) 57 return true; 58 59 deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr); 60 61 /* translate fifo addr to queue index */ 62 switch (deviceId) { 63 case WLAN_TX_HIQ_DEVICE_ID: 64 PageIdx = HI_QUEUE_IDX; 65 break; 66 67 case WLAN_TX_MIQ_DEVICE_ID: 68 PageIdx = MID_QUEUE_IDX; 69 break; 70 71 case WLAN_TX_LOQ_DEVICE_ID: 72 PageIdx = LOW_QUEUE_IDX; 73 break; 74 } 75 76 query_free_page: 77 /* check if hardware tx fifo page is enough */ 78 if (!rtw_hal_sdio_query_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num)) { 79 if (!bUpdatePageNum) { 80 /* Total number of page is NOT available, so update current FIFO status */ 81 HalQueryTxBufferStatus8723BSdio(padapter); 82 bUpdatePageNum = true; 83 goto query_free_page; 84 } else { 85 bUpdatePageNum = false; 86 enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf); 87 return true; 88 } 89 } 90 91 if ( 92 (padapter->bSurpriseRemoved) || 93 (padapter->bDriverStopped) 94 ) 95 goto free_xmitbuf; 96 97 if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == false) 98 goto free_xmitbuf; 99 100 traffic_check_for_leave_lps(padapter, true, pxmitbuf->agg_num); 101 102 rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf); 103 104 rtw_hal_sdio_update_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num); 105 106 free_xmitbuf: 107 /* rtw_free_xmitframe(pxmitpriv, pframe); */ 108 /* pxmitbuf->priv_data = NULL; */ 109 rtw_free_xmitbuf(pxmitpriv, pxmitbuf); 110 111 return _FAIL; 112 } 113 114 /* 115 * Description 116 *Transmit xmitbuf to hardware tx fifo 117 * 118 * Return 119 *_SUCCESS ok 120 *_FAIL something error 121 */ 122 s32 rtl8723bs_xmit_buf_handler(struct adapter *padapter) 123 { 124 struct xmit_priv *pxmitpriv; 125 u8 queue_empty, queue_pending; 126 s32 ret; 127 128 129 pxmitpriv = &padapter->xmitpriv; 130 131 if (wait_for_completion_interruptible(&pxmitpriv->xmit_comp)) { 132 netdev_emerg(padapter->pnetdev, 133 "%s: down SdioXmitBufSema fail!\n", __func__); 134 return _FAIL; 135 } 136 137 ret = (padapter->bDriverStopped) || (padapter->bSurpriseRemoved); 138 if (ret) 139 return _FAIL; 140 141 queue_pending = check_pending_xmitbuf(pxmitpriv); 142 143 if (!queue_pending) 144 return _SUCCESS; 145 146 ret = rtw_register_tx_alive(padapter); 147 if (ret != _SUCCESS) { 148 return _SUCCESS; 149 } 150 151 do { 152 queue_empty = rtl8723_dequeue_writeport(padapter); 153 /* dump secondary adapter xmitbuf */ 154 } while (!queue_empty); 155 156 rtw_unregister_tx_alive(padapter); 157 158 return _SUCCESS; 159 } 160 161 /* 162 * Description: 163 *Aggregation packets and send to hardware 164 * 165 * Return: 166 *0 Success 167 *-1 Hardware resource(TX FIFO) not ready 168 *-2 Software resource(xmitbuf) not ready 169 */ 170 static s32 xmit_xmitframes(struct adapter *padapter, struct xmit_priv *pxmitpriv) 171 { 172 s32 err, ret; 173 u32 k = 0; 174 struct hw_xmit *hwxmits, *phwxmit; 175 u8 idx, hwentry; 176 struct tx_servq *ptxservq; 177 struct list_head *sta_plist, *sta_phead, *frame_plist, *frame_phead, *tmp; 178 struct xmit_frame *pxmitframe; 179 struct __queue *pframe_queue; 180 struct xmit_buf *pxmitbuf; 181 u32 txlen, max_xmit_len; 182 u8 txdesc_size = TXDESC_SIZE; 183 int inx[4]; 184 185 err = 0; 186 hwxmits = pxmitpriv->hwxmits; 187 hwentry = pxmitpriv->hwxmit_entry; 188 ptxservq = NULL; 189 pxmitframe = NULL; 190 pframe_queue = NULL; 191 pxmitbuf = NULL; 192 193 if (padapter->registrypriv.wifi_spec == 1) { 194 for (idx = 0; idx < 4; idx++) 195 inx[idx] = pxmitpriv->wmm_para_seq[idx]; 196 } else { 197 inx[0] = 0; 198 inx[1] = 1; 199 inx[2] = 2; 200 inx[3] = 3; 201 } 202 203 /* 0(VO), 1(VI), 2(BE), 3(BK) */ 204 for (idx = 0; idx < hwentry; idx++) { 205 phwxmit = hwxmits + inx[idx]; 206 207 if ( 208 (check_pending_xmitbuf(pxmitpriv)) && 209 (padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic) 210 ) { 211 if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) { 212 err = -2; 213 break; 214 } 215 } 216 217 max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, inx[idx]); 218 219 spin_lock_bh(&pxmitpriv->lock); 220 221 sta_phead = get_list_head(phwxmit->sta_queue); 222 /* because stop_sta_xmit may delete sta_plist at any time */ 223 /* so we should add lock here, or while loop can not exit */ 224 list_for_each_safe(sta_plist, tmp, sta_phead) { 225 ptxservq = list_entry(sta_plist, struct tx_servq, 226 tx_pending); 227 228 pframe_queue = &ptxservq->sta_pending; 229 230 frame_phead = get_list_head(pframe_queue); 231 232 while (list_empty(frame_phead) == false) { 233 frame_plist = get_next(frame_phead); 234 pxmitframe = container_of(frame_plist, struct xmit_frame, list); 235 236 /* check xmit_buf size enough or not */ 237 txlen = txdesc_size + rtw_wlan_pkt_size(pxmitframe); 238 if (!pxmitbuf || 239 ((_RND(pxmitbuf->len, 8) + txlen) > max_xmit_len) || 240 (k >= (rtw_hal_sdio_max_txoqt_free_space(padapter) - 1)) 241 ) { 242 if (pxmitbuf) { 243 /* pxmitbuf->priv_data will be NULL, and will crash here */ 244 if (pxmitbuf->len > 0 && 245 pxmitbuf->priv_data) { 246 struct xmit_frame *pframe; 247 pframe = (struct xmit_frame *)pxmitbuf->priv_data; 248 pframe->agg_num = k; 249 pxmitbuf->agg_num = k; 250 rtl8723b_update_txdesc(pframe, pframe->buf_addr); 251 rtw_free_xmitframe(pxmitpriv, pframe); 252 pxmitbuf->priv_data = NULL; 253 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf); 254 /* can not yield under lock */ 255 /* yield(); */ 256 } else 257 rtw_free_xmitbuf(pxmitpriv, pxmitbuf); 258 } 259 260 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv); 261 if (!pxmitbuf) { 262 #ifdef DBG_XMIT_BUF 263 netdev_err(padapter->pnetdev, 264 "%s: xmit_buf is not enough!\n", 265 __func__); 266 #endif 267 err = -2; 268 complete(&(pxmitpriv->xmit_comp)); 269 break; 270 } 271 k = 0; 272 } 273 274 /* ok to send, remove frame from queue */ 275 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true) 276 if ( 277 (pxmitframe->attrib.psta->state & WIFI_SLEEP_STATE) && 278 (pxmitframe->attrib.triggered == 0) 279 ) 280 break; 281 282 list_del_init(&pxmitframe->list); 283 ptxservq->qcnt--; 284 phwxmit->accnt--; 285 286 if (k == 0) { 287 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe); 288 pxmitbuf->priv_data = (u8 *)pxmitframe; 289 } 290 291 /* coalesce the xmitframe to xmitbuf */ 292 pxmitframe->pxmitbuf = pxmitbuf; 293 pxmitframe->buf_addr = pxmitbuf->ptail; 294 295 ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); 296 if (ret == _FAIL) { 297 netdev_err(padapter->pnetdev, 298 "%s: coalesce FAIL!", 299 __func__); 300 /* Todo: error handler */ 301 } else { 302 k++; 303 if (k != 1) 304 rtl8723b_update_txdesc(pxmitframe, pxmitframe->buf_addr); 305 rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz); 306 307 txlen = txdesc_size + pxmitframe->attrib.last_txcmdsz; 308 pxmitframe->pg_num = (txlen + 127) / 128; 309 pxmitbuf->pg_num += (txlen + 127) / 128; 310 pxmitbuf->ptail += _RND(txlen, 8); /* round to 8 bytes alignment */ 311 pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen; 312 } 313 314 if (k != 1) 315 rtw_free_xmitframe(pxmitpriv, pxmitframe); 316 pxmitframe = NULL; 317 } 318 319 if (list_empty(&pframe_queue->queue)) 320 list_del_init(&ptxservq->tx_pending); 321 322 if (err) 323 break; 324 } 325 spin_unlock_bh(&pxmitpriv->lock); 326 327 /* dump xmit_buf to hw tx fifo */ 328 if (pxmitbuf) { 329 if (pxmitbuf->len > 0) { 330 struct xmit_frame *pframe; 331 pframe = (struct xmit_frame *)pxmitbuf->priv_data; 332 pframe->agg_num = k; 333 pxmitbuf->agg_num = k; 334 rtl8723b_update_txdesc(pframe, pframe->buf_addr); 335 rtw_free_xmitframe(pxmitpriv, pframe); 336 pxmitbuf->priv_data = NULL; 337 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf); 338 yield(); 339 } else 340 rtw_free_xmitbuf(pxmitpriv, pxmitbuf); 341 pxmitbuf = NULL; 342 } 343 344 if (err) 345 break; 346 } 347 348 return err; 349 } 350 351 /* 352 * Description 353 *Transmit xmitframe from queue 354 * 355 * Return 356 *_SUCCESS ok 357 *_FAIL something error 358 */ 359 static s32 rtl8723bs_xmit_handler(struct adapter *padapter) 360 { 361 struct xmit_priv *pxmitpriv; 362 s32 ret; 363 364 365 pxmitpriv = &padapter->xmitpriv; 366 367 if (wait_for_completion_interruptible(&pxmitpriv->SdioXmitStart)) { 368 netdev_emerg(padapter->pnetdev, "%s: SdioXmitStart fail!\n", 369 __func__); 370 return _FAIL; 371 } 372 373 next: 374 if ( 375 (padapter->bDriverStopped) || 376 (padapter->bSurpriseRemoved) 377 ) 378 return _FAIL; 379 380 spin_lock_bh(&pxmitpriv->lock); 381 ret = rtw_txframes_pending(padapter); 382 spin_unlock_bh(&pxmitpriv->lock); 383 if (ret == 0) { 384 return _SUCCESS; 385 } 386 387 /* dequeue frame and write to hardware */ 388 389 ret = xmit_xmitframes(padapter, pxmitpriv); 390 if (ret == -2) { 391 /* here sleep 1ms will cause big TP loss of TX */ 392 /* from 50+ to 40+ */ 393 if (padapter->registrypriv.wifi_spec) 394 msleep(1); 395 else 396 yield(); 397 goto next; 398 } 399 400 spin_lock_bh(&pxmitpriv->lock); 401 ret = rtw_txframes_pending(padapter); 402 spin_unlock_bh(&pxmitpriv->lock); 403 if (ret == 1) { 404 goto next; 405 } 406 407 return _SUCCESS; 408 } 409 410 int rtl8723bs_xmit_thread(void *context) 411 { 412 s32 ret; 413 struct adapter *padapter; 414 struct xmit_priv *pxmitpriv; 415 u8 thread_name[20]; 416 417 ret = _SUCCESS; 418 padapter = context; 419 pxmitpriv = &padapter->xmitpriv; 420 421 rtw_sprintf(thread_name, 20, "RTWHALXT-%s", ADPT_ARG(padapter)); 422 thread_enter(thread_name); 423 424 do { 425 ret = rtl8723bs_xmit_handler(padapter); 426 if (signal_pending(current)) { 427 flush_signals(current); 428 } 429 } while (_SUCCESS == ret); 430 431 complete(&pxmitpriv->SdioXmitTerminate); 432 433 return 0; 434 } 435 436 s32 rtl8723bs_mgnt_xmit( 437 struct adapter *padapter, struct xmit_frame *pmgntframe 438 ) 439 { 440 s32 ret = _SUCCESS; 441 struct pkt_attrib *pattrib; 442 struct xmit_buf *pxmitbuf; 443 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 444 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 445 u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 446 u8 txdesc_size = TXDESC_SIZE; 447 448 pattrib = &pmgntframe->attrib; 449 pxmitbuf = pmgntframe->pxmitbuf; 450 451 rtl8723b_update_txdesc(pmgntframe, pmgntframe->buf_addr); 452 453 pxmitbuf->len = txdesc_size + pattrib->last_txcmdsz; 454 pxmitbuf->pg_num = (pxmitbuf->len + 127) / 128; /* 128 is tx page size */ 455 pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len; 456 pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe); 457 458 rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz); 459 460 rtw_free_xmitframe(pxmitpriv, pmgntframe); 461 462 pxmitbuf->priv_data = NULL; 463 464 if (GetFrameSubType(pframe) == WIFI_BEACON) { /* dump beacon directly */ 465 ret = rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr], pxmitbuf->len, (u8 *)pxmitbuf); 466 if (ret != _SUCCESS) 467 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR); 468 469 rtw_free_xmitbuf(pxmitpriv, pxmitbuf); 470 } else 471 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf); 472 473 return ret; 474 } 475 476 /* 477 * Description: 478 *Handle xmitframe(packet) come from rtw_xmit() 479 * 480 * Return: 481 *true dump packet directly ok 482 *false enqueue, temporary can't transmit packets to hardware 483 */ 484 s32 rtl8723bs_hal_xmit( 485 struct adapter *padapter, struct xmit_frame *pxmitframe 486 ) 487 { 488 struct xmit_priv *pxmitpriv; 489 s32 err; 490 491 492 pxmitframe->attrib.qsel = pxmitframe->attrib.priority; 493 pxmitpriv = &padapter->xmitpriv; 494 495 if ( 496 (pxmitframe->frame_tag == DATA_FRAMETAG) && 497 (pxmitframe->attrib.ether_type != 0x0806) && 498 (pxmitframe->attrib.ether_type != 0x888e) && 499 (pxmitframe->attrib.dhcp_pkt != 1) 500 ) { 501 if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) 502 rtw_issue_addbareq_cmd(padapter, pxmitframe); 503 } 504 505 spin_lock_bh(&pxmitpriv->lock); 506 err = rtw_xmitframe_enqueue(padapter, pxmitframe); 507 spin_unlock_bh(&pxmitpriv->lock); 508 if (err != _SUCCESS) { 509 rtw_free_xmitframe(pxmitpriv, pxmitframe); 510 511 pxmitpriv->tx_drop++; 512 return true; 513 } 514 515 complete(&pxmitpriv->SdioXmitStart); 516 517 return false; 518 } 519 520 s32 rtl8723bs_hal_xmitframe_enqueue( 521 struct adapter *padapter, struct xmit_frame *pxmitframe 522 ) 523 { 524 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 525 s32 err; 526 527 err = rtw_xmitframe_enqueue(padapter, pxmitframe); 528 if (err != _SUCCESS) { 529 rtw_free_xmitframe(pxmitpriv, pxmitframe); 530 531 pxmitpriv->tx_drop++; 532 } else { 533 complete(&pxmitpriv->SdioXmitStart); 534 } 535 536 return err; 537 538 } 539 540 /* 541 * Return 542 *_SUCCESS start thread ok 543 *_FAIL start thread fail 544 * 545 */ 546 s32 rtl8723bs_init_xmit_priv(struct adapter *padapter) 547 { 548 struct xmit_priv *xmitpriv = &padapter->xmitpriv; 549 struct hal_com_data *phal; 550 551 552 phal = GET_HAL_DATA(padapter); 553 554 spin_lock_init(&phal->SdioTxFIFOFreePageLock); 555 init_completion(&xmitpriv->SdioXmitStart); 556 init_completion(&xmitpriv->SdioXmitTerminate); 557 558 return _SUCCESS; 559 } 560 561 void rtl8723bs_free_xmit_priv(struct adapter *padapter) 562 { 563 struct xmit_priv *pxmitpriv; 564 struct xmit_buf *pxmitbuf; 565 struct __queue *pqueue; 566 struct list_head *plist, *phead; 567 struct list_head tmplist; 568 569 570 pxmitpriv = &padapter->xmitpriv; 571 pqueue = &pxmitpriv->pending_xmitbuf_queue; 572 phead = get_list_head(pqueue); 573 INIT_LIST_HEAD(&tmplist); 574 575 spin_lock_bh(&pqueue->lock); 576 if (!list_empty(&pqueue->queue)) { 577 /* Insert tmplist to end of queue, and delete phead */ 578 /* then tmplist become head of queue. */ 579 list_add_tail(&tmplist, phead); 580 list_del_init(phead); 581 } 582 spin_unlock_bh(&pqueue->lock); 583 584 phead = &tmplist; 585 while (list_empty(phead) == false) { 586 plist = get_next(phead); 587 list_del_init(plist); 588 589 pxmitbuf = container_of(plist, struct xmit_buf, list); 590 rtw_free_xmitframe(pxmitpriv, (struct xmit_frame *)pxmitbuf->priv_data); 591 pxmitbuf->priv_data = NULL; 592 rtw_free_xmitbuf(pxmitpriv, pxmitbuf); 593 } 594 } 595