// SPDX-License-Identifier: GPL-2.0
/******************************************************************************
 *
 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
 *
 ******************************************************************************/

#include <drv_types.h>
#include <rtw_debug.h>
#include <rtl8723b_hal.h>

static u8 rtw_sdio_wait_enough_TxOQT_space(struct adapter *padapter, u8 agg_num)
{
	u32 n = 0;
	struct hal_com_data *pHalData = GET_HAL_DATA(padapter);

	while (pHalData->SdioTxOQTFreeSpace < agg_num) {
		if (
			(padapter->bSurpriseRemoved) ||
			(padapter->bDriverStopped)
		)
			return false;

		HalQueryTxOQTBufferStatus8723BSdio(padapter);

		if ((++n % 60) == 0) {
			msleep(1);
			/* yield(); */
		}
	}

	pHalData->SdioTxOQTFreeSpace -= agg_num;

	/* if (n > 1) */
	/* 	++priv->pshare->nr_out_of_txoqt_space; */

	return true;
}

static s32 rtl8723_dequeue_writeport(struct adapter *padapter)
{
	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
	struct xmit_buf *pxmitbuf;
	struct adapter *pri_padapter = padapter;
	s32 ret = 0;
	u8 PageIdx = 0;
	u32 deviceId;
	u8 bUpdatePageNum = false;

	ret = ret || check_fwstate(pmlmepriv, _FW_UNDER_SURVEY);

	if (ret)
		pxmitbuf = dequeue_pending_xmitbuf_under_survey(pxmitpriv);
	else
		pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);

	if (!pxmitbuf)
		return true;

	deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr);

	/*  translate fifo addr to queue index */
	switch (deviceId) {
	case WLAN_TX_HIQ_DEVICE_ID:
		PageIdx = HI_QUEUE_IDX;
		break;

	case WLAN_TX_MIQ_DEVICE_ID:
		PageIdx = MID_QUEUE_IDX;
		break;

	case WLAN_TX_LOQ_DEVICE_ID:
		PageIdx = LOW_QUEUE_IDX;
		break;
	}

query_free_page:
	/*  check if hardware tx fifo page is enough */
	if (!rtw_hal_sdio_query_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num)) {
		if (!bUpdatePageNum) {
			/*  Total number of page is NOT available, so update current FIFO status */
			HalQueryTxBufferStatus8723BSdio(padapter);
			bUpdatePageNum = true;
			goto query_free_page;
		} else {
			bUpdatePageNum = false;
			enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
			return true;
		}
	}

	if (
		(padapter->bSurpriseRemoved) ||
		(padapter->bDriverStopped)
	)
		goto free_xmitbuf;

	if (rtw_sdio_wait_enough_TxOQT_space(padapter, pxmitbuf->agg_num) == false)
		goto free_xmitbuf;

	traffic_check_for_leave_lps(padapter, true, pxmitbuf->agg_num);

	rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8 *)pxmitbuf);

	rtw_hal_sdio_update_tx_freepage(pri_padapter, PageIdx, pxmitbuf->pg_num);

free_xmitbuf:
	/* rtw_free_xmitframe(pxmitpriv, pframe); */
	/* pxmitbuf->priv_data = NULL; */
	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);

	return _FAIL;
}

/*
 * Description
 *Transmit xmitbuf to hardware tx fifo
 *
 * Return
 *_SUCCESS	ok
 *_FAIL		something error
 */
s32 rtl8723bs_xmit_buf_handler(struct adapter *padapter)
{
	struct xmit_priv *pxmitpriv;
	u8 queue_empty, queue_pending;
	s32 ret;


	pxmitpriv = &padapter->xmitpriv;

	if (wait_for_completion_interruptible(&pxmitpriv->xmit_comp)) {
		netdev_emerg(padapter->pnetdev,
			     "%s: down SdioXmitBufSema fail!\n", __func__);
		return _FAIL;
	}

	ret = (padapter->bDriverStopped) || (padapter->bSurpriseRemoved);
	if (ret)
		return _FAIL;

	queue_pending = check_pending_xmitbuf(pxmitpriv);

	if (!queue_pending)
		return _SUCCESS;

	ret = rtw_register_tx_alive(padapter);
	if (ret != _SUCCESS) {
		return _SUCCESS;
	}

	do {
		queue_empty = rtl8723_dequeue_writeport(padapter);
/* 	dump secondary adapter xmitbuf */
	} while (!queue_empty);

	rtw_unregister_tx_alive(padapter);

	return _SUCCESS;
}

