1 /******************************************************************************
2 *
3 * Copyright(c) 2015 - 2016 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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _RTL8822BE_XMIT_C_
21
22 #include <drv_types.h> /* PADAPTER, rtw_xmit.h and etc. */
23 #include <hal_data.h> /* HAL_DATA_TYPE */
24 #include "../halmac/halmac_api.h"
25 #include "../rtl8822b.h"
26 #include "rtl8822be.h"
27
28 /* Debug Buffer Descriptor Ring */
29 /*#define BUF_DESC_DEBUG*/
30 #ifdef BUF_DESC_DEBUG
31 #define buf_desc_debug(...) do {\
32 RTW_INFO("BUF_DESC:" __VA_ARGS__);\
33 } while (0)
34 #else
35 #define buf_desc_debug(...) do {} while (0)
36 #endif
37
rtl8822be_xmit_tasklet(void * priv)38 static void rtl8822be_xmit_tasklet(void *priv)
39 {
40 _irqL irqL;
41 _adapter *padapter = (_adapter *)priv;
42 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
43 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
44
45 /* try to deal with the pending packets */
46 rtl8822be_xmitframe_resume(padapter);
47
48 }
49
rtl8822be_init_xmit_priv(_adapter * padapter)50 s32 rtl8822be_init_xmit_priv(_adapter *padapter)
51 {
52 s32 ret = _SUCCESS;
53 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
54 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
55
56 _rtw_spinlock_init(&pdvobjpriv->irq_th_lock);
57
58 #ifdef PLATFORM_LINUX
59 tasklet_init(&pxmitpriv->xmit_tasklet,
60 (void(*)(unsigned long))rtl8822be_xmit_tasklet,
61 (unsigned long)padapter);
62 #endif
63
64 return ret;
65 }
66
rtl8822be_free_xmit_priv(_adapter * padapter)67 void rtl8822be_free_xmit_priv(_adapter *padapter)
68 {
69 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
70
71 _rtw_spinlock_free(&pdvobjpriv->irq_th_lock);
72 }
73
rtl8822be_enqueue_xmitbuf(struct rtw_tx_ring * ring,struct xmit_buf * pxmitbuf)74 static s32 rtl8822be_enqueue_xmitbuf(struct rtw_tx_ring *ring,
75 struct xmit_buf *pxmitbuf)
76 {
77 _irqL irqL;
78 _queue *ppending_queue = &ring->queue;
79
80 _func_enter_;
81
82 if (pxmitbuf == NULL)
83 return _FAIL;
84
85 rtw_list_delete(&pxmitbuf->list);
86 rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(ppending_queue));
87 ring->qlen++;
88
89 _func_exit_;
90
91 return _SUCCESS;
92 }
93
rtl8822be_dequeue_xmitbuf(struct rtw_tx_ring * ring)94 struct xmit_buf *rtl8822be_dequeue_xmitbuf(struct rtw_tx_ring *ring)
95 {
96 _irqL irqL;
97 _list *plist, *phead;
98 struct xmit_buf *pxmitbuf = NULL;
99 _queue *ppending_queue = &ring->queue;
100
101 _func_enter_;
102
103 if (_rtw_queue_empty(ppending_queue) == _TRUE)
104 pxmitbuf = NULL;
105 else {
106
107 phead = get_list_head(ppending_queue);
108 plist = get_next(phead);
109 pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
110 rtw_list_delete(&(pxmitbuf->list));
111 ring->qlen--;
112 }
113
114 _func_exit_;
115
116 return pxmitbuf;
117 }
118
get_txbd(_adapter * padapter,u8 q_idx)119 static u8 *get_txbd(_adapter *padapter, u8 q_idx)
120 {
121 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
122 struct rtw_tx_ring *ring;
123 u8 *ptxbd = NULL;
124 int idx = 0;
125
126 ring = &pxmitpriv->tx_ring[q_idx];
127
128 /* DO NOT use last entry. */
129 /* (len -1) to avoid wrap around overlap problem in cycler queue. */
130 if (ring->qlen == (ring->entries - 1)) {
131 RTW_INFO("No more TX desc@%d, ring->idx = %d,idx = %d\n",
132 q_idx, ring->idx, idx);
133 return NULL;
134 }
135
136 if (q_idx == BCN_QUEUE_INX)
137 idx = 0;
138 else
139 idx = (ring->idx + ring->qlen) % ring->entries;
140
141 ptxbd = (u8 *)&ring->buf_desc[idx];
142
143 return ptxbd;
144 }
145
146 /*
147 * Get txbd reg addr according to q_sel
148 */
get_txbd_rw_reg(u16 q_idx)149 static u16 get_txbd_rw_reg(u16 q_idx)
150 {
151 u16 txbd_reg_addr = REG_BEQ_TXBD_IDX;
152
153 switch (q_idx) {
154
155 case BK_QUEUE_INX:
156 txbd_reg_addr = REG_BKQ_TXBD_IDX;
157 break;
158
159 case BE_QUEUE_INX:
160 txbd_reg_addr = REG_BEQ_TXBD_IDX;
161 break;
162
163 case VI_QUEUE_INX:
164 txbd_reg_addr = REG_VIQ_TXBD_IDX;
165 break;
166
167 case VO_QUEUE_INX:
168 txbd_reg_addr = REG_VOQ_TXBD_IDX;
169 break;
170
171 case BCN_QUEUE_INX:
172 txbd_reg_addr = REG_BEQ_TXBD_IDX; /* need check */
173 break;
174
175 case TXCMD_QUEUE_INX:
176 txbd_reg_addr = REG_H2CQ_TXBD_IDX;
177 break;
178
179 case MGT_QUEUE_INX:
180 txbd_reg_addr = REG_MGQ_TXBD_IDX;
181 break;
182
183 case HIGH_QUEUE_INX:
184 txbd_reg_addr = REG_HI0Q_TXBD_IDX; /* need check */
185 break;
186
187 default:
188 break;
189 }
190
191 return txbd_reg_addr;
192 }
193
__rtw_alloc_cmdxmitframe_8822be(struct xmit_priv * pxmitpriv,enum cmdbuf_type buf_type)194 struct xmit_frame *__rtw_alloc_cmdxmitframe_8822be(struct xmit_priv *pxmitpriv,
195 enum cmdbuf_type buf_type)
196 {
197 _adapter *padapter;
198 u16 queue_idx = BCN_QUEUE_INX;
199 u8 *ptxdesc = NULL;
200
201 padapter = GET_PRIMARY_ADAPTER(pxmitpriv->adapter);
202 ptxdesc = get_txbd(padapter, BCN_QUEUE_INX);
203
204 /* set OWN bit in Beacon tx descriptor */
205 if (ptxdesc != NULL)
206 SET_TX_BD_OWN(ptxdesc, 0);
207 else
208 return NULL;
209
210 return __rtw_alloc_cmdxmitframe(pxmitpriv, CMDBUF_BEACON);
211 }
212
213 /*
214 * Update Read/Write pointer
215 * Read pointer is h/w descriptor index
216 * Write pointer is host desciptor index:
217 * For tx side, if own bit is set in packet index n,
218 * host pointer (write pointer) point to index n + 1.)
219 */
fill_txbd_own(_adapter * padapter,u8 * txbd,u16 queue_idx,struct rtw_tx_ring * ptxring)220 void fill_txbd_own(_adapter *padapter, u8 *txbd, u16 queue_idx,
221 struct rtw_tx_ring *ptxring)
222 {
223 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
224 struct rtw_tx_ring *ring;
225 u16 host_wp = 0;
226
227 if (queue_idx == BCN_QUEUE_INX) {
228
229 SET_TX_BD_OWN(txbd, 1);
230
231 /* kick start */
232 rtw_write8(padapter, REG_RX_RXBD_NUM + 1,
233 rtw_read8(padapter, REG_RX_RXBD_NUM + 1) | BIT(4));
234
235 return;
236 }
237
238 /*
239 * update h/w index
240 * for tx side, if own bit is set in packet index n,
241 * host pointer (write pointer) point to index n + 1.
242 */
243
244 /* for current tx packet, enqueue has been ring->qlen++ before.
245 * so, host_wp = ring->idx + ring->qlen.
246 */
247 host_wp = (ptxring->idx + ptxring->qlen) % ptxring->entries;
248 rtw_write16(padapter, get_txbd_rw_reg(queue_idx), host_wp);
249 }
250
ffaddr2dma(u32 addr)251 static u16 ffaddr2dma(u32 addr)
252 {
253 u16 dma_ctrl;
254
255 switch (addr) {
256 case VO_QUEUE_INX:
257 dma_ctrl = BIT3;
258 break;
259 case VI_QUEUE_INX:
260 dma_ctrl = BIT2;
261 break;
262 case BE_QUEUE_INX:
263 dma_ctrl = BIT1;
264 break;
265 case BK_QUEUE_INX:
266 dma_ctrl = BIT0;
267 break;
268 case BCN_QUEUE_INX:
269 dma_ctrl = BIT4;
270 break;
271 case MGT_QUEUE_INX:
272 dma_ctrl = BIT6;
273 break;
274 case HIGH_QUEUE_INX:
275 dma_ctrl = BIT7;
276 break;
277 default:
278 dma_ctrl = 0;
279 break;
280 }
281
282 return dma_ctrl;
283 }
284
285 /*
286 * Fill tx buffer desciptor. Map each buffer address in tx buffer descriptor
287 * segment. Designed for tx buffer descriptor architecture
288 * Input *pmem: pointer to the Tx Buffer Descriptor
289 */
rtl8822be_update_txbd(struct xmit_frame * pxmitframe,u8 * txbd,s32 sz)290 static void rtl8822be_update_txbd(struct xmit_frame *pxmitframe,
291 u8 *txbd, s32 sz)
292 {
293 _adapter *padapter = pxmitframe->padapter;
294 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
295 dma_addr_t mapping;
296 u32 i = 0;
297 u16 seg_num =
298 ((TX_BUFFER_SEG_NUM == 0) ? 2 : ((TX_BUFFER_SEG_NUM == 1) ? 4 : 8));
299 u16 tx_page_size_reg = 1;
300 u16 page_size_length = 0;
301
302 /* map TX DESC buf_addr (including TX DESC + tx data) */
303 mapping = pci_map_single(pdvobjpriv->ppcidev, pxmitframe->buf_addr ,
304 sz + TX_WIFI_INFO_SIZE, PCI_DMA_TODEVICE);
305
306 /* Calculate page size.
307 * Total buffer length including TX_WIFI_INFO and PacketLen */
308 if (tx_page_size_reg > 0) {
309 page_size_length = (sz + TX_WIFI_INFO_SIZE) /
310 (tx_page_size_reg * 128);
311 if (((sz + TX_WIFI_INFO_SIZE) % (tx_page_size_reg * 128)) > 0)
312 page_size_length++;
313 }
314
315 /*
316 * Reset all tx buffer desciprtor content
317 * -- Reset first element
318 */
319 SET_TX_BD_TX_BUFF_SIZE0(txbd, 0);
320 SET_TX_BD_PSB(txbd, 0);
321 SET_TX_BD_OWN(txbd, 0);
322
323 /* -- Reset second and other element */
324 for (i = 1 ; i < seg_num ; i++) {
325 SET_TXBUFFER_DESC_LEN_WITH_OFFSET(txbd, i, 0);
326 SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(txbd, i, 0);
327 SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(txbd, i, 0);
328 }
329
330 /*
331 * Fill buffer length of the first buffer,
332 * For 8822be, it is required that TX_WIFI_INFO is put in first segment,
333 * and the size of the first segment cannot be larger than
334 * TX_WIFI_INFO_SIZE.
335 */
336 SET_TX_BD_TX_BUFF_SIZE0(txbd, TX_WIFI_INFO_SIZE);
337 SET_TX_BD_PSB(txbd, page_size_length);
338 /* starting addr of TXDESC */
339 SET_TX_BD_PHYSICAL_ADDR0_LOW(txbd, mapping);
340
341 /*
342 * It is assumed that in linux implementation, packet is coalesced
343 * in only one buffer. Extension mode is not supported here
344 */
345 SET_TXBUFFER_DESC_LEN_WITH_OFFSET(txbd, 1, sz);
346 /* don't using extendsion mode. */
347 SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(txbd, 1, 0);
348 SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(txbd, 1,
349 mapping + TX_WIFI_INFO_SIZE); /* pkt */
350
351 /*buf_desc_debug("TX:%s, txbd = 0x%p\n", __FUNCTION__, txbd);*/
352 buf_desc_debug("%s, txbd = 0x%08x\n", __func__, txbd);
353 buf_desc_debug("TXBD:, 00h(0x%08x)\n", *((u32 *)(txbd)));
354 buf_desc_debug("TXBD:, 04h(0x%08x)\n", *((u32 *)(txbd + 4)));
355 buf_desc_debug("TXBD:, 08h(0x%08x)\n", *((u32 *)(txbd + 8)));
356 buf_desc_debug("TXBD:, 12h(0x%08x)\n", *((u32 *)(txbd + 12)));
357
358 }
359
update_txdesc(struct xmit_frame * pxmitframe,s32 sz)360 static s32 update_txdesc(struct xmit_frame *pxmitframe, s32 sz)
361 {
362 uint qsel;
363 u8 data_rate, pwr_status;
364 _adapter *padapter = pxmitframe->padapter;
365 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
366 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
367 struct pkt_attrib *pattrib = &pxmitframe->attrib;
368 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
369 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
370 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
371 u8 *ptxdesc;
372 sint bmcst = IS_MCAST(pattrib->ra);
373 u16 SWDefineContent = 0x0;
374 u8 DriverFixedRate = 0x0;
375
376 ptxdesc = pxmitframe->buf_addr;
377 _rtw_memset(ptxdesc, 0, TXDESC_SIZE);
378
379 /* offset 0 */
380 /*SET_TX_DESC_FIRST_SEG_8812(ptxdesc, 1);*/
381 SET_TX_DESC_LS_8822B(ptxdesc, 1);
382 /*SET_TX_DESC_OWN_8812(ptxdesc, 1);*/
383
384 SET_TX_DESC_TXPKTSIZE_8822B(ptxdesc, sz);
385 SET_TX_DESC_OFFSET_8822B(ptxdesc, TXDESC_SIZE);
386
387 #ifdef CONFIG_TX_EARLY_MODE
388 SET_TX_DESC_PKT_OFFSET_8812(ptxdesc, 1);
389 SET_TX_DESC_OFFSET_8822B(ptxdesc, TXDESC_SIZE + EARLY_MODE_INFO_SIZE);
390 #endif
391
392 if (bmcst)
393 SET_TX_DESC_BMC_8822B(ptxdesc, 1);
394
395 SET_TX_DESC_MACID_8822B(ptxdesc, pattrib->mac_id);
396 SET_TX_DESC_RATE_ID_8822B(ptxdesc, pattrib->raid);
397
398 SET_TX_DESC_QSEL_8822B(ptxdesc, pattrib->qsel);
399
400 if (!pattrib->qos_en) {
401 /* Hw set sequence number */
402 SET_TX_DESC_EN_HWSEQ_8822B(ptxdesc, 1);
403 SET_TX_DESC_EN_HWEXSEQ_8822B(ptxdesc, 0);
404 SET_TX_DESC_DISQSELSEQ_8822B(ptxdesc, 1);
405 SET_TX_DESC_HW_SSN_SEL_8822B(ptxdesc, 0);
406 } else
407 SET_TX_DESC_SW_SEQ_8822B(ptxdesc, pattrib->seqnum);
408
409 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
410 rtl8822b_fill_txdesc_sectype(pattrib, ptxdesc);
411 rtl8822b_fill_txdesc_vcs(padapter, pattrib, ptxdesc);
412
413 #ifdef CONFIG_CONCURRENT_MODE
414 if (bmcst)
415 rtl8822b_fill_txdesc_force_bmc_camid(pattrib, ptxdesc);
416 #endif
417
418 if ((pattrib->ether_type != 0x888e) &&
419 (pattrib->ether_type != 0x0806) &&
420 (pattrib->ether_type != 0x88b4) &&
421 (pattrib->dhcp_pkt != 1)
422 #ifdef CONFIG_AUTO_AP_MODE
423 && (pattrib->pctrl != _TRUE)
424 #endif
425 ) {
426 /* Non EAP & ARP & DHCP type data packet */
427
428 if (pattrib->ampdu_en == _TRUE) {
429 /* 8822b does NOT support AGG broadcast pkt */
430 if (!bmcst)
431 SET_TX_DESC_AGG_EN_8822B(ptxdesc, 1);
432
433 SET_TX_DESC_MAX_AGG_NUM_8822B(ptxdesc, 0x1f);
434 /* Set A-MPDU aggregation. */
435 SET_TX_DESC_AMPDU_DENSITY_8822B(ptxdesc,
436 pattrib->ampdu_spacing);
437 } else
438 SET_TX_DESC_BK_8822B(ptxdesc, 1);
439
440 rtl8822b_fill_txdesc_phy(padapter, pattrib, ptxdesc);
441
442 /* DATA Rate FB LMT */
443 /* compatibility for MCC consideration, use pmlmeext->cur_channel */
444 if (pmlmeext->cur_channel > 14)
445 /* for 5G. OFMD 6M */
446 SET_TX_DESC_DATA_RTY_LOWEST_RATE_8822B(
447 ptxdesc, 4);
448 else
449 /* for 2.4G. CCK 1M */
450 SET_TX_DESC_DATA_RTY_LOWEST_RATE_8822B(
451 ptxdesc, 0);
452
453 if (pHalData->fw_ractrl == _FALSE) {
454 SET_TX_DESC_USE_RATE_8822B(ptxdesc, 1);
455 DriverFixedRate = 0x01;
456
457 if (pHalData->INIDATA_RATE[pattrib->mac_id] &
458 BIT(7))
459 SET_TX_DESC_DATA_SHORT_8822B(
460 ptxdesc, 1);
461
462 SET_TX_DESC_DATARATE_8822B(ptxdesc,
463 pHalData->INIDATA_RATE[pattrib->mac_id]
464 & 0x7F);
465 }
466
467 if (padapter->fix_rate != 0xFF) {
468 /* modify data rate by iwpriv */
469 SET_TX_DESC_USE_RATE_8822B(ptxdesc, 1);
470
471 DriverFixedRate = 0x01;
472 if (padapter->fix_rate & BIT(7))
473 SET_TX_DESC_DATA_SHORT_8822B(
474 ptxdesc, 1);
475
476 SET_TX_DESC_DATARATE_8822B(ptxdesc,
477 (padapter->fix_rate & 0x7F));
478 if (!padapter->data_fb)
479 SET_TX_DESC_DISDATAFB_8822B(ptxdesc, 1);
480 }
481
482 if (pattrib->ldpc)
483 SET_TX_DESC_DATA_LDPC_8822B(ptxdesc, 1);
484 if (pattrib->stbc)
485 SET_TX_DESC_DATA_STBC_8822B(ptxdesc, 1);
486 } else {
487 /*
488 * EAP data packet and ARP packet and DHCP.
489 * Use the 1M data rate to send the EAP/ARP packet.
490 * This will maybe make the handshake smooth.
491 */
492
493 SET_TX_DESC_USE_RATE_8822B(ptxdesc, 1);
494 DriverFixedRate = 0x01;
495 SET_TX_DESC_BK_8822B(ptxdesc, 1);
496
497 /* HW will ignore this setting if the transmission rate
498 * is legacy OFDM. */
499 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
500 SET_TX_DESC_DATA_SHORT_8822B(ptxdesc, 1);
501
502 SET_TX_DESC_DATARATE_8822B(ptxdesc,
503 MRateToHwRate(pmlmeext->tx_rate));
504 }
505
506 #ifdef CONFIG_TDLS
507 #ifdef CONFIG_XMIT_ACK
508 /* CCX-TXRPT ack for xmit mgmt frames. */
509 if (pxmitframe->ack_report) {
510 SET_TX_DESC_SPE_RPT_8812(ptxdesc, 1);
511 #ifdef DBG_CCX
512 RTW_INFO("%s set tx report\n", __func__);
513 #endif
514 }
515 #endif /* CONFIG_XMIT_ACK */
516 #endif
517 } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) {
518 SET_TX_DESC_USE_RATE_8822B(ptxdesc, 1);
519 DriverFixedRate = 0x01;
520
521 #ifdef CONFIG_INTEL_PROXIM
522 if ((padapter->proximity.proxim_on == _TRUE) &&
523 (pattrib->intel_proxim == _TRUE)) {
524 RTW_INFO("\n %s pattrib->rate=%d\n",
525 __func__, pattrib->rate);
526 SET_TX_DESC_DATARATE_8822B(ptxdesc, pattrib->rate);
527 } else
528 #endif
529 SET_TX_DESC_DATARATE_8822B(ptxdesc,
530 MRateToHwRate(pattrib->rate));
531
532 #if 1 /* 8822bu add */
533 /* VHT NDPA or HT NDPA Packet for Beamformer. */
534 if ((pattrib->subtype == WIFI_NDPA) ||
535 ((pattrib->subtype == WIFI_ACTION_NOACK) &&
536 (pattrib->order == 1))) {
537
538 SET_TX_DESC_NAVUSEHDR_8822B(ptxdesc, 1);
539
540 SET_TX_DESC_DATA_BW_8822B(ptxdesc,
541 rtl8822b_bw_mapping(padapter, pattrib));
542 SET_TX_DESC_RTS_SC_8822B(ptxdesc,
543 rtl8822b_sc_mapping(padapter, pattrib));
544
545 SET_TX_DESC_RTY_LMT_EN_8822B(ptxdesc, 1);
546 SET_TX_DESC_RTS_DATA_RTY_LMT_8822B(ptxdesc, 5);
547 SET_TX_DESC_DISRTSFB_8822B(ptxdesc, 1);
548 SET_TX_DESC_NDPA_8822B(ptxdesc, 1);
549 } else {
550 SET_TX_DESC_RTY_LMT_EN_8822B(ptxdesc, 1);
551 if (pattrib->retry_ctrl == _TRUE)
552 SET_TX_DESC_RTS_DATA_RTY_LMT_8822B(ptxdesc, 6);
553 else
554 SET_TX_DESC_RTS_DATA_RTY_LMT_8822B(ptxdesc, 12);
555 }
556 #endif
557
558 #ifdef CONFIG_XMIT_ACK
559 /* CCX-TXRPT ack for xmit mgmt frames. */
560 if (pxmitframe->ack_report) {
561 SET_TX_DESC_SPE_RPT_8822B(ptxdesc, 1);
562 #ifdef DBG_CCX
563 RTW_INFO("%s set tx report\n", __func__);
564 #endif
565 }
566 #endif /* CONFIG_XMIT_ACK */
567 } else if ((pxmitframe->frame_tag & 0x0f) == TXAGG_FRAMETAG)
568 RTW_INFO("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
569 #ifdef CONFIG_MP_INCLUDED
570 else if (((pxmitframe->frame_tag & 0x0f) == MP_FRAMETAG) &&
571 (padapter->registrypriv.mp_mode == 1))
572 fill_txdesc_for_mp(padapter, ptxdesc);
573 #endif
574 else {
575 RTW_INFO("pxmitframe->frame_tag = %d\n",
576 pxmitframe->frame_tag);
577
578 SET_TX_DESC_USE_RATE_8822B(ptxdesc, 1);
579 DriverFixedRate = 0x01;
580 SET_TX_DESC_DATARATE_8822B(ptxdesc,
581 MRateToHwRate(pmlmeext->tx_rate));
582 }
583
584 #ifdef CONFIG_ANTENNA_DIVERSITY
585 ODM_SetTxAntByTxInfo(&pHalData->odmpriv, ptxdesc,
586 pxmitframe->attrib.mac_id);
587 #endif
588
589 #ifdef CONFIG_BEAMFORMING
590 SET_TX_DESC_G_ID_8822B(ptxdesc, pattrib->txbf_g_id);
591 SET_TX_DESC_P_AID_8822B(ptxdesc, pattrib->txbf_p_aid);
592 #endif
593
594 /*SET_TX_DESC_TX_BUFFER_SIZE_8812(ptxdesc, sz);*/
595
596 if (DriverFixedRate)
597 SWDefineContent |= 0x01;
598
599 SET_TX_DESC_SW_DEFINE_8822B(ptxdesc, SWDefineContent);
600
601 rtl8822b_cal_txdesc_chksum(padapter, ptxdesc);
602 rtl8822b_dbg_dump_tx_desc(padapter, pxmitframe->frame_tag, ptxdesc);
603 return 0;
604 }
605
rtl8822be_dump_xframe(_adapter * padapter,struct xmit_frame * pxmitframe)606 s32 rtl8822be_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
607 {
608 s32 ret = _SUCCESS;
609 s32 inner_ret = _SUCCESS;
610 _irqL irqL;
611 int t, sz, w_sz, pull = 0;
612 u32 ff_hwaddr;
613 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
614 struct pkt_attrib *pattrib = &pxmitframe->attrib;
615 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
616 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
617 struct security_priv *psecuritypriv = &padapter->securitypriv;
618 u8 *txbd;
619 struct rtw_tx_ring *ptx_ring;
620
621 DBG_COUNTER(padapter->tx_logs.intf_tx_dump_xframe);
622 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
623 ("rtl8822be_dump_xframe()\n"));
624
625 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
626 (pxmitframe->attrib.ether_type != 0x0806) &&
627 (pxmitframe->attrib.ether_type != 0x888e) &&
628 (pxmitframe->attrib.dhcp_pkt != 1))
629 rtw_issue_addbareq_cmd(padapter, pxmitframe);
630
631 for (t = 0; t < pattrib->nr_frags; t++) {
632
633 if (inner_ret != _SUCCESS && ret == _SUCCESS)
634 ret = _FAIL;
635
636 if (t != (pattrib->nr_frags - 1)) {
637 RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
638 ("pattrib->nr_frags=%d\n", pattrib->nr_frags));
639
640 sz = pxmitpriv->frag_len - 4;
641
642 if (!psecuritypriv->sw_encrypt)
643 sz -= pattrib->icv_len;
644 } else {
645 /* no frag */
646 sz = pattrib->last_txcmdsz;
647 }
648
649 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
650
651 _enter_critical(&pdvobjpriv->irq_th_lock, &irqL);
652 txbd = get_txbd(GET_PRIMARY_ADAPTER(padapter), ff_hwaddr);
653
654 ptx_ring = &(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.tx_ring[ff_hwaddr]);
655
656 #ifndef CONFIG_BCN_ICF
657 if (BCN_QUEUE_INX == ff_hwaddr)
658 padapter->xmitpriv.beaconDMAing = _TRUE;
659 #endif
660
661 if (txbd == NULL) {
662 _exit_critical(&pdvobjpriv->irq_th_lock, &irqL);
663 rtw_sctx_done_err(&pxmitbuf->sctx,
664 RTW_SCTX_DONE_TX_DESC_NA);
665 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
666 RTW_INFO("##### Tx desc unavailable !#####\n");
667 DBG_COUNTER(padapter->tx_logs.intf_tx_dump_xframe_err_txdesc);
668 break;
669 }
670
671 if (pattrib->qsel != HALMAC_TXDESC_QSEL_H2C_CMD)
672 update_txdesc(pxmitframe, sz);
673
674 /* rtl8822be_update_txbd() must be called after update_txdesc().
675 * It rely on rtl8822be_update_txbd() to map it into non cache
676 * memory */
677
678 rtl8822be_update_txbd(pxmitframe, txbd, sz);
679
680 if (pxmitbuf->buf_tag != XMITBUF_CMD)
681 rtl8822be_enqueue_xmitbuf(ptx_ring, pxmitbuf);
682
683 pxmitbuf->len = sz + TX_WIFI_INFO_SIZE;
684 w_sz = sz;
685
686 /* Please comment here */
687 wmb();
688 fill_txbd_own(padapter, txbd, ff_hwaddr, ptx_ring);
689
690 _exit_critical(&pdvobjpriv->irq_th_lock, &irqL);
691
692 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz,
693 (unsigned char *)pxmitbuf);
694 if (inner_ret != _SUCCESS)
695 DBG_COUNTER(padapter->tx_logs.intf_tx_dump_xframe_err_port);
696
697 rtw_count_tx_stats(padapter, pxmitframe, sz);
698 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
699 ("rtw_write_port, w_sz=%d\n", w_sz));
700 }
701
702 rtw_free_xmitframe(pxmitpriv, pxmitframe);
703
704 if (ret != _SUCCESS)
705 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
706
707 return ret;
708 }
709
710 /*
711 * Packet should not be dequeued if there is no available descriptor
712 * return: _SUCCESS if there is available descriptor
713 */
check_tx_desc_resource(_adapter * padapter,int prio)714 static u8 check_tx_desc_resource(_adapter *padapter, int prio)
715 {
716 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
717 struct rtw_tx_ring *ring;
718
719 ring = &pxmitpriv->tx_ring[prio];
720
721 /*
722 * for now we reserve two free descriptor as a safety boundary
723 * between the tail and the head
724 */
725
726 if ((ring->entries - ring->qlen) >= 2)
727 return _TRUE;
728 else
729 return _FALSE;
730 }
731
check_nic_enough_desc_all(_adapter * padapter)732 static u8 check_nic_enough_desc_all(_adapter *padapter)
733 {
734 u8 status = (check_tx_desc_resource(padapter, VI_QUEUE_INX) &&
735 check_tx_desc_resource(padapter, VO_QUEUE_INX) &&
736 check_tx_desc_resource(padapter, BE_QUEUE_INX) &&
737 check_tx_desc_resource(padapter, BK_QUEUE_INX) &&
738 check_tx_desc_resource(padapter, MGT_QUEUE_INX) &&
739 check_tx_desc_resource(padapter, TXCMD_QUEUE_INX) &&
740 check_tx_desc_resource(padapter, HIGH_QUEUE_INX));
741 return status;
742 }
743 #ifdef TX_AMSDU
xmitframe_amsdu_direct(_adapter * padapter,struct xmit_frame * pxmitframe)744 static s32 xmitframe_amsdu_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
745 {
746 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
747 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
748 s32 res = _SUCCESS;
749
750 res = rtw_xmitframe_coalesce_amsdu(padapter, pxmitframe, NULL);
751
752 if(res == _FAIL)
753 goto free_frame;
754
755 DBG_COUNTER(padapter->tx_logs.intf_tx_dequeue);
756 res = rtl8822be_dump_xframe(padapter, pxmitframe);
757
758 if (res == _FAIL) {
759 DBG_COUNTER(padapter->tx_logs.intf_tx_dequeue_err_coalesce);
760 goto free_frame;
761 }
762
763 return res;
764
765 free_frame:
766 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
767 rtw_free_xmitframe(pxmitpriv, pxmitframe);
768
769 return res;
770 }
771 #endif
772
xmitframe_direct(_adapter * padapter,struct xmit_frame * pxmitframe)773 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
774 {
775 s32 res = _SUCCESS;
776
777 DBG_COUNTER(padapter->tx_logs.intf_tx_direct);
778 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
779 if (res == _SUCCESS)
780 rtl8822be_dump_xframe(padapter, pxmitframe);
781 else
782 DBG_COUNTER(padapter->tx_logs.intf_tx_direct_err_coalesce);
783
784 return res;
785 }
786
rtl8822be_xmitframe_resume(_adapter * padapter)787 void rtl8822be_xmitframe_resume(_adapter *padapter)
788 {
789 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
790 struct xmit_frame *pxmitframe = NULL;
791 struct xmit_buf *pxmitbuf = NULL;
792 int res = _SUCCESS, xcnt = 0;
793
794 #ifdef TX_AMSDU
795 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
796 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
797
798 int tx_amsdu = padapter->tx_amsdu;
799 int tx_amsdu_rate = padapter->tx_amsdu_rate;
800 int current_tx_rate = pdvobjpriv->traffic_stat.cur_tx_tp;
801
802 struct pkt_attrib *pattrib = NULL;
803
804 struct xmit_frame *pxmitframe_next = NULL;
805 struct xmit_buf *pxmitbuf_next = NULL;
806 struct pkt_attrib *pattrib_next = NULL;
807 int num_frame = 0;
808
809 u8 amsdu_timeout = 0;
810 #endif
811
812 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("%s()\n", __func__));
813
814 while (1) {
815 if (RTW_CANNOT_RUN(padapter)) {
816 RTW_INFO("%s => bDriverStopped or bSurpriseRemoved\n",
817 __func__);
818 break;
819 }
820
821 if (!check_nic_enough_desc_all(padapter))
822 break;
823
824 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
825 if (!pxmitbuf)
826 break;
827
828 #ifdef TX_AMSDU
829 if(tx_amsdu == 0)
830 goto dump_pkt;
831
832 if(!check_fwstate(pmlmepriv, WIFI_STATION_STATE))
833 goto dump_pkt;
834
835 pxmitframe = rtw_get_xframe(pxmitpriv, &num_frame);
836
837 if(num_frame == 0 || pxmitframe == NULL || !check_amsdu(pxmitframe))
838 goto dump_pkt;
839
840 if(tx_amsdu == 1)
841 {
842 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
843 if (pxmitframe)
844 {
845 pxmitframe->pxmitbuf = pxmitbuf;
846 pxmitframe->buf_addr = pxmitbuf->pbuf;
847 pxmitbuf->priv_data = pxmitframe;
848 xmitframe_amsdu_direct(padapter, pxmitframe);
849 pxmitpriv->amsdu_debug_coalesce_one++;
850 continue;
851 }
852 else
853 {
854 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
855 break;
856 }
857 }
858 else if(tx_amsdu == 2 && ((tx_amsdu_rate == 0) || (current_tx_rate > tx_amsdu_rate)))
859 {
860
861 if(num_frame == 1)
862 {
863 pattrib = &pxmitframe->attrib;
864 amsdu_timeout = rtw_amsdu_get_timer_status(padapter, pattrib->priority);
865
866 if(amsdu_timeout == RTW_AMSDU_TIMER_UNSET)
867 {
868 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
869 rtw_amsdu_set_timer_status(padapter, pattrib->priority, RTW_AMSDU_TIMER_SETTING);
870 rtw_amsdu_set_timer(padapter, pattrib->priority);
871 pxmitpriv->amsdu_debug_set_timer++;
872 break;
873 }
874 else if(amsdu_timeout == RTW_AMSDU_TIMER_SETTING)
875 {
876 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
877 break;
878 }
879 else if(amsdu_timeout == RTW_AMSDU_TIMER_TIMEOUT)
880 {
881 rtw_amsdu_set_timer_status(padapter, pattrib->priority, RTW_AMSDU_TIMER_UNSET);
882 pxmitpriv->amsdu_debug_timeout++;
883 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
884 if (pxmitframe)
885 {
886 pxmitframe->pxmitbuf = pxmitbuf;
887 pxmitframe->buf_addr = pxmitbuf->pbuf;
888 pxmitbuf->priv_data = pxmitframe;
889 xmitframe_amsdu_direct(padapter, pxmitframe);
890 break;
891 }
892 else
893 {
894 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
895 break;
896 }
897
898 }
899 }
900 else/* num_frame > 1*/
901 {
902 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
903
904 if(!pxmitframe)
905 {
906 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
907 break;
908 }
909
910 pxmitframe->pxmitbuf = pxmitbuf;
911 pxmitframe->buf_addr = pxmitbuf->pbuf;
912 pxmitbuf->priv_data = pxmitframe;
913
914 pxmitframe_next = rtw_get_xframe(pxmitpriv, &num_frame);
915
916 if(num_frame == 0)
917 {
918 xmitframe_amsdu_direct(padapter, pxmitframe);
919 pxmitpriv->amsdu_debug_coalesce_one++;
920 break;
921 }
922
923 if(!check_amsdu(pxmitframe_next))
924 {
925 xmitframe_amsdu_direct(padapter, pxmitframe);
926 pxmitpriv->amsdu_debug_coalesce_one++;
927 continue;
928 }
929 else
930 {
931 pxmitbuf_next = rtw_alloc_xmitbuf(pxmitpriv);
932 if (!pxmitbuf_next)
933 {
934 xmitframe_amsdu_direct(padapter, pxmitframe);
935 pxmitpriv->amsdu_debug_coalesce_one++;
936 continue;
937 }
938
939 pxmitframe_next = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
940 if(!pxmitframe_next)
941 {
942 rtw_free_xmitbuf(pxmitpriv, pxmitbuf_next);
943 xmitframe_amsdu_direct(padapter, pxmitframe);
944 pxmitpriv->amsdu_debug_coalesce_one++;
945 continue;
946 }
947 pxmitframe_next->pxmitbuf = pxmitbuf_next;
948 pxmitframe_next->buf_addr = pxmitbuf_next->pbuf;
949 pxmitbuf_next->priv_data = pxmitframe_next;
950
951 rtw_xmitframe_coalesce_amsdu(padapter, pxmitframe_next , pxmitframe);
952 rtw_free_xmitframe(pxmitpriv, pxmitframe);
953 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
954
955 rtl8822be_dump_xframe(padapter, pxmitframe_next);
956 pxmitpriv->amsdu_debug_coalesce_two++;
957
958 continue;
959 }
960
961 }
962
963 }
964 dump_pkt:
965 #endif
966
967 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits,
968 pxmitpriv->hwxmit_entry);
969
970 if (pxmitframe) {
971 pxmitframe->pxmitbuf = pxmitbuf;
972 pxmitframe->buf_addr = pxmitbuf->pbuf;
973 pxmitbuf->priv_data = pxmitframe;
974
975 if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
976 if (pxmitframe->attrib.priority <= 15) {
977 /* TID0~15 */
978 res = rtw_xmitframe_coalesce(padapter,
979 pxmitframe->pkt, pxmitframe);
980 }
981
982 /* always return ndis_packet after
983 * rtw_xmitframe_coalesce */
984 rtw_os_xmit_complete(padapter, pxmitframe);
985 }
986
987 DBG_COUNTER(padapter->tx_logs.intf_tx_dequeue);
988 RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_,
989 ("%s(): rtl8822be_dump_xframe\n", __func__));
990
991 if (res == _SUCCESS)
992 rtl8822be_dump_xframe(padapter, pxmitframe);
993 else {
994 DBG_COUNTER(padapter->tx_logs.intf_tx_dequeue_err_coalesce);
995 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
996 rtw_free_xmitframe(pxmitpriv, pxmitframe);
997 }
998
999 xcnt++;
1000 } else {
1001 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1002 break;
1003 }
1004 }
1005 }
1006
check_nic_enough_desc(_adapter * padapter,struct pkt_attrib * pattrib)1007 static u8 check_nic_enough_desc(_adapter *padapter, struct pkt_attrib *pattrib)
1008 {
1009 u32 prio;
1010 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1011 struct rtw_tx_ring *ring;
1012
1013 switch (pattrib->qsel) {
1014 case 0:
1015 case 3:
1016 prio = BE_QUEUE_INX;
1017 break;
1018 case 1:
1019 case 2:
1020 prio = BK_QUEUE_INX;
1021 break;
1022 case 4:
1023 case 5:
1024 prio = VI_QUEUE_INX;
1025 break;
1026 case 6:
1027 case 7:
1028 prio = VO_QUEUE_INX;
1029 break;
1030 default:
1031 prio = BE_QUEUE_INX;
1032 break;
1033 }
1034
1035 ring = &pxmitpriv->tx_ring[prio];
1036
1037 /*
1038 * for now we reserve two free descriptor as a safety boundary
1039 * between the tail and the head
1040 */
1041 if ((ring->entries - ring->qlen) >= 2)
1042 return _TRUE;
1043 else
1044 return _FALSE;
1045 }
1046
1047 /*
1048 * Return
1049 * _TRUE dump packet directly
1050 * _FALSE enqueue packet
1051 */
pre_xmitframe(_adapter * padapter,struct xmit_frame * pxmitframe)1052 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
1053 {
1054 _irqL irqL;
1055 s32 res;
1056 struct xmit_buf *pxmitbuf = NULL;
1057 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1058 struct pkt_attrib *pattrib = &pxmitframe->attrib;
1059 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1060
1061 #ifdef TX_AMSDU
1062 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
1063 int tx_amsdu = padapter->tx_amsdu;
1064 int tx_amsdu_rate = padapter->tx_amsdu_rate;
1065 int current_tx_rate = pdvobjpriv->traffic_stat.cur_tx_tp;
1066
1067 u8 amsdu_timeout = 0;
1068 #endif
1069
1070 _enter_critical_bh(&pxmitpriv->lock, &irqL);
1071
1072 if ((rtw_txframes_sta_ac_pending(padapter, pattrib) > 0) ||
1073 (check_nic_enough_desc(padapter, pattrib) == _FALSE)) {
1074 DBG_COUNTER(padapter->tx_logs.intf_tx_pending_ac);
1075 goto enqueue;
1076 }
1077
1078 if (rtw_xmit_ac_blocked(padapter) == _TRUE) {
1079 DBG_COUNTER(padapter->tx_logs.intf_tx_pending_fw_under_survey);
1080 goto enqueue;
1081 }
1082
1083 if (padapter->dvobj->iface_state.lg_sta_num) {
1084 DBG_COUNTER(padapter->tx_logs.intf_tx_pending_fw_under_linking);
1085 goto enqueue;
1086 }
1087
1088 #ifdef TX_AMSDU
1089 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1090 {
1091 if(tx_amsdu == 1)
1092 goto enqueue;
1093 else if(tx_amsdu == 2 && (tx_amsdu_rate == 0 || current_tx_rate > tx_amsdu_rate))
1094 goto enqueue;
1095 }
1096 #endif
1097
1098 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1099 if (pxmitbuf == NULL) {
1100 DBG_COUNTER(padapter->tx_logs.intf_tx_pending_xmitbuf);
1101 goto enqueue;
1102 }
1103
1104 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1105
1106 pxmitframe->pxmitbuf = pxmitbuf;
1107 pxmitframe->buf_addr = pxmitbuf->pbuf;
1108 pxmitbuf->priv_data = pxmitframe;
1109
1110 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
1111 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1112 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1113 }
1114
1115 return _TRUE;
1116
1117 enqueue:
1118 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
1119
1120 #ifdef TX_AMSDU
1121 if(res == _SUCCESS && tx_amsdu == 2)
1122 {
1123 amsdu_timeout = rtw_amsdu_get_timer_status(padapter, pattrib->priority);
1124 if(amsdu_timeout == RTW_AMSDU_TIMER_SETTING)
1125 {
1126 rtw_amsdu_cancel_timer(padapter, pattrib->priority);
1127 rtw_amsdu_set_timer_status(padapter, pattrib->priority, RTW_AMSDU_TIMER_UNSET);
1128 }
1129 }
1130 #endif
1131
1132 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1133
1134 if (res != _SUCCESS) {
1135 RT_TRACE(_module_xmit_osdep_c_, _drv_err_,
1136 ("pre_xmitframe: enqueue xmitframe fail\n"));
1137 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1138
1139 pxmitpriv->tx_drop++;
1140 return _TRUE;
1141 }
1142
1143 #ifdef TX_AMSDU
1144 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1145 #endif
1146
1147 return _FALSE;
1148 }
1149
rtl8822be_mgnt_xmit(_adapter * padapter,struct xmit_frame * pmgntframe)1150 s32 rtl8822be_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
1151 {
1152 return rtl8822be_dump_xframe(padapter, pmgntframe);
1153 }
1154
1155 /*
1156 * Return
1157 * _TRUE dump packet directly ok
1158 * _FALSE temporary can't transmit packets to hardware
1159 */
rtl8822be_hal_xmit(_adapter * padapter,struct xmit_frame * pxmitframe)1160 s32 rtl8822be_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
1161 {
1162 DBG_COUNTER(padapter->tx_logs.intf_tx);
1163 return pre_xmitframe(padapter, pxmitframe);
1164 }
1165
rtl8822be_hal_xmitframe_enqueue(_adapter * padapter,struct xmit_frame * pxmitframe)1166 s32 rtl8822be_hal_xmitframe_enqueue(_adapter *padapter,
1167 struct xmit_frame *pxmitframe)
1168 {
1169 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1170 s32 err;
1171
1172 DBG_COUNTER(padapter->tx_logs.intf_tx_enqueue);
1173 err = rtw_xmitframe_enqueue(padapter, pxmitframe);
1174 if (err != _SUCCESS) {
1175 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1176 pxmitpriv->tx_drop++;
1177 } else {
1178 #ifdef PLATFORM_LINUX
1179 if (check_nic_enough_desc(padapter,
1180 &pxmitframe->attrib) == _TRUE)
1181 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1182 #endif
1183 }
1184
1185 return err;
1186 }
1187
rtl8822be_init_txbd_ring(_adapter * padapter,unsigned int q_idx,unsigned int entries)1188 int rtl8822be_init_txbd_ring(_adapter *padapter, unsigned int q_idx,
1189 unsigned int entries)
1190 {
1191 struct xmit_priv *t_priv = &padapter->xmitpriv;
1192 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
1193 struct pci_dev *pdev = pdvobjpriv->ppcidev;
1194 struct tx_buf_desc *txbd;
1195 u8 *tx_desc;
1196 dma_addr_t dma;
1197 int i;
1198
1199 _func_enter_;
1200
1201 RTW_INFO("%s entries num:%d\n", __func__, entries);
1202
1203 txbd = pci_alloc_consistent(pdev, sizeof(*txbd) * entries, &dma);
1204
1205 if (!txbd || (unsigned long)txbd & 0xFF) {
1206 RTW_INFO("Cannot allocate TXBD (q_idx = %d)\n", q_idx);
1207 return _FAIL;
1208 }
1209
1210 _rtw_memset(txbd, 0, sizeof(*txbd) * entries);
1211 t_priv->tx_ring[q_idx].buf_desc = txbd;
1212 t_priv->tx_ring[q_idx].dma = dma;
1213 t_priv->tx_ring[q_idx].idx = 0;
1214 t_priv->tx_ring[q_idx].entries = entries;
1215 _rtw_init_queue(&t_priv->tx_ring[q_idx].queue);
1216 t_priv->tx_ring[q_idx].qlen = 0;
1217
1218 RTW_INFO("%s queue:%d, ring_addr:%p\n", __func__, q_idx, txbd);
1219
1220 _func_exit_;
1221
1222 return _SUCCESS;
1223 }
1224
rtl8822be_free_txbd_ring(_adapter * padapter,unsigned int prio)1225 void rtl8822be_free_txbd_ring(_adapter *padapter, unsigned int prio)
1226 {
1227 struct xmit_priv *t_priv = &padapter->xmitpriv;
1228 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
1229 struct pci_dev *pdev = pdvobjpriv->ppcidev;
1230 struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
1231 u8 *txbd;
1232 struct xmit_buf *pxmitbuf;
1233
1234 _func_enter_;
1235
1236 while (ring->qlen) {
1237 txbd = (u8 *)(&ring->buf_desc[ring->idx]);
1238 SET_TX_BD_OWN(txbd, 0);
1239
1240 if (prio != BCN_QUEUE_INX)
1241 ring->idx = (ring->idx + 1) % ring->entries;
1242
1243 pxmitbuf = rtl8822be_dequeue_xmitbuf(ring);
1244
1245 if (pxmitbuf) {
1246 pci_unmap_single(pdev,
1247 GET_TX_BD_PHYSICAL_ADDR0_LOW(txbd),
1248 pxmitbuf->len, PCI_DMA_TODEVICE);
1249
1250 rtw_free_xmitbuf(t_priv, pxmitbuf);
1251
1252 } else {
1253 RTW_INFO("%s qlen=%d!=0,but have xmitbuf in pendingQ\n",
1254 __func__, ring->qlen);
1255 break;
1256 }
1257 }
1258
1259 pci_free_consistent(pdev, sizeof(*ring->buf_desc) * ring->entries,
1260 ring->buf_desc, ring->dma);
1261 ring->buf_desc = NULL;
1262
1263 _func_exit_;
1264 }
1265
1266 /*
1267 * Draw a line to show queue status. For debug
1268 * i: queue index / W:HW index / h:host index / .: enpty entry / *:ready to DMA
1269 * Example: R- 3- 4- 8 ..iW***h..... (i=3,W=4,h=8,
1270 * *** means 3 tx_desc is reaady to dma)
1271 */
1272 #ifdef BUF_DESC_DEBUG
_draw_queue(PADAPTER Adapter,int prio)1273 static void _draw_queue(PADAPTER Adapter, int prio)
1274 {
1275 int i;
1276 u8 line[TXBD_NUM + 1];
1277 u16 hw, host;
1278 u32 index, tmp_4bytes = 0;
1279
1280 struct xmit_priv *t_priv = &Adapter->xmitpriv;
1281 struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
1282
1283 tmp_4bytes = rtw_read32(Adapter, get_txbd_rw_reg(prio));
1284 hw = (u16)((tmp_4bytes >> 16) & 0x7ff);
1285 host = (u16)(tmp_4bytes & 0x7ff);
1286
1287 index = ring->idx;
1288 _rtw_memset(line, '.', TXBD_NUM);
1289
1290 /* ready to return to driver */
1291 if (index <= hw) {
1292 for (i = index; i < hw; i++)
1293 line[i] = ':';
1294 } else { /* wrap */
1295 for (i = index; i < TXBD_NUM; i++)
1296 line[i] = ':';
1297 for (i = 0; i < hw; i++)
1298 line[i] = ':';
1299 }
1300
1301 /* ready to dma */
1302 if (hw <= host) {
1303 for (i = hw; i < host; i++)
1304 line[i] = '*';
1305 } else { /* wrap */
1306 for (i = hw; i < TXBD_NUM; i++)
1307 line[i] = '*';
1308 for (i = 0; i < host; i++)
1309 line[i] = '*';
1310 }
1311
1312 line[index] = 'i'; /* software queue index */
1313 line[host] = 'h'; /* host index */
1314 line[hw] = 'W'; /* hardware index */
1315 line[TXBD_NUM] = 0x0;
1316
1317 /* Q2:10-20-30: */
1318 buf_desc_debug("Q%d:%02d-%02d-%02d %s\n", prio, index, hw, host, line);
1319 }
1320 #endif
1321
1322 /*
1323 * Read pointer is h/w descriptor index
1324 * Write pointer is host desciptor index: For tx side, if own bit is set in
1325 * packet index n, host pointer (write pointer) point to index n + 1.
1326 */
rtl8822be_check_txdesc_closed(PADAPTER Adapter,u32 queue_idx,struct rtw_tx_ring * ring)1327 static u32 rtl8822be_check_txdesc_closed(PADAPTER Adapter, u32 queue_idx,
1328 struct rtw_tx_ring *ring)
1329 {
1330 /*
1331 * hw_rp_cache is used to reduce REG access.
1332 */
1333 u32 tmp32;
1334
1335 /* bcn queue should not enter this function */
1336 if (queue_idx == BCN_QUEUE_INX)
1337 return _TRUE;
1338
1339 /* qlen == 0 --> don't need to process */
1340 if (ring->qlen == 0)
1341 return _FALSE;
1342
1343 /* sw_rp == hw_rp_cache --> sync hw_rp */
1344 if (ring->idx == ring->hw_rp_cache) {
1345
1346 tmp32 = rtw_read32(Adapter, get_txbd_rw_reg(queue_idx));
1347
1348 ring->hw_rp_cache = (tmp32 >> 16) & 0x0FFF;
1349 }
1350
1351 /* check if need to handle TXOK */
1352 if (ring->idx == ring->hw_rp_cache)
1353 return _FALSE;
1354
1355 return _TRUE;
1356 }
1357
1358 #ifdef CONFIG_BCN_ICF
rtl8822be_tx_isr(PADAPTER Adapter,int prio)1359 void rtl8822be_tx_isr(PADAPTER Adapter, int prio)
1360 {
1361 struct xmit_priv *t_priv = &Adapter->xmitpriv;
1362 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
1363 struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
1364 struct xmit_buf *pxmitbuf;
1365 u8 *tx_desc;
1366 u16 tmp_4bytes;
1367 u16 desc_idx_hw = 0, desc_idx_host = 0;
1368
1369
1370 while (ring->qlen) {
1371 tx_desc = (u8 *)&ring->buf_desc[ring->idx];
1372
1373 /* beacon use cmd buf Never run into here */
1374 if (!rtl8822be_check_txdesc_closed(Adapter, prio, ring))
1375 return;
1376
1377 buf_desc_debug("TX: %s, q_idx = %d, tx_bd = %04x, close [%04x] r_idx [%04x]\n",
1378 __func__, prio, (u32)tx_desc, ring->idx,
1379 (ring->idx + 1) % ring->entries);
1380
1381 ring->idx = (ring->idx + 1) % ring->entries;
1382 pxmitbuf = rtl8822be_dequeue_xmitbuf(ring);
1383
1384 if (pxmitbuf) {
1385 pci_unmap_single(pdvobjpriv->ppcidev,
1386 GET_TX_BD_PHYSICAL_ADDR0_LOW(tx_desc),
1387 pxmitbuf->len, PCI_DMA_TODEVICE);
1388
1389 rtw_sctx_done(&pxmitbuf->sctx);
1390 rtw_free_xmitbuf(&(pxmitbuf->padapter->xmitpriv),
1391 pxmitbuf);
1392 } else {
1393 RTW_INFO("%s qlen=%d!=0,but have xmitbuf in pendingQ\n",
1394 __func__, ring->qlen);
1395 }
1396 }
1397
1398 if (check_tx_desc_resource(Adapter, prio)
1399 && rtw_xmit_ac_blocked(Adapter) != _TRUE)
1400 rtw_mi_xmit_tasklet_schedule(Adapter);
1401 }
1402
1403 #else /* !CONFIG_BCN_ICF */
rtl8822be_tx_isr(PADAPTER Adapter,int prio)1404 void rtl8822be_tx_isr(PADAPTER Adapter, int prio)
1405 {
1406 struct xmit_priv *t_priv = &Adapter->xmitpriv;
1407 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
1408 struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
1409 struct xmit_buf *pxmitbuf;
1410 u8 *tx_desc;
1411 u16 tmp_4bytes;
1412 u16 desc_idx_hw = 0, desc_idx_host = 0;
1413
1414
1415 while (ring->qlen) {
1416 tx_desc = (u8 *)&ring->buf_desc[ring->idx];
1417
1418 /*
1419 * beacon packet will only use the first descriptor defautly,
1420 * check register to see whether h/w has consumed buffer
1421 * descriptor
1422 */
1423 if (prio != BCN_QUEUE_INX) {
1424 if (!rtl8822be_check_txdesc_closed(Adapter,
1425 prio, ring->idx))
1426 return;
1427
1428 buf_desc_debug("TX: %s, queue_idx = %d, tx_desc = %04x, close desc [%04x] and update ring->idx to [%04x]\n",
1429 __func__, prio, (u32)tx_desc, ring->idx,
1430 (ring->idx + 1) % ring->entries);
1431 ring->idx = (ring->idx + 1) % ring->entries;
1432 }
1433 #if 0 /* 8822b change 00[31] to DISQSELSEQ */
1434 else if (prio == BCN_QUEUE_INX)
1435 SET_TX_DESC_OWN_92E(tx_desc, 0);
1436 #endif
1437
1438 pxmitbuf = rtl8822be_dequeue_xmitbuf(ring);
1439 if (pxmitbuf) {
1440 pci_unmap_single(pdvobjpriv->ppcidev,
1441 GET_TX_BD_PHYSICAL_ADDR0_LOW(tx_desc),
1442 pxmitbuf->len, PCI_DMA_TODEVICE);
1443 rtw_sctx_done(&pxmitbuf->sctx);
1444 rtw_free_xmitbuf(&(pxmitbuf->padapter->xmitpriv),
1445 pxmitbuf);
1446 } else {
1447 RTW_INFO("%s qlen=%d!=0,but have xmitbuf in pendingQ\n",
1448 __func__, ring->qlen);
1449 }
1450 }
1451
1452 if ((prio != BCN_QUEUE_INX) && check_tx_desc_resource(Adapter, prio)
1453 && rtw_xmit_ac_blocked(Adapter) != _TRUE)
1454 rtw_mi_xmit_tasklet_schedule(Adapter);
1455 }
1456 #endif /* CONFIG_BCN_ICF */
1457
1458 #ifdef CONFIG_HOSTAPD_MLME
rtl8812ae_hostap_mgnt_xmit_cb(struct urb * urb)1459 static void rtl8812ae_hostap_mgnt_xmit_cb(struct urb *urb)
1460 {
1461 #ifdef PLATFORM_LINUX
1462 struct sk_buff *skb = (struct sk_buff *)urb->context;
1463
1464 dev_kfree_skb_any(skb);
1465 #endif
1466 }
1467
rtl8822be_hostap_mgnt_xmit_entry(_adapter * padapter,_pkt * pkt)1468 s32 rtl8822be_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1469 {
1470 #ifdef PLATFORM_LINUX
1471 u16 fc;
1472 int rc, len, pipe;
1473 unsigned int bmcst, tid, qsel;
1474 struct sk_buff *skb, *pxmit_skb;
1475 struct urb *urb;
1476 unsigned char *pxmitbuf;
1477 struct tx_desc *ptxdesc;
1478 struct rtw_ieee80211_hdr *tx_hdr;
1479 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
1480 struct net_device *pnetdev = padapter->pnetdev;
1481 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1482 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
1483
1484
1485 skb = pkt;
1486 len = skb->len;
1487 tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
1488 fc = le16_to_cpu(tx_hdr->frame_ctl);
1489 bmcst = IS_MCAST(tx_hdr->addr1);
1490
1491 if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
1492 goto _exit;
1493
1494 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
1495 /* http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html */
1496 pxmit_skb = dev_alloc_skb(len + TXDESC_SIZE);
1497 #else
1498 pxmit_skb = netdev_alloc_skb(pnetdev, len + TXDESC_SIZE);
1499 #endif
1500
1501 if (!pxmit_skb)
1502 goto _exit;
1503
1504 pxmitbuf = pxmit_skb->data;
1505
1506 urb = usb_alloc_urb(0, GFP_ATOMIC);
1507 if (!urb)
1508 goto _exit;
1509
1510 /* ----- fill tx desc ----- */
1511 ptxdesc = (struct tx_desc *)pxmitbuf;
1512 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1513
1514 /* offset 0 */
1515 ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
1516 /* default = 32 bytes for TX Desc */
1517 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) &
1518 0x00ff0000);
1519 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1520
1521 if (bmcst)
1522 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1523
1524 /* offset 4 */
1525 ptxdesc->txdw1 |= cpu_to_le32(0x00);/* MAC_ID */
1526
1527 ptxdesc->txdw1 |= cpu_to_le32((0x12 << QSEL_SHT) & 0x00001f00);
1528
1529 ptxdesc->txdw1 |= cpu_to_le32((0x06 << 16) & 0x000f0000);/* b mode */
1530
1531 /* offset 8 */
1532
1533 /* offset 12 */
1534 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl) << 16) &
1535 0xffff0000);
1536
1537 /* offset 16 */
1538 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
1539
1540 /* offset 20 */
1541
1542 rtl8188e_cal_txdesc_chksum(ptxdesc);
1543 /* ----- end of fill tx desc ----- */
1544
1545 skb_put(pxmit_skb, len + TXDESC_SIZE);
1546 pxmitbuf = pxmitbuf + TXDESC_SIZE;
1547 _rtw_memcpy(pxmitbuf, skb->data, len);
1548
1549 /* ----- prepare urb for submit ----- */
1550
1551 /* translate DMA FIFO addr to pipehandle */
1552 /*pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);*/
1553 pipe = usb_sndbulkpipe(pdvobj->pusbdev,
1554 pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX] & 0x0f);
1555
1556 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe, pxmit_skb->data,
1557 pxmit_skb->len, rtl8188ee_hostap_mgnt_xmit_cb, pxmit_skb);
1558
1559 urb->transfer_flags |= URB_ZERO_PACKET;
1560 usb_anchor_urb(urb, &phostapdpriv->anchored);
1561 rc = usb_submit_urb(urb, GFP_ATOMIC);
1562 if (rc < 0) {
1563 usb_unanchor_urb(urb);
1564 kfree_skb(skb);
1565 }
1566 usb_free_urb(urb);
1567
1568
1569 _exit:
1570
1571 dev_kfree_skb_any(skb);
1572 #endif
1573 return 0;
1574
1575 }
1576 #endif
1577