2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
28 * s_vGenerateTxParameter - Generate tx dma required parameter.
29 * vGenerateMACHeader - Translate 802.3 to 802.11 header
30 * cbGetFragCount - Calculate fragment number count
31 * csBeacon_xmit - beacon tx function
32 * csMgmt_xmit - management tx function
33 * s_cbFillTxBufHead - fulfill tx dma buffer header
34 * s_uGetDataDuration - get tx data required duration
35 * s_uFillDataHead- fulfill tx data duration header
36 * s_uGetRTSCTSDuration- get rtx/cts required duration
37 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
38 * s_uGetTxRsvTime- get frame reserved time
39 * s_vFillCTSHead- fulfill CTS ctl header
40 * s_vFillFragParameter- Set fragment ctl parameter.
41 * s_vFillRTSHead- fulfill RTS ctl header
42 * s_vFillTxKey- fulfill tx encrypt key
43 * s_vSWencryption- Software encrypt header
44 * vDMA0_tx_80211- tx 802.11 frame via dma0
45 * vGenerateFIFOHeader- Generate tx FIFO ctl header
58 /*--------------------- Static Definitions -------------------------*/
60 /*--------------------- Static Classes ----------------------------*/
62 /*--------------------- Static Variables --------------------------*/
64 /*--------------------- Static Functions --------------------------*/
66 /*--------------------- Static Definitions -------------------------*/
67 #define CRITICAL_PACKET_LEN 256 /* if packet size < 256 -> in-direct send
68 packet size >= 256 -> direct send */
70 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
71 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
72 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
75 static const unsigned short wFB_Opt0[2][5] = {
76 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
77 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
79 static const unsigned short wFB_Opt1[2][5] = {
80 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
81 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
88 #define RTSDUR_BA_F0 4
89 #define RTSDUR_AA_F0 5
90 #define RTSDUR_BA_F1 6
91 #define RTSDUR_AA_F1 7
92 #define CTSDUR_BA_F0 8
93 #define CTSDUR_BA_F1 9
96 #define DATADUR_A_F0 12
97 #define DATADUR_A_F1 13
99 /*--------------------- Static Functions --------------------------*/
103 struct vnt_private *pDevice,
104 unsigned char byPktType,
106 unsigned int cbFrameLength,
109 struct ieee80211_hdr *hdr,
110 unsigned short wCurrentRate,
111 unsigned char byFBOption
116 s_vGenerateTxParameter(
117 struct vnt_private *pDevice,
118 unsigned char byPktType,
119 struct vnt_tx_fifo_head *,
123 unsigned int cbFrameSize,
125 unsigned int uDMAIdx,
127 unsigned short wCurrentRate
131 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
132 unsigned char *pbyTxBufferAddr,
133 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
134 unsigned int uNodeIndex);
139 struct vnt_private *pDevice,
140 unsigned char byPktType,
142 unsigned int cbFrameLength,
143 unsigned int uDMAIdx,
145 unsigned int uFragIdx,
146 unsigned int cbLastFragmentSize,
147 unsigned int uMACfragNum,
148 unsigned char byFBOption,
149 unsigned short wCurrentRate,
153 /*--------------------- Export Variables --------------------------*/
155 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
157 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
161 /*byPktType : PK_TYPE_11A 0
169 struct vnt_private *pDevice,
170 unsigned char byPktType,
171 unsigned int cbFrameLength,
172 unsigned short wRate,
176 unsigned int uDataTime, uAckTime;
178 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
179 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
180 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
181 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
185 return uDataTime + pDevice->uSIFS + uAckTime;
190 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
191 u32 frame_length, u16 rate, bool need_ack)
193 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
194 frame_length, rate, need_ack));
197 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
201 struct vnt_private *pDevice,
202 unsigned char byRTSRsvType,
203 unsigned char byPktType,
204 unsigned int cbFrameLength,
205 unsigned short wCurrentRate
208 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
210 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
212 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
213 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
214 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
215 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
216 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
217 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
218 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
219 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
220 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
221 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
222 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
223 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
224 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
225 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
226 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
227 return cpu_to_le16((u16)uRrvTime);
231 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
232 return cpu_to_le16((u16)uRrvTime);
235 /* byFreqType 0: 5GHz, 1:2.4Ghz */
239 struct vnt_private *pDevice,
240 unsigned char byDurType,
241 unsigned int cbFrameLength,
242 unsigned char byPktType,
243 unsigned short wRate,
245 unsigned int uFragIdx,
246 unsigned int cbLastFragmentSize,
247 unsigned int uMACfragNum,
248 unsigned char byFBOption
251 bool bLastFrag = false;
252 unsigned int uAckTime = 0, uNextPktTime = 0;
254 if (uFragIdx == (uMACfragNum-1))
258 case DATADUR_B: /* DATADUR_B */
259 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
261 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
262 return pDevice->uSIFS + uAckTime;
266 } else {/* First Frag or Mid Frag */
267 if (uFragIdx == (uMACfragNum-2))
268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
273 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
274 return pDevice->uSIFS + uAckTime + uNextPktTime;
276 return pDevice->uSIFS + uNextPktTime;
281 case DATADUR_A: /* DATADUR_A */
282 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
284 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
285 return pDevice->uSIFS + uAckTime;
289 } else {/* First Frag or Mid Frag */
290 if (uFragIdx == (uMACfragNum-2))
291 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
296 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
297 return pDevice->uSIFS + uAckTime + uNextPktTime;
299 return pDevice->uSIFS + uNextPktTime;
304 case DATADUR_A_F0: /* DATADUR_A_F0 */
305 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
307 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
308 return pDevice->uSIFS + uAckTime;
312 } else { /* First Frag or Mid Frag */
313 if (byFBOption == AUTO_FB_0) {
314 if (wRate < RATE_18M)
316 else if (wRate > RATE_54M)
319 if (uFragIdx == (uMACfragNum-2))
320 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
324 } else { /* (byFBOption == AUTO_FB_1) */
325 if (wRate < RATE_18M)
327 else if (wRate > RATE_54M)
330 if (uFragIdx == (uMACfragNum-2))
331 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
338 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
339 return pDevice->uSIFS + uAckTime + uNextPktTime;
341 return pDevice->uSIFS + uNextPktTime;
346 case DATADUR_A_F1: /* DATADUR_A_F1 */
347 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
349 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
350 return pDevice->uSIFS + uAckTime;
354 } else { /* First Frag or Mid Frag */
355 if (byFBOption == AUTO_FB_0) {
356 if (wRate < RATE_18M)
358 else if (wRate > RATE_54M)
361 if (uFragIdx == (uMACfragNum-2))
362 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
366 } else { /* (byFBOption == AUTO_FB_1) */
367 if (wRate < RATE_18M)
369 else if (wRate > RATE_54M)
372 if (uFragIdx == (uMACfragNum-2))
373 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
378 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
379 return pDevice->uSIFS + uAckTime + uNextPktTime;
381 return pDevice->uSIFS + uNextPktTime;
393 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
396 s_uGetRTSCTSDuration(
397 struct vnt_private *pDevice,
398 unsigned char byDurType,
399 unsigned int cbFrameLength,
400 unsigned char byPktType,
401 unsigned short wRate,
403 unsigned char byFBOption
406 unsigned int uCTSTime = 0, uDurTime = 0;
409 case RTSDUR_BB: /* RTSDuration_bb */
410 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
411 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
414 case RTSDUR_BA: /* RTSDuration_ba */
415 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
416 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
419 case RTSDUR_AA: /* RTSDuration_aa */
420 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
421 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
424 case CTSDUR_BA: /* CTSDuration_ba */
425 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
428 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
429 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
430 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
431 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
432 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
433 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
437 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
438 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
439 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
440 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
441 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
442 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
446 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
447 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
448 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
449 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
450 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
451 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
455 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
456 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
457 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
458 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
459 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
460 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
464 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
465 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
466 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
467 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
468 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
472 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
473 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
474 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
475 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
476 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
484 return cpu_to_le16((u16)uDurTime);
490 struct vnt_private *pDevice,
491 unsigned char byPktType,
493 unsigned int cbFrameLength,
494 unsigned int uDMAIdx,
496 unsigned int uFragIdx,
497 unsigned int cbLastFragmentSize,
498 unsigned int uMACfragNum,
499 unsigned char byFBOption,
500 unsigned short wCurrentRate,
505 if (pTxDataHead == NULL)
509 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
510 if (byFBOption == AUTO_FB_NONE) {
511 struct vnt_tx_datahead_g *buf = pTxDataHead;
512 /* Get SignalField, ServiceField & Length */
513 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
516 vnt_get_phy_field(pDevice, cbFrameLength,
517 pDevice->byTopCCKBasicRate,
518 PK_TYPE_11B, &buf->b);
521 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
523 buf->duration_a = dur;
524 buf->duration_b = dur;
526 /* Get Duration and TimeStamp */
528 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
529 byPktType, wCurrentRate, bNeedAck, uFragIdx,
530 cbLastFragmentSize, uMACfragNum,
533 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
534 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
535 bNeedAck, uFragIdx, cbLastFragmentSize,
536 uMACfragNum, byFBOption));
539 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
540 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
542 return buf->duration_a;
545 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
546 /* Get SignalField, ServiceField & Length */
547 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
550 vnt_get_phy_field(pDevice, cbFrameLength,
551 pDevice->byTopCCKBasicRate,
552 PK_TYPE_11B, &buf->b);
553 /* Get Duration and TimeStamp */
554 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
555 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
556 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
557 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
559 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
560 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
561 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
563 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
564 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
566 return buf->duration_a;
567 } /* if (byFBOption == AUTO_FB_NONE) */
568 } else if (byPktType == PK_TYPE_11A) {
569 if (byFBOption != AUTO_FB_NONE) {
571 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
572 /* Get SignalField, ServiceField & Length */
573 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
576 /* Get Duration and TimeStampOff */
577 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
578 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
579 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
582 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
583 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
584 return buf->duration;
586 struct vnt_tx_datahead_ab *buf = pTxDataHead;
587 /* Get SignalField, ServiceField & Length */
588 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
589 byPktType, &buf->ab);
592 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
596 /* Get Duration and TimeStampOff */
598 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
599 wCurrentRate, bNeedAck, uFragIdx,
600 cbLastFragmentSize, uMACfragNum,
604 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
605 return buf->duration;
608 struct vnt_tx_datahead_ab *buf = pTxDataHead;
609 /* Get SignalField, ServiceField & Length */
610 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
611 byPktType, &buf->ab);
614 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
618 /* Get Duration and TimeStampOff */
620 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
621 wCurrentRate, bNeedAck, uFragIdx,
622 cbLastFragmentSize, uMACfragNum,
626 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
627 return buf->duration;
636 struct vnt_private *pDevice,
637 unsigned char byPktType,
639 unsigned int cbFrameLength,
642 struct ieee80211_hdr *hdr,
643 unsigned short wCurrentRate,
644 unsigned char byFBOption
647 unsigned int uRTSFrameLen = 20;
653 /* When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
654 in this case we need to decrease its length by 4. */
658 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
659 Otherwise, we need to modify codes for them. */
660 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
661 if (byFBOption == AUTO_FB_NONE) {
662 struct vnt_rts_g *buf = pvRTS;
663 /* Get SignalField, ServiceField & Length */
664 vnt_get_phy_field(pDevice, uRTSFrameLen,
665 pDevice->byTopCCKBasicRate,
666 PK_TYPE_11B, &buf->b);
668 vnt_get_phy_field(pDevice, uRTSFrameLen,
669 pDevice->byTopOFDMBasicRate,
673 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
674 cbFrameLength, PK_TYPE_11B,
675 pDevice->byTopCCKBasicRate,
676 bNeedAck, byFBOption);
678 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
679 cbFrameLength, byPktType,
680 wCurrentRate, bNeedAck,
683 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
684 cbFrameLength, byPktType,
685 wCurrentRate, bNeedAck,
688 buf->data.duration = buf->duration_aa;
689 /* Get RTS Frame body */
690 buf->data.frame_control =
691 cpu_to_le16(IEEE80211_FTYPE_CTL |
692 IEEE80211_STYPE_RTS);
694 ether_addr_copy(buf->data.ra, hdr->addr1);
695 ether_addr_copy(buf->data.ta, hdr->addr2);
697 struct vnt_rts_g_fb *buf = pvRTS;
698 /* Get SignalField, ServiceField & Length */
699 vnt_get_phy_field(pDevice, uRTSFrameLen,
700 pDevice->byTopCCKBasicRate,
701 PK_TYPE_11B, &buf->b);
703 vnt_get_phy_field(pDevice, uRTSFrameLen,
704 pDevice->byTopOFDMBasicRate,
708 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
709 cbFrameLength, PK_TYPE_11B,
710 pDevice->byTopCCKBasicRate,
711 bNeedAck, byFBOption);
713 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
714 cbFrameLength, byPktType,
715 wCurrentRate, bNeedAck,
718 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
719 cbFrameLength, byPktType,
720 wCurrentRate, bNeedAck,
722 buf->rts_duration_ba_f0 =
723 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
724 cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck,
727 buf->rts_duration_aa_f0 =
728 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
729 cbFrameLength, byPktType,
730 wCurrentRate, bNeedAck,
732 buf->rts_duration_ba_f1 =
733 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
734 cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck,
737 buf->rts_duration_aa_f1 =
738 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
739 cbFrameLength, byPktType,
740 wCurrentRate, bNeedAck,
742 buf->data.duration = buf->duration_aa;
743 /* Get RTS Frame body */
744 buf->data.frame_control =
745 cpu_to_le16(IEEE80211_FTYPE_CTL |
746 IEEE80211_STYPE_RTS);
748 ether_addr_copy(buf->data.ra, hdr->addr1);
749 ether_addr_copy(buf->data.ta, hdr->addr2);
750 } /* if (byFBOption == AUTO_FB_NONE) */
751 } else if (byPktType == PK_TYPE_11A) {
752 if (byFBOption == AUTO_FB_NONE) {
753 struct vnt_rts_ab *buf = pvRTS;
754 /* Get SignalField, ServiceField & Length */
755 vnt_get_phy_field(pDevice, uRTSFrameLen,
756 pDevice->byTopOFDMBasicRate,
757 byPktType, &buf->ab);
760 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
761 cbFrameLength, byPktType,
762 wCurrentRate, bNeedAck,
764 buf->data.duration = buf->duration;
765 /* Get RTS Frame body */
766 buf->data.frame_control =
767 cpu_to_le16(IEEE80211_FTYPE_CTL |
768 IEEE80211_STYPE_RTS);
770 ether_addr_copy(buf->data.ra, hdr->addr1);
771 ether_addr_copy(buf->data.ta, hdr->addr2);
773 struct vnt_rts_a_fb *buf = pvRTS;
774 /* Get SignalField, ServiceField & Length */
775 vnt_get_phy_field(pDevice, uRTSFrameLen,
776 pDevice->byTopOFDMBasicRate,
780 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
781 cbFrameLength, byPktType,
782 wCurrentRate, bNeedAck,
784 buf->rts_duration_f0 =
785 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
786 cbFrameLength, byPktType,
787 wCurrentRate, bNeedAck,
789 buf->rts_duration_f1 =
790 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
791 cbFrameLength, byPktType,
792 wCurrentRate, bNeedAck,
794 buf->data.duration = buf->duration;
795 /* Get RTS Frame body */
796 buf->data.frame_control =
797 cpu_to_le16(IEEE80211_FTYPE_CTL |
798 IEEE80211_STYPE_RTS);
800 ether_addr_copy(buf->data.ra, hdr->addr1);
801 ether_addr_copy(buf->data.ta, hdr->addr2);
803 } else if (byPktType == PK_TYPE_11B) {
804 struct vnt_rts_ab *buf = pvRTS;
805 /* Get SignalField, ServiceField & Length */
806 vnt_get_phy_field(pDevice, uRTSFrameLen,
807 pDevice->byTopCCKBasicRate,
808 PK_TYPE_11B, &buf->ab);
811 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
812 byPktType, wCurrentRate, bNeedAck,
815 buf->data.duration = buf->duration;
816 /* Get RTS Frame body */
817 buf->data.frame_control =
818 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
820 ether_addr_copy(buf->data.ra, hdr->addr1);
821 ether_addr_copy(buf->data.ta, hdr->addr2);
828 struct vnt_private *pDevice,
829 unsigned int uDMAIdx,
830 unsigned char byPktType,
832 unsigned int cbFrameLength,
835 unsigned short wCurrentRate,
836 unsigned char byFBOption
839 unsigned int uCTSFrameLen = 14;
845 /* When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
846 in this case we need to decrease its length by 4. */
850 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
851 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
853 struct vnt_cts_fb *buf = pvCTS;
854 /* Get SignalField, ServiceField & Length */
855 vnt_get_phy_field(pDevice, uCTSFrameLen,
856 pDevice->byTopCCKBasicRate,
857 PK_TYPE_11B, &buf->b);
860 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
861 cbFrameLength, byPktType,
862 wCurrentRate, bNeedAck,
865 /* Get CTSDuration_ba_f0 */
866 buf->cts_duration_ba_f0 =
867 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
868 cbFrameLength, byPktType,
869 wCurrentRate, bNeedAck,
872 /* Get CTSDuration_ba_f1 */
873 buf->cts_duration_ba_f1 =
874 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
875 cbFrameLength, byPktType,
876 wCurrentRate, bNeedAck,
879 /* Get CTS Frame body */
880 buf->data.duration = buf->duration_ba;
882 buf->data.frame_control =
883 cpu_to_le16(IEEE80211_FTYPE_CTL |
884 IEEE80211_STYPE_CTS);
886 buf->reserved2 = 0x0;
888 ether_addr_copy(buf->data.ra,
889 pDevice->abyCurrentNetAddr);
890 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
891 struct vnt_cts *buf = pvCTS;
892 /* Get SignalField, ServiceField & Length */
893 vnt_get_phy_field(pDevice, uCTSFrameLen,
894 pDevice->byTopCCKBasicRate,
895 PK_TYPE_11B, &buf->b);
897 /* Get CTSDuration_ba */
899 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
900 cbFrameLength, byPktType,
901 wCurrentRate, bNeedAck,
904 /* Get CTS Frame body */
905 buf->data.duration = buf->duration_ba;
907 buf->data.frame_control =
908 cpu_to_le16(IEEE80211_FTYPE_CTL |
909 IEEE80211_STYPE_CTS);
911 buf->reserved2 = 0x0;
912 ether_addr_copy(buf->data.ra,
913 pDevice->abyCurrentNetAddr);
921 * Generate FIFO control for MAC & Baseband controller
925 * pDevice - Pointer to adapter
926 * pTxDataHead - Transmit Data Buffer
927 * pTxBufHead - pTxBufHead
928 * pvRrvTime - pvRrvTime
931 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
932 * bNeedACK - If need ACK
933 * uDescIdx - Desc Index
940 * unsigned int cbFrameSize, Hdr+Payload+FCS */
943 s_vGenerateTxParameter(
944 struct vnt_private *pDevice,
945 unsigned char byPktType,
946 struct vnt_tx_fifo_head *tx_buffer_head,
950 unsigned int cbFrameSize,
952 unsigned int uDMAIdx,
954 unsigned short wCurrentRate
957 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
958 bool bDisCRC = false;
959 unsigned char byFBOption = AUTO_FB_NONE;
961 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
963 if (fifo_ctl & FIFOCTL_CRCDIS)
966 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
967 byFBOption = AUTO_FB_0;
968 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
969 byFBOption = AUTO_FB_1;
974 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
975 if (pvRTS != NULL) { /* RTS_need
977 struct vnt_rrv_time_rts *buf = pvRrvTime;
979 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
980 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
981 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
982 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
983 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
985 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
986 } else {/* RTS_needless, PCF mode */
987 struct vnt_rrv_time_cts *buf = pvRrvTime;
989 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
990 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
991 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
994 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
996 } else if (byPktType == PK_TYPE_11A) {
997 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
998 struct vnt_rrv_time_ab *buf = pvRrvTime;
1000 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1001 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1004 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1005 } else if (pvRTS == NULL) {/* RTS_needless, non PCF mode */
1006 struct vnt_rrv_time_ab *buf = pvRrvTime;
1008 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1010 } else if (byPktType == PK_TYPE_11B) {
1011 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1012 struct vnt_rrv_time_ab *buf = pvRrvTime;
1014 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1015 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1018 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1019 } else { /* RTS_needless, non PCF mode */
1020 struct vnt_rrv_time_ab *buf = pvRrvTime;
1022 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1028 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1029 unsigned char *pbyTxBufferAddr,
1030 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1031 unsigned int is_pspoll)
1033 struct vnt_td_info *td_info = pHeadTD->td_info;
1034 struct sk_buff *skb = td_info->skb;
1035 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1036 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1037 struct vnt_tx_fifo_head *tx_buffer_head =
1038 (struct vnt_tx_fifo_head *)td_info->buf;
1039 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1040 unsigned int cbFrameSize;
1042 unsigned char *pbyBuffer;
1043 unsigned int uLength = 0;
1044 unsigned int cbMICHDR = 0;
1045 unsigned int uMACfragNum = 1;
1046 unsigned int uPadding = 0;
1047 unsigned int cbReqCount = 0;
1048 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1049 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1050 struct vnt_tx_desc *ptdCurr;
1051 unsigned int cbHeaderLength = 0;
1053 struct vnt_mic_hdr *pMICHDR;
1057 unsigned short wTxBufSize; /* FFinfo size */
1058 unsigned char byFBOption = AUTO_FB_NONE;
1060 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1062 cbFrameSize = skb->len + 4;
1064 if (info->control.hw_key) {
1065 switch (info->control.hw_key->cipher) {
1066 case WLAN_CIPHER_SUITE_CCMP:
1067 cbMICHDR = sizeof(struct vnt_mic_hdr);
1072 cbFrameSize += info->control.hw_key->icv_len;
1074 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1075 /* MAC Header should be padding 0 to DW alignment. */
1076 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1082 * Use for AUTO FALL BACK
1084 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1085 byFBOption = AUTO_FB_0;
1086 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1087 byFBOption = AUTO_FB_1;
1090 /* Set RrvTime/RTS/CTS Buffer */
1091 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1092 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1094 if (byFBOption == AUTO_FB_NONE) {
1095 if (bRTS) {/* RTS_need */
1096 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1097 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1098 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1100 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1101 cbMICHDR + sizeof(struct vnt_rts_g));
1102 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1103 cbMICHDR + sizeof(struct vnt_rts_g) +
1104 sizeof(struct vnt_tx_datahead_g);
1105 } else { /* RTS_needless */
1106 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1107 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1109 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1110 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1111 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1112 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1113 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1116 /* Auto Fall Back */
1117 if (bRTS) {/* RTS_need */
1118 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1119 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1120 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1122 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1123 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1124 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1125 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1126 } else { /* RTS_needless */
1127 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1128 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1130 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1131 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1132 cbMICHDR + sizeof(struct vnt_cts_fb));
1133 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1134 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1136 } /* Auto Fall Back */
1137 } else {/* 802.11a/b packet */
1139 if (byFBOption == AUTO_FB_NONE) {
1141 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1142 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1143 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1145 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1146 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1147 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1148 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1149 } else { /* RTS_needless, need MICHDR */
1150 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1151 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1154 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1155 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1156 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1159 /* Auto Fall Back */
1160 if (bRTS) { /* RTS_need */
1161 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1162 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1163 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1165 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1166 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1167 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1168 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1169 } else { /* RTS_needless */
1170 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1171 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1174 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1175 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1176 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1178 } /* Auto Fall Back */
1181 td_info->mic_hdr = pMICHDR;
1183 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1185 /* Fill FIFO,RrvTime,RTS,and CTS */
1186 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1187 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1189 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1190 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1192 hdr->duration_id = uDuration;
1194 cbReqCount = cbHeaderLength + uPadding + skb->len;
1195 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1196 uLength = cbHeaderLength + uPadding;
1198 /* Copy the Packet into a tx Buffer */
1199 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1203 ptdCurr->td_info->req_count = (u16)cbReqCount;
1205 return cbHeaderLength;
1208 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1209 struct ieee80211_key_conf *tx_key,
1210 struct sk_buff *skb, u16 payload_len,
1211 struct vnt_mic_hdr *mic_hdr)
1214 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1216 /* strip header and icv len from payload */
1217 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1218 payload_len -= tx_key->icv_len;
1220 switch (tx_key->cipher) {
1221 case WLAN_CIPHER_SUITE_WEP40:
1222 case WLAN_CIPHER_SUITE_WEP104:
1223 memcpy(key_buffer, iv, 3);
1224 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1226 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1227 memcpy(key_buffer + 8, iv, 3);
1228 memcpy(key_buffer + 11,
1229 tx_key->key, WLAN_KEY_LEN_WEP40);
1233 case WLAN_CIPHER_SUITE_TKIP:
1234 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1237 case WLAN_CIPHER_SUITE_CCMP:
1243 mic_hdr->payload_len = cpu_to_be16(payload_len);
1244 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1246 pn64 = atomic64_read(&tx_key->tx_pn);
1247 mic_hdr->ccmp_pn[5] = pn64;
1248 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1249 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1250 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1251 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1252 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1254 if (ieee80211_has_a4(hdr->frame_control))
1255 mic_hdr->hlen = cpu_to_be16(28);
1257 mic_hdr->hlen = cpu_to_be16(22);
1259 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1260 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1261 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1263 mic_hdr->frame_control = cpu_to_le16(
1264 le16_to_cpu(hdr->frame_control) & 0xc78f);
1265 mic_hdr->seq_ctrl = cpu_to_le16(
1266 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1268 if (ieee80211_has_a4(hdr->frame_control))
1269 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1271 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1279 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1280 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1282 struct vnt_td_info *td_info = head_td->td_info;
1283 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1284 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1285 struct ieee80211_rate *rate;
1286 struct ieee80211_key_conf *tx_key;
1287 struct ieee80211_hdr *hdr;
1288 struct vnt_tx_fifo_head *tx_buffer_head =
1289 (struct vnt_tx_fifo_head *)td_info->buf;
1290 u16 tx_body_size = skb->len, current_rate;
1292 bool is_pspoll = false;
1294 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1296 hdr = (struct ieee80211_hdr *)(skb->data);
1298 rate = ieee80211_get_tx_rate(priv->hw, info);
1300 current_rate = rate->hw_value;
1301 if (priv->wCurrentRate != current_rate &&
1302 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1303 priv->wCurrentRate = current_rate;
1305 RFbSetPower(priv, priv->wCurrentRate,
1306 priv->hw->conf.chandef.chan->hw_value);
1309 if (current_rate > RATE_11M) {
1310 if (info->band == IEEE80211_BAND_5GHZ) {
1311 pkt_type = PK_TYPE_11A;
1313 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1314 pkt_type = PK_TYPE_11GB;
1316 pkt_type = PK_TYPE_11GA;
1319 pkt_type = PK_TYPE_11B;
1322 /*Set fifo controls */
1323 if (pkt_type == PK_TYPE_11A)
1324 tx_buffer_head->fifo_ctl = 0;
1325 else if (pkt_type == PK_TYPE_11B)
1326 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1327 else if (pkt_type == PK_TYPE_11GB)
1328 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1329 else if (pkt_type == PK_TYPE_11GA)
1330 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1332 /* generate interrupt */
1333 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1335 if (!ieee80211_is_data(hdr->frame_control)) {
1336 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1337 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1338 tx_buffer_head->time_stamp =
1339 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1341 tx_buffer_head->time_stamp =
1342 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1345 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1346 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1348 if (ieee80211_has_retry(hdr->frame_control))
1349 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1351 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1352 priv->byPreambleType = PREAMBLE_SHORT;
1354 priv->byPreambleType = PREAMBLE_LONG;
1356 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1357 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1359 if (ieee80211_has_a4(hdr->frame_control)) {
1360 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1361 priv->bLongHeader = true;
1364 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1367 tx_buffer_head->frag_ctl =
1368 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1370 if (info->control.hw_key) {
1371 tx_key = info->control.hw_key;
1373 switch (info->control.hw_key->cipher) {
1374 case WLAN_CIPHER_SUITE_WEP40:
1375 case WLAN_CIPHER_SUITE_WEP104:
1376 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1378 case WLAN_CIPHER_SUITE_TKIP:
1379 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1381 case WLAN_CIPHER_SUITE_CCMP:
1382 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1388 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1390 /* legacy rates TODO use ieee80211_tx_rate */
1391 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1392 if (priv->byAutoFBCtrl == AUTO_FB_0)
1393 tx_buffer_head->fifo_ctl |=
1394 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1395 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1396 tx_buffer_head->fifo_ctl |=
1397 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1401 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1403 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1404 dma_idx, head_td, is_pspoll);
1406 if (info->control.hw_key) {
1407 tx_key = info->control.hw_key;
1408 if (tx_key->keylen > 0)
1409 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1410 tx_key, skb, tx_body_size, td_info->mic_hdr);
1416 static int vnt_beacon_xmit(struct vnt_private *priv,
1417 struct sk_buff *skb)
1419 struct vnt_tx_short_buf_head *short_head =
1420 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1421 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1422 (priv->tx_beacon_bufs + sizeof(*short_head));
1423 struct ieee80211_tx_info *info;
1424 u32 frame_size = skb->len + 4;
1427 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1429 if (priv->byBBType == BB_TYPE_11A) {
1430 current_rate = RATE_6M;
1432 /* Get SignalField,ServiceField,Length */
1433 vnt_get_phy_field(priv, frame_size, current_rate,
1434 PK_TYPE_11A, &short_head->ab);
1436 /* Get Duration and TimeStampOff */
1437 short_head->duration =
1438 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1439 frame_size, PK_TYPE_11A, current_rate,
1440 false, 0, 0, 1, AUTO_FB_NONE));
1442 short_head->time_stamp_off =
1443 vnt_time_stamp_off(priv, current_rate);
1445 current_rate = RATE_1M;
1446 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1448 /* Get SignalField,ServiceField,Length */
1449 vnt_get_phy_field(priv, frame_size, current_rate,
1450 PK_TYPE_11B, &short_head->ab);
1452 /* Get Duration and TimeStampOff */
1453 short_head->duration =
1454 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1455 frame_size, PK_TYPE_11B, current_rate,
1456 false, 0, 0, 1, AUTO_FB_NONE));
1458 short_head->time_stamp_off =
1459 vnt_time_stamp_off(priv, current_rate);
1462 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1465 memcpy(mgmt_hdr, skb->data, skb->len);
1467 /* time stamp always 0 */
1468 mgmt_hdr->u.beacon.timestamp = 0;
1470 info = IEEE80211_SKB_CB(skb);
1471 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1472 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1474 hdr->duration_id = 0;
1475 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1478 priv->wSeqCounter++;
1479 if (priv->wSeqCounter > 0x0fff)
1480 priv->wSeqCounter = 0;
1482 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1484 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1486 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1487 /* Set auto Transmit on */
1488 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1489 /* Poll Transmit the adapter */
1490 MACvTransmitBCN(priv->PortOffset);
1495 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1497 struct sk_buff *beacon;
1499 beacon = ieee80211_beacon_get(priv->hw, vif);
1503 if (vnt_beacon_xmit(priv, beacon)) {
1504 ieee80211_free_txskb(priv->hw, beacon);
1511 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1512 struct ieee80211_bss_conf *conf)
1514 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1516 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1518 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1520 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1522 return vnt_beacon_make(priv, vif);