/*
 * Description:
 *Aggregation packets and send to hardware
 *
 * Return:
 *0	Success
 *-1	Hardware resource(TX FIFO) not ready
 *-2	Software resource(xmitbuf) not ready
 */
static s32 xmit_xmitframes(struct adapter *padapter, struct xmit_priv *pxmitpriv)
{
	s32 err, ret;
	u32 k = 0;
	struct hw_xmit *hwxmits, *phwxmit;
	u8 idx, hwentry;
	struct tx_servq *ptxservq;
	struct list_head *sta_plist, *sta_phead, *frame_plist, *frame_phead, *tmp;
	struct xmit_frame *pxmitframe;
	struct __queue *pframe_queue;
	struct xmit_buf *pxmitbuf;
	u32 txlen, max_xmit_len;
	u8 txdesc_size = TXDESC_SIZE;
	int inx[4];

	err = 0;
	hwxmits = pxmitpriv->hwxmits;
	hwentry = pxmitpriv->hwxmit_entry;
	ptxservq = NULL;
	pxmitframe = NULL;
	pframe_queue = NULL;
	pxmitbuf = NULL;

	if (padapter->registrypriv.wifi_spec == 1) {
		for (idx = 0; idx < 4; idx++)
			inx[idx] = pxmitpriv->wmm_para_seq[idx];
	} else {
		inx[0] = 0;
		inx[1] = 1;
		inx[2] = 2;
		inx[3] = 3;
	}

	/*  0(VO), 1(VI), 2(BE), 3(BK) */
	for (idx = 0; idx < hwentry; idx++) {
		phwxmit = hwxmits + inx[idx];

		if (
			(check_pending_xmitbuf(pxmitpriv)) &&
			(padapter->mlmepriv.LinkDetectInfo.bHigherBusyTxTraffic)
		) {
			if ((phwxmit->accnt > 0) && (phwxmit->accnt < 5)) {
				err = -2;
				break;
			}
		}

		max_xmit_len = rtw_hal_get_sdio_tx_max_length(padapter, inx[idx]);

		spin_lock_bh(&pxmitpriv->lock);

		sta_phead = get_list_head(phwxmit->sta_queue);
		/* because stop_sta_xmit may delete sta_plist at any time */
		/* so we should add lock here, or while loop can not exit */
		list_for_each_safe(sta_plist, tmp, sta_phead) {
			ptxservq = list_entry(sta_plist, struct tx_servq,
					      tx_pending);

			pframe_queue = &ptxservq->sta_pending;

			frame_phead = get_list_head(pframe_queue);

			while (list_empty(frame_phead) == false) {
				frame_plist = get_next(frame_phead);
				pxmitframe = container_of(frame_plist, struct xmit_frame, list);

				/*  check xmit_buf size enough or not */
				txlen = txdesc_size + rtw_wlan_pkt_size(pxmitframe);
				if (!pxmitbuf ||
					((_RND(pxmitbuf->len, 8) + txlen) > max_xmit_len) ||
					(k >= (rtw_hal_sdio_max_txoqt_free_space(padapter) - 1))
				) {
					if (pxmitbuf) {
						/* pxmitbuf->priv_data will be NULL, and will crash here */
						if (pxmitbuf->len > 0 &&
						    pxmitbuf->priv_data) {
							struct xmit_frame *pframe;
							pframe = (struct xmit_frame *)pxmitbuf->priv_data;
							pframe->agg_num = k;
							pxmitbuf->agg_num = k;
							rtl8723b_update_txdesc(pframe, pframe->buf_addr);
							rtw_free_xmitframe(pxmitpriv, pframe);
							pxmitbuf->priv_data = NULL;
							enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
							/* can not yield under lock */
							/* yield(); */
						} else
							rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
					}

					pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
					if (!pxmitbuf) {
#ifdef DBG_XMIT_BUF
						netdev_err(padapter->pnetdev,
							   "%s: xmit_buf is not enough!\n",
							   __func__);
#endif
						err = -2;
						complete(&(pxmitpriv->xmit_comp));
						break;
					}
					k = 0;
				}

				/*  ok to send, remove frame from queue */
				if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true)
					if (
						(pxmitframe->attrib.psta->state & WIFI_SLEEP_STATE) &&
						(pxmitframe->attrib.triggered == 0)
					)
						break;

				list_del_init(&pxmitframe->list);
				ptxservq->qcnt--;
				phwxmit->accnt--;

				if (k == 0) {
					pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
					pxmitbuf->priv_data = (u8 *)pxmitframe;
				}

				/*  coalesce the xmitframe to xmitbuf */
				pxmitframe->pxmitbuf = pxmitbuf;
				pxmitframe->buf_addr = pxmitbuf->ptail;

				ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
				if (ret == _FAIL) {
					netdev_err(padapter->pnetdev,
						   "%s: coalesce FAIL!",
						   __func__);
					/*  Todo: error handler */
				} else {
					k++;
					if (k != 1)
						rtl8723b_update_txdesc(pxmitframe, pxmitframe->buf_addr);
					rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz);

					txlen = txdesc_size + pxmitframe->attrib.last_txcmdsz;
					pxmitframe->pg_num = (txlen + 127) / 128;
					pxmitbuf->pg_num += (txlen + 127) / 128;
				    /* if (k != 1) */
					/* 	((struct xmit_frame*)pxmitbuf->priv_data)->pg_num += pxmitframe->pg_num; */
					pxmitbuf->ptail += _RND(txlen, 8); /*  round to 8 bytes alignment */
					pxmitbuf->len = _RND(pxmitbuf->len, 8) + txlen;
				}

				if (k != 1)
					rtw_free_xmitframe(pxmitpriv, pxmitframe);
				pxmitframe = NULL;
			}

			if (list_empty(&pframe_queue->queue))
				list_del_init(&ptxservq->tx_pending);

			if (err)
				break;
		}
		spin_unlock_bh(&pxmitpriv->lock);

		/*  dump xmit_buf to hw tx fifo */
		if (pxmitbuf) {
			if (pxmitbuf->len > 0) {
				struct xmit_frame *pframe;
				pframe = (struct xmit_frame *)pxmitbuf->priv_data;
				pframe->agg_num = k;
				pxmitbuf->agg_num = k;
				rtl8723b_update_txdesc(pframe, pframe->buf_addr);
				rtw_free_xmitframe(pxmitpriv, pframe);
				pxmitbuf->priv_data = NULL;
				enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
				yield();
			} else
				rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
			pxmitbuf = NULL;
		}

		if (err)
			break;
	}

	return err;
}

