cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtl871x_xmit.c (30133B)


      1// SPDX-License-Identifier: GPL-2.0
      2/******************************************************************************
      3 * rtl871x_xmit.c
      4 *
      5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
      6 * Linux device driver for RTL8192SU
      7 *
      8 * Modifications for inclusion into the Linux staging tree are
      9 * Copyright(c) 2010 Larry Finger. All rights reserved.
     10 *
     11 * Contact information:
     12 * WLAN FAE <wlanfae@realtek.com>
     13 * Larry Finger <Larry.Finger@lwfinger.net>
     14 *
     15 ******************************************************************************/
     16
     17#define _RTL871X_XMIT_C_
     18
     19#include "osdep_service.h"
     20#include "drv_types.h"
     21#include "osdep_intf.h"
     22#include "usb_ops.h"
     23
     24#include <linux/ieee80211.h>
     25
     26static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
     27static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
     28static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
     29static void alloc_hwxmits(struct _adapter *padapter);
     30static void free_hwxmits(struct _adapter *padapter);
     31
     32static void _init_txservq(struct tx_servq *ptxservq)
     33{
     34	INIT_LIST_HEAD(&ptxservq->tx_pending);
     35	_init_queue(&ptxservq->sta_pending);
     36	ptxservq->qcnt = 0;
     37}
     38
     39void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
     40{
     41	memset((unsigned char *)psta_xmitpriv, 0,
     42		 sizeof(struct sta_xmit_priv));
     43	spin_lock_init(&psta_xmitpriv->lock);
     44	_init_txservq(&psta_xmitpriv->be_q);
     45	_init_txservq(&psta_xmitpriv->bk_q);
     46	_init_txservq(&psta_xmitpriv->vi_q);
     47	_init_txservq(&psta_xmitpriv->vo_q);
     48	INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
     49	INIT_LIST_HEAD(&psta_xmitpriv->apsd);
     50}
     51
     52int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
     53			  struct _adapter *padapter)
     54{
     55	sint i;
     56	struct xmit_buf *pxmitbuf;
     57	struct xmit_frame *pxframe;
     58
     59	memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
     60	spin_lock_init(&pxmitpriv->lock);
     61	/*
     62	 *Please insert all the queue initialization using _init_queue below
     63	 */
     64	pxmitpriv->adapter = padapter;
     65	_init_queue(&pxmitpriv->be_pending);
     66	_init_queue(&pxmitpriv->bk_pending);
     67	_init_queue(&pxmitpriv->vi_pending);
     68	_init_queue(&pxmitpriv->vo_pending);
     69	_init_queue(&pxmitpriv->bm_pending);
     70	_init_queue(&pxmitpriv->legacy_dz_queue);
     71	_init_queue(&pxmitpriv->apsd_queue);
     72	_init_queue(&pxmitpriv->free_xmit_queue);
     73	/*
     74	 * Please allocate memory with sz = (struct xmit_frame) * NR_XMITFRAME,
     75	 * and initialize free_xmit_frame below.
     76	 * Please also apply  free_txobj to link_up all the xmit_frames...
     77	 */
     78	pxmitpriv->pallocated_frame_buf =
     79		kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4,
     80			GFP_ATOMIC);
     81	if (!pxmitpriv->pallocated_frame_buf) {
     82		pxmitpriv->pxmit_frame_buf = NULL;
     83		return -ENOMEM;
     84	}
     85	pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
     86			((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
     87	pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
     88	for (i = 0; i < NR_XMITFRAME; i++) {
     89		INIT_LIST_HEAD(&(pxframe->list));
     90		pxframe->padapter = padapter;
     91		pxframe->frame_tag = DATA_FRAMETAG;
     92		pxframe->pkt = NULL;
     93		pxframe->buf_addr = NULL;
     94		pxframe->pxmitbuf = NULL;
     95		list_add_tail(&(pxframe->list),
     96				 &(pxmitpriv->free_xmit_queue.queue));
     97		pxframe++;
     98	}
     99	pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
    100	/*
    101	 * init xmit hw_txqueue
    102	 */
    103	_r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
    104	_r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
    105	_r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
    106	_r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
    107	_r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
    108	pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
    109	pxmitpriv->txirp_cnt = 1;
    110	/*per AC pending irp*/
    111	pxmitpriv->beq_cnt = 0;
    112	pxmitpriv->bkq_cnt = 0;
    113	pxmitpriv->viq_cnt = 0;
    114	pxmitpriv->voq_cnt = 0;
    115	/*init xmit_buf*/
    116	_init_queue(&pxmitpriv->free_xmitbuf_queue);
    117	_init_queue(&pxmitpriv->pending_xmitbuf_queue);
    118	pxmitpriv->pallocated_xmitbuf =
    119		kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC);
    120	if (!pxmitpriv->pallocated_xmitbuf) {
    121		kfree(pxmitpriv->pallocated_frame_buf);
    122		pxmitpriv->pallocated_frame_buf = NULL;
    123		return -ENOMEM;
    124	}
    125	pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
    126			      ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
    127	pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
    128	for (i = 0; i < NR_XMITBUFF; i++) {
    129		INIT_LIST_HEAD(&pxmitbuf->list);
    130		pxmitbuf->pallocated_buf =
    131			kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC);
    132		if (!pxmitbuf->pallocated_buf)
    133			return -ENOMEM;
    134		pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
    135				 ((addr_t) (pxmitbuf->pallocated_buf) &
    136				 (XMITBUF_ALIGN_SZ - 1));
    137		if (r8712_xmit_resource_alloc(padapter, pxmitbuf))
    138			return -ENOMEM;
    139		list_add_tail(&pxmitbuf->list,
    140				 &(pxmitpriv->free_xmitbuf_queue.queue));
    141		pxmitbuf++;
    142	}
    143	pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
    144	INIT_WORK(&padapter->wk_filter_rx_ff0, r8712_SetFilter);
    145	alloc_hwxmits(padapter);
    146	init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
    147	tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh);
    148	return 0;
    149}
    150
    151void _free_xmit_priv(struct xmit_priv *pxmitpriv)
    152{
    153	int i;
    154	struct _adapter *padapter = pxmitpriv->adapter;
    155	struct xmit_frame *pxmitframe = (struct xmit_frame *)
    156					pxmitpriv->pxmit_frame_buf;
    157	struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
    158
    159	if (!pxmitpriv->pxmit_frame_buf)
    160		return;
    161	for (i = 0; i < NR_XMITFRAME; i++) {
    162		r8712_xmit_complete(padapter, pxmitframe);
    163		pxmitframe++;
    164	}
    165	for (i = 0; i < NR_XMITBUFF; i++) {
    166		r8712_xmit_resource_free(padapter, pxmitbuf);
    167		kfree(pxmitbuf->pallocated_buf);
    168		pxmitbuf++;
    169	}
    170	kfree(pxmitpriv->pallocated_frame_buf);
    171	kfree(pxmitpriv->pallocated_xmitbuf);
    172	free_hwxmits(padapter);
    173}
    174
    175int r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
    176			struct pkt_attrib *pattrib)
    177{
    178	struct pkt_file pktfile;
    179	struct sta_info *psta = NULL;
    180	struct ethhdr etherhdr;
    181
    182	struct tx_cmd txdesc;
    183
    184	bool bmcast;
    185	struct sta_priv		*pstapriv = &padapter->stapriv;
    186	struct security_priv	*psecuritypriv = &padapter->securitypriv;
    187	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
    188	struct qos_priv		*pqospriv = &pmlmepriv->qospriv;
    189
    190	_r8712_open_pktfile(pkt, &pktfile);
    191
    192	_r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);
    193
    194	pattrib->ether_type = ntohs(etherhdr.h_proto);
    195
    196	/*
    197	 * If driver xmit ARP packet, driver can set ps mode to initial
    198	 * setting. It stands for getting DHCP or fix IP.
    199	 */
    200	if (pattrib->ether_type == 0x0806) {
    201		if (padapter->pwrctrlpriv.pwr_mode !=
    202		    padapter->registrypriv.power_mgnt) {
    203			del_timer_sync(&pmlmepriv->dhcp_timer);
    204			r8712_set_ps_mode(padapter,
    205					  padapter->registrypriv.power_mgnt,
    206					  padapter->registrypriv.smart_ps);
    207		}
    208	}
    209
    210	memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
    211	memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
    212	pattrib->pctrl = 0;
    213	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
    214	    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
    215		memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
    216		memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
    217	} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
    218		memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
    219		memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
    220	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
    221		memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
    222		memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
    223	} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
    224		/*firstly, filter packet not belongs to mp*/
    225		if (pattrib->ether_type != 0x8712)
    226			return -EINVAL;
    227		/* for mp storing the txcmd per packet,
    228		 * according to the info of txcmd to update pattrib
    229		 */
    230		/*get MP_TXDESC_SIZE bytes txcmd per packet*/
    231		_r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
    232		memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
    233		memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
    234		pattrib->pctrl = 1;
    235	}
    236	/* r8712_xmitframe_coalesce() overwrite this!*/
    237	pattrib->pktlen = pktfile.pkt_len;
    238	if (pattrib->ether_type == ETH_P_IP) {
    239		/* The following is for DHCP and ARP packet, we use cck1M to
    240		 * tx these packets and let LPS awake some time
    241		 * to prevent DHCP protocol fail
    242		 */
    243		u8 tmp[24];
    244
    245		_r8712_pktfile_read(&pktfile, &tmp[0], 24);
    246		pattrib->dhcp_pkt = 0;
    247		if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
    248			if (pattrib->ether_type == ETH_P_IP) {/* IP header*/
    249				if (((tmp[21] == 68) && (tmp[23] == 67)) ||
    250					((tmp[21] == 67) && (tmp[23] == 68))) {
    251					/* 68 : UDP BOOTP client
    252					 * 67 : UDP BOOTP server
    253					 * Use low rate to send DHCP packet.
    254					 */
    255					pattrib->dhcp_pkt = 1;
    256				}
    257			}
    258		}
    259	}
    260	bmcast = is_multicast_ether_addr(pattrib->ra);
    261	/* get sta_info*/
    262	if (bmcast) {
    263		psta = r8712_get_bcmc_stainfo(padapter);
    264		pattrib->mac_id = 4;
    265	} else {
    266		if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
    267			psta = r8712_get_stainfo(pstapriv,
    268						 get_bssid(pmlmepriv));
    269			pattrib->mac_id = 5;
    270		} else {
    271			psta = r8712_get_stainfo(pstapriv, pattrib->ra);
    272			if (!psta)  /* drop the pkt */
    273				return -ENOMEM;
    274			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
    275				pattrib->mac_id = 5;
    276			else
    277				pattrib->mac_id = psta->mac_id;
    278		}
    279	}
    280
    281	if (psta) {
    282		pattrib->psta = psta;
    283	} else {
    284		/* if we cannot get psta => drrp the pkt */
    285		return -ENOMEM;
    286	}
    287
    288	pattrib->ack_policy = 0;
    289	/* get ether_hdr_len */
    290	pattrib->pkt_hdrlen = ETH_HLEN;
    291
    292	if (pqospriv->qos_option) {
    293		r8712_set_qos(&pktfile, pattrib);
    294	} else {
    295		pattrib->hdrlen = WLAN_HDR_A3_LEN;
    296		pattrib->subtype = IEEE80211_FTYPE_DATA;
    297		pattrib->priority = 0;
    298	}
    299	if (psta->ieee8021x_blocked) {
    300		pattrib->encrypt = 0;
    301		if ((pattrib->ether_type != 0x888e) &&
    302		    !check_fwstate(pmlmepriv, WIFI_MP_STATE))
    303			return -EINVAL;
    304	} else {
    305		GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
    306	}
    307	switch (pattrib->encrypt) {
    308	case _WEP40_:
    309	case _WEP104_:
    310		pattrib->iv_len = 4;
    311		pattrib->icv_len = 4;
    312		break;
    313	case _TKIP_:
    314		pattrib->iv_len = 8;
    315		pattrib->icv_len = 4;
    316		if (padapter->securitypriv.busetkipkey == _FAIL)
    317			return -EINVAL;
    318		break;
    319	case _AES_:
    320		pattrib->iv_len = 8;
    321		pattrib->icv_len = 8;
    322		break;
    323	default:
    324		pattrib->iv_len = 0;
    325		pattrib->icv_len = 0;
    326		break;
    327	}
    328
    329	if (pattrib->encrypt &&
    330	    (padapter->securitypriv.sw_encrypt ||
    331	    !psecuritypriv->hw_decrypted))
    332		pattrib->bswenc = true;
    333	else
    334		pattrib->bswenc = false;
    335	/* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
    336	 * some settings above.
    337	 */
    338	if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
    339		pattrib->priority =
    340		    (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f;
    341	return 0;
    342}
    343
    344static int xmitframe_addmic(struct _adapter *padapter,
    345			    struct xmit_frame *pxmitframe)
    346{
    347	u32	curfragnum, length;
    348	u8	*pframe, *payload, mic[8];
    349	struct	mic_data micdata;
    350	struct	sta_info *stainfo;
    351	struct	qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
    352	struct	pkt_attrib  *pattrib = &pxmitframe->attrib;
    353	struct	security_priv *psecpriv = &padapter->securitypriv;
    354	struct	xmit_priv *pxmitpriv = &padapter->xmitpriv;
    355	u8 priority[4] = {};
    356	bool bmcst = is_multicast_ether_addr(pattrib->ra);
    357
    358	if (pattrib->psta)
    359		stainfo = pattrib->psta;
    360	else
    361		stainfo = r8712_get_stainfo(&padapter->stapriv,
    362					    &pattrib->ra[0]);
    363	if (pattrib->encrypt == _TKIP_) {
    364		/*encode mic code*/
    365		if (stainfo) {
    366			u8 null_key[16] = {};
    367
    368			pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
    369			if (bmcst) {
    370				if (!memcmp(psecpriv->XGrptxmickey
    371				   [psecpriv->XGrpKeyid].skey,
    372				   null_key, 16))
    373					return -ENOMEM;
    374				/*start to calculate the mic code*/
    375				r8712_secmicsetkey(&micdata,
    376					psecpriv->XGrptxmickey
    377					[psecpriv->XGrpKeyid].skey);
    378			} else {
    379				if (!memcmp(&stainfo->tkiptxmickey.skey[0],
    380					    null_key, 16))
    381					return -ENOMEM;
    382				/* start to calculate the mic code */
    383				r8712_secmicsetkey(&micdata,
    384					     &stainfo->tkiptxmickey.skey[0]);
    385			}
    386			if (pframe[1] & 1) {   /* ToDS==1 */
    387				r8712_secmicappend(&micdata,
    388						   &pframe[16], 6); /*DA*/
    389				if (pframe[1] & 2)  /* From Ds==1 */
    390					r8712_secmicappend(&micdata,
    391							   &pframe[24], 6);
    392				else
    393					r8712_secmicappend(&micdata,
    394							   &pframe[10], 6);
    395			} else {	/* ToDS==0 */
    396				r8712_secmicappend(&micdata,
    397						   &pframe[4], 6); /* DA */
    398				if (pframe[1] & 2)  /* From Ds==1 */
    399					r8712_secmicappend(&micdata,
    400							   &pframe[16], 6);
    401				else
    402					r8712_secmicappend(&micdata,
    403							   &pframe[10], 6);
    404			}
    405			if (pqospriv->qos_option == 1)
    406				priority[0] = (u8)pxmitframe->attrib.priority;
    407			r8712_secmicappend(&micdata, &priority[0], 4);
    408			payload = pframe;
    409			for (curfragnum = 0; curfragnum < pattrib->nr_frags;
    410			     curfragnum++) {
    411				payload = (u8 *)RND4((addr_t)(payload));
    412				payload += pattrib->hdrlen + pattrib->iv_len;
    413				if ((curfragnum + 1) == pattrib->nr_frags) {
    414					length = pattrib->last_txcmdsz -
    415						  pattrib->hdrlen -
    416						  pattrib->iv_len -
    417						  ((psecpriv->sw_encrypt)
    418						  ? pattrib->icv_len : 0);
    419					r8712_secmicappend(&micdata, payload,
    420							   length);
    421					payload = payload + length;
    422				} else {
    423					length = pxmitpriv->frag_len -
    424					    pattrib->hdrlen - pattrib->iv_len -
    425					    ((psecpriv->sw_encrypt) ?
    426					    pattrib->icv_len : 0);
    427					r8712_secmicappend(&micdata, payload,
    428							   length);
    429					payload = payload + length +
    430						  pattrib->icv_len;
    431				}
    432			}
    433			r8712_secgetmic(&micdata, &(mic[0]));
    434			/* add mic code  and add the mic code length in
    435			 * last_txcmdsz
    436			 */
    437			memcpy(payload, &(mic[0]), 8);
    438			pattrib->last_txcmdsz += 8;
    439			payload = payload - pattrib->last_txcmdsz + 8;
    440		}
    441	}
    442	return 0;
    443}
    444
    445static sint xmitframe_swencrypt(struct _adapter *padapter,
    446				struct xmit_frame *pxmitframe)
    447{
    448	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
    449
    450	if (pattrib->bswenc) {
    451		switch (pattrib->encrypt) {
    452		case _WEP40_:
    453		case _WEP104_:
    454			r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
    455			break;
    456		case _TKIP_:
    457			r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
    458			break;
    459		case _AES_:
    460			r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
    461			break;
    462		default:
    463				break;
    464		}
    465	}
    466	return _SUCCESS;
    467}
    468
    469static int make_wlanhdr(struct _adapter *padapter, u8 *hdr,
    470			struct pkt_attrib *pattrib)
    471{
    472	u16 *qc;
    473
    474	struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
    475	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
    476	struct qos_priv *pqospriv = &pmlmepriv->qospriv;
    477	__le16 *fctrl = &pwlanhdr->frame_control;
    478	u8 *bssid;
    479
    480	memset(hdr, 0, WLANHDR_OFFSET);
    481	SetFrameSubType(fctrl, pattrib->subtype);
    482	if (!(pattrib->subtype & IEEE80211_FTYPE_DATA))
    483		return 0;
    484
    485	bssid = get_bssid(pmlmepriv);
    486
    487	if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
    488		/* to_ds = 1, fr_ds = 0; */
    489		SetToDs(fctrl);
    490		ether_addr_copy(pwlanhdr->addr1, bssid);
    491		ether_addr_copy(pwlanhdr->addr2, pattrib->src);
    492		ether_addr_copy(pwlanhdr->addr3, pattrib->dst);
    493	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
    494		/* to_ds = 0, fr_ds = 1; */
    495		SetFrDs(fctrl);
    496		ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
    497		ether_addr_copy(pwlanhdr->addr2, bssid);
    498		ether_addr_copy(pwlanhdr->addr3, pattrib->src);
    499	} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
    500		   check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
    501		ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
    502		ether_addr_copy(pwlanhdr->addr2, pattrib->src);
    503		ether_addr_copy(pwlanhdr->addr3, bssid);
    504	} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
    505		ether_addr_copy(pwlanhdr->addr1, pattrib->dst);
    506		ether_addr_copy(pwlanhdr->addr2, pattrib->src);
    507		ether_addr_copy(pwlanhdr->addr3, bssid);
    508	} else {
    509		return -EINVAL;
    510	}
    511
    512	if (pattrib->encrypt)
    513		SetPrivacy(fctrl);
    514	if (pqospriv->qos_option) {
    515		qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
    516		if (pattrib->priority)
    517			SetPriority(qc, pattrib->priority);
    518		SetAckpolicy(qc, pattrib->ack_policy);
    519	}
    520	/* TODO: fill HT Control Field */
    521	/* Update Seq Num will be handled by f/w */
    522	{
    523		struct sta_info *psta;
    524		bool bmcst = is_multicast_ether_addr(pattrib->ra);
    525
    526		if (pattrib->psta)
    527			psta = pattrib->psta;
    528		else if (bmcst)
    529			psta = r8712_get_bcmc_stainfo(padapter);
    530		else
    531			psta = r8712_get_stainfo(&padapter->stapriv,
    532						 pattrib->ra);
    533
    534		if (psta) {
    535			u16 *txtid = psta->sta_xmitpriv.txseq_tid;
    536
    537			txtid[pattrib->priority]++;
    538			txtid[pattrib->priority] &= 0xFFF;
    539			pattrib->seqnum = txtid[pattrib->priority];
    540			SetSeqNum(hdr, pattrib->seqnum);
    541		}
    542	}
    543
    544	return 0;
    545}
    546
    547static sint r8712_put_snap(u8 *data, u16 h_proto)
    548{
    549	struct ieee80211_snap_hdr *snap;
    550	const u8 *oui;
    551
    552	snap = (struct ieee80211_snap_hdr *)data;
    553	snap->dsap = 0xaa;
    554	snap->ssap = 0xaa;
    555	snap->ctrl = 0x03;
    556	if (h_proto == 0x8137 || h_proto == 0x80f3)
    557		oui = P802_1H_OUI;
    558	else
    559		oui = RFC1042_OUI;
    560	snap->oui[0] = oui[0];
    561	snap->oui[1] = oui[1];
    562	snap->oui[2] = oui[2];
    563	*(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
    564	return SNAP_SIZE + sizeof(u16);
    565}
    566
    567/*
    568 * This sub-routine will perform all the following:
    569 * 1. remove 802.3 header.
    570 * 2. create wlan_header, based on the info in pxmitframe
    571 * 3. append sta's iv/ext-iv
    572 * 4. append LLC
    573 * 5. move frag chunk from pframe to pxmitframe->mem
    574 * 6. apply sw-encrypt, if necessary.
    575 */
    576sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
    577			struct xmit_frame *pxmitframe)
    578{
    579	struct pkt_file pktfile;
    580
    581	sint	frg_len, mpdu_len, llc_sz;
    582	u32	mem_sz;
    583	u8	frg_inx;
    584	addr_t addr;
    585	u8 *pframe, *mem_start, *ptxdesc;
    586	struct sta_info		*psta;
    587	struct security_priv	*psecpriv = &padapter->securitypriv;
    588	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
    589	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
    590	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
    591	u8 *pbuf_start;
    592	bool bmcst = is_multicast_ether_addr(pattrib->ra);
    593
    594	if (!pattrib->psta)
    595		return _FAIL;
    596	psta = pattrib->psta;
    597	if (!pxmitframe->buf_addr)
    598		return _FAIL;
    599	pbuf_start = pxmitframe->buf_addr;
    600	ptxdesc = pbuf_start;
    601	mem_start = pbuf_start + TXDESC_OFFSET;
    602	if (make_wlanhdr(padapter, mem_start, pattrib))
    603		return _FAIL;
    604	_r8712_open_pktfile(pkt, &pktfile);
    605	_r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
    606	if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
    607		/* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
    608		if (pattrib->ether_type == 0x8712) {
    609			/* take care -  update_txdesc overwrite this */
    610			_r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
    611		}
    612	}
    613	pattrib->pktlen = pktfile.pkt_len;
    614	frg_inx = 0;
    615	frg_len = pxmitpriv->frag_len - 4;
    616	while (1) {
    617		llc_sz = 0;
    618		mpdu_len = frg_len;
    619		pframe = mem_start;
    620		SetMFrag(mem_start);
    621		pframe += pattrib->hdrlen;
    622		mpdu_len -= pattrib->hdrlen;
    623		/* adding icv, if necessary...*/
    624		if (pattrib->iv_len) {
    625			if (psta) {
    626				switch (pattrib->encrypt) {
    627				case _WEP40_:
    628				case _WEP104_:
    629					WEP_IV(pattrib->iv, psta->txpn,
    630					       (u8)psecpriv->PrivacyKeyIndex);
    631					break;
    632				case _TKIP_:
    633					if (bmcst)
    634						TKIP_IV(pattrib->iv,
    635						    psta->txpn,
    636						    (u8)psecpriv->XGrpKeyid);
    637					else
    638						TKIP_IV(pattrib->iv, psta->txpn,
    639							0);
    640					break;
    641				case _AES_:
    642					if (bmcst)
    643						AES_IV(pattrib->iv, psta->txpn,
    644						    (u8)psecpriv->XGrpKeyid);
    645					else
    646						AES_IV(pattrib->iv, psta->txpn,
    647						       0);
    648					break;
    649				}
    650			}
    651			memcpy(pframe, pattrib->iv, pattrib->iv_len);
    652			pframe += pattrib->iv_len;
    653			mpdu_len -= pattrib->iv_len;
    654		}
    655		if (frg_inx == 0) {
    656			llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
    657			pframe += llc_sz;
    658			mpdu_len -= llc_sz;
    659		}
    660		if ((pattrib->icv_len > 0) && (pattrib->bswenc))
    661			mpdu_len -= pattrib->icv_len;
    662		if (bmcst)
    663			mem_sz = _r8712_pktfile_read(&pktfile, pframe,
    664				 pattrib->pktlen);
    665		else
    666			mem_sz = _r8712_pktfile_read(&pktfile, pframe,
    667				 mpdu_len);
    668		pframe += mem_sz;
    669		if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
    670			memcpy(pframe, pattrib->icv, pattrib->icv_len);
    671			pframe += pattrib->icv_len;
    672		}
    673		frg_inx++;
    674		if (bmcst || r8712_endofpktfile(&pktfile)) {
    675			pattrib->nr_frags = frg_inx;
    676			pattrib->last_txcmdsz = pattrib->hdrlen +
    677						pattrib->iv_len +
    678						((pattrib->nr_frags == 1) ?
    679						llc_sz : 0) +
    680						((pattrib->bswenc) ?
    681						pattrib->icv_len : 0) + mem_sz;
    682			ClearMFrag(mem_start);
    683			break;
    684		}
    685		addr = (addr_t)(pframe);
    686		mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
    687		memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
    688	}
    689
    690	if (xmitframe_addmic(padapter, pxmitframe))
    691		return _FAIL;
    692	xmitframe_swencrypt(padapter, pxmitframe);
    693	return _SUCCESS;
    694}
    695
    696void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
    697{
    698	uint	protection;
    699	u8	*perp;
    700	uint	erp_len;
    701	struct	xmit_priv *pxmitpriv = &padapter->xmitpriv;
    702	struct	registry_priv *pregistrypriv = &padapter->registrypriv;
    703
    704	switch (pxmitpriv->vcs_setting) {
    705	case DISABLE_VCS:
    706		pxmitpriv->vcs = NONE_VCS;
    707		break;
    708	case ENABLE_VCS:
    709		break;
    710	case AUTO_VCS:
    711	default:
    712		perp = r8712_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len);
    713		if (!perp) {
    714			pxmitpriv->vcs = NONE_VCS;
    715		} else {
    716			protection = (*(perp + 2)) & BIT(1);
    717			if (protection) {
    718				if (pregistrypriv->vcs_type == RTS_CTS)
    719					pxmitpriv->vcs = RTS_CTS;
    720				else
    721					pxmitpriv->vcs = CTS_TO_SELF;
    722			} else {
    723				pxmitpriv->vcs = NONE_VCS;
    724			}
    725		}
    726		break;
    727	}
    728}
    729
    730struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
    731{
    732	unsigned long irqL;
    733	struct xmit_buf *pxmitbuf;
    734	struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
    735
    736	spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
    737	pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
    738					    struct xmit_buf, list);
    739	if (pxmitbuf) {
    740		list_del_init(&pxmitbuf->list);
    741		pxmitpriv->free_xmitbuf_cnt--;
    742	}
    743	spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
    744	return pxmitbuf;
    745}
    746
    747void r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
    748{
    749	unsigned long irqL;
    750	struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
    751
    752	if (!pxmitbuf)
    753		return;
    754	spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
    755	list_del_init(&pxmitbuf->list);
    756	list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
    757	pxmitpriv->free_xmitbuf_cnt++;
    758	spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
    759}
    760
    761/*
    762 * Calling context:
    763 * 1. OS_TXENTRY
    764 * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
    765 *
    766 * If we turn on USE_RXTHREAD, then, no need for critical section.
    767 * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
    768 *
    769 * Must be very very cautious...
    770 *
    771 */
    772struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
    773{
    774	/*
    775	 * Please remember to use all the osdep_service api,
    776	 * and lock/unlock or _enter/_exit critical to protect
    777	 * pfree_xmit_queue
    778	 */
    779	unsigned long irqL;
    780	struct xmit_frame *pxframe;
    781	struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
    782
    783	spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
    784	pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
    785					   struct xmit_frame, list);
    786	if (pxframe) {
    787		list_del_init(&pxframe->list);
    788		pxmitpriv->free_xmitframe_cnt--;
    789		pxframe->buf_addr = NULL;
    790		pxframe->pxmitbuf = NULL;
    791		pxframe->attrib.psta = NULL;
    792		pxframe->pkt = NULL;
    793	}
    794	spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
    795	return pxframe;
    796}
    797
    798void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
    799			  struct xmit_frame *pxmitframe)
    800{
    801	unsigned long irqL;
    802	struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
    803	struct _adapter *padapter = pxmitpriv->adapter;
    804
    805	if (!pxmitframe)
    806		return;
    807	spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
    808	list_del_init(&pxmitframe->list);
    809	if (pxmitframe->pkt)
    810		pxmitframe->pkt = NULL;
    811	list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
    812	pxmitpriv->free_xmitframe_cnt++;
    813	spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
    814	if (netif_queue_stopped(padapter->pnetdev))
    815		netif_wake_queue(padapter->pnetdev);
    816}
    817
    818void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
    819		      struct xmit_frame *pxmitframe)
    820{
    821	if (!pxmitframe)
    822		return;
    823	if (pxmitframe->frame_tag == DATA_FRAMETAG)
    824		r8712_free_xmitframe(pxmitpriv, pxmitframe);
    825}
    826
    827void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
    828				struct  __queue *pframequeue)
    829{
    830	unsigned long irqL;
    831	struct list_head *plist, *phead;
    832	struct	xmit_frame	*pxmitframe;
    833
    834	spin_lock_irqsave(&(pframequeue->lock), irqL);
    835	phead = &pframequeue->queue;
    836	plist = phead->next;
    837	while (!end_of_queue_search(phead, plist)) {
    838		pxmitframe = container_of(plist, struct xmit_frame, list);
    839		plist = plist->next;
    840		r8712_free_xmitframe(pxmitpriv, pxmitframe);
    841	}
    842	spin_unlock_irqrestore(&(pframequeue->lock), irqL);
    843}
    844
    845static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
    846					       struct  __queue **ppstapending,
    847					       struct sta_info *psta, sint up)
    848{
    849	struct tx_servq *ptxservq;
    850	struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
    851
    852	switch (up) {
    853	case 1:
    854	case 2:
    855		ptxservq = &(psta->sta_xmitpriv.bk_q);
    856		*ppstapending = &padapter->xmitpriv.bk_pending;
    857		(phwxmits + 3)->accnt++;
    858		break;
    859	case 4:
    860	case 5:
    861		ptxservq = &(psta->sta_xmitpriv.vi_q);
    862		*ppstapending = &padapter->xmitpriv.vi_pending;
    863		(phwxmits + 1)->accnt++;
    864		break;
    865	case 6:
    866	case 7:
    867		ptxservq = &(psta->sta_xmitpriv.vo_q);
    868		*ppstapending = &padapter->xmitpriv.vo_pending;
    869		(phwxmits + 0)->accnt++;
    870		break;
    871	case 0:
    872	case 3:
    873	default:
    874		ptxservq = &(psta->sta_xmitpriv.be_q);
    875		*ppstapending = &padapter->xmitpriv.be_pending;
    876		(phwxmits + 2)->accnt++;
    877		break;
    878	}
    879	return ptxservq;
    880}
    881
    882/*
    883 * Will enqueue pxmitframe to the proper queue, and indicate it
    884 * to xx_pending list.....
    885 */
    886int r8712_xmit_classifier(struct _adapter *padapter,
    887			  struct xmit_frame *pxmitframe)
    888{
    889	unsigned long irqL0;
    890	struct  __queue *pstapending;
    891	struct sta_info	*psta;
    892	struct tx_servq	*ptxservq;
    893	struct pkt_attrib *pattrib = &pxmitframe->attrib;
    894	struct sta_priv *pstapriv = &padapter->stapriv;
    895	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
    896	bool bmcst = is_multicast_ether_addr(pattrib->ra);
    897
    898	if (pattrib->psta) {
    899		psta = pattrib->psta;
    900	} else {
    901		if (bmcst) {
    902			psta = r8712_get_bcmc_stainfo(padapter);
    903		} else {
    904			if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
    905				psta = r8712_get_stainfo(pstapriv,
    906				       get_bssid(pmlmepriv));
    907			else
    908				psta = r8712_get_stainfo(pstapriv, pattrib->ra);
    909		}
    910	}
    911	if (!psta)
    912		return -EINVAL;
    913	ptxservq = get_sta_pending(padapter, &pstapending,
    914		   psta, pattrib->priority);
    915	spin_lock_irqsave(&pstapending->lock, irqL0);
    916	if (list_empty(&ptxservq->tx_pending))
    917		list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
    918	list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
    919	ptxservq->qcnt++;
    920	spin_unlock_irqrestore(&pstapending->lock, irqL0);
    921	return 0;
    922}
    923
    924static void alloc_hwxmits(struct _adapter *padapter)
    925{
    926	struct hw_xmit *hwxmits;
    927	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
    928
    929	pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
    930	pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry,
    931				sizeof(struct hw_xmit), GFP_ATOMIC);
    932	if (!pxmitpriv->hwxmits)
    933		return;
    934	hwxmits = pxmitpriv->hwxmits;
    935	if (pxmitpriv->hwxmit_entry == 5) {
    936		pxmitpriv->bmc_txqueue.head = 0;
    937		hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
    938		hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
    939		pxmitpriv->vo_txqueue.head = 0;
    940		hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
    941		hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
    942		pxmitpriv->vi_txqueue.head = 0;
    943		hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
    944		hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
    945		pxmitpriv->bk_txqueue.head = 0;
    946		hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
    947		hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
    948		pxmitpriv->be_txqueue.head = 0;
    949		hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
    950		hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
    951	} else if (pxmitpriv->hwxmit_entry == 4) {
    952		pxmitpriv->vo_txqueue.head = 0;
    953		hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
    954		hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
    955		pxmitpriv->vi_txqueue.head = 0;
    956		hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
    957		hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
    958		pxmitpriv->be_txqueue.head = 0;
    959		hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
    960		hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
    961		pxmitpriv->bk_txqueue.head = 0;
    962		hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
    963		hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
    964	}
    965}
    966
    967static void free_hwxmits(struct _adapter *padapter)
    968{
    969	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
    970
    971	kfree(pxmitpriv->hwxmits);
    972}
    973
    974static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
    975{
    976	sint i;
    977
    978	for (i = 0; i < entry; i++, phwxmit++) {
    979		spin_lock_init(&phwxmit->xmit_lock);
    980		INIT_LIST_HEAD(&phwxmit->pending);
    981		phwxmit->txcmdcnt = 0;
    982		phwxmit->accnt = 0;
    983	}
    984}
    985
    986void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
    987			struct xmit_buf *pxmitbuf)
    988{
    989	/* pxmitbuf attach to pxmitframe */
    990	pxmitframe->pxmitbuf = pxmitbuf;
    991	/* urb and irp connection */
    992	pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
    993	/* buffer addr assoc */
    994	pxmitframe->buf_addr = pxmitbuf->pbuf;
    995	/* pxmitframe attach to pxmitbuf */
    996	pxmitbuf->priv_data = pxmitframe;
    997}
    998
    999/*
   1000 * tx_action == 0 == no frames to transmit
   1001 * tx_action > 0 ==> we have frames to transmit
   1002 * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
   1003 *						 to transmit 1 frame.
   1004 */
   1005
   1006int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
   1007{
   1008	unsigned long irqL;
   1009	int ret;
   1010	struct xmit_buf *pxmitbuf = NULL;
   1011	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
   1012	struct pkt_attrib *pattrib = &pxmitframe->attrib;
   1013
   1014	r8712_do_queue_select(padapter, pattrib);
   1015	spin_lock_irqsave(&pxmitpriv->lock, irqL);
   1016	if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
   1017		ret = false;
   1018		r8712_xmit_enqueue(padapter, pxmitframe);
   1019		spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
   1020		return ret;
   1021	}
   1022	pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
   1023	if (!pxmitbuf) { /*enqueue packet*/
   1024		ret = false;
   1025		r8712_xmit_enqueue(padapter, pxmitframe);
   1026		spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
   1027	} else { /*dump packet directly*/
   1028		spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
   1029		ret = true;
   1030		xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
   1031		r8712_xmit_direct(padapter, pxmitframe);
   1032	}
   1033	return ret;
   1034}