brintos

brintos / linux-shallow public Read only

0
0
Text · 47.0 KiB · 3705cb1 Raw
1463 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.4 * All rights reserved.5 *6 * Purpose: handle WMAC/802.3/802.11 rx & tx functions7 *8 * Author: Lyndon Chen9 *10 * Date: May 20, 200311 *12 * Functions:13 *      s_vGenerateTxParameter - Generate tx dma required parameter.14 *      vGenerateMACHeader - Translate 802.3 to 802.11 header15 *      cbGetFragCount - Calculate fragment number count16 *      csBeacon_xmit - beacon tx function17 *      csMgmt_xmit - management tx function18 *      s_cbFillTxBufHead - fulfill tx dma buffer header19 *      s_uGetDataDuration - get tx data required duration20 *      s_uFillDataHead- fulfill tx data duration header21 *      s_uGetRTSCTSDuration- get rtx/cts required duration22 *      get_rtscts_time- get rts/cts reserved time23 *      s_uGetTxRsvTime- get frame reserved time24 *      s_vFillCTSHead- fulfill CTS ctl header25 *      s_vFillFragParameter- Set fragment ctl parameter.26 *      s_vFillRTSHead- fulfill RTS ctl header27 *      s_vFillTxKey- fulfill tx encrypt key28 *      s_vSWencryption- Software encrypt header29 *      vDMA0_tx_80211- tx 802.11 frame via dma030 *      vGenerateFIFOHeader- Generate tx FIFO ctl header31 *32 * Revision History:33 *34 */35 36#include "device.h"37#include "rxtx.h"38#include "card.h"39#include "mac.h"40#include "baseband.h"41#include "rf.h"42 43/*---------------------  Static Definitions -------------------------*/44 45/*---------------------  Static Classes  ----------------------------*/46 47/*---------------------  Static Variables  --------------------------*/48 49/*---------------------  Static Functions  --------------------------*/50 51/*---------------------  Static Definitions -------------------------*/52/* if packet size < 256 -> in-direct send53 * vpacket size >= 256 -> direct send54 */55#define CRITICAL_PACKET_LEN      25656 57static const unsigned short time_stamp_off[2][MAX_RATE] = {58	{384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */59	{384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */60};61 62static const unsigned short fb_opt0[2][5] = {63	{RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */64	{RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */65};66 67static const unsigned short fb_opt1[2][5] = {68	{RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */69	{RATE_6M,  RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */70};71 72#define RTSDUR_BB       073#define RTSDUR_BA       174#define RTSDUR_AA       275#define CTSDUR_BA       376#define RTSDUR_BA_F0    477#define RTSDUR_AA_F0    578#define RTSDUR_BA_F1    679#define RTSDUR_AA_F1    780#define CTSDUR_BA_F0    881#define CTSDUR_BA_F1    982#define DATADUR_B       1083#define DATADUR_A       1184#define DATADUR_A_F0    1285#define DATADUR_A_F1    1386 87/*---------------------  Static Functions  --------------------------*/88static89void90s_vFillRTSHead(91	struct vnt_private *pDevice,92	unsigned char byPktType,93	void *pvRTS,94	unsigned int	cbFrameLength,95	bool bNeedAck,96	bool bDisCRC,97	struct ieee80211_hdr *hdr,98	unsigned short wCurrentRate,99	unsigned char byFBOption100);101 102static103void104s_vGenerateTxParameter(105	struct vnt_private *pDevice,106	unsigned char byPktType,107	struct vnt_tx_fifo_head *,108	void *pvRrvTime,109	void *pvRTS,110	void *pvCTS,111	unsigned int	cbFrameSize,112	bool bNeedACK,113	unsigned int	uDMAIdx,114	void *psEthHeader,115	unsigned short wCurrentRate116);117 118static unsigned int119s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,120		  unsigned char *pbyTxBufferAddr,121		  unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,122		  unsigned int uNodeIndex);123 124static125__le16126s_uFillDataHead(127	struct vnt_private *pDevice,128	unsigned char byPktType,129	void *pTxDataHead,130	unsigned int cbFrameLength,131	unsigned int uDMAIdx,132	bool bNeedAck,133	unsigned int uFragIdx,134	unsigned int cbLastFragmentSize,135	unsigned int uMACfragNum,136	unsigned char byFBOption,137	unsigned short wCurrentRate,138	bool is_pspoll139);140 141/*---------------------  Export Variables  --------------------------*/142 143static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)144{145	return cpu_to_le16(time_stamp_off[priv->preamble_type % 2]146							[rate % MAX_RATE]);147}148 149/* byPktType : PK_TYPE_11A     0150 * PK_TYPE_11B     1151 * PK_TYPE_11GB    2152 * PK_TYPE_11GA    3153 */154static155unsigned int156s_uGetTxRsvTime(157	struct vnt_private *pDevice,158	unsigned char byPktType,159	unsigned int cbFrameLength,160	unsigned short wRate,161	bool bNeedAck162)163{164	unsigned int uDataTime, uAckTime;165 166	uDataTime = bb_get_frame_time(pDevice->preamble_type, byPktType, cbFrameLength, wRate);167 168	if (!bNeedAck)169		return uDataTime;170 171	/*172	 * CCK mode  - 11b173	 * OFDM mode - 11g 2.4G & 11a 5G174	 */175	uAckTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14,176				     byPktType == PK_TYPE_11B ?177				     pDevice->byTopCCKBasicRate :178				     pDevice->byTopOFDMBasicRate);179 180	return uDataTime + pDevice->uSIFS + uAckTime;181}182 183static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,184				    u32 frame_length, u16 rate, bool need_ack)185{186	return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,187						frame_length, rate, need_ack));188}189 190/* byFreqType: 0=>5GHZ 1=>2.4GHZ */191static __le16 get_rtscts_time(struct vnt_private *priv,192			      unsigned char rts_rsvtype,193			      unsigned char pkt_type,194			      unsigned int frame_length,195			      unsigned short current_rate)196{197	unsigned int rrv_time = 0;198	unsigned int rts_time = 0;199	unsigned int cts_time = 0;200	unsigned int ack_time = 0;201	unsigned int data_time = 0;202 203	data_time = bb_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate);204	if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */205		rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);206		ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);207		cts_time = ack_time;208	} else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */209		rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);210		cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);211		ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);212	} else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */213		rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopOFDMBasicRate);214		ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);215		cts_time = ack_time;216	} else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */217		cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);218		ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);219		rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;220		return cpu_to_le16((u16)rrv_time);221	}222 223	/* RTSRrvTime */224	rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;225	return cpu_to_le16((u16)rrv_time);226}227 228/* byFreqType 0: 5GHz, 1:2.4Ghz */229static230unsigned int231s_uGetDataDuration(232	struct vnt_private *pDevice,233	unsigned char byDurType,234	unsigned int cbFrameLength,235	unsigned char byPktType,236	unsigned short wRate,237	bool bNeedAck,238	unsigned int uFragIdx,239	unsigned int cbLastFragmentSize,240	unsigned int uMACfragNum,241	unsigned char byFBOption242)243{244	bool bLastFrag = false;245	unsigned int uAckTime = 0, uNextPktTime = 0, len;246 247	if (uFragIdx == (uMACfragNum - 1))248		bLastFrag = true;249 250	if (uFragIdx == (uMACfragNum - 2))251		len = cbLastFragmentSize;252	else253		len = cbFrameLength;254 255	switch (byDurType) {256	case DATADUR_B:    /* DATADUR_B */257		if (bNeedAck) {258			uAckTime = bb_get_frame_time(pDevice->preamble_type,259						     byPktType, 14,260						     pDevice->byTopCCKBasicRate);261		}262		/* Non Frag or Last Frag */263		if ((uMACfragNum == 1) || bLastFrag) {264			if (!bNeedAck)265				return 0;266		} else {267			/* First Frag or Mid Frag */268			uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,269						       len, wRate, bNeedAck);270		}271 272		return pDevice->uSIFS + uAckTime + uNextPktTime;273 274	case DATADUR_A:    /* DATADUR_A */275		if (bNeedAck) {276			uAckTime = bb_get_frame_time(pDevice->preamble_type,277						     byPktType, 14,278						     pDevice->byTopOFDMBasicRate);279		}280		/* Non Frag or Last Frag */281		if ((uMACfragNum == 1) || bLastFrag) {282			if (!bNeedAck)283				return 0;284		} else {285			/* First Frag or Mid Frag */286			uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,287						       len, wRate, bNeedAck);288		}289 290		return pDevice->uSIFS + uAckTime + uNextPktTime;291 292	case DATADUR_A_F0:    /* DATADUR_A_F0 */293	case DATADUR_A_F1:    /* DATADUR_A_F1 */294		if (bNeedAck) {295			uAckTime = bb_get_frame_time(pDevice->preamble_type,296						     byPktType, 14,297						     pDevice->byTopOFDMBasicRate);298		}299		/* Non Frag or Last Frag */300		if ((uMACfragNum == 1) || bLastFrag) {301			if (!bNeedAck)302				return 0;303		} else {304			/* First Frag or Mid Frag */305			if (wRate < RATE_18M)306				wRate = RATE_18M;307			else if (wRate > RATE_54M)308				wRate = RATE_54M;309 310			wRate -= RATE_18M;311 312			if (byFBOption == AUTO_FB_0)313				wRate = fb_opt0[FB_RATE0][wRate];314			else315				wRate = fb_opt1[FB_RATE0][wRate];316 317			uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,318						       len, wRate, bNeedAck);319		}320 321		return pDevice->uSIFS + uAckTime + uNextPktTime;322 323	default:324		break;325	}326 327	return 0;328}329 330/* byFreqType: 0=>5GHZ 1=>2.4GHZ */331static332__le16333s_uGetRTSCTSDuration(334	struct vnt_private *pDevice,335	unsigned char byDurType,336	unsigned int cbFrameLength,337	unsigned char byPktType,338	unsigned short wRate,339	bool bNeedAck,340	unsigned char byFBOption341)342{343	unsigned int uCTSTime = 0, uDurTime = 0;344 345	switch (byDurType) {346	case RTSDUR_BB:    /* RTSDuration_bb */347		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);348		uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);349		break;350 351	case RTSDUR_BA:    /* RTSDuration_ba */352		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);353		uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);354		break;355 356	case RTSDUR_AA:    /* RTSDuration_aa */357		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);358		uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);359		break;360 361	case CTSDUR_BA:    /* CTSDuration_ba */362		uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);363		break;364 365	case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */366		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);367		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))368			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);369		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))370			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);371 372		break;373 374	case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */375		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);376		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))377			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);378		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))379			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);380 381		break;382 383	case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */384		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);385		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))386			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);387		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))388			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);389 390		break;391 392	case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */393		uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);394		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))395			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);396		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))397			uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);398 399		break;400 401	case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */402		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))403			uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);404		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))405			uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);406 407		break;408 409	case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */410		if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))411			uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);412		else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))413			uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);414 415		break;416 417	default:418		break;419	}420 421	return cpu_to_le16((u16)uDurTime);422}423 424static425__le16426s_uFillDataHead(427	struct vnt_private *pDevice,428	unsigned char byPktType,429	void *pTxDataHead,430	unsigned int cbFrameLength,431	unsigned int uDMAIdx,432	bool bNeedAck,433	unsigned int uFragIdx,434	unsigned int cbLastFragmentSize,435	unsigned int uMACfragNum,436	unsigned char byFBOption,437	unsigned short wCurrentRate,438	bool is_pspoll439)440{441	struct vnt_tx_datahead_ab *buf = pTxDataHead;442 443	if (!pTxDataHead)444		return 0;445 446	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {447		/* Auto Fallback */448		struct vnt_tx_datahead_g_fb *buf = pTxDataHead;449 450		if (byFBOption == AUTO_FB_NONE) {451			struct vnt_tx_datahead_g *buf = pTxDataHead;452			/* Get SignalField, ServiceField & Length */453			vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,454					  byPktType, &buf->a);455 456			vnt_get_phy_field(pDevice, cbFrameLength,457					  pDevice->byTopCCKBasicRate,458					  PK_TYPE_11B, &buf->b);459 460			if (is_pspoll) {461				__le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));462 463				buf->duration_a = dur;464				buf->duration_b = dur;465			} else {466				/* Get Duration and TimeStamp */467				buf->duration_a =468					cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,469									    byPktType, wCurrentRate, bNeedAck, uFragIdx,470									    cbLastFragmentSize, uMACfragNum,471									    byFBOption));472				buf->duration_b =473					cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,474									    PK_TYPE_11B, pDevice->byTopCCKBasicRate,475									    bNeedAck, uFragIdx, cbLastFragmentSize,476									    uMACfragNum, byFBOption));477			}478 479			buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);480			buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);481 482			return buf->duration_a;483		}484 485		/* Get SignalField, ServiceField & Length */486		vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,487				  byPktType, &buf->a);488 489		vnt_get_phy_field(pDevice, cbFrameLength,490				  pDevice->byTopCCKBasicRate,491				  PK_TYPE_11B, &buf->b);492		/* Get Duration and TimeStamp */493		buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,494								      wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));495		buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,496								      pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));497		buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,498									 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));499		buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,500									 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));501 502		buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);503		buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);504 505		return buf->duration_a;506		  /* if (byFBOption == AUTO_FB_NONE) */507	} else if (byPktType == PK_TYPE_11A) {508		struct vnt_tx_datahead_ab *buf = pTxDataHead;509 510		if (byFBOption != AUTO_FB_NONE) {511			/* Auto Fallback */512			struct vnt_tx_datahead_a_fb *buf = pTxDataHead;513			/* Get SignalField, ServiceField & Length */514			vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,515					  byPktType, &buf->a);516 517			/* Get Duration and TimeStampOff */518			buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,519									    wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));520			buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,521									       wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));522			buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,523									       wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));524			buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);525			return buf->duration;526		}527 528		/* Get SignalField, ServiceField & Length */529		vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,530				  byPktType, &buf->ab);531 532		if (is_pspoll) {533			__le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));534 535			buf->duration = dur;536		} else {537			/* Get Duration and TimeStampOff */538			buf->duration =539				cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,540								    wCurrentRate, bNeedAck, uFragIdx,541								    cbLastFragmentSize, uMACfragNum,542								    byFBOption));543		}544 545		buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);546		return buf->duration;547	}548 549	/* Get SignalField, ServiceField & Length */550	vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,551			  byPktType, &buf->ab);552 553	if (is_pspoll) {554		__le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));555 556		buf->duration = dur;557	} else {558		/* Get Duration and TimeStampOff */559		buf->duration =560			cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,561							    wCurrentRate, bNeedAck, uFragIdx,562							    cbLastFragmentSize, uMACfragNum,563							    byFBOption));564	}565 566	buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);567	return buf->duration;568}569 570static571void572s_vFillRTSHead(573	struct vnt_private *pDevice,574	unsigned char byPktType,575	void *pvRTS,576	unsigned int cbFrameLength,577	bool bNeedAck,578	bool bDisCRC,579	struct ieee80211_hdr *hdr,580	unsigned short wCurrentRate,581	unsigned char byFBOption582)583{584	unsigned int uRTSFrameLen = 20;585 586	if (!pvRTS)587		return;588 589	if (bDisCRC) {590		/* When CRCDIS bit is on, H/W forgot to generate FCS for591		 * RTS frame, in this case we need to decrease its length by 4.592		 */593		uRTSFrameLen -= 4;594	}595 596	/* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,597	 * so we don't need to take them into account.598	 * Otherwise, we need to modify codes for them.599	 */600	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {601		if (byFBOption == AUTO_FB_NONE) {602			struct vnt_rts_g *buf = pvRTS;603			/* Get SignalField, ServiceField & Length */604			vnt_get_phy_field(pDevice, uRTSFrameLen,605					  pDevice->byTopCCKBasicRate,606					  PK_TYPE_11B, &buf->b);607 608			vnt_get_phy_field(pDevice, uRTSFrameLen,609					  pDevice->byTopOFDMBasicRate,610					  byPktType, &buf->a);611			/* Get Duration */612			buf->duration_bb =613				s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,614						     cbFrameLength, PK_TYPE_11B,615						     pDevice->byTopCCKBasicRate,616						     bNeedAck, byFBOption);617			buf->duration_aa =618				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,619						     cbFrameLength, byPktType,620						     wCurrentRate, bNeedAck,621						     byFBOption);622			buf->duration_ba =623				s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,624						     cbFrameLength, byPktType,625						     wCurrentRate, bNeedAck,626						     byFBOption);627 628			buf->data.duration = buf->duration_aa;629			/* Get RTS Frame body */630			buf->data.frame_control =631					cpu_to_le16(IEEE80211_FTYPE_CTL |632						    IEEE80211_STYPE_RTS);633 634			ether_addr_copy(buf->data.ra, hdr->addr1);635			ether_addr_copy(buf->data.ta, hdr->addr2);636		} else {637			struct vnt_rts_g_fb *buf = pvRTS;638			/* Get SignalField, ServiceField & Length */639			vnt_get_phy_field(pDevice, uRTSFrameLen,640					  pDevice->byTopCCKBasicRate,641					  PK_TYPE_11B, &buf->b);642 643			vnt_get_phy_field(pDevice, uRTSFrameLen,644					  pDevice->byTopOFDMBasicRate,645					  byPktType, &buf->a);646			/* Get Duration */647			buf->duration_bb =648				s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,649						     cbFrameLength, PK_TYPE_11B,650						     pDevice->byTopCCKBasicRate,651						     bNeedAck, byFBOption);652			buf->duration_aa =653				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,654						     cbFrameLength, byPktType,655						     wCurrentRate, bNeedAck,656						     byFBOption);657			buf->duration_ba =658				s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,659						     cbFrameLength, byPktType,660						     wCurrentRate, bNeedAck,661						     byFBOption);662			buf->rts_duration_ba_f0 =663				s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,664						     cbFrameLength, byPktType,665						     wCurrentRate, bNeedAck,666						     byFBOption);667			buf->rts_duration_aa_f0 =668				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,669						     cbFrameLength, byPktType,670						     wCurrentRate, bNeedAck,671						     byFBOption);672			buf->rts_duration_ba_f1 =673				s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,674						     cbFrameLength, byPktType,675						     wCurrentRate, bNeedAck,676						     byFBOption);677			buf->rts_duration_aa_f1 =678				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,679						     cbFrameLength, byPktType,680						     wCurrentRate, bNeedAck,681						     byFBOption);682			buf->data.duration = buf->duration_aa;683			/* Get RTS Frame body */684			buf->data.frame_control =685					cpu_to_le16(IEEE80211_FTYPE_CTL |686						    IEEE80211_STYPE_RTS);687 688			ether_addr_copy(buf->data.ra, hdr->addr1);689			ether_addr_copy(buf->data.ta, hdr->addr2);690		} /* if (byFBOption == AUTO_FB_NONE) */691	} else if (byPktType == PK_TYPE_11A) {692		if (byFBOption == AUTO_FB_NONE) {693			struct vnt_rts_ab *buf = pvRTS;694			/* Get SignalField, ServiceField & Length */695			vnt_get_phy_field(pDevice, uRTSFrameLen,696					  pDevice->byTopOFDMBasicRate,697					  byPktType, &buf->ab);698			/* Get Duration */699			buf->duration =700				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,701						     cbFrameLength, byPktType,702						     wCurrentRate, bNeedAck,703						     byFBOption);704			buf->data.duration = buf->duration;705			/* Get RTS Frame body */706			buf->data.frame_control =707					cpu_to_le16(IEEE80211_FTYPE_CTL |708						    IEEE80211_STYPE_RTS);709 710			ether_addr_copy(buf->data.ra, hdr->addr1);711			ether_addr_copy(buf->data.ta, hdr->addr2);712		} else {713			struct vnt_rts_a_fb *buf = pvRTS;714			/* Get SignalField, ServiceField & Length */715			vnt_get_phy_field(pDevice, uRTSFrameLen,716					  pDevice->byTopOFDMBasicRate,717					  byPktType, &buf->a);718			/* Get Duration */719			buf->duration =720				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,721						     cbFrameLength, byPktType,722						     wCurrentRate, bNeedAck,723						     byFBOption);724			buf->rts_duration_f0 =725				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,726						     cbFrameLength, byPktType,727						     wCurrentRate, bNeedAck,728						     byFBOption);729			buf->rts_duration_f1 =730				s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,731						     cbFrameLength, byPktType,732						     wCurrentRate, bNeedAck,733						     byFBOption);734			buf->data.duration = buf->duration;735			/* Get RTS Frame body */736			buf->data.frame_control =737					cpu_to_le16(IEEE80211_FTYPE_CTL |738						    IEEE80211_STYPE_RTS);739 740			ether_addr_copy(buf->data.ra, hdr->addr1);741			ether_addr_copy(buf->data.ta, hdr->addr2);742		}743	} else if (byPktType == PK_TYPE_11B) {744		struct vnt_rts_ab *buf = pvRTS;745		/* Get SignalField, ServiceField & Length */746		vnt_get_phy_field(pDevice, uRTSFrameLen,747				  pDevice->byTopCCKBasicRate,748				  PK_TYPE_11B, &buf->ab);749		/* Get Duration */750		buf->duration =751			s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,752					     byPktType, wCurrentRate, bNeedAck,753					     byFBOption);754 755		buf->data.duration = buf->duration;756		/* Get RTS Frame body */757		buf->data.frame_control =758			cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);759 760		ether_addr_copy(buf->data.ra, hdr->addr1);761		ether_addr_copy(buf->data.ta, hdr->addr2);762	}763}764 765static766void767s_vFillCTSHead(768	struct vnt_private *pDevice,769	unsigned int uDMAIdx,770	unsigned char byPktType,771	void *pvCTS,772	unsigned int cbFrameLength,773	bool bNeedAck,774	bool bDisCRC,775	unsigned short wCurrentRate,776	unsigned char byFBOption777)778{779	unsigned int uCTSFrameLen = 14;780 781	if (!pvCTS)782		return;783 784	if (bDisCRC) {785		/* When CRCDIS bit is on, H/W forgot to generate FCS for786		 * CTS frame, in this case we need to decrease its length by 4.787		 */788		uCTSFrameLen -= 4;789	}790 791	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {792		if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {793			/* Auto Fall back */794			struct vnt_cts_fb *buf = pvCTS;795			/* Get SignalField, ServiceField & Length */796			vnt_get_phy_field(pDevice, uCTSFrameLen,797					  pDevice->byTopCCKBasicRate,798					  PK_TYPE_11B, &buf->b);799 800			buf->duration_ba =801				s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,802						     cbFrameLength, byPktType,803						     wCurrentRate, bNeedAck,804						     byFBOption);805 806			/* Get CTSDuration_ba_f0 */807			buf->cts_duration_ba_f0 =808				s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,809						     cbFrameLength, byPktType,810						     wCurrentRate, bNeedAck,811						     byFBOption);812 813			/* Get CTSDuration_ba_f1 */814			buf->cts_duration_ba_f1 =815				s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,816						     cbFrameLength, byPktType,817						     wCurrentRate, bNeedAck,818						     byFBOption);819 820			/* Get CTS Frame body */821			buf->data.duration = buf->duration_ba;822 823			buf->data.frame_control =824				cpu_to_le16(IEEE80211_FTYPE_CTL |825					    IEEE80211_STYPE_CTS);826 827			buf->reserved2 = 0x0;828 829			ether_addr_copy(buf->data.ra,830					pDevice->abyCurrentNetAddr);831		} else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */832			struct vnt_cts *buf = pvCTS;833			/* Get SignalField, ServiceField & Length */834			vnt_get_phy_field(pDevice, uCTSFrameLen,835					  pDevice->byTopCCKBasicRate,836					  PK_TYPE_11B, &buf->b);837 838			/* Get CTSDuration_ba */839			buf->duration_ba =840				s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,841						     cbFrameLength, byPktType,842						     wCurrentRate, bNeedAck,843						     byFBOption);844 845			/* Get CTS Frame body */846			buf->data.duration = buf->duration_ba;847 848			buf->data.frame_control =849				cpu_to_le16(IEEE80211_FTYPE_CTL |850					    IEEE80211_STYPE_CTS);851 852			buf->reserved2 = 0x0;853			ether_addr_copy(buf->data.ra,854					pDevice->abyCurrentNetAddr);855		}856	}857}858 859/*860 *861 * Description:862 *      Generate FIFO control for MAC & Baseband controller863 *864 * Parameters:865 *  In:866 *      pDevice         - Pointer to adapter867 *      pTxDataHead     - Transmit Data Buffer868 *      pTxBufHead      - pTxBufHead869 *      pvRrvTime        - pvRrvTime870 *      pvRTS            - RTS Buffer871 *      pCTS            - CTS Buffer872 *      cbFrameSize     - Transmit Data Length (Hdr+Payload+FCS)873 *      bNeedACK        - If need ACK874 *      uDescIdx        - Desc Index875 *  Out:876 *      none877 *878 * Return Value: none879 *880 -881 * unsigned int cbFrameSize, Hdr+Payload+FCS882 */883static884void885s_vGenerateTxParameter(886	struct vnt_private *pDevice,887	unsigned char byPktType,888	struct vnt_tx_fifo_head *tx_buffer_head,889	void *pvRrvTime,890	void *pvRTS,891	void *pvCTS,892	unsigned int cbFrameSize,893	bool bNeedACK,894	unsigned int uDMAIdx,895	void *psEthHeader,896	unsigned short wCurrentRate897)898{899	u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);900	bool bDisCRC = false;901	unsigned char byFBOption = AUTO_FB_NONE;902 903	tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);904 905	if (fifo_ctl & FIFOCTL_CRCDIS)906		bDisCRC = true;907 908	if (fifo_ctl & FIFOCTL_AUTO_FB_0)909		byFBOption = AUTO_FB_0;910	else if (fifo_ctl & FIFOCTL_AUTO_FB_1)911		byFBOption = AUTO_FB_1;912 913	if (!pvRrvTime)914		return;915 916	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {917		if (pvRTS) { /* RTS_need */918			/* Fill RsvTime */919			struct vnt_rrv_time_rts *buf = pvRrvTime;920 921			buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);922			buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);923			buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);924			buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);925			buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);926 927			s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);928		} else {/* RTS_needless, PCF mode */929			struct vnt_rrv_time_cts *buf = pvRrvTime;930 931			buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);932			buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);933			buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);934 935			/* Fill CTS */936			s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);937		}938	} else if (byPktType == PK_TYPE_11A) {939		if (pvRTS) {/* RTS_need, non PCF mode */940			struct vnt_rrv_time_ab *buf = pvRrvTime;941 942			buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);943			buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);944 945			/* Fill RTS */946			s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);947		} else if (!pvRTS) {/* RTS_needless, non PCF mode */948			struct vnt_rrv_time_ab *buf = pvRrvTime;949 950			buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);951		}952	} else if (byPktType == PK_TYPE_11B) {953		if (pvRTS) {/* RTS_need, non PCF mode */954			struct vnt_rrv_time_ab *buf = pvRrvTime;955 956			buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);957			buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);958 959			/* Fill RTS */960			s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);961		} else { /* RTS_needless, non PCF mode */962			struct vnt_rrv_time_ab *buf = pvRrvTime;963 964			buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);965		}966	}967}968 969static unsigned int970s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,971		  unsigned char *pbyTxBufferAddr,972		  unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,973		  unsigned int is_pspoll)974{975	struct vnt_td_info *td_info = pHeadTD->td_info;976	struct sk_buff *skb = td_info->skb;977	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);978	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;979	struct vnt_tx_fifo_head *tx_buffer_head =980			(struct vnt_tx_fifo_head *)td_info->buf;981	u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);982	unsigned int cbFrameSize;983	__le16 uDuration;984	unsigned char *pbyBuffer;985	unsigned int uLength = 0;986	unsigned int cbMICHDR = 0;987	unsigned int uMACfragNum = 1;988	unsigned int uPadding = 0;989	unsigned int cbReqCount = 0;990	bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);991	bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);992	struct vnt_tx_desc *ptdCurr;993	unsigned int cbHeaderLength = 0;994	void *pvRrvTime = NULL;995	struct vnt_mic_hdr *pMICHDR = NULL;996	void *pvRTS = NULL;997	void *pvCTS = NULL;998	void *pvTxDataHd = NULL;999	unsigned short wTxBufSize;   /* FFinfo size */1000	unsigned char byFBOption = AUTO_FB_NONE;1001 1002	cbFrameSize = skb->len + 4;1003 1004	if (info->control.hw_key) {1005		switch (info->control.hw_key->cipher) {1006		case WLAN_CIPHER_SUITE_CCMP:1007			cbMICHDR = sizeof(struct vnt_mic_hdr);1008			break;1009		default:1010			break;1011		}1012 1013		cbFrameSize += info->control.hw_key->icv_len;1014 1015		if (pDevice->local_id > REV_ID_VT3253_A1) {1016			/* MAC Header should be padding 0 to DW alignment. */1017			uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);1018			uPadding %= 4;1019		}1020	}1021 1022	/*1023	 * Use for AUTO FALL BACK1024	 */1025	if (fifo_ctl & FIFOCTL_AUTO_FB_0)1026		byFBOption = AUTO_FB_0;1027	else if (fifo_ctl & FIFOCTL_AUTO_FB_1)1028		byFBOption = AUTO_FB_1;1029 1030	/* Set RrvTime/RTS/CTS Buffer */1031	wTxBufSize = sizeof(struct vnt_tx_fifo_head);1032	if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */1033 1034		if (byFBOption == AUTO_FB_NONE) {1035			if (bRTS) {/* RTS_need */1036				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1037				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));1038				pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);1039				pvCTS = NULL;1040				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1041							cbMICHDR + sizeof(struct vnt_rts_g));1042				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1043							cbMICHDR + sizeof(struct vnt_rts_g) +1044							sizeof(struct vnt_tx_datahead_g);1045			} else { /* RTS_needless */1046				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1047				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));1048				pvRTS = NULL;1049				pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);1050				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +1051						sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));1052				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +1053							cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);1054			}1055		} else {1056			/* Auto Fall Back */1057			if (bRTS) {/* RTS_need */1058				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1059				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));1060				pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);1061				pvCTS = NULL;1062				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1063					cbMICHDR + sizeof(struct vnt_rts_g_fb));1064				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +1065					cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);1066			} else { /* RTS_needless */1067				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1068				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));1069				pvRTS = NULL;1070				pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);1071				pvTxDataHd = (void  *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +1072					cbMICHDR + sizeof(struct vnt_cts_fb));1073				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +1074					cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);1075			}1076		} /* Auto Fall Back */1077	} else {/* 802.11a/b packet */1078 1079		if (byFBOption == AUTO_FB_NONE) {1080			if (bRTS) {1081				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1082				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1083				pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1084				pvCTS = NULL;1085				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +1086					sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));1087				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1088					cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);1089			} else { /* RTS_needless, need MICHDR */1090				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1091				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1092				pvRTS = NULL;1093				pvCTS = NULL;1094				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1095				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1096					cbMICHDR + sizeof(struct vnt_tx_datahead_ab);1097			}1098		} else {1099			/* Auto Fall Back */1100			if (bRTS) { /* RTS_need */1101				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1102				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1103				pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1104				pvCTS = NULL;1105				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +1106					sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));1107				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1108					cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);1109			} else { /* RTS_needless */1110				pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);1111				pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));1112				pvRTS = NULL;1113				pvCTS = NULL;1114				pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);1115				cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +1116					cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);1117			}1118		} /* Auto Fall Back */1119	}1120 1121	td_info->mic_hdr = pMICHDR;1122 1123	memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));1124 1125	/* Fill FIFO,RrvTime,RTS,and CTS */1126	s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,1127			       cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);1128	/* Fill DataHead */1129	uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,1130				    0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);1131 1132	hdr->duration_id = uDuration;1133 1134	cbReqCount = cbHeaderLength + uPadding + skb->len;1135	pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;1136	uLength = cbHeaderLength + uPadding;1137 1138	/* Copy the Packet into a tx Buffer */1139	memcpy((pbyBuffer + uLength), skb->data, skb->len);1140 1141	ptdCurr = pHeadTD;1142 1143	ptdCurr->td_info->req_count = (u16)cbReqCount;1144 1145	return cbHeaderLength;1146}1147 1148static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,1149			   struct ieee80211_key_conf *tx_key,1150			   struct sk_buff *skb,	u16 payload_len,1151			   struct vnt_mic_hdr *mic_hdr)1152{1153	u64 pn64;1154	u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));1155 1156	/* strip header and icv len from payload */1157	payload_len -= ieee80211_get_hdrlen_from_skb(skb);1158	payload_len -= tx_key->icv_len;1159 1160	switch (tx_key->cipher) {1161	case WLAN_CIPHER_SUITE_WEP40:1162	case WLAN_CIPHER_SUITE_WEP104:1163		memcpy(key_buffer, iv, 3);1164		memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);1165 1166		if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {1167			memcpy(key_buffer + 8, iv, 3);1168			memcpy(key_buffer + 11,1169			       tx_key->key, WLAN_KEY_LEN_WEP40);1170		}1171 1172		break;1173	case WLAN_CIPHER_SUITE_TKIP:1174		ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);1175 1176		break;1177	case WLAN_CIPHER_SUITE_CCMP:1178 1179		if (!mic_hdr)1180			return;1181 1182		mic_hdr->id = 0x59;1183		mic_hdr->payload_len = cpu_to_be16(payload_len);1184		ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);1185 1186		pn64 = atomic64_read(&tx_key->tx_pn);1187		mic_hdr->ccmp_pn[5] = pn64;1188		mic_hdr->ccmp_pn[4] = pn64 >> 8;1189		mic_hdr->ccmp_pn[3] = pn64 >> 16;1190		mic_hdr->ccmp_pn[2] = pn64 >> 24;1191		mic_hdr->ccmp_pn[1] = pn64 >> 32;1192		mic_hdr->ccmp_pn[0] = pn64 >> 40;1193 1194		if (ieee80211_has_a4(hdr->frame_control))1195			mic_hdr->hlen = cpu_to_be16(28);1196		else1197			mic_hdr->hlen = cpu_to_be16(22);1198 1199		ether_addr_copy(mic_hdr->addr1, hdr->addr1);1200		ether_addr_copy(mic_hdr->addr2, hdr->addr2);1201		ether_addr_copy(mic_hdr->addr3, hdr->addr3);1202 1203		mic_hdr->frame_control = cpu_to_le16(1204			le16_to_cpu(hdr->frame_control) & 0xc78f);1205		mic_hdr->seq_ctrl = cpu_to_le16(1206				le16_to_cpu(hdr->seq_ctrl) & 0xf);1207 1208		if (ieee80211_has_a4(hdr->frame_control))1209			ether_addr_copy(mic_hdr->addr4, hdr->addr4);1210 1211		memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);1212 1213		break;1214	default:1215		break;1216	}1217}1218 1219int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,1220			     struct vnt_tx_desc *head_td, struct sk_buff *skb)1221{1222	struct vnt_td_info *td_info = head_td->td_info;1223	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);1224	struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];1225	struct ieee80211_rate *rate;1226	struct ieee80211_key_conf *tx_key;1227	struct ieee80211_hdr *hdr;1228	struct vnt_tx_fifo_head *tx_buffer_head =1229			(struct vnt_tx_fifo_head *)td_info->buf;1230	u16 tx_body_size = skb->len, current_rate;1231	u8 pkt_type;1232	bool is_pspoll = false;1233 1234	memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));1235 1236	hdr = (struct ieee80211_hdr *)(skb->data);1237 1238	rate = ieee80211_get_tx_rate(priv->hw, info);1239 1240	current_rate = rate->hw_value;1241	if (priv->wCurrentRate != current_rate &&1242	    !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {1243		priv->wCurrentRate = current_rate;1244 1245		RFbSetPower(priv, priv->wCurrentRate,1246			    priv->hw->conf.chandef.chan->hw_value);1247	}1248 1249	if (current_rate > RATE_11M) {1250		if (info->band == NL80211_BAND_5GHZ) {1251			pkt_type = PK_TYPE_11A;1252		} else {1253			if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)1254				pkt_type = PK_TYPE_11GB;1255			else1256				pkt_type = PK_TYPE_11GA;1257		}1258	} else {1259		pkt_type = PK_TYPE_11B;1260	}1261 1262	/*Set fifo controls */1263	if (pkt_type == PK_TYPE_11A)1264		tx_buffer_head->fifo_ctl = 0;1265	else if (pkt_type == PK_TYPE_11B)1266		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);1267	else if (pkt_type == PK_TYPE_11GB)1268		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);1269	else if (pkt_type == PK_TYPE_11GA)1270		tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);1271 1272	/* generate interrupt */1273	tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);1274 1275	if (!ieee80211_is_data(hdr->frame_control)) {1276		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);1277		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);1278		tx_buffer_head->time_stamp =1279			cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);1280	} else {1281		tx_buffer_head->time_stamp =1282			cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);1283	}1284 1285	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))1286		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);1287 1288	if (ieee80211_has_retry(hdr->frame_control))1289		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);1290 1291	if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)1292		priv->preamble_type = PREAMBLE_SHORT;1293	else1294		priv->preamble_type = PREAMBLE_LONG;1295 1296	if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)1297		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);1298 1299	if (ieee80211_has_a4(hdr->frame_control)) {1300		tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);1301		priv->bLongHeader = true;1302	}1303 1304	if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)1305		is_pspoll = true;1306 1307	tx_buffer_head->frag_ctl =1308			cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);1309 1310	if (info->control.hw_key) {1311		switch (info->control.hw_key->cipher) {1312		case WLAN_CIPHER_SUITE_WEP40:1313		case WLAN_CIPHER_SUITE_WEP104:1314			tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);1315			break;1316		case WLAN_CIPHER_SUITE_TKIP:1317			tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);1318			break;1319		case WLAN_CIPHER_SUITE_CCMP:1320			tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);1321			break;1322		default:1323			break;1324		}1325	}1326 1327	tx_buffer_head->current_rate = cpu_to_le16(current_rate);1328 1329	/* legacy rates TODO use ieee80211_tx_rate */1330	if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {1331		if (priv->byAutoFBCtrl == AUTO_FB_0)1332			tx_buffer_head->fifo_ctl |=1333						cpu_to_le16(FIFOCTL_AUTO_FB_0);1334		else if (priv->byAutoFBCtrl == AUTO_FB_1)1335			tx_buffer_head->fifo_ctl |=1336						cpu_to_le16(FIFOCTL_AUTO_FB_1);1337	}1338 1339	tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);1340 1341	s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,1342			  dma_idx, head_td, is_pspoll);1343 1344	if (info->control.hw_key) {1345		tx_key = info->control.hw_key;1346		if (tx_key->keylen > 0)1347			vnt_fill_txkey(hdr, tx_buffer_head->tx_key,1348				       tx_key, skb, tx_body_size,1349				       td_info->mic_hdr);1350	}1351 1352	return 0;1353}1354 1355static int vnt_beacon_xmit(struct vnt_private *priv,1356			   struct sk_buff *skb)1357{1358	struct vnt_tx_short_buf_head *short_head =1359		(struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;1360	struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)1361				(priv->tx_beacon_bufs + sizeof(*short_head));1362	struct ieee80211_tx_info *info;1363	u32 frame_size = skb->len + 4;1364	u16 current_rate;1365 1366	memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));1367 1368	if (priv->byBBType == BB_TYPE_11A) {1369		current_rate = RATE_6M;1370 1371		/* Get SignalField,ServiceField,Length */1372		vnt_get_phy_field(priv, frame_size, current_rate,1373				  PK_TYPE_11A, &short_head->ab);1374 1375		/* Get Duration and TimeStampOff */1376		short_head->duration =1377			cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,1378							    frame_size, PK_TYPE_11A, current_rate,1379							    false, 0, 0, 1, AUTO_FB_NONE));1380 1381		short_head->time_stamp_off =1382				vnt_time_stamp_off(priv, current_rate);1383	} else {1384		current_rate = RATE_1M;1385		short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);1386 1387		/* Get SignalField,ServiceField,Length */1388		vnt_get_phy_field(priv, frame_size, current_rate,1389				  PK_TYPE_11B, &short_head->ab);1390 1391		/* Get Duration and TimeStampOff */1392		short_head->duration =1393			cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,1394							    frame_size, PK_TYPE_11B, current_rate,1395							    false, 0, 0, 1, AUTO_FB_NONE));1396 1397		short_head->time_stamp_off =1398			vnt_time_stamp_off(priv, current_rate);1399	}1400 1401	short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);1402 1403	/* Copy Beacon */1404	memcpy(mgmt_hdr, skb->data, skb->len);1405 1406	/* time stamp always 0 */1407	mgmt_hdr->u.beacon.timestamp = 0;1408 1409	info = IEEE80211_SKB_CB(skb);1410	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {1411		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;1412 1413		hdr->duration_id = 0;1414		hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);1415	}1416 1417	priv->wSeqCounter++;1418	if (priv->wSeqCounter > 0x0fff)1419		priv->wSeqCounter = 0;1420 1421	priv->wBCNBufLen = sizeof(*short_head) + skb->len;1422 1423	iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);1424 1425	iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2);1426	/* Set auto Transmit on */1427	vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);1428	/* Poll Transmit the adapter */1429	iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL);1430 1431	return 0;1432}1433 1434int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)1435{1436	struct sk_buff *beacon;1437 1438	beacon = ieee80211_beacon_get(priv->hw, vif, 0);1439	if (!beacon)1440		return -ENOMEM;1441 1442	if (vnt_beacon_xmit(priv, beacon)) {1443		ieee80211_free_txskb(priv->hw, beacon);1444		return -ENODEV;1445	}1446 1447	return 0;1448}1449 1450int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,1451		      struct ieee80211_bss_conf *conf)1452{1453	iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);1454 1455	iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);1456 1457	CARDvSetFirstNextTBTT(priv, conf->beacon_int);1458 1459	card_set_beacon_period(priv, conf->beacon_int);1460 1461	return vnt_beacon_make(priv, vif);1462}1463