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 /* if packet size < 256 -> in-direct send
68 * vpacket size >= 256 -> direct send
70 #define CRITICAL_PACKET_LEN 256
72 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
73 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
74 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
77 static const unsigned short wFB_Opt0[2][5] = {
78 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
79 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
81 static const unsigned short wFB_Opt1[2][5] = {
82 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
83 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
90 #define RTSDUR_BA_F0 4
91 #define RTSDUR_AA_F0 5
92 #define RTSDUR_BA_F1 6
93 #define RTSDUR_AA_F1 7
94 #define CTSDUR_BA_F0 8
95 #define CTSDUR_BA_F1 9
98 #define DATADUR_A_F0 12
99 #define DATADUR_A_F1 13
101 /*--------------------- Static Functions --------------------------*/
105 struct vnt_private *pDevice,
106 unsigned char byPktType,
108 unsigned int cbFrameLength,
111 struct ieee80211_hdr *hdr,
112 unsigned short wCurrentRate,
113 unsigned char byFBOption
118 s_vGenerateTxParameter(
119 struct vnt_private *pDevice,
120 unsigned char byPktType,
121 struct vnt_tx_fifo_head *,
125 unsigned int cbFrameSize,
127 unsigned int uDMAIdx,
129 unsigned short wCurrentRate
133 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
134 unsigned char *pbyTxBufferAddr,
135 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
136 unsigned int uNodeIndex);
141 struct vnt_private *pDevice,
142 unsigned char byPktType,
144 unsigned int cbFrameLength,
145 unsigned int uDMAIdx,
147 unsigned int uFragIdx,
148 unsigned int cbLastFragmentSize,
149 unsigned int uMACfragNum,
150 unsigned char byFBOption,
151 unsigned short wCurrentRate,
155 /*--------------------- Export Variables --------------------------*/
157 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
159 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
163 /* byPktType : PK_TYPE_11A 0
171 struct vnt_private *pDevice,
172 unsigned char byPktType,
173 unsigned int cbFrameLength,
174 unsigned short wRate,
178 unsigned int uDataTime, uAckTime;
180 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
181 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
183 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
184 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
187 return uDataTime + pDevice->uSIFS + uAckTime;
192 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
193 u32 frame_length, u16 rate, bool need_ack)
195 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
196 frame_length, rate, need_ack));
199 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
203 struct vnt_private *pDevice,
204 unsigned char byRTSRsvType,
205 unsigned char byPktType,
206 unsigned int cbFrameLength,
207 unsigned short wCurrentRate
210 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
212 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
214 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
215 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
216 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
217 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
218 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
219 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
220 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
221 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
222 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
223 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
224 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
225 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
226 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
227 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
228 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
229 return cpu_to_le16((u16)uRrvTime);
233 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
234 return cpu_to_le16((u16)uRrvTime);
237 /* byFreqType 0: 5GHz, 1:2.4Ghz */
241 struct vnt_private *pDevice,
242 unsigned char byDurType,
243 unsigned int cbFrameLength,
244 unsigned char byPktType,
245 unsigned short wRate,
247 unsigned int uFragIdx,
248 unsigned int cbLastFragmentSize,
249 unsigned int uMACfragNum,
250 unsigned char byFBOption
253 bool bLastFrag = false;
254 unsigned int uAckTime = 0, uNextPktTime = 0;
256 if (uFragIdx == (uMACfragNum-1))
260 case DATADUR_B: /* DATADUR_B */
261 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
263 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
264 return pDevice->uSIFS + uAckTime;
268 } else {/* First Frag or Mid Frag */
269 if (uFragIdx == (uMACfragNum-2))
270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
272 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
275 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
276 return pDevice->uSIFS + uAckTime + uNextPktTime;
278 return pDevice->uSIFS + uNextPktTime;
283 case DATADUR_A: /* DATADUR_A */
284 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
286 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
287 return pDevice->uSIFS + uAckTime;
291 } else {/* First Frag or Mid Frag */
292 if (uFragIdx == (uMACfragNum-2))
293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
295 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
298 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
299 return pDevice->uSIFS + uAckTime + uNextPktTime;
301 return pDevice->uSIFS + uNextPktTime;
306 case DATADUR_A_F0: /* DATADUR_A_F0 */
307 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
309 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
310 return pDevice->uSIFS + uAckTime;
314 } else { /* First Frag or Mid Frag */
315 if (byFBOption == AUTO_FB_0) {
316 if (wRate < RATE_18M)
318 else if (wRate > RATE_54M)
321 if (uFragIdx == (uMACfragNum-2))
322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
324 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
326 } else { /* (byFBOption == AUTO_FB_1) */
327 if (wRate < RATE_18M)
329 else if (wRate > RATE_54M)
332 if (uFragIdx == (uMACfragNum-2))
333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
335 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
340 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
341 return pDevice->uSIFS + uAckTime + uNextPktTime;
343 return pDevice->uSIFS + uNextPktTime;
348 case DATADUR_A_F1: /* DATADUR_A_F1 */
349 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
351 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
352 return pDevice->uSIFS + uAckTime;
356 } else { /* First Frag or Mid Frag */
357 if (byFBOption == AUTO_FB_0) {
358 if (wRate < RATE_18M)
360 else if (wRate > RATE_54M)
363 if (uFragIdx == (uMACfragNum-2))
364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
366 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
368 } else { /* (byFBOption == AUTO_FB_1) */
369 if (wRate < RATE_18M)
371 else if (wRate > RATE_54M)
374 if (uFragIdx == (uMACfragNum-2))
375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
377 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
380 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
381 return pDevice->uSIFS + uAckTime + uNextPktTime;
383 return pDevice->uSIFS + uNextPktTime;
395 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
398 s_uGetRTSCTSDuration(
399 struct vnt_private *pDevice,
400 unsigned char byDurType,
401 unsigned int cbFrameLength,
402 unsigned char byPktType,
403 unsigned short wRate,
405 unsigned char byFBOption
408 unsigned int uCTSTime = 0, uDurTime = 0;
411 case RTSDUR_BB: /* RTSDuration_bb */
412 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
413 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
416 case RTSDUR_BA: /* RTSDuration_ba */
417 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
418 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
421 case RTSDUR_AA: /* RTSDuration_aa */
422 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
423 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
426 case CTSDUR_BA: /* CTSDuration_ba */
427 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
430 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
431 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
432 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
433 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
434 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
435 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
439 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
440 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
441 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
442 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
443 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
444 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
448 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
449 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
450 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
451 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
452 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
453 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
457 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
458 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
459 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
460 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
461 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
462 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
466 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
467 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
468 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
469 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
470 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
474 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
475 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
476 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
477 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
478 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
486 return cpu_to_le16((u16)uDurTime);
492 struct vnt_private *pDevice,
493 unsigned char byPktType,
495 unsigned int cbFrameLength,
496 unsigned int uDMAIdx,
498 unsigned int uFragIdx,
499 unsigned int cbLastFragmentSize,
500 unsigned int uMACfragNum,
501 unsigned char byFBOption,
502 unsigned short wCurrentRate,
511 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
512 if (byFBOption == AUTO_FB_NONE) {
513 struct vnt_tx_datahead_g *buf = pTxDataHead;
514 /* Get SignalField, ServiceField & Length */
515 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
518 vnt_get_phy_field(pDevice, cbFrameLength,
519 pDevice->byTopCCKBasicRate,
520 PK_TYPE_11B, &buf->b);
523 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
525 buf->duration_a = dur;
526 buf->duration_b = dur;
528 /* Get Duration and TimeStamp */
530 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
531 byPktType, wCurrentRate, bNeedAck, uFragIdx,
532 cbLastFragmentSize, uMACfragNum,
535 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
536 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
537 bNeedAck, uFragIdx, cbLastFragmentSize,
538 uMACfragNum, byFBOption));
541 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
542 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
544 return buf->duration_a;
547 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
548 /* Get SignalField, ServiceField & Length */
549 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
552 vnt_get_phy_field(pDevice, cbFrameLength,
553 pDevice->byTopCCKBasicRate,
554 PK_TYPE_11B, &buf->b);
555 /* Get Duration and TimeStamp */
556 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
557 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
559 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
560 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
561 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
562 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
563 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
565 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
566 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
568 return buf->duration_a;
569 } /* if (byFBOption == AUTO_FB_NONE) */
570 } else if (byPktType == PK_TYPE_11A) {
571 if (byFBOption != AUTO_FB_NONE) {
573 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
574 /* Get SignalField, ServiceField & Length */
575 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
578 /* Get Duration and TimeStampOff */
579 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
582 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
583 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
584 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
585 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
586 return buf->duration;
588 struct vnt_tx_datahead_ab *buf = pTxDataHead;
589 /* Get SignalField, ServiceField & Length */
590 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
591 byPktType, &buf->ab);
594 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
598 /* Get Duration and TimeStampOff */
600 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
601 wCurrentRate, bNeedAck, uFragIdx,
602 cbLastFragmentSize, uMACfragNum,
606 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
607 return buf->duration;
610 struct vnt_tx_datahead_ab *buf = pTxDataHead;
611 /* Get SignalField, ServiceField & Length */
612 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
613 byPktType, &buf->ab);
616 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
620 /* Get Duration and TimeStampOff */
622 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
623 wCurrentRate, bNeedAck, uFragIdx,
624 cbLastFragmentSize, uMACfragNum,
628 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
629 return buf->duration;
638 struct vnt_private *pDevice,
639 unsigned char byPktType,
641 unsigned int cbFrameLength,
644 struct ieee80211_hdr *hdr,
645 unsigned short wCurrentRate,
646 unsigned char byFBOption
649 unsigned int uRTSFrameLen = 20;
655 /* When CRCDIS bit is on, H/W forgot to generate FCS for
656 * RTS frame, in this case we need to decrease its length by 4.
661 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
662 * so we don't need to take them into account.
663 * Otherwise, we need to modify codes for them.
665 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
666 if (byFBOption == AUTO_FB_NONE) {
667 struct vnt_rts_g *buf = pvRTS;
668 /* Get SignalField, ServiceField & Length */
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopCCKBasicRate,
671 PK_TYPE_11B, &buf->b);
673 vnt_get_phy_field(pDevice, uRTSFrameLen,
674 pDevice->byTopOFDMBasicRate,
678 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
679 cbFrameLength, PK_TYPE_11B,
680 pDevice->byTopCCKBasicRate,
681 bNeedAck, byFBOption);
683 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
684 cbFrameLength, byPktType,
685 wCurrentRate, bNeedAck,
688 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
689 cbFrameLength, byPktType,
690 wCurrentRate, bNeedAck,
693 buf->data.duration = buf->duration_aa;
694 /* Get RTS Frame body */
695 buf->data.frame_control =
696 cpu_to_le16(IEEE80211_FTYPE_CTL |
697 IEEE80211_STYPE_RTS);
699 ether_addr_copy(buf->data.ra, hdr->addr1);
700 ether_addr_copy(buf->data.ta, hdr->addr2);
702 struct vnt_rts_g_fb *buf = pvRTS;
703 /* Get SignalField, ServiceField & Length */
704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopCCKBasicRate,
706 PK_TYPE_11B, &buf->b);
708 vnt_get_phy_field(pDevice, uRTSFrameLen,
709 pDevice->byTopOFDMBasicRate,
713 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
714 cbFrameLength, PK_TYPE_11B,
715 pDevice->byTopCCKBasicRate,
716 bNeedAck, byFBOption);
718 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
719 cbFrameLength, byPktType,
720 wCurrentRate, bNeedAck,
723 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
724 cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck,
727 buf->rts_duration_ba_f0 =
728 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
729 cbFrameLength, byPktType,
730 wCurrentRate, bNeedAck,
732 buf->rts_duration_aa_f0 =
733 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
734 cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck,
737 buf->rts_duration_ba_f1 =
738 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
739 cbFrameLength, byPktType,
740 wCurrentRate, bNeedAck,
742 buf->rts_duration_aa_f1 =
743 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
744 cbFrameLength, byPktType,
745 wCurrentRate, bNeedAck,
747 buf->data.duration = buf->duration_aa;
748 /* Get RTS Frame body */
749 buf->data.frame_control =
750 cpu_to_le16(IEEE80211_FTYPE_CTL |
751 IEEE80211_STYPE_RTS);
753 ether_addr_copy(buf->data.ra, hdr->addr1);
754 ether_addr_copy(buf->data.ta, hdr->addr2);
755 } /* if (byFBOption == AUTO_FB_NONE) */
756 } else if (byPktType == PK_TYPE_11A) {
757 if (byFBOption == AUTO_FB_NONE) {
758 struct vnt_rts_ab *buf = pvRTS;
759 /* Get SignalField, ServiceField & Length */
760 vnt_get_phy_field(pDevice, uRTSFrameLen,
761 pDevice->byTopOFDMBasicRate,
762 byPktType, &buf->ab);
765 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
766 cbFrameLength, byPktType,
767 wCurrentRate, bNeedAck,
769 buf->data.duration = buf->duration;
770 /* Get RTS Frame body */
771 buf->data.frame_control =
772 cpu_to_le16(IEEE80211_FTYPE_CTL |
773 IEEE80211_STYPE_RTS);
775 ether_addr_copy(buf->data.ra, hdr->addr1);
776 ether_addr_copy(buf->data.ta, hdr->addr2);
778 struct vnt_rts_a_fb *buf = pvRTS;
779 /* Get SignalField, ServiceField & Length */
780 vnt_get_phy_field(pDevice, uRTSFrameLen,
781 pDevice->byTopOFDMBasicRate,
785 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
786 cbFrameLength, byPktType,
787 wCurrentRate, bNeedAck,
789 buf->rts_duration_f0 =
790 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
791 cbFrameLength, byPktType,
792 wCurrentRate, bNeedAck,
794 buf->rts_duration_f1 =
795 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
796 cbFrameLength, byPktType,
797 wCurrentRate, bNeedAck,
799 buf->data.duration = buf->duration;
800 /* Get RTS Frame body */
801 buf->data.frame_control =
802 cpu_to_le16(IEEE80211_FTYPE_CTL |
803 IEEE80211_STYPE_RTS);
805 ether_addr_copy(buf->data.ra, hdr->addr1);
806 ether_addr_copy(buf->data.ta, hdr->addr2);
808 } else if (byPktType == PK_TYPE_11B) {
809 struct vnt_rts_ab *buf = pvRTS;
810 /* Get SignalField, ServiceField & Length */
811 vnt_get_phy_field(pDevice, uRTSFrameLen,
812 pDevice->byTopCCKBasicRate,
813 PK_TYPE_11B, &buf->ab);
816 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
817 byPktType, wCurrentRate, bNeedAck,
820 buf->data.duration = buf->duration;
821 /* Get RTS Frame body */
822 buf->data.frame_control =
823 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
825 ether_addr_copy(buf->data.ra, hdr->addr1);
826 ether_addr_copy(buf->data.ta, hdr->addr2);
833 struct vnt_private *pDevice,
834 unsigned int uDMAIdx,
835 unsigned char byPktType,
837 unsigned int cbFrameLength,
840 unsigned short wCurrentRate,
841 unsigned char byFBOption
844 unsigned int uCTSFrameLen = 14;
850 /* When CRCDIS bit is on, H/W forgot to generate FCS for
851 * CTS frame, in this case we need to decrease its length by 4.
856 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
857 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
859 struct vnt_cts_fb *buf = pvCTS;
860 /* Get SignalField, ServiceField & Length */
861 vnt_get_phy_field(pDevice, uCTSFrameLen,
862 pDevice->byTopCCKBasicRate,
863 PK_TYPE_11B, &buf->b);
866 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
867 cbFrameLength, byPktType,
868 wCurrentRate, bNeedAck,
871 /* Get CTSDuration_ba_f0 */
872 buf->cts_duration_ba_f0 =
873 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
874 cbFrameLength, byPktType,
875 wCurrentRate, bNeedAck,
878 /* Get CTSDuration_ba_f1 */
879 buf->cts_duration_ba_f1 =
880 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
881 cbFrameLength, byPktType,
882 wCurrentRate, bNeedAck,
885 /* Get CTS Frame body */
886 buf->data.duration = buf->duration_ba;
888 buf->data.frame_control =
889 cpu_to_le16(IEEE80211_FTYPE_CTL |
890 IEEE80211_STYPE_CTS);
892 buf->reserved2 = 0x0;
894 ether_addr_copy(buf->data.ra,
895 pDevice->abyCurrentNetAddr);
896 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
897 struct vnt_cts *buf = pvCTS;
898 /* Get SignalField, ServiceField & Length */
899 vnt_get_phy_field(pDevice, uCTSFrameLen,
900 pDevice->byTopCCKBasicRate,
901 PK_TYPE_11B, &buf->b);
903 /* Get CTSDuration_ba */
905 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
906 cbFrameLength, byPktType,
907 wCurrentRate, bNeedAck,
910 /* Get CTS Frame body */
911 buf->data.duration = buf->duration_ba;
913 buf->data.frame_control =
914 cpu_to_le16(IEEE80211_FTYPE_CTL |
915 IEEE80211_STYPE_CTS);
917 buf->reserved2 = 0x0;
918 ether_addr_copy(buf->data.ra,
919 pDevice->abyCurrentNetAddr);
927 * Generate FIFO control for MAC & Baseband controller
931 * pDevice - Pointer to adapter
932 * pTxDataHead - Transmit Data Buffer
933 * pTxBufHead - pTxBufHead
934 * pvRrvTime - pvRrvTime
937 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
938 * bNeedACK - If need ACK
939 * uDescIdx - Desc Index
946 * unsigned int cbFrameSize, Hdr+Payload+FCS
950 s_vGenerateTxParameter(
951 struct vnt_private *pDevice,
952 unsigned char byPktType,
953 struct vnt_tx_fifo_head *tx_buffer_head,
957 unsigned int cbFrameSize,
959 unsigned int uDMAIdx,
961 unsigned short wCurrentRate
964 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
965 bool bDisCRC = false;
966 unsigned char byFBOption = AUTO_FB_NONE;
968 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
970 if (fifo_ctl & FIFOCTL_CRCDIS)
973 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
974 byFBOption = AUTO_FB_0;
975 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
976 byFBOption = AUTO_FB_1;
981 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
982 if (pvRTS != NULL) { /* RTS_need */
984 struct vnt_rrv_time_rts *buf = pvRrvTime;
986 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
987 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
988 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
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);
992 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
993 } else {/* RTS_needless, PCF mode */
994 struct vnt_rrv_time_cts *buf = pvRrvTime;
996 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
997 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
998 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
1001 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1003 } else if (byPktType == PK_TYPE_11A) {
1004 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1005 struct vnt_rrv_time_ab *buf = pvRrvTime;
1007 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1008 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1011 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1012 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
1013 struct vnt_rrv_time_ab *buf = pvRrvTime;
1015 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1017 } else if (byPktType == PK_TYPE_11B) {
1018 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
1019 struct vnt_rrv_time_ab *buf = pvRrvTime;
1021 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1022 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1025 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1026 } else { /* RTS_needless, non PCF mode */
1027 struct vnt_rrv_time_ab *buf = pvRrvTime;
1029 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1035 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1036 unsigned char *pbyTxBufferAddr,
1037 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1038 unsigned int is_pspoll)
1040 struct vnt_td_info *td_info = pHeadTD->td_info;
1041 struct sk_buff *skb = td_info->skb;
1042 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1043 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1044 struct vnt_tx_fifo_head *tx_buffer_head =
1045 (struct vnt_tx_fifo_head *)td_info->buf;
1046 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1047 unsigned int cbFrameSize;
1049 unsigned char *pbyBuffer;
1050 unsigned int uLength = 0;
1051 unsigned int cbMICHDR = 0;
1052 unsigned int uMACfragNum = 1;
1053 unsigned int uPadding = 0;
1054 unsigned int cbReqCount = 0;
1055 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1056 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1057 struct vnt_tx_desc *ptdCurr;
1058 unsigned int cbHeaderLength = 0;
1060 struct vnt_mic_hdr *pMICHDR;
1064 unsigned short wTxBufSize; /* FFinfo size */
1065 unsigned char byFBOption = AUTO_FB_NONE;
1067 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1069 cbFrameSize = skb->len + 4;
1071 if (info->control.hw_key) {
1072 switch (info->control.hw_key->cipher) {
1073 case WLAN_CIPHER_SUITE_CCMP:
1074 cbMICHDR = sizeof(struct vnt_mic_hdr);
1079 cbFrameSize += info->control.hw_key->icv_len;
1081 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1082 /* MAC Header should be padding 0 to DW alignment. */
1083 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1089 * Use for AUTO FALL BACK
1091 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1092 byFBOption = AUTO_FB_0;
1093 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1094 byFBOption = AUTO_FB_1;
1097 /* Set RrvTime/RTS/CTS Buffer */
1098 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1099 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1101 if (byFBOption == AUTO_FB_NONE) {
1102 if (bRTS) {/* RTS_need */
1103 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1104 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1105 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1107 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1108 cbMICHDR + sizeof(struct vnt_rts_g));
1109 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1110 cbMICHDR + sizeof(struct vnt_rts_g) +
1111 sizeof(struct vnt_tx_datahead_g);
1112 } else { /* RTS_needless */
1113 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1114 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1116 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1117 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1118 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1119 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1120 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1123 /* Auto Fall Back */
1124 if (bRTS) {/* RTS_need */
1125 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1126 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1127 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1129 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1130 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1131 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1132 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1133 } else { /* RTS_needless */
1134 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1135 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1137 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1138 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1139 cbMICHDR + sizeof(struct vnt_cts_fb));
1140 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1141 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1143 } /* Auto Fall Back */
1144 } else {/* 802.11a/b packet */
1146 if (byFBOption == AUTO_FB_NONE) {
1148 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1149 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1150 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1152 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1153 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1154 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1155 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1156 } else { /* RTS_needless, need MICHDR */
1157 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1158 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1161 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1162 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1163 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1166 /* Auto Fall Back */
1167 if (bRTS) { /* RTS_need */
1168 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1169 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1170 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1172 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1173 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1174 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1175 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1176 } else { /* RTS_needless */
1177 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1178 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1181 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1182 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1183 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1185 } /* Auto Fall Back */
1188 td_info->mic_hdr = pMICHDR;
1190 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1192 /* Fill FIFO,RrvTime,RTS,and CTS */
1193 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1194 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1196 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1197 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1199 hdr->duration_id = uDuration;
1201 cbReqCount = cbHeaderLength + uPadding + skb->len;
1202 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1203 uLength = cbHeaderLength + uPadding;
1205 /* Copy the Packet into a tx Buffer */
1206 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1210 ptdCurr->td_info->req_count = (u16)cbReqCount;
1212 return cbHeaderLength;
1215 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1216 struct ieee80211_key_conf *tx_key,
1217 struct sk_buff *skb, u16 payload_len,
1218 struct vnt_mic_hdr *mic_hdr)
1221 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1223 /* strip header and icv len from payload */
1224 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1225 payload_len -= tx_key->icv_len;
1227 switch (tx_key->cipher) {
1228 case WLAN_CIPHER_SUITE_WEP40:
1229 case WLAN_CIPHER_SUITE_WEP104:
1230 memcpy(key_buffer, iv, 3);
1231 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1233 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1234 memcpy(key_buffer + 8, iv, 3);
1235 memcpy(key_buffer + 11,
1236 tx_key->key, WLAN_KEY_LEN_WEP40);
1240 case WLAN_CIPHER_SUITE_TKIP:
1241 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1244 case WLAN_CIPHER_SUITE_CCMP:
1250 mic_hdr->payload_len = cpu_to_be16(payload_len);
1251 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1253 pn64 = atomic64_read(&tx_key->tx_pn);
1254 mic_hdr->ccmp_pn[5] = pn64;
1255 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1256 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1257 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1258 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1259 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1261 if (ieee80211_has_a4(hdr->frame_control))
1262 mic_hdr->hlen = cpu_to_be16(28);
1264 mic_hdr->hlen = cpu_to_be16(22);
1266 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1267 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1268 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1270 mic_hdr->frame_control = cpu_to_le16(
1271 le16_to_cpu(hdr->frame_control) & 0xc78f);
1272 mic_hdr->seq_ctrl = cpu_to_le16(
1273 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1275 if (ieee80211_has_a4(hdr->frame_control))
1276 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1278 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1286 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1287 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1289 struct vnt_td_info *td_info = head_td->td_info;
1290 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1291 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1292 struct ieee80211_rate *rate;
1293 struct ieee80211_key_conf *tx_key;
1294 struct ieee80211_hdr *hdr;
1295 struct vnt_tx_fifo_head *tx_buffer_head =
1296 (struct vnt_tx_fifo_head *)td_info->buf;
1297 u16 tx_body_size = skb->len, current_rate;
1299 bool is_pspoll = false;
1301 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1303 hdr = (struct ieee80211_hdr *)(skb->data);
1305 rate = ieee80211_get_tx_rate(priv->hw, info);
1307 current_rate = rate->hw_value;
1308 if (priv->wCurrentRate != current_rate &&
1309 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1310 priv->wCurrentRate = current_rate;
1312 RFbSetPower(priv, priv->wCurrentRate,
1313 priv->hw->conf.chandef.chan->hw_value);
1316 if (current_rate > RATE_11M) {
1317 if (info->band == NL80211_BAND_5GHZ) {
1318 pkt_type = PK_TYPE_11A;
1320 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1321 pkt_type = PK_TYPE_11GB;
1323 pkt_type = PK_TYPE_11GA;
1326 pkt_type = PK_TYPE_11B;
1329 /*Set fifo controls */
1330 if (pkt_type == PK_TYPE_11A)
1331 tx_buffer_head->fifo_ctl = 0;
1332 else if (pkt_type == PK_TYPE_11B)
1333 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1334 else if (pkt_type == PK_TYPE_11GB)
1335 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1336 else if (pkt_type == PK_TYPE_11GA)
1337 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1339 /* generate interrupt */
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1342 if (!ieee80211_is_data(hdr->frame_control)) {
1343 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1344 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1345 tx_buffer_head->time_stamp =
1346 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1348 tx_buffer_head->time_stamp =
1349 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1352 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1353 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1355 if (ieee80211_has_retry(hdr->frame_control))
1356 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1358 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1359 priv->byPreambleType = PREAMBLE_SHORT;
1361 priv->byPreambleType = PREAMBLE_LONG;
1363 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1364 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1366 if (ieee80211_has_a4(hdr->frame_control)) {
1367 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1368 priv->bLongHeader = true;
1371 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1374 tx_buffer_head->frag_ctl =
1375 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1377 if (info->control.hw_key) {
1378 tx_key = info->control.hw_key;
1380 switch (info->control.hw_key->cipher) {
1381 case WLAN_CIPHER_SUITE_WEP40:
1382 case WLAN_CIPHER_SUITE_WEP104:
1383 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1385 case WLAN_CIPHER_SUITE_TKIP:
1386 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1388 case WLAN_CIPHER_SUITE_CCMP:
1389 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1395 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1397 /* legacy rates TODO use ieee80211_tx_rate */
1398 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1399 if (priv->byAutoFBCtrl == AUTO_FB_0)
1400 tx_buffer_head->fifo_ctl |=
1401 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1402 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1403 tx_buffer_head->fifo_ctl |=
1404 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1408 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1410 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1411 dma_idx, head_td, is_pspoll);
1413 if (info->control.hw_key) {
1414 tx_key = info->control.hw_key;
1415 if (tx_key->keylen > 0)
1416 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1417 tx_key, skb, tx_body_size, td_info->mic_hdr);
1423 static int vnt_beacon_xmit(struct vnt_private *priv,
1424 struct sk_buff *skb)
1426 struct vnt_tx_short_buf_head *short_head =
1427 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1428 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1429 (priv->tx_beacon_bufs + sizeof(*short_head));
1430 struct ieee80211_tx_info *info;
1431 u32 frame_size = skb->len + 4;
1434 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1436 if (priv->byBBType == BB_TYPE_11A) {
1437 current_rate = RATE_6M;
1439 /* Get SignalField,ServiceField,Length */
1440 vnt_get_phy_field(priv, frame_size, current_rate,
1441 PK_TYPE_11A, &short_head->ab);
1443 /* Get Duration and TimeStampOff */
1444 short_head->duration =
1445 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1446 frame_size, PK_TYPE_11A, current_rate,
1447 false, 0, 0, 1, AUTO_FB_NONE));
1449 short_head->time_stamp_off =
1450 vnt_time_stamp_off(priv, current_rate);
1452 current_rate = RATE_1M;
1453 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1455 /* Get SignalField,ServiceField,Length */
1456 vnt_get_phy_field(priv, frame_size, current_rate,
1457 PK_TYPE_11B, &short_head->ab);
1459 /* Get Duration and TimeStampOff */
1460 short_head->duration =
1461 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1462 frame_size, PK_TYPE_11B, current_rate,
1463 false, 0, 0, 1, AUTO_FB_NONE));
1465 short_head->time_stamp_off =
1466 vnt_time_stamp_off(priv, current_rate);
1469 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1472 memcpy(mgmt_hdr, skb->data, skb->len);
1474 /* time stamp always 0 */
1475 mgmt_hdr->u.beacon.timestamp = 0;
1477 info = IEEE80211_SKB_CB(skb);
1478 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1479 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1481 hdr->duration_id = 0;
1482 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1485 priv->wSeqCounter++;
1486 if (priv->wSeqCounter > 0x0fff)
1487 priv->wSeqCounter = 0;
1489 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1491 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1493 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1494 /* Set auto Transmit on */
1495 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1496 /* Poll Transmit the adapter */
1497 MACvTransmitBCN(priv->PortOffset);
1502 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1504 struct sk_buff *beacon;
1506 beacon = ieee80211_beacon_get(priv->hw, vif);
1510 if (vnt_beacon_xmit(priv, beacon)) {
1511 ieee80211_free_txskb(priv->hw, beacon);
1518 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1519 struct ieee80211_bss_conf *conf)
1521 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1523 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1525 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1527 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1529 return vnt_beacon_make(priv, vif);