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