linux/drivers/staging/rtl8712/rtl8712_xmit.c

// SPDX-License-Identifier: GPL-2.0
/******************************************************************************
 * rtl8712_xmit.c
 *
 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
 * Linux device driver for RTL8192SU
 *
 * Modifications for inclusion into the Linux staging tree are
 * Copyright(c) 2010 Larry Finger. All rights reserved.
 *
 * Contact information:
 * WLAN FAE <[email protected]>
 * Larry Finger <[email protected]>
 *
 ******************************************************************************/

#define _RTL8712_XMIT_C_

#include "osdep_service.h"
#include "drv_types.h"
#include "wifi.h"
#include "osdep_intf.h"
#include "usb_ops.h"

static void dump_xframe(struct _adapter *padapter,
			struct xmit_frame *pxmitframe);
static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz);

sint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag)
{}

int r8712_txframes_sta_ac_pending(struct _adapter *padapter,
				  struct pkt_attrib *pattrib)
{}

static u32 get_ff_hwaddr(struct xmit_frame *pxmitframe)
{}

static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv,
						struct hw_xmit *phwxmit, struct tx_servq *ptxservq,
						struct  __queue *pframe_queue)
{}

static struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv,
					    struct hw_xmit *phwxmit_i, sint entry)
{}

void r8712_do_queue_select(struct _adapter *padapter, struct pkt_attrib *pattrib)
{}

#ifdef CONFIG_R8712_TX_AGGR
void r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf)
{
	struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf;

	/* Fill up TxCmd Descriptor according as USB FW Tx Aggregation info.*/
	/* dw0 */
	ptx_desc->txdw0 = cpu_to_le32(CMD_HDR_SZ & 0xffff);
	ptx_desc->txdw0 |=
		cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) &
			    0x00ff0000);
	ptx_desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);

	/* dw1 */
	ptx_desc->txdw1 |= cpu_to_le32((0x13 << QSEL_SHT) & 0x00001f00);
}

void r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf)
{
	struct xmit_frame *pxmitframe = (struct xmit_frame *)
		pxmitbuf->priv_data;
	struct _adapter *padapter = pxmitframe->padapter;
	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
	struct cmd_hdr *pcmd_hdr = (struct cmd_hdr  *)
		(pxmitbuf->pbuf + TXDESC_SIZE);

	/* Fill up Cmd Header for USB FW Tx Aggregation.*/
	/* dw0 */
	pcmd_hdr->cmd_dw0 = cpu_to_le32((GEN_CMD_CODE(_AMSDU_TO_AMPDU) << 16) |
					(pcmdpriv->cmd_seq << 24));
	pcmdpriv->cmd_seq++;
}

void r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf,
			    struct xmit_frame *pxmitframe)
{
	struct _adapter *padapter = pxmitframe->padapter;
	struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf;
	int last_txcmdsz = 0;
	int padding_sz = 0;

	/* 802.3->802.11 converter */
	r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
	/* free skb struct */
	r8712_xmit_complete(padapter, pxmitframe);
	if (pxmitframe->attrib.ether_type != 0x0806) {
		if ((pxmitframe->attrib.ether_type != 0x888e) &&
		    (pxmitframe->attrib.dhcp_pkt != 1)) {
			r8712_issue_addbareq_cmd(padapter, pxmitframe->attrib.priority);
		}
	}
	pxmitframe->last[0] = 1;
	update_txdesc(pxmitframe, (uint *)(pxmitframe->buf_addr), pxmitframe->attrib.last_txcmdsz);
	/*padding zero */
	last_txcmdsz = pxmitframe->attrib.last_txcmdsz;
	padding_sz = (8 - (last_txcmdsz % 8));
	if ((last_txcmdsz % 8) != 0) {
		int i;

		for (i = 0; i < padding_sz; i++)
			*(pxmitframe->buf_addr + TXDESC_SIZE + last_txcmdsz +
			  i) = 0;
	}
	/* Add the new mpdu's length */
	ptx_desc->txdw0 = cpu_to_le32((ptx_desc->txdw0 & 0xffff0000) |
		((ptx_desc->txdw0 & 0x0000ffff) +
			((TXDESC_SIZE + last_txcmdsz + padding_sz) &
			 0x0000ffff)));
}

