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