[go: nahoru, domu]

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