12865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger/******************************************************************************
22865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * rtl8712_xmit.c
32865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
42865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
52865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * Linux device driver for RTL8192SU
62865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
72865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * This program is free software; you can redistribute it and/or modify it
82865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * under the terms of version 2 of the GNU General Public License as
92865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * published by the Free Software Foundation.
102865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
112865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * This program is distributed in the hope that it will be useful, but WITHOUT
122865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
132865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
142865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * more details.
152865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
162865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * You should have received a copy of the GNU General Public License along with
172865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * this program; if not, write to the Free Software Foundation, Inc.,
182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
202865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * Modifications for inclusion into the Linux staging tree are
212865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * Copyright(c) 2010 Larry Finger. All rights reserved.
222865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * Contact information:
242865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * WLAN FAE <wlanfae@realtek.com>
252865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger * Larry Finger <Larry.Finger@lwfinger.net>
262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger *
272865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger ******************************************************************************/
282865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
292865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger#define _RTL8712_XMIT_C_
302865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
312865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger#include "osdep_service.h"
322865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger#include "drv_types.h"
332865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger#include "wifi.h"
342865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger#include "osdep_intf.h"
352865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger#include "usb_ops.h"
362865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
372865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerstatic void dump_xframe(struct _adapter *padapter,
382865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			struct xmit_frame *pxmitframe);
39ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Baharstatic void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz);
402865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
412865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingersint _r8712_init_hw_txqueue(struct hw_txqueue *phw_txqueue, u8 ac_tag)
422865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
432865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	phw_txqueue->ac_tag = ac_tag;
442865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	switch (ac_tag) {
452865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case BE_QUEUE_INX:
462865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ;
472865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
482865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case BK_QUEUE_INX:
492865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phw_txqueue->ff_hwaddr = RTL8712_DMA_BKQ;
502865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
512865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case VI_QUEUE_INX:
522865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phw_txqueue->ff_hwaddr = RTL8712_DMA_VIQ;
532865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
542865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case VO_QUEUE_INX:
552865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phw_txqueue->ff_hwaddr = RTL8712_DMA_VOQ;
562865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
572865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case BMC_QUEUE_INX:
582865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phw_txqueue->ff_hwaddr = RTL8712_DMA_BEQ;
592865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
602865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
612865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return _SUCCESS;
622865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
632865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
642865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerint r8712_txframes_sta_ac_pending(struct _adapter *padapter,
652865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				  struct pkt_attrib *pattrib)
662865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
672865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct sta_info *psta;
682865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct tx_servq *ptxservq;
692865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	int priority = pattrib->priority;
702865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
712865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	psta = pattrib->psta;
722865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	switch (priority) {
732865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 1:
742865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 2:
752865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxservq = &(psta->sta_xmitpriv.bk_q);
762865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
772865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 4:
782865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 5:
792865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxservq = &(psta->sta_xmitpriv.vi_q);
802865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
812865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 6:
822865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 7:
832865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxservq = &(psta->sta_xmitpriv.vo_q);
842865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		break;
852865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 0:
862865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	case 3:
872865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	default:
882865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxservq = &(psta->sta_xmitpriv.be_q);
892865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	break;
902865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
912865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return ptxservq->qcnt;
922865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
932865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
942865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerstatic u32 get_ff_hwaddr(struct xmit_frame *pxmitframe)
952865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
962865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	u32 addr = 0;
972865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct pkt_attrib *pattrib = &pxmitframe->attrib;
982865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct _adapter *padapter = pxmitframe->padapter;
992865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
1002865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
1012865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
1022865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		addr = RTL8712_DMA_H2CCMD;
1032865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
1042865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		addr = RTL8712_DMA_MGTQ;
1052865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	else if (pdvobj->nr_endpoint == 6) {
1062865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		switch (pattrib->priority) {
1072865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0:
1082865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 3:
1092865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_BEQ;
1102865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1112865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 1:
1122865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 2:
1132865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_BKQ;
1142865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1152865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 4:
1162865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 5:
1172865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_VIQ;
1182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 6:
1202865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 7:
1212865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_VOQ;
1222865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x10:
1242865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x11:
1252865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x12:
1262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x13:
1272865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_H2CCMD;
1282865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1292865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		default:
1302865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_BEQ;
1312865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1322865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
1332865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	} else if (pdvobj->nr_endpoint == 4) {
1342865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		switch (pattrib->qsel) {
1352865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0:
1362865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 3:
1372865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 1:
1382865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 2:
1392865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/
1402865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1412865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 4:
1422865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 5:
1432865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 6:
1442865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 7:
1452865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_VOQ;/*RTL8712_EP_HI;*/
1462865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1472865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x10:
1482865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x11:
1492865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x12:
1502865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		case 0x13:
151859171ca92f2865453b4b2e17bf679c67044a833Joe Perches			addr = RTL8712_DMA_H2CCMD;
1522865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1532865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		default:
1542865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/
1552865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			break;
1562865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
1572865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
1582865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return addr;
1592865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
1602865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
1612865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerstatic struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv,
1622865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger					 struct hw_xmit *phwxmit,
1632865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger					 struct tx_servq *ptxservq,
1642865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger					 struct  __queue *pframe_queue)
1652865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
1662865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct list_head *xmitframe_plist, *xmitframe_phead;
1672865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct	xmit_frame *pxmitframe = NULL;
1682865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
169e99a428a1daed550142a08f6acb5265a1d108e65James A Shackleford	xmitframe_phead = &pframe_queue->queue;
170849fb0a8878336732165eb482d3f0e8a4f71dd03James A Shackleford	xmitframe_plist = xmitframe_phead->next;
1712865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if ((end_of_queue_search(xmitframe_phead, xmitframe_plist)) == false) {
1722865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		pxmitframe = LIST_CONTAINOR(xmitframe_plist,
1732865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			     struct xmit_frame, list);
17429197b7c45a144883d87cb8eaf337026cd886a20James A Shackleford		list_del_init(&pxmitframe->list);
1752865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxservq->qcnt--;
1762865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phwxmit->txcmdcnt++;
1772865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
1782865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return pxmitframe;
1792865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
1802865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
1812865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerstatic struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv,
1822865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				     struct hw_xmit *phwxmit_i, sint entry)
1832865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
1842865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	unsigned long irqL0;
1852865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct list_head *sta_plist, *sta_phead;
1862865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct hw_xmit *phwxmit;
1872865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct tx_servq *ptxservq = NULL;
1882865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct  __queue *pframe_queue = NULL;
1892865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct	xmit_frame *pxmitframe = NULL;
1902865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	int i, inx[4];
1912865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	int j, tmp, acirp_cnt[4];
1922865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
1932865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	/*entry indx: 0->vo, 1->vi, 2->be, 3->bk.*/
1942865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	inx[0] = 0; acirp_cnt[0] = pxmitpriv->voq_cnt;
1952865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	inx[1] = 1; acirp_cnt[1] = pxmitpriv->viq_cnt;
1962865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	inx[2] = 2; acirp_cnt[2] = pxmitpriv->beq_cnt;
1972865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	inx[3] = 3; acirp_cnt[3] = pxmitpriv->bkq_cnt;
1982865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	for (i = 0; i < 4; i++) {
1992865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		for (j = i + 1; j < 4; j++) {
2002865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			if (acirp_cnt[j] < acirp_cnt[i]) {
2012865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				tmp = acirp_cnt[i];
2022865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				acirp_cnt[i] = acirp_cnt[j];
2032865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				acirp_cnt[j] = tmp;
2042865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				tmp = inx[i];
2052865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				inx[i] = inx[j];
2062865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				inx[j] = tmp;
2072865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			}
2082865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
2092865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
2102865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	spin_lock_irqsave(&pxmitpriv->lock, irqL0);
2112865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	for (i = 0; i < entry; i++) {
2122865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		phwxmit = phwxmit_i + inx[i];
213e99a428a1daed550142a08f6acb5265a1d108e65James A Shackleford		sta_phead = &phwxmit->sta_queue->queue;
214849fb0a8878336732165eb482d3f0e8a4f71dd03James A Shackleford		sta_plist = sta_phead->next;
2152865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		while ((end_of_queue_search(sta_phead, sta_plist)) == false) {
2162865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq,
2172865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				  tx_pending);
2182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			pframe_queue = &ptxservq->sta_pending;
2192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			pxmitframe = dequeue_one_xmitframe(pxmitpriv, phwxmit,
2202865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				     ptxservq, pframe_queue);
2212865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			if (pxmitframe) {
2222865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				phwxmit->accnt--;
2232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				goto exit_dequeue_xframe_ex;
2242865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			}
225849fb0a8878336732165eb482d3f0e8a4f71dd03James A Shackleford			sta_plist = sta_plist->next;
2262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/*Remove sta node when there are no pending packets.*/
227df353f61afb917ff66b2e784b0ffb85d0ebb29a4James A Shackleford			if (list_empty(&pframe_queue->queue)) {
228849fb0a8878336732165eb482d3f0e8a4f71dd03James A Shackleford				/* must be done after sta_plist->next
229849fb0a8878336732165eb482d3f0e8a4f71dd03James A Shackleford				 * and before break
230849fb0a8878336732165eb482d3f0e8a4f71dd03James A Shackleford				 */
23129197b7c45a144883d87cb8eaf337026cd886a20James A Shackleford				list_del_init(&ptxservq->tx_pending);
2322865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			}
2332865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
2342865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
2352865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerexit_dequeue_xframe_ex:
2362865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	spin_unlock_irqrestore(&pxmitpriv->lock, irqL0);
2372865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return pxmitframe;
2382865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
2392865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
2402865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingervoid r8712_do_queue_select(struct _adapter *padapter,
2412865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			   struct pkt_attrib *pattrib)
2422865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
243ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar	unsigned int qsel = 0;
2442865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
2452865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
2462865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (pdvobj->nr_endpoint == 6)
247ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		qsel = (unsigned int) pattrib->priority;
248ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar	else if (pdvobj->nr_endpoint == 4) {
249ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		qsel = (unsigned int) pattrib->priority;
250ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		if (qsel == 0 || qsel == 3)
251ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar			qsel = 3;
252ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		else if (qsel == 1 || qsel == 2)
253ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar			qsel = 1;
254ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		else if (qsel == 4 || qsel == 5)
255ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar			qsel = 5;
256ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		else if (qsel == 6 || qsel == 7)
257ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar			qsel = 7;
258ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar		else
259ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar			qsel = 3;
260ee5b1aadfd5cda257337a9b9777114a10c18c31eAli Bahar	}
2612865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	pattrib->qsel = qsel;
2622865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
2632865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
26493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
26593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Baharu8 r8712_construct_txaggr_cmd_desc(struct xmit_buf *pxmitbuf)
26693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar{
26793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf;
26893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
26993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* Fill up TxCmd Descriptor according as USB FW Tx Aaggregation info.*/
27093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* dw0 */
27193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	ptx_desc->txdw0 = cpu_to_le32(CMD_HDR_SZ&0xffff);
27293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	ptx_desc->txdw0 |=
27393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);
27493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	ptx_desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
27593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
27693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* dw1 */
27793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	ptx_desc->txdw1 |= cpu_to_le32((0x13<<QSEL_SHT)&0x00001f00);
27893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
27993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	return _SUCCESS;
28093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar}
28193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
28293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Baharu8 r8712_construct_txaggr_cmd_hdr(struct xmit_buf *pxmitbuf)
28393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar{
28493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct xmit_frame *pxmitframe = (struct xmit_frame *)
28593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		pxmitbuf->priv_data;
28693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct _adapter *padapter = pxmitframe->padapter;
28793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
28893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct cmd_hdr *pcmd_hdr = (struct cmd_hdr  *)
28993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		(pxmitbuf->pbuf + TXDESC_SIZE);
29093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
29193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* Fill up Cmd Header for USB FW Tx Aggregation.*/
29293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* dw0 */
29393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pcmd_hdr->cmd_dw0 = cpu_to_le32((GEN_CMD_CODE(_AMSDU_TO_AMPDU) << 16) |
29493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					(pcmdpriv->cmd_seq << 24));
29593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pcmdpriv->cmd_seq++;
29693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
29793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	return _SUCCESS;
29893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar}
29993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
30093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Baharu8 r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf,
30193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			struct xmit_frame *pxmitframe)
30293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar{
30393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct _adapter *padapter = pxmitframe->padapter;
30493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct tx_desc *ptx_desc = (struct tx_desc *)pxmitbuf->pbuf;
30593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	int last_txcmdsz = 0;
30693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	int padding_sz = 0;
30793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
30893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* 802.3->802.11 convertor */
30993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
31093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* free skb struct */
31193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	r8712_xmit_complete(padapter, pxmitframe);
31293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	if (pxmitframe->attrib.ether_type != 0x0806) {
31393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if ((pxmitframe->attrib.ether_type != 0x888e) &&
31493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			(pxmitframe->attrib.dhcp_pkt != 1)) {
31593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			r8712_issue_addbareq_cmd(padapter,
31693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					pxmitframe->attrib.priority);
31793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		}
31893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	}
31993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->last[0] = 1;
32093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	update_txdesc(pxmitframe, (uint *)(pxmitframe->buf_addr),
32193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		pxmitframe->attrib.last_txcmdsz);
32293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/*padding zero */
32393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	last_txcmdsz = pxmitframe->attrib.last_txcmdsz;
32493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	padding_sz = (8 - (last_txcmdsz % 8));
32593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	if ((last_txcmdsz % 8) != 0) {
32693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		int i;
32702a29d2d9209ad24258432057886a5af5816c388Tapasweni Pathak
32893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		for (i = 0; i < padding_sz; i++)
32993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			*(pxmitframe->buf_addr+TXDESC_SIZE+last_txcmdsz+i) = 0;
33093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	}
33193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* Add the new mpdu's length */
33293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	ptx_desc->txdw0 = cpu_to_le32((ptx_desc->txdw0&0xffff0000) |
33393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		((ptx_desc->txdw0&0x0000ffff)+
33493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			((TXDESC_SIZE+last_txcmdsz+padding_sz)&0x0000ffff)));
33593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
33693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	return _SUCCESS;
33793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar}
33893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
33993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
34093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Baharu8 r8712_xmitframe_aggr_1st(struct xmit_buf *pxmitbuf,
34193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			struct xmit_frame *pxmitframe)
34293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar{
34393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* linux complete context doesnt need to protect */
34493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->pxmitbuf = pxmitbuf;
34593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitbuf->priv_data = pxmitframe;
34693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
34793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* buffer addr assoc */
34893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->buf_addr = pxmitbuf->pbuf+TXDESC_SIZE+CMD_HDR_SZ;
34993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/*RTL8712_DMA_H2CCMD */
35093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	r8712_construct_txaggr_cmd_desc(pxmitbuf);
35193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	r8712_construct_txaggr_cmd_hdr(pxmitbuf);
35293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	if (r8712_append_mpdu_unit(pxmitbuf, pxmitframe) == _SUCCESS)
35393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		pxmitbuf->aggr_nr = 1;
35493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
35593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	return _SUCCESS;
35693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar}
35793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
35893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Baharu16 r8712_xmitframe_aggr_next(struct xmit_buf *pxmitbuf,
35993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			struct xmit_frame *pxmitframe)
36093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar{
36193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->pxmitbuf = pxmitbuf;
36293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitbuf->priv_data = pxmitframe;
36393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
36493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* buffer addr assoc */
36593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->buf_addr = pxmitbuf->pbuf + TXDESC_SIZE +
36693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		(((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff);
36793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	if (r8712_append_mpdu_unit(pxmitbuf, pxmitframe) == _SUCCESS) {
36893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		r8712_free_xmitframe_ex(&pxmitframe->padapter->xmitpriv,
36993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					pxmitframe);
37093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		pxmitbuf->aggr_nr++;
37193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	}
37293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
37393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	return TXDESC_SIZE +
37493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		(((struct tx_desc *)pxmitbuf->pbuf)->txdw0 & 0x0000ffff);
37593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar}
37693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
37793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Baharu8 r8712_dump_aggr_xframe(struct xmit_buf *pxmitbuf,
37893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			struct xmit_frame *pxmitframe)
37993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar{
38093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct _adapter *padapter = pxmitframe->padapter;
38193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct dvobj_priv *pdvobj = (struct dvobj_priv *) &padapter->dvobjpriv;
382c06df2334ce9a0072c94ffffcd8977fe726015f1Devendra Naga	struct tx_desc *ptxdesc = (struct tx_desc *)pxmitbuf->pbuf;
38393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct cmd_hdr *pcmd_hdr = (struct cmd_hdr *)
38493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		(pxmitbuf->pbuf + TXDESC_SIZE);
38593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	u16 total_length = (u16) (ptxdesc->txdw0 & 0xffff);
38693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
38793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* use 1st xmitframe as media */
38893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
38993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pcmd_hdr->cmd_dw0 = cpu_to_le32(((total_length-CMD_HDR_SZ)&0x0000ffff)|
39093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					(pcmd_hdr->cmd_dw0&0xffff0000));
39193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
39293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	/* urb length in cmd_dw1 */
39393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pcmd_hdr->cmd_dw1 = cpu_to_le32((pxmitbuf->aggr_nr & 0xff)|
39493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					((total_length+TXDESC_SIZE) << 16));
39593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->last[0] = 1;
39693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->bpending[0] = false;
39793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	pxmitframe->mem_addr = pxmitbuf->pbuf;
39893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
39993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	if ((pdvobj->ishighspeed && ((total_length+TXDESC_SIZE)%0x200) == 0) ||
40093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		((!pdvobj->ishighspeed &&
40193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			((total_length+TXDESC_SIZE)%0x40) == 0))) {
40293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		ptxdesc->txdw0 |= cpu_to_le32
40393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			(((TXDESC_SIZE+OFFSET_SZ+8)<<OFFSET_SHT)&0x00ff0000);
40493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		/*32 bytes for TX Desc + 8 bytes pending*/
40593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	} else {
40693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		ptxdesc->txdw0 |= cpu_to_le32
40793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);
40893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		/*default = 32 bytes for TX Desc*/
40993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	}
41093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	r8712_write_port(pxmitframe->padapter, RTL8712_DMA_H2CCMD,
41193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			total_length+TXDESC_SIZE, (u8 *)pxmitframe);
41293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
41393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	return _SUCCESS;
41493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar}
41593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
41693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
41793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
4182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerstatic void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz)
4192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
4202865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	uint qsel;
4212865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct _adapter *padapter = pxmitframe->padapter;
4222865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4242865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct security_priv *psecuritypriv = &padapter->securitypriv;
4252865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct pkt_attrib *pattrib = &pxmitframe->attrib;
4262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
4272865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct dvobj_priv *pdvobj = (struct dvobj_priv *)&padapter->dvobjpriv;
42893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
42993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct cmd_priv *pcmdpriv = (struct cmd_priv *)&padapter->cmdpriv;
43093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
4312865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	u8 blnSetTxDescOffset;
4322865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	sint bmcst = IS_MCAST(pattrib->ra);
4332865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
4342865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct tx_desc txdesc_mp;
4352865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
4362865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	memcpy(&txdesc_mp, ptxdesc, sizeof(struct tx_desc));
4372865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	memset(ptxdesc, 0, sizeof(struct tx_desc));
4382865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	/* offset 0 */
4392865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
4402865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (pdvobj->ishighspeed) {
4412865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (((sz + TXDESC_SIZE) % 512) == 0)
4422865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			blnSetTxDescOffset = 1;
4432865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		else
4442865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			blnSetTxDescOffset = 0;
4452865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	} else {
4462865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (((sz + TXDESC_SIZE) % 64) == 0)
4472865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			blnSetTxDescOffset = 1;
4482865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		else
4492865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			blnSetTxDescOffset = 0;
4502865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
4512865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (blnSetTxDescOffset) {
4522865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* 32 bytes for TX Desc + 8 bytes pending */
4532865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ + 8) <<
4542865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			      OFFSET_SHT) & 0x00ff0000);
4552865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	} else {
4562865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* default = 32 bytes for TX Desc */
4572865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ) <<
4582865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				  OFFSET_SHT) & 0x00ff0000);
4592865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
4602865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
4612865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4622865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 4 */
4632865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= cpu_to_le32((pattrib->mac_id)&0x1f);
46493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
46593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
46693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		/* dirty workaround, need to check if it is aggr cmd. */
46793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if ((u8 *)pmem != (u8 *)pxmitframe->pxmitbuf->pbuf) {
46893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw0 |= cpu_to_le32
46993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((0x3 << TYPE_SHT)&TYPE_MSK);
47093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			qsel = (uint)(pattrib->qsel & 0x0000001f);
47193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			if (qsel == 2)
47293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				qsel = 0;
47393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw1 |= cpu_to_le32
47493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((qsel << QSEL_SHT) & 0x00001f00);
47593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw2 = cpu_to_le32
47693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((qsel << RTS_RC_SHT)&0x001f0000);
47793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw6 |= cpu_to_le32
47893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((0x5 << RSVD6_SHT)&RSVD6_MSK);
47993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		} else {
48093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw0 |= cpu_to_le32
48193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((0x3 << TYPE_SHT)&TYPE_MSK);
48293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw1 |= cpu_to_le32
48393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((0x13 << QSEL_SHT) & 0x00001f00);
48493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			qsel = (uint)(pattrib->qsel & 0x0000001f);
48593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			if (qsel == 2)
48693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				qsel = 0;
48793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw2 = cpu_to_le32
48893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				((qsel << RTS_RC_SHT)&0x0001f000);
48993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			ptxdesc->txdw7 |= cpu_to_le32
49093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				(pcmdpriv->cmd_seq << 24);
49193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			pcmdpriv->cmd_seq++;
49293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		}
49393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		pattrib->qsel = 0x13;
49493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#else
4952865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		qsel = (uint)(pattrib->qsel & 0x0000001f);
4962865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
49793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
4982865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (!pqospriv->qos_option)
4992865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/*Non-QoS*/
5002865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
5012865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			switch (pattrib->encrypt) {	/*SEC_TYPE*/
5022865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			case _WEP40_:
5032865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			case _WEP104_:
5042865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				ptxdesc->txdw1 |= cpu_to_le32((0x01 << 22) &
5052865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger						  0x00c00000);
5062865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				/*KEY_ID when WEP is used;*/
5072865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				ptxdesc->txdw1 |= cpu_to_le32((psecuritypriv->
5082865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger						  PrivacyKeyIndex << 17) &
5092865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger						  0x00060000);
5102865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				break;
5112865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			case _TKIP_:
5122865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			case _TKIP_WTMIC_:
5132865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				ptxdesc->txdw1 |= cpu_to_le32((0x02 << 22) &
5142865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger						  0x00c00000);
5152865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				break;
5162865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			case _AES_:
5172865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				ptxdesc->txdw1 |= cpu_to_le32((0x03 << 22) &
5182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger						  0x00c00000);
5192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				break;
5202865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			case _NO_PRIVACY_:
5212865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			default:
5222865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				break;
5232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			}
5242865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
5252865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/*offset 8*/
5262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (bmcst)
5272865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw2 |= cpu_to_le32(BMC);
5282865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
5292865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/*offset 12*/
5302865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* f/w will increase the seqnum by itself, driver pass the
5312865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * correct priority to fw
5322865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * fw will check the correct priority for increasing the
5332865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * seqnum per tid. about usb using 4-endpoint, qsel points out
5342865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * the correct mapping between AC&Endpoint,
5352865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * the purpose is that correct mapping lets the MAC release
5362865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * the AC Queue list correctly. */
5372865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) &
5382865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				 0x0fff0000);
5392865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if ((pattrib->ether_type != 0x888e) &&
5402865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		    (pattrib->ether_type != 0x0806) &&
5412865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		    (pattrib->dhcp_pkt != 1)) {
5422865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/*Not EAP & ARP type data packet*/
5432865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			if (phtpriv->ht_option == 1) { /*B/G/N Mode*/
5442865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				if (phtpriv->ampdu_enable != true)
5452865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger					ptxdesc->txdw2 |= cpu_to_le32(BK);
5462865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			}
5472865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		} else {
5482865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/* EAP data packet and ARP packet.
5492865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			 * Use the 1M data rate to send the EAP/ARP packet.
5502865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			 * This will maybe make the handshake smooth.
5512865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			 */
5522865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/*driver uses data rate*/
5532865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw4 = cpu_to_le32(0x80000000);
5542865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/*1M*/
5552865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
5562865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (pattrib->pctrl == 1) { /* mp tx packets */
5572865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			struct tx_desc *ptxdesc_mp;
55802a29d2d9209ad24258432057886a5af5816c388Tapasweni Pathak
5592865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc_mp = &txdesc_mp;
5602865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/* offset 8 */
5612865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw2 = cpu_to_le32(ptxdesc_mp->txdw2);
5622865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			if (bmcst)
5632865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger				ptxdesc->txdw2 |= cpu_to_le32(BMC);
5642865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw2 |= cpu_to_le32(BK);
5652865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/* offset 16 */
5662865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw4 = cpu_to_le32(ptxdesc_mp->txdw4);
5672865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			/* offset 20 */
5682865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw5 = cpu_to_le32(ptxdesc_mp->txdw5);
5692865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			pattrib->pctrl = 0;/* reset to zero; */
5702865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
5712865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	} else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
5722865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 4 */
5732865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= (0x05) & 0x1f;/*CAM_ID(MAC_ID), default=5;*/
5742865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		qsel = (uint)(pattrib->qsel & 0x0000001f);
5752865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
5762865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/* Non-QoS */
5772865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 8 */
5782865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (bmcst)
5792865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			ptxdesc->txdw2 |= cpu_to_le32(BMC);
5802865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 12 */
5812865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* f/w will increase the seqnum by itself, driver pass the
5822865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * correct priority to fw
5832865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * fw will check the correct priority for increasing the seqnum
5842865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * per tid. about usb using 4-endpoint, qsel points out the
5852865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * correct mapping between AC&Endpoint,
5862865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * the purpose is that correct mapping let the MAC releases
5872865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		 * the AC Queue list correctly. */
5882865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw3 = cpu_to_le32((pattrib->priority << SEQ_SHT) &
5892865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger					      0x0fff0000);
5902865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 16 */
5912865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/
5922865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 20 */
5932865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw5 = cpu_to_le32(0x001f8000);/* gtest 1M */
5942865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	} else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
5952865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 4 */
5962865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		qsel = 0x13;
5972865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
5982865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	} else {
5992865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/* offset 4 */
6002865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		qsel = (uint)(pattrib->priority&0x0000001f);
6012865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
6022865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/*offset 8*/
6032865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/*offset 12*/
6042865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw3 = cpu_to_le32((pattrib->seqnum << SEQ_SHT) &
6052865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger					      0x0fff0000);
6062865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/*offset 16*/
6072865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw4 = cpu_to_le32(0x80002040);/*gtest*/
6082865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		/*offset 20*/
6092865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ptxdesc->txdw5 = cpu_to_le32(0x001f9600);/*gtest*/
6102865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
6112865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
6122865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
6132865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerint r8712_xmitframe_complete(struct _adapter *padapter,
6142865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			     struct xmit_priv *pxmitpriv,
6152865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			     struct xmit_buf *pxmitbuf)
6162865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
6172865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct hw_xmit *phwxmits;
6182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	sint hwentry;
6192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct xmit_frame *pxmitframe = NULL;
62093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
62193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar	struct xmit_frame *p2ndxmitframe = NULL;
62293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#else
6232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	int res = _SUCCESS, xcnt = 0;
62493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
6252865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
6262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	phwxmits = pxmitpriv->hwxmits;
6272865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	hwentry = pxmitpriv->hwxmit_entry;
6282865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (pxmitbuf == NULL) {
6292865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
6302865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (!pxmitbuf)
6312865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			return false;
63293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
63393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		pxmitbuf->aggr_nr = 0;
63493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
6352865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
63607a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar	/* 1st frame dequeued */
63707a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar	pxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits, hwentry);
63807a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar	/* need to remember the 1st frame */
63907a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar	if (pxmitframe != NULL) {
64007a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar
64193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
64293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		/* 1. dequeue 2nd frame
64393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		 * 2. aggr if 2nd xframe is dequeued, else dump directly
64493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		 */
64593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if (AGGR_NR_HIGH_BOUND > 1)
64693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			p2ndxmitframe = dequeue_xframe_ex(pxmitpriv, phwxmits,
64793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar							hwentry);
64893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if (pxmitframe->frame_tag != DATA_FRAMETAG) {
64993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
65093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			return false;
65193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		}
65293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if (p2ndxmitframe != NULL)
65393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			if (p2ndxmitframe->frame_tag != DATA_FRAMETAG) {
65493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
65593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				return false;
65693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			}
65793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		r8712_xmitframe_aggr_1st(pxmitbuf, pxmitframe);
65893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if (p2ndxmitframe != NULL) {
65993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			u16 total_length;
66002a29d2d9209ad24258432057886a5af5816c388Tapasweni Pathak
66193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			total_length = r8712_xmitframe_aggr_next(
66293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				pxmitbuf, p2ndxmitframe);
66393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			do {
66493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				p2ndxmitframe = dequeue_xframe_ex(
66593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					pxmitpriv, phwxmits, hwentry);
66693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				if (p2ndxmitframe != NULL)
66793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					total_length =
66893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar						r8712_xmitframe_aggr_next(
66993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar							pxmitbuf,
67093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar							p2ndxmitframe);
67193c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				else
67293c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar					break;
67393c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			} while (total_length <= 0x1800 &&
67493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				pxmitbuf->aggr_nr <= AGGR_NR_HIGH_BOUND);
67593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		}
67693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		if (pxmitbuf->aggr_nr > 0)
67793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar			r8712_dump_aggr_xframe(pxmitbuf, pxmitframe);
67893c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar
67993c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#else
68007a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar
68107a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
68207a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		if (pxmitframe->frame_tag == DATA_FRAMETAG) {
68307a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar			if (pxmitframe->attrib.priority <= 15)
68407a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar				res = r8712_xmitframe_coalesce(padapter,
68507a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar					pxmitframe->pkt, pxmitframe);
68607a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar			/* always return ndis_packet after
68707a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar			 * r8712_xmitframe_coalesce */
68807a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar			r8712_xmit_complete(padapter, pxmitframe);
6892865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
69007a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		if (res == _SUCCESS)
69107a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar			dump_xframe(padapter, pxmitframe);
69207a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		else
69307a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar			r8712_free_xmitframe_ex(pxmitpriv, pxmitframe);
69407a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		xcnt++;
69593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
69607a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar
69707a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar	} else { /* pxmitframe == NULL && p2ndxmitframe == NULL */
69807a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		r8712_free_xmitbuf(pxmitpriv, pxmitbuf);
69907a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar		return false;
70007a6b03707d3e6c5e1de2869a79b0bdca97ee2acAli Bahar	}
7012865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return true;
7022865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
7032865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
7042865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerstatic void dump_xframe(struct _adapter *padapter,
7052865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			struct xmit_frame *pxmitframe)
7062865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
7072865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	int t, sz, w_sz;
7082865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	u8 *mem_addr;
7092865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	u32 ff_hwaddr;
7102865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct pkt_attrib *pattrib = &pxmitframe->attrib;
7112865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7122865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	struct security_priv *psecuritypriv = &padapter->securitypriv;
7132865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
7142865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (pxmitframe->attrib.ether_type != 0x0806) {
7152865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (pxmitframe->attrib.ether_type != 0x888e)
7162865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			r8712_issue_addbareq_cmd(padapter, pattrib->priority);
7172865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
7182865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	mem_addr = pxmitframe->buf_addr;
7192865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	for (t = 0; t < pattrib->nr_frags; t++) {
7202865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		if (t != (pattrib->nr_frags - 1)) {
7212865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			sz = pxmitpriv->frag_len;
7222865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 :
7232865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			     pattrib->icv_len);
7242865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			pxmitframe->last[t] = 0;
7252865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		} else {
7262865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			sz = pattrib->last_txcmdsz;
7272865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			pxmitframe->last[t] = 1;
7282865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		}
7292865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		update_txdesc(pxmitframe, (uint *)mem_addr, sz);
7302865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		w_sz = sz + TXDESC_SIZE;
7312865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		pxmitframe->mem_addr = mem_addr;
7322865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		pxmitframe->bpending[t] = false;
7332865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		ff_hwaddr = get_ff_hwaddr(pxmitframe);
73493c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#ifdef CONFIG_R8712_TX_AGGR
73593c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar		r8712_write_port(padapter, RTL8712_DMA_H2CCMD, w_sz,
73693c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar				(unsigned char *)pxmitframe);
73793c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#else
7382865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		r8712_write_port(padapter, ff_hwaddr, w_sz,
7392865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger			   (unsigned char *)pxmitframe);
74093c55dda092c7ec2a0bc6a93b5ab220ddbdffb95Ali Bahar#endif
7412865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		mem_addr += w_sz;
7422865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		mem_addr = (u8 *)RND4(((addr_t)(mem_addr)));
7432865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
7442865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
7452865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
7462865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerint r8712_xmit_direct(struct _adapter *padapter, struct xmit_frame *pxmitframe)
7472865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
7482865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	int res = _SUCCESS;
7492865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
7502865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	res = r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
7512865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	pxmitframe->pkt = NULL;
7522865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (res == _SUCCESS)
7532865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		dump_xframe(padapter, pxmitframe);
7542865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return res;
7552865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
7562865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger
7572865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Fingerint r8712_xmit_enqueue(struct _adapter *padapter, struct xmit_frame *pxmitframe)
7582865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger{
7592865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	if (r8712_xmit_classifier(padapter, pxmitframe) == _FAIL) {
7602865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		pxmitframe->pkt = NULL;
7612865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger		return _FAIL;
7622865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	}
7632865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger	return _SUCCESS;
7642865d42c78a9121caad52cb02d1fbb7f5cdbc4efLarry Finger}
765