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