/*
 * Description
 *Transmit xmitframe from queue
 *
 * Return
 *_SUCCESS	ok
 *_FAIL		something error
 */
static s32 rtl8723bs_xmit_handler(struct adapter *padapter)
{
	struct xmit_priv *pxmitpriv;
	s32 ret;


	pxmitpriv = &padapter->xmitpriv;

	if (wait_for_completion_interruptible(&pxmitpriv->SdioXmitStart)) {
		netdev_emerg(padapter->pnetdev, "%s: SdioXmitStart fail!\n",
			     __func__);
		return _FAIL;
	}

next:
	if (
		(padapter->bDriverStopped) ||
		(padapter->bSurpriseRemoved)
	)
		return _FAIL;

	spin_lock_bh(&pxmitpriv->lock);
	ret = rtw_txframes_pending(padapter);
	spin_unlock_bh(&pxmitpriv->lock);
	if (ret == 0) {
		return _SUCCESS;
	}

	/*  dequeue frame and write to hardware */

	ret = xmit_xmitframes(padapter, pxmitpriv);
	if (ret == -2) {
		/* here sleep 1ms will cause big TP loss of TX */
		/* from 50+ to 40+ */
		if (padapter->registrypriv.wifi_spec)
			msleep(1);
		else
			yield();
		goto next;
	}

	spin_lock_bh(&pxmitpriv->lock);
	ret = rtw_txframes_pending(padapter);
	spin_unlock_bh(&pxmitpriv->lock);
	if (ret == 1) {
		goto next;
	}

	return _SUCCESS;
}

int rtl8723bs_xmit_thread(void *context)
{
	s32 ret;
	struct adapter *padapter;
	struct xmit_priv *pxmitpriv;
	u8 thread_name[20];

	ret = _SUCCESS;
	padapter = context;
	pxmitpriv = &padapter->xmitpriv;

	rtw_sprintf(thread_name, 20, "RTWHALXT-%s", ADPT_ARG(padapter));
	thread_enter(thread_name);

	do {
		ret = rtl8723bs_xmit_handler(padapter);
		if (signal_pending(current)) {
			flush_signals(current);
		}
	} while (_SUCCESS == ret);

	complete(&pxmitpriv->SdioXmitTerminate);

	return 0;
}

