xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8822be/hal/rtl8822b/pci/rtl8822be_xmit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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