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.
17 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
24 * s_vGenerateTxParameter - Generate tx dma required parameter.
25 * vGenerateMACHeader - Translate 802.3 to 802.11 header
26 * cbGetFragCount - Calculate fragment number count
27 * csBeacon_xmit - beacon tx function
28 * csMgmt_xmit - management tx function
29 * s_cbFillTxBufHead - fulfill tx dma buffer header
30 * s_uGetDataDuration - get tx data required duration
31 * s_uFillDataHead- fulfill tx data duration header
32 * s_uGetRTSCTSDuration- get rtx/cts required duration
33 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
34 * s_uGetTxRsvTime- get frame reserved time
35 * s_vFillCTSHead- fulfill CTS ctl header
36 * s_vFillFragParameter- Set fragment ctl parameter.
37 * s_vFillRTSHead- fulfill RTS ctl header
38 * s_vFillTxKey- fulfill tx encrypt key
39 * s_vSWencryption- Software encrypt header
40 * vDMA0_tx_80211- tx 802.11 frame via dma0
41 * vGenerateFIFOHeader- Generate tx FIFO ctl header
54 /*--------------------- Static Definitions -------------------------*/
56 /*--------------------- Static Classes ----------------------------*/
58 /*--------------------- Static Variables --------------------------*/
60 /*--------------------- Static Functions --------------------------*/
62 /*--------------------- Static Definitions -------------------------*/
63 /* if packet size < 256 -> in-direct send
64 * vpacket size >= 256 -> direct send
66 #define CRITICAL_PACKET_LEN 256
68 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
69 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
70 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
73 static const unsigned short wFB_Opt0[2][5] = {
74 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
75 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
77 static const unsigned short wFB_Opt1[2][5] = {
78 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
79 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
86 #define RTSDUR_BA_F0 4
87 #define RTSDUR_AA_F0 5
88 #define RTSDUR_BA_F1 6
89 #define RTSDUR_AA_F1 7
90 #define CTSDUR_BA_F0 8
91 #define CTSDUR_BA_F1 9
94 #define DATADUR_A_F0 12
95 #define DATADUR_A_F1 13
97 /*--------------------- Static Functions --------------------------*/
101 struct vnt_private *pDevice,
102 unsigned char byPktType,
104 unsigned int cbFrameLength,
107 struct ieee80211_hdr *hdr,
108 unsigned short wCurrentRate,
109 unsigned char byFBOption
114 s_vGenerateTxParameter(
115 struct vnt_private *pDevice,
116 unsigned char byPktType,
117 struct vnt_tx_fifo_head *,
121 unsigned int cbFrameSize,
123 unsigned int uDMAIdx,
125 unsigned short wCurrentRate
129 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
130 unsigned char *pbyTxBufferAddr,
131 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
132 unsigned int uNodeIndex);
137 struct vnt_private *pDevice,
138 unsigned char byPktType,
140 unsigned int cbFrameLength,
141 unsigned int uDMAIdx,
143 unsigned int uFragIdx,
144 unsigned int cbLastFragmentSize,
145 unsigned int uMACfragNum,
146 unsigned char byFBOption,
147 unsigned short wCurrentRate,
151 /*--------------------- Export Variables --------------------------*/
153 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
155 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
159 /* byPktType : PK_TYPE_11A 0
167 struct vnt_private *pDevice,
168 unsigned char byPktType,
169 unsigned int cbFrameLength,
170 unsigned short wRate,
174 unsigned int uDataTime, uAckTime;
176 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
177 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
178 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
179 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
180 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
183 return uDataTime + pDevice->uSIFS + uAckTime;
188 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
189 u32 frame_length, u16 rate, bool need_ack)
191 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
192 frame_length, rate, need_ack));
195 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
199 struct vnt_private *pDevice,
200 unsigned char byRTSRsvType,
201 unsigned char byPktType,
202 unsigned int cbFrameLength,
203 unsigned short wCurrentRate
206 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
208 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
210 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
211 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
212 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
213 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
214 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
215 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
216 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
217 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
218 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
219 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
220 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
221 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
222 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
223 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
224 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
225 return cpu_to_le16((u16)uRrvTime);
229 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
230 return cpu_to_le16((u16)uRrvTime);
233 /* byFreqType 0: 5GHz, 1:2.4Ghz */
237 struct vnt_private *pDevice,
238 unsigned char byDurType,
239 unsigned int cbFrameLength,
240 unsigned char byPktType,
241 unsigned short wRate,
243 unsigned int uFragIdx,
244 unsigned int cbLastFragmentSize,
245 unsigned int uMACfragNum,
246 unsigned char byFBOption
249 bool bLastFrag = false;
250 unsigned int uAckTime = 0, uNextPktTime = 0;
252 if (uFragIdx == (uMACfragNum-1))
256 case DATADUR_B: /* DATADUR_B */
257 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
259 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
260 return pDevice->uSIFS + uAckTime;
264 } else {/* First Frag or Mid Frag */
265 if (uFragIdx == (uMACfragNum-2))
266 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
271 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
272 return pDevice->uSIFS + uAckTime + uNextPktTime;
274 return pDevice->uSIFS + uNextPktTime;
279 case DATADUR_A: /* DATADUR_A */
280 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
282 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
283 return pDevice->uSIFS + uAckTime;
287 } else {/* First Frag or Mid Frag */
288 if (uFragIdx == (uMACfragNum-2))
289 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
291 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
294 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
295 return pDevice->uSIFS + uAckTime + uNextPktTime;
297 return pDevice->uSIFS + uNextPktTime;
302 case DATADUR_A_F0: /* DATADUR_A_F0 */
303 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
305 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
306 return pDevice->uSIFS + uAckTime;
310 } else { /* First Frag or Mid Frag */
311 if (byFBOption == AUTO_FB_0) {
312 if (wRate < RATE_18M)
314 else if (wRate > RATE_54M)
317 if (uFragIdx == (uMACfragNum-2))
318 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
320 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
322 } else { /* (byFBOption == AUTO_FB_1) */
323 if (wRate < RATE_18M)
325 else if (wRate > RATE_54M)
328 if (uFragIdx == (uMACfragNum-2))
329 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
331 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
336 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
337 return pDevice->uSIFS + uAckTime + uNextPktTime;
339 return pDevice->uSIFS + uNextPktTime;
344 case DATADUR_A_F1: /* DATADUR_A_F1 */
345 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
347 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
348 return pDevice->uSIFS + uAckTime;
352 } else { /* First Frag or Mid Frag */
353 if (byFBOption == AUTO_FB_0) {
354 if (wRate < RATE_18M)
356 else if (wRate > RATE_54M)
359 if (uFragIdx == (uMACfragNum-2))
360 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
362 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
364 } else { /* (byFBOption == AUTO_FB_1) */
365 if (wRate < RATE_18M)
367 else if (wRate > RATE_54M)
370 if (uFragIdx == (uMACfragNum-2))
371 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
373 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
376 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
377 return pDevice->uSIFS + uAckTime + uNextPktTime;
379 return pDevice->uSIFS + uNextPktTime;
391 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
394 s_uGetRTSCTSDuration(
395 struct vnt_private *pDevice,
396 unsigned char byDurType,
397 unsigned int cbFrameLength,
398 unsigned char byPktType,
399 unsigned short wRate,
401 unsigned char byFBOption
404 unsigned int uCTSTime = 0, uDurTime = 0;
407 case RTSDUR_BB: /* RTSDuration_bb */
408 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
409 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
412 case RTSDUR_BA: /* RTSDuration_ba */
413 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
414 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
417 case RTSDUR_AA: /* RTSDuration_aa */
418 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
419 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
422 case CTSDUR_BA: /* CTSDuration_ba */
423 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
426 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
427 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
428 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
429 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
430 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
431 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
435 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
436 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
437 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
438 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
439 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
440 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
444 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
445 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
446 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
447 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
448 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
449 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
453 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
454 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
455 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
456 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
457 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
458 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
462 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
463 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
464 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
465 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
466 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
470 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
471 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
472 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
473 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
474 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
482 return cpu_to_le16((u16)uDurTime);
488 struct vnt_private *pDevice,
489 unsigned char byPktType,
491 unsigned int cbFrameLength,
492 unsigned int uDMAIdx,
494 unsigned int uFragIdx,
495 unsigned int cbLastFragmentSize,
496 unsigned int uMACfragNum,
497 unsigned char byFBOption,
498 unsigned short wCurrentRate,
507 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
508 if (byFBOption == AUTO_FB_NONE) {
509 struct vnt_tx_datahead_g *buf = pTxDataHead;
510 /* Get SignalField, ServiceField & Length */
511 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
514 vnt_get_phy_field(pDevice, cbFrameLength,
515 pDevice->byTopCCKBasicRate,
516 PK_TYPE_11B, &buf->b);
519 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
521 buf->duration_a = dur;
522 buf->duration_b = dur;
524 /* Get Duration and TimeStamp */
526 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
527 byPktType, wCurrentRate, bNeedAck, uFragIdx,
528 cbLastFragmentSize, uMACfragNum,
531 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
532 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
533 bNeedAck, uFragIdx, cbLastFragmentSize,
534 uMACfragNum, byFBOption));
537 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
538 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
540 return buf->duration_a;
543 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
544 /* Get SignalField, ServiceField & Length */
545 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
548 vnt_get_phy_field(pDevice, cbFrameLength,
549 pDevice->byTopCCKBasicRate,
550 PK_TYPE_11B, &buf->b);
551 /* Get Duration and TimeStamp */
552 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
553 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
554 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
555 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
556 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
557 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
559 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
561 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
562 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
564 return buf->duration_a;
565 } /* if (byFBOption == AUTO_FB_NONE) */
566 } else if (byPktType == PK_TYPE_11A) {
567 if (byFBOption != AUTO_FB_NONE) {
569 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
570 /* Get SignalField, ServiceField & Length */
571 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
574 /* Get Duration and TimeStampOff */
575 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
576 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
577 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
578 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
579 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
582 return buf->duration;
584 struct vnt_tx_datahead_ab *buf = pTxDataHead;
585 /* Get SignalField, ServiceField & Length */
586 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
587 byPktType, &buf->ab);
590 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
594 /* Get Duration and TimeStampOff */
596 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
597 wCurrentRate, bNeedAck, uFragIdx,
598 cbLastFragmentSize, uMACfragNum,
602 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
603 return buf->duration;
606 struct vnt_tx_datahead_ab *buf = pTxDataHead;
607 /* Get SignalField, ServiceField & Length */
608 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
609 byPktType, &buf->ab);
612 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
616 /* Get Duration and TimeStampOff */
618 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
619 wCurrentRate, bNeedAck, uFragIdx,
620 cbLastFragmentSize, uMACfragNum,
624 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
625 return buf->duration;
634 struct vnt_private *pDevice,
635 unsigned char byPktType,
637 unsigned int cbFrameLength,
640 struct ieee80211_hdr *hdr,
641 unsigned short wCurrentRate,
642 unsigned char byFBOption
645 unsigned int uRTSFrameLen = 20;
651 /* When CRCDIS bit is on, H/W forgot to generate FCS for
652 * RTS frame, in this case we need to decrease its length by 4.
657 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
658 * so we don't need to take them into account.
659 * Otherwise, we need to modify codes for them.
661 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
662 if (byFBOption == AUTO_FB_NONE) {
663 struct vnt_rts_g *buf = pvRTS;
664 /* Get SignalField, ServiceField & Length */
665 vnt_get_phy_field(pDevice, uRTSFrameLen,
666 pDevice->byTopCCKBasicRate,
667 PK_TYPE_11B, &buf->b);
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopOFDMBasicRate,
674 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
675 cbFrameLength, PK_TYPE_11B,
676 pDevice->byTopCCKBasicRate,
677 bNeedAck, byFBOption);
679 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
680 cbFrameLength, byPktType,
681 wCurrentRate, bNeedAck,
684 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
685 cbFrameLength, byPktType,
686 wCurrentRate, bNeedAck,
689 buf->data.duration = buf->duration_aa;
690 /* Get RTS Frame body */
691 buf->data.frame_control =
692 cpu_to_le16(IEEE80211_FTYPE_CTL |
693 IEEE80211_STYPE_RTS);
695 ether_addr_copy(buf->data.ra, hdr->addr1);
696 ether_addr_copy(buf->data.ta, hdr->addr2);
698 struct vnt_rts_g_fb *buf = pvRTS;
699 /* Get SignalField, ServiceField & Length */
700 vnt_get_phy_field(pDevice, uRTSFrameLen,
701 pDevice->byTopCCKBasicRate,
702 PK_TYPE_11B, &buf->b);
704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopOFDMBasicRate,
709 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
710 cbFrameLength, PK_TYPE_11B,
711 pDevice->byTopCCKBasicRate,
712 bNeedAck, byFBOption);
714 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
715 cbFrameLength, byPktType,
716 wCurrentRate, bNeedAck,
719 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
720 cbFrameLength, byPktType,
721 wCurrentRate, bNeedAck,
723 buf->rts_duration_ba_f0 =
724 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
725 cbFrameLength, byPktType,
726 wCurrentRate, bNeedAck,
728 buf->rts_duration_aa_f0 =
729 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
730 cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck,
733 buf->rts_duration_ba_f1 =
734 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
735 cbFrameLength, byPktType,
736 wCurrentRate, bNeedAck,
738 buf->rts_duration_aa_f1 =
739 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
740 cbFrameLength, byPktType,
741 wCurrentRate, bNeedAck,
743 buf->data.duration = buf->duration_aa;
744 /* Get RTS Frame body */
745 buf->data.frame_control =
746 cpu_to_le16(IEEE80211_FTYPE_CTL |
747 IEEE80211_STYPE_RTS);
749 ether_addr_copy(buf->data.ra, hdr->addr1);
750 ether_addr_copy(buf->data.ta, hdr->addr2);
751 } /* if (byFBOption == AUTO_FB_NONE) */
752 } else if (byPktType == PK_TYPE_11A) {
753 if (byFBOption == AUTO_FB_NONE) {
754 struct vnt_rts_ab *buf = pvRTS;
755 /* Get SignalField, ServiceField & Length */
756 vnt_get_phy_field(pDevice, uRTSFrameLen,
757 pDevice->byTopOFDMBasicRate,
758 byPktType, &buf->ab);
761 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
762 cbFrameLength, byPktType,
763 wCurrentRate, bNeedAck,
765 buf->data.duration = buf->duration;
766 /* Get RTS Frame body */
767 buf->data.frame_control =
768 cpu_to_le16(IEEE80211_FTYPE_CTL |
769 IEEE80211_STYPE_RTS);
771 ether_addr_copy(buf->data.ra, hdr->addr1);
772 ether_addr_copy(buf->data.ta, hdr->addr2);
774 struct vnt_rts_a_fb *buf = pvRTS;
775 /* Get SignalField, ServiceField & Length */
776 vnt_get_phy_field(pDevice, uRTSFrameLen,
777 pDevice->byTopOFDMBasicRate,
781 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
782 cbFrameLength, byPktType,
783 wCurrentRate, bNeedAck,
785 buf->rts_duration_f0 =
786 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
787 cbFrameLength, byPktType,
788 wCurrentRate, bNeedAck,
790 buf->rts_duration_f1 =
791 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
792 cbFrameLength, byPktType,
793 wCurrentRate, bNeedAck,
795 buf->data.duration = buf->duration;
796 /* Get RTS Frame body */
797 buf->data.frame_control =
798 cpu_to_le16(IEEE80211_FTYPE_CTL |
799 IEEE80211_STYPE_RTS);
801 ether_addr_copy(buf->data.ra, hdr->addr1);
802 ether_addr_copy(buf->data.ta, hdr->addr2);
804 } else if (byPktType == PK_TYPE_11B) {
805 struct vnt_rts_ab *buf = pvRTS;
806 /* Get SignalField, ServiceField & Length */
807 vnt_get_phy_field(pDevice, uRTSFrameLen,
808 pDevice->byTopCCKBasicRate,
809 PK_TYPE_11B, &buf->ab);
812 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
813 byPktType, wCurrentRate, bNeedAck,
816 buf->data.duration = buf->duration;
817 /* Get RTS Frame body */
818 buf->data.frame_control =
819 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
821 ether_addr_copy(buf->data.ra, hdr->addr1);
822 ether_addr_copy(buf->data.ta, hdr->addr2);
829 struct vnt_private *pDevice,
830 unsigned int uDMAIdx,
831 unsigned char byPktType,
833 unsigned int cbFrameLength,
836 unsigned short wCurrentRate,
837 unsigned char byFBOption
840 unsigned int uCTSFrameLen = 14;
846 /* When CRCDIS bit is on, H/W forgot to generate FCS for
847 * CTS frame, in this case we need to decrease its length by 4.
852 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
853 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
855 struct vnt_cts_fb *buf = pvCTS;
856 /* Get SignalField, ServiceField & Length */
857 vnt_get_phy_field(pDevice, uCTSFrameLen,
858 pDevice->byTopCCKBasicRate,
859 PK_TYPE_11B, &buf->b);
862 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
863 cbFrameLength, byPktType,
864 wCurrentRate, bNeedAck,
867 /* Get CTSDuration_ba_f0 */
868 buf->cts_duration_ba_f0 =
869 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
870 cbFrameLength, byPktType,
871 wCurrentRate, bNeedAck,
874 /* Get CTSDuration_ba_f1 */
875 buf->cts_duration_ba_f1 =
876 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
877 cbFrameLength, byPktType,
878 wCurrentRate, bNeedAck,
881 /* Get CTS Frame body */
882 buf->data.duration = buf->duration_ba;
884 buf->data.frame_control =
885 cpu_to_le16(IEEE80211_FTYPE_CTL |
886 IEEE80211_STYPE_CTS);
888 buf->reserved2 = 0x0;
890 ether_addr_copy(buf->data.ra,
891 pDevice->abyCurrentNetAddr);
892 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
893 struct vnt_cts *buf = pvCTS;
894 /* Get SignalField, ServiceField & Length */
895 vnt_get_phy_field(pDevice, uCTSFrameLen,
896 pDevice->byTopCCKBasicRate,
897 PK_TYPE_11B, &buf->b);
899 /* Get CTSDuration_ba */
901 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
902 cbFrameLength, byPktType,
903 wCurrentRate, bNeedAck,
906 /* Get CTS Frame body */
907 buf->data.duration = buf->duration_ba;
909 buf->data.frame_control =
910 cpu_to_le16(IEEE80211_FTYPE_CTL |
911 IEEE80211_STYPE_CTS);
913 buf->reserved2 = 0x0;
914 ether_addr_copy(buf->data.ra,
915 pDevice->abyCurrentNetAddr);
923 * Generate FIFO control for MAC & Baseband controller
927 * pDevice - Pointer to adapter
928 * pTxDataHead - Transmit Data Buffer
929 * pTxBufHead - pTxBufHead
930 * pvRrvTime - pvRrvTime
933 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
934 * bNeedACK - If need ACK
935 * uDescIdx - Desc Index
942 * unsigned int cbFrameSize, Hdr+Payload+FCS
946 s_vGenerateTxParameter(
947 struct vnt_private *pDevice,
948 unsigned char byPktType,
949 struct vnt_tx_fifo_head *tx_buffer_head,
953 unsigned int cbFrameSize,
955 unsigned int uDMAIdx,
957 unsigned short wCurrentRate
960 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
961 bool bDisCRC = false;
962 unsigned char byFBOption = AUTO_FB_NONE;
964 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
966 if (fifo_ctl & FIFOCTL_CRCDIS)
969 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
970 byFBOption = AUTO_FB_0;
971 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
972 byFBOption = AUTO_FB_1;
977 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
978 if (pvRTS != NULL) { /* RTS_need */
980 struct vnt_rrv_time_rts *buf = pvRrvTime;
982 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
983 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
984 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
985 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
986 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
988 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
989 } else {/* RTS_needless, PCF mode */
990 struct vnt_rrv_time_cts *buf = pvRrvTime;
992 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
993 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
994 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
997 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
999 } else if (byPktType == PK_TYPE_11A) {
1000 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1001 struct vnt_rrv_time_ab *buf = pvRrvTime;
1003 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1004 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1007 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1008 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
1009 struct vnt_rrv_time_ab *buf = pvRrvTime;
1011 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1013 } else if (byPktType == PK_TYPE_11B) {
1014 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1015 struct vnt_rrv_time_ab *buf = pvRrvTime;
1017 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1018 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1021 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1022 } else { /* RTS_needless, non PCF mode */
1023 struct vnt_rrv_time_ab *buf = pvRrvTime;
1025 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1031 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1032 unsigned char *pbyTxBufferAddr,
1033 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1034 unsigned int is_pspoll)
1036 struct vnt_td_info *td_info = pHeadTD->td_info;
1037 struct sk_buff *skb = td_info->skb;
1038 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1039 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1040 struct vnt_tx_fifo_head *tx_buffer_head =
1041 (struct vnt_tx_fifo_head *)td_info->buf;
1042 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1043 unsigned int cbFrameSize;
1045 unsigned char *pbyBuffer;
1046 unsigned int uLength = 0;
1047 unsigned int cbMICHDR = 0;
1048 unsigned int uMACfragNum = 1;
1049 unsigned int uPadding = 0;
1050 unsigned int cbReqCount = 0;
1051 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1052 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1053 struct vnt_tx_desc *ptdCurr;
1054 unsigned int cbHeaderLength = 0;
1056 struct vnt_mic_hdr *pMICHDR;
1060 unsigned short wTxBufSize; /* FFinfo size */
1061 unsigned char byFBOption = AUTO_FB_NONE;
1063 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1065 cbFrameSize = skb->len + 4;
1067 if (info->control.hw_key) {
1068 switch (info->control.hw_key->cipher) {
1069 case WLAN_CIPHER_SUITE_CCMP:
1070 cbMICHDR = sizeof(struct vnt_mic_hdr);
1075 cbFrameSize += info->control.hw_key->icv_len;
1077 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1078 /* MAC Header should be padding 0 to DW alignment. */
1079 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1085 * Use for AUTO FALL BACK
1087 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1088 byFBOption = AUTO_FB_0;
1089 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1090 byFBOption = AUTO_FB_1;
1093 /* Set RrvTime/RTS/CTS Buffer */
1094 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1095 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1097 if (byFBOption == AUTO_FB_NONE) {
1098 if (bRTS) {/* RTS_need */
1099 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1100 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1101 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1103 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1104 cbMICHDR + sizeof(struct vnt_rts_g));
1105 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1106 cbMICHDR + sizeof(struct vnt_rts_g) +
1107 sizeof(struct vnt_tx_datahead_g);
1108 } else { /* RTS_needless */
1109 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1110 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1112 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1113 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1114 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1115 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1116 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1119 /* Auto Fall Back */
1120 if (bRTS) {/* RTS_need */
1121 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1122 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1123 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1125 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1126 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1127 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1128 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1129 } else { /* RTS_needless */
1130 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1131 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1133 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1134 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1135 cbMICHDR + sizeof(struct vnt_cts_fb));
1136 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1137 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1139 } /* Auto Fall Back */
1140 } else {/* 802.11a/b packet */
1142 if (byFBOption == AUTO_FB_NONE) {
1144 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1145 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1146 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1148 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1149 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1150 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1151 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1152 } else { /* RTS_needless, need MICHDR */
1153 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1154 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1157 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1158 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1159 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1162 /* Auto Fall Back */
1163 if (bRTS) { /* RTS_need */
1164 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1165 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1166 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1168 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1169 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1170 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1171 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1172 } else { /* RTS_needless */
1173 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1174 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1177 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1178 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1179 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1181 } /* Auto Fall Back */
1184 td_info->mic_hdr = pMICHDR;
1186 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1188 /* Fill FIFO,RrvTime,RTS,and CTS */
1189 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1190 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1192 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1193 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1195 hdr->duration_id = uDuration;
1197 cbReqCount = cbHeaderLength + uPadding + skb->len;
1198 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1199 uLength = cbHeaderLength + uPadding;
1201 /* Copy the Packet into a tx Buffer */
1202 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1206 ptdCurr->td_info->req_count = (u16)cbReqCount;
1208 return cbHeaderLength;
1211 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1212 struct ieee80211_key_conf *tx_key,
1213 struct sk_buff *skb, u16 payload_len,
1214 struct vnt_mic_hdr *mic_hdr)
1217 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1219 /* strip header and icv len from payload */
1220 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1221 payload_len -= tx_key->icv_len;
1223 switch (tx_key->cipher) {
1224 case WLAN_CIPHER_SUITE_WEP40:
1225 case WLAN_CIPHER_SUITE_WEP104:
1226 memcpy(key_buffer, iv, 3);
1227 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1229 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1230 memcpy(key_buffer + 8, iv, 3);
1231 memcpy(key_buffer + 11,
1232 tx_key->key, WLAN_KEY_LEN_WEP40);
1236 case WLAN_CIPHER_SUITE_TKIP:
1237 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1240 case WLAN_CIPHER_SUITE_CCMP:
1246 mic_hdr->payload_len = cpu_to_be16(payload_len);
1247 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1249 pn64 = atomic64_read(&tx_key->tx_pn);
1250 mic_hdr->ccmp_pn[5] = pn64;
1251 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1252 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1253 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1254 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1255 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1257 if (ieee80211_has_a4(hdr->frame_control))
1258 mic_hdr->hlen = cpu_to_be16(28);
1260 mic_hdr->hlen = cpu_to_be16(22);
1262 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1263 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1264 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1266 mic_hdr->frame_control = cpu_to_le16(
1267 le16_to_cpu(hdr->frame_control) & 0xc78f);
1268 mic_hdr->seq_ctrl = cpu_to_le16(
1269 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1271 if (ieee80211_has_a4(hdr->frame_control))
1272 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1274 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1282 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1283 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1285 struct vnt_td_info *td_info = head_td->td_info;
1286 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1287 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1288 struct ieee80211_rate *rate;
1289 struct ieee80211_key_conf *tx_key;
1290 struct ieee80211_hdr *hdr;
1291 struct vnt_tx_fifo_head *tx_buffer_head =
1292 (struct vnt_tx_fifo_head *)td_info->buf;
1293 u16 tx_body_size = skb->len, current_rate;
1295 bool is_pspoll = false;
1297 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1299 hdr = (struct ieee80211_hdr *)(skb->data);
1301 rate = ieee80211_get_tx_rate(priv->hw, info);
1303 current_rate = rate->hw_value;
1304 if (priv->wCurrentRate != current_rate &&
1305 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1306 priv->wCurrentRate = current_rate;
1308 RFbSetPower(priv, priv->wCurrentRate,
1309 priv->hw->conf.chandef.chan->hw_value);
1312 if (current_rate > RATE_11M) {
1313 if (info->band == NL80211_BAND_5GHZ) {
1314 pkt_type = PK_TYPE_11A;
1316 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1317 pkt_type = PK_TYPE_11GB;
1319 pkt_type = PK_TYPE_11GA;
1322 pkt_type = PK_TYPE_11B;
1325 /*Set fifo controls */
1326 if (pkt_type == PK_TYPE_11A)
1327 tx_buffer_head->fifo_ctl = 0;
1328 else if (pkt_type == PK_TYPE_11B)
1329 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1330 else if (pkt_type == PK_TYPE_11GB)
1331 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1332 else if (pkt_type == PK_TYPE_11GA)
1333 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1335 /* generate interrupt */
1336 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1338 if (!ieee80211_is_data(hdr->frame_control)) {
1339 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1341 tx_buffer_head->time_stamp =
1342 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1344 tx_buffer_head->time_stamp =
1345 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1348 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1349 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1351 if (ieee80211_has_retry(hdr->frame_control))
1352 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1354 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1355 priv->byPreambleType = PREAMBLE_SHORT;
1357 priv->byPreambleType = PREAMBLE_LONG;
1359 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1360 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1362 if (ieee80211_has_a4(hdr->frame_control)) {
1363 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1364 priv->bLongHeader = true;
1367 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1370 tx_buffer_head->frag_ctl =
1371 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1373 if (info->control.hw_key) {
1374 tx_key = info->control.hw_key;
1376 switch (info->control.hw_key->cipher) {
1377 case WLAN_CIPHER_SUITE_WEP40:
1378 case WLAN_CIPHER_SUITE_WEP104:
1379 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1381 case WLAN_CIPHER_SUITE_TKIP:
1382 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1384 case WLAN_CIPHER_SUITE_CCMP:
1385 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1391 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1393 /* legacy rates TODO use ieee80211_tx_rate */
1394 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1395 if (priv->byAutoFBCtrl == AUTO_FB_0)
1396 tx_buffer_head->fifo_ctl |=
1397 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1398 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1399 tx_buffer_head->fifo_ctl |=
1400 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1404 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1406 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1407 dma_idx, head_td, is_pspoll);
1409 if (info->control.hw_key) {
1410 tx_key = info->control.hw_key;
1411 if (tx_key->keylen > 0)
1412 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1413 tx_key, skb, tx_body_size, td_info->mic_hdr);
1419 static int vnt_beacon_xmit(struct vnt_private *priv,
1420 struct sk_buff *skb)
1422 struct vnt_tx_short_buf_head *short_head =
1423 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1424 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1425 (priv->tx_beacon_bufs + sizeof(*short_head));
1426 struct ieee80211_tx_info *info;
1427 u32 frame_size = skb->len + 4;
1430 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1432 if (priv->byBBType == BB_TYPE_11A) {
1433 current_rate = RATE_6M;
1435 /* Get SignalField,ServiceField,Length */
1436 vnt_get_phy_field(priv, frame_size, current_rate,
1437 PK_TYPE_11A, &short_head->ab);
1439 /* Get Duration and TimeStampOff */
1440 short_head->duration =
1441 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1442 frame_size, PK_TYPE_11A, current_rate,
1443 false, 0, 0, 1, AUTO_FB_NONE));
1445 short_head->time_stamp_off =
1446 vnt_time_stamp_off(priv, current_rate);
1448 current_rate = RATE_1M;
1449 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1451 /* Get SignalField,ServiceField,Length */
1452 vnt_get_phy_field(priv, frame_size, current_rate,
1453 PK_TYPE_11B, &short_head->ab);
1455 /* Get Duration and TimeStampOff */
1456 short_head->duration =
1457 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1458 frame_size, PK_TYPE_11B, current_rate,
1459 false, 0, 0, 1, AUTO_FB_NONE));
1461 short_head->time_stamp_off =
1462 vnt_time_stamp_off(priv, current_rate);
1465 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1468 memcpy(mgmt_hdr, skb->data, skb->len);
1470 /* time stamp always 0 */
1471 mgmt_hdr->u.beacon.timestamp = 0;
1473 info = IEEE80211_SKB_CB(skb);
1474 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1475 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1477 hdr->duration_id = 0;
1478 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1481 priv->wSeqCounter++;
1482 if (priv->wSeqCounter > 0x0fff)
1483 priv->wSeqCounter = 0;
1485 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1487 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1489 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1490 /* Set auto Transmit on */
1491 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1492 /* Poll Transmit the adapter */
1493 MACvTransmitBCN(priv->PortOffset);
1498 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1500 struct sk_buff *beacon;
1502 beacon = ieee80211_beacon_get(priv->hw, vif);
1506 if (vnt_beacon_xmit(priv, beacon)) {
1507 ieee80211_free_txskb(priv->hw, beacon);
1514 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1515 struct ieee80211_bss_conf *conf)
1517 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1519 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1521 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1523 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1525 return vnt_beacon_make(priv, vif);