s32 rtl8723bs_mgnt_xmit(
	struct adapter *padapter, struct xmit_frame *pmgntframe
)
{
	s32 ret = _SUCCESS;
	struct pkt_attrib *pattrib;
	struct xmit_buf *pxmitbuf;
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
	u8 *pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
	u8 txdesc_size = TXDESC_SIZE;

	pattrib = &pmgntframe->attrib;
	pxmitbuf = pmgntframe->pxmitbuf;

	rtl8723b_update_txdesc(pmgntframe, pmgntframe->buf_addr);

	pxmitbuf->len = txdesc_size + pattrib->last_txcmdsz;
	pxmitbuf->pg_num = (pxmitbuf->len + 127) / 128; /*  128 is tx page size */
	pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len;
	pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe);

	rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz);

	rtw_free_xmitframe(pxmitpriv, pmgntframe);

	pxmitbuf->priv_data = NULL;

	if (GetFrameSubType(pframe) == WIFI_BEACON) { /* dump beacon directly */
		ret = rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[pxmitbuf->ff_hwaddr], pxmitbuf->len, (u8 *)pxmitbuf);
		if (ret != _SUCCESS)
			rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);

		rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
	} else
		enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);

	return ret;
}

/*
 * Description:
 *Handle xmitframe(packet) come from rtw_xmit()
 *
 * Return:
 *true	dump packet directly ok
 *false	enqueue, temporary can't transmit packets to hardware
 */
s32 rtl8723bs_hal_xmit(
	struct adapter *padapter, struct xmit_frame *pxmitframe
)
{
	struct xmit_priv *pxmitpriv;
	s32 err;


	pxmitframe->attrib.qsel = pxmitframe->attrib.priority;
	pxmitpriv = &padapter->xmitpriv;

	if (
		(pxmitframe->frame_tag == DATA_FRAMETAG) &&
		(pxmitframe->attrib.ether_type != 0x0806) &&
		(pxmitframe->attrib.ether_type != 0x888e) &&
		(pxmitframe->attrib.dhcp_pkt != 1)
	) {
		if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
			rtw_issue_addbareq_cmd(padapter, pxmitframe);
	}

	err = rtw_xmitframe_enqueue(padapter, pxmitframe);
	if (err != _SUCCESS) {
		rtw_free_xmitframe(pxmitpriv, pxmitframe);

		pxmitpriv->tx_drop++;
		return true;
	}

	complete(&pxmitpriv->SdioXmitStart);

	return false;
}

s32	rtl8723bs_hal_xmitframe_enqueue(
	struct adapter *padapter, struct xmit_frame *pxmitframe
)
{
	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
	s32 err;

	err = rtw_xmitframe_enqueue(padapter, pxmitframe);
	if (err != _SUCCESS) {
		rtw_free_xmitframe(pxmitpriv, pxmitframe);

		pxmitpriv->tx_drop++;
	} else {
		complete(&pxmitpriv->SdioXmitStart);
	}

	return err;

}

/*
 * Return
 *_SUCCESS	start thread ok
 *_FAIL		start thread fail
 *
 */
s32 rtl8723bs_init_xmit_priv(struct adapter *padapter)
{
	struct xmit_priv *xmitpriv = &padapter->xmitpriv;
	struct hal_com_data *phal;


	phal = GET_HAL_DATA(padapter);

	spin_lock_init(&phal->SdioTxFIFOFreePageLock);
	init_completion(&xmitpriv->SdioXmitStart);
	init_completion(&xmitpriv->SdioXmitTerminate);

	return _SUCCESS;
}

void rtl8723bs_free_xmit_priv(struct adapter *padapter)
{
	struct xmit_priv *pxmitpriv;
	struct xmit_buf *pxmitbuf;
	struct __queue *pqueue;
	struct list_head *plist, *phead;
	struct list_head tmplist;


	pxmitpriv = &padapter->xmitpriv;
	pqueue = &pxmitpriv->pending_xmitbuf_queue;
	phead = get_list_head(pqueue);
	INIT_LIST_HEAD(&tmplist);

	spin_lock_bh(&pqueue->lock);
	if (!list_empty(&pqueue->queue)) {
		/*  Insert tmplist to end of queue, and delete phead */
		/*  then tmplist become head of queue. */
		list_add_tail(&tmplist, phead);
		list_del_init(phead);
	}
	spin_unlock_bh(&pqueue->lock);

	phead = &tmplist;
	while (list_empty(phead) == false) {
		plist = get_next(phead);
		list_del_init(plist);

		pxmitbuf = container_of(plist, struct xmit_buf, list);
		rtw_free_xmitframe(pxmitpriv, (struct xmit_frame *)pxmitbuf->priv_data);
		pxmitbuf->priv_data = NULL;
		rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
	}
}