void r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf,
			      struct xmit_frame *pxmitframe)
{
	/* linux complete context doesn't need to protect */
	pxmitframe->pxmitbuf = pxmitbuf;
	pxmitbuf->priv_data = pxmitframe;
	pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
	/* buffer addr assoc */
	pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE + CMD_HDR_SZ;
	/*RTL8712_DMA_H2CCMD */
	r8712_construct_txaggr_cmd_desc(pxmitbuf);
	r8712_construct_txaggr_cmd_hdr(pxmitbuf);
	r8712_append_mpdu_unit(pxmitbuf, pxmitframe);
	pxmitbuf->aggr_nr = 1;
}

u16 r8712_xmitframe_aggr_next(struct xmit_buf *pxmitbuf, struct xmit_frame *pxmitframe)
{
	pxmitframe->pxmitbuf = pxmitbuf;
	pxmitbuf->priv_data = pxmitframe;
	pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
	/* buffer addr assoc */
	pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE +
		(((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff);
	r8712_append_mpdu_unit(pxmitbuf, pxmitframe);
	r8712_free_xmitframe_ex(&pxmitframe->padapter->xmitpriv,
				pxmitframe);
	pxmitbuf->aggr_nr++;

	return TXDESC_SIZE +
		(((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff);
}

void r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf,
			    struct xmit_frame *pxmitframe)
{
	struct _adapter *padapter = pxmitframe->padapter;
	struct dvobj_priv *pdvobj = &padapter->dvobjpriv;
	struct tx_desc *ptxdesc = pxmitbuf->pbuf;
	struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *)
		(pxmitbuf->pbuf + TXDESC_SIZE);
	u16 total_length = (u16)(ptxdesc->txdw0 & 0xffff);

	/* use 1st xmitframe as media */
	xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
	pcmd_hdr->cmd_dw0 = cpu_to_le32(((total_length - CMD_HDR_SZ) &
					 0x0000ffff) | (pcmd_hdr->cmd_dw0 &
							0xffff0000));

	/* urb length in cmd_dw1 */
	pcmd_hdr->cmd_dw1 = cpu_to_le32((pxmitbuf->aggr_nr & 0xff) |
					((total_length + TXDESC_SIZE) << 16));
	pxmitframe->last[0] = 1;
	pxmitframe->bpending[0] = false;
	pxmitframe->mem_addr = pxmitbuf->pbuf;

	if ((pdvobj->ishighspeed && ((total_length + TXDESC_SIZE) % 0x200) == 0) ||
	    ((!pdvobj->ishighspeed && ((total_length + TXDESC_SIZE) %
	    0x40) == 0))) {
		ptxdesc->txdw0 |= cpu_to_le32
			(((TXDESC_SIZE + OFFSET_SZ + 8) << OFFSET_SHT) &
			 0x00ff0000);
		/*32 bytes for TX Desc + 8 bytes pending*/
	} else {
		ptxdesc->txdw0 |= cpu_to_le32
			(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) &
			 0x00ff0000);
		/*default = 32 bytes for TX Desc*/
	}
	r8712_write_port(pxmitframe->padapter, RTL8712_DMA_H2CCMD, total_length + TXDESC_SIZE,
			 (u8 *)pxmitframe);
}

#endif

static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz)
{}

int r8712_xmitframe_complete(struct _adapter *padapter,
			     struct xmit_priv *pxmitpriv,
			     struct xmit_buf *pxmitbuf)
{}

static void dump_xframe(struct _adapter *padapter,
			struct xmit_frame *pxmitframe)
{}

void r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe)
{}

int r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe)
{}