1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
8 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
15 * s_vGenerateTxParameter - Generate tx dma required parameter.
16 * vGenerateMACHeader - Translate 802.3 to 802.11 header
17 * cbGetFragCount - Calculate fragment number count
18 * csBeacon_xmit - beacon tx function
19 * csMgmt_xmit - management tx function
20 * s_cbFillTxBufHead - fulfill tx dma buffer header
21 * s_uGetDataDuration - get tx data required duration
22 * s_uFillDataHead- fulfill tx data duration header
23 * s_uGetRTSCTSDuration- get rtx/cts required duration
24 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
25 * s_uGetTxRsvTime- get frame reserved time
26 * s_vFillCTSHead- fulfill CTS ctl header
27 * s_vFillFragParameter- Set fragment ctl parameter.
28 * s_vFillRTSHead- fulfill RTS ctl header
29 * s_vFillTxKey- fulfill tx encrypt key
30 * s_vSWencryption- Software encrypt header
31 * vDMA0_tx_80211- tx 802.11 frame via dma0
32 * vGenerateFIFOHeader- Generate tx FIFO ctl header
45 /*--------------------- Static Definitions -------------------------*/
47 /*--------------------- Static Classes ----------------------------*/
49 /*--------------------- Static Variables --------------------------*/
51 /*--------------------- Static Functions --------------------------*/
53 /*--------------------- Static Definitions -------------------------*/
54 /* if packet size < 256 -> in-direct send
55 * vpacket size >= 256 -> direct send
57 #define CRITICAL_PACKET_LEN 256
59 static const unsigned short wTimeStampOff[2][MAX_RATE] = {
60 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
61 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
64 static const unsigned short wFB_Opt0[2][5] = {
65 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
66 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
68 static const unsigned short wFB_Opt1[2][5] = {
69 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
70 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
77 #define RTSDUR_BA_F0 4
78 #define RTSDUR_AA_F0 5
79 #define RTSDUR_BA_F1 6
80 #define RTSDUR_AA_F1 7
81 #define CTSDUR_BA_F0 8
82 #define CTSDUR_BA_F1 9
85 #define DATADUR_A_F0 12
86 #define DATADUR_A_F1 13
88 /*--------------------- Static Functions --------------------------*/
92 struct vnt_private *pDevice,
93 unsigned char byPktType,
95 unsigned int cbFrameLength,
98 struct ieee80211_hdr *hdr,
99 unsigned short wCurrentRate,
100 unsigned char byFBOption
105 s_vGenerateTxParameter(
106 struct vnt_private *pDevice,
107 unsigned char byPktType,
108 struct vnt_tx_fifo_head *,
112 unsigned int cbFrameSize,
114 unsigned int uDMAIdx,
116 unsigned short wCurrentRate
120 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
121 unsigned char *pbyTxBufferAddr,
122 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
123 unsigned int uNodeIndex);
128 struct vnt_private *pDevice,
129 unsigned char byPktType,
131 unsigned int cbFrameLength,
132 unsigned int uDMAIdx,
134 unsigned int uFragIdx,
135 unsigned int cbLastFragmentSize,
136 unsigned int uMACfragNum,
137 unsigned char byFBOption,
138 unsigned short wCurrentRate,
142 /*--------------------- Export Variables --------------------------*/
144 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
146 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
150 /* byPktType : PK_TYPE_11A 0
158 struct vnt_private *pDevice,
159 unsigned char byPktType,
160 unsigned int cbFrameLength,
161 unsigned short wRate,
165 unsigned int uDataTime, uAckTime;
167 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
168 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
169 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
170 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
171 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
174 return uDataTime + pDevice->uSIFS + uAckTime;
179 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
180 u32 frame_length, u16 rate, bool need_ack)
182 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
183 frame_length, rate, need_ack));
186 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
190 struct vnt_private *pDevice,
191 unsigned char byRTSRsvType,
192 unsigned char byPktType,
193 unsigned int cbFrameLength,
194 unsigned short wCurrentRate
197 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
199 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
201 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
202 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
203 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
204 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
205 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
206 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
207 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
208 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
209 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
210 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
211 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
212 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
213 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
214 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
215 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
216 return cpu_to_le16((u16)uRrvTime);
220 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
221 return cpu_to_le16((u16)uRrvTime);
224 /* byFreqType 0: 5GHz, 1:2.4Ghz */
228 struct vnt_private *pDevice,
229 unsigned char byDurType,
230 unsigned int cbFrameLength,
231 unsigned char byPktType,
232 unsigned short wRate,
234 unsigned int uFragIdx,
235 unsigned int cbLastFragmentSize,
236 unsigned int uMACfragNum,
237 unsigned char byFBOption
240 bool bLastFrag = false;
241 unsigned int uAckTime = 0, uNextPktTime = 0;
243 if (uFragIdx == (uMACfragNum-1))
247 case DATADUR_B: /* DATADUR_B */
248 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
250 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
251 return pDevice->uSIFS + uAckTime;
255 } else {/* First Frag or Mid Frag */
256 if (uFragIdx == (uMACfragNum-2))
257 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
259 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
262 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
263 return pDevice->uSIFS + uAckTime + uNextPktTime;
265 return pDevice->uSIFS + uNextPktTime;
270 case DATADUR_A: /* DATADUR_A */
271 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
273 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
274 return pDevice->uSIFS + uAckTime;
278 } else {/* First Frag or Mid Frag */
279 if (uFragIdx == (uMACfragNum-2))
280 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
282 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
285 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
286 return pDevice->uSIFS + uAckTime + uNextPktTime;
288 return pDevice->uSIFS + uNextPktTime;
293 case DATADUR_A_F0: /* DATADUR_A_F0 */
294 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
296 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
297 return pDevice->uSIFS + uAckTime;
301 } else { /* First Frag or Mid Frag */
302 if (byFBOption == AUTO_FB_0) {
303 if (wRate < RATE_18M)
305 else if (wRate > RATE_54M)
308 if (uFragIdx == (uMACfragNum-2))
309 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
311 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
313 } else { /* (byFBOption == AUTO_FB_1) */
314 if (wRate < RATE_18M)
316 else if (wRate > RATE_54M)
319 if (uFragIdx == (uMACfragNum-2))
320 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
326 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
327 return pDevice->uSIFS + uAckTime + uNextPktTime;
329 return pDevice->uSIFS + uNextPktTime;
334 case DATADUR_A_F1: /* DATADUR_A_F1 */
335 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
337 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
338 return pDevice->uSIFS + uAckTime;
342 } else { /* First Frag or Mid Frag */
343 if (byFBOption == AUTO_FB_0) {
344 if (wRate < RATE_18M)
346 else if (wRate > RATE_54M)
349 if (uFragIdx == (uMACfragNum-2))
350 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
352 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
354 } else { /* (byFBOption == AUTO_FB_1) */
355 if (wRate < RATE_18M)
357 else if (wRate > RATE_54M)
360 if (uFragIdx == (uMACfragNum-2))
361 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
363 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
366 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
367 return pDevice->uSIFS + uAckTime + uNextPktTime;
369 return pDevice->uSIFS + uNextPktTime;
381 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
384 s_uGetRTSCTSDuration(
385 struct vnt_private *pDevice,
386 unsigned char byDurType,
387 unsigned int cbFrameLength,
388 unsigned char byPktType,
389 unsigned short wRate,
391 unsigned char byFBOption
394 unsigned int uCTSTime = 0, uDurTime = 0;
397 case RTSDUR_BB: /* RTSDuration_bb */
398 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
399 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
402 case RTSDUR_BA: /* RTSDuration_ba */
403 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
404 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
407 case RTSDUR_AA: /* RTSDuration_aa */
408 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
409 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
412 case CTSDUR_BA: /* CTSDuration_ba */
413 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
416 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
417 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
418 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
419 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
420 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
421 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
425 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
426 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
427 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
428 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
429 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
430 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
434 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
435 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
436 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
437 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
438 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
439 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
443 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
444 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
445 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
446 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
447 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
448 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
452 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
453 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
454 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
455 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
456 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
460 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
461 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
462 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
463 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
464 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
472 return cpu_to_le16((u16)uDurTime);
478 struct vnt_private *pDevice,
479 unsigned char byPktType,
481 unsigned int cbFrameLength,
482 unsigned int uDMAIdx,
484 unsigned int uFragIdx,
485 unsigned int cbLastFragmentSize,
486 unsigned int uMACfragNum,
487 unsigned char byFBOption,
488 unsigned short wCurrentRate,
495 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
496 if (byFBOption == AUTO_FB_NONE) {
497 struct vnt_tx_datahead_g *buf = pTxDataHead;
498 /* Get SignalField, ServiceField & Length */
499 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
502 vnt_get_phy_field(pDevice, cbFrameLength,
503 pDevice->byTopCCKBasicRate,
504 PK_TYPE_11B, &buf->b);
507 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
509 buf->duration_a = dur;
510 buf->duration_b = dur;
512 /* Get Duration and TimeStamp */
514 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
515 byPktType, wCurrentRate, bNeedAck, uFragIdx,
516 cbLastFragmentSize, uMACfragNum,
519 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
520 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
521 bNeedAck, uFragIdx, cbLastFragmentSize,
522 uMACfragNum, byFBOption));
525 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
526 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
528 return buf->duration_a;
531 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
532 /* Get SignalField, ServiceField & Length */
533 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
536 vnt_get_phy_field(pDevice, cbFrameLength,
537 pDevice->byTopCCKBasicRate,
538 PK_TYPE_11B, &buf->b);
539 /* Get Duration and TimeStamp */
540 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
541 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
542 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
543 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
544 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
545 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
546 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
547 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
549 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
550 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
552 return buf->duration_a;
553 } /* if (byFBOption == AUTO_FB_NONE) */
554 } else if (byPktType == PK_TYPE_11A) {
555 if (byFBOption != AUTO_FB_NONE) {
557 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
558 /* Get SignalField, ServiceField & Length */
559 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
562 /* Get Duration and TimeStampOff */
563 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
564 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
565 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
566 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
567 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
568 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
569 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
570 return buf->duration;
572 struct vnt_tx_datahead_ab *buf = pTxDataHead;
573 /* Get SignalField, ServiceField & Length */
574 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
575 byPktType, &buf->ab);
578 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
582 /* Get Duration and TimeStampOff */
584 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
585 wCurrentRate, bNeedAck, uFragIdx,
586 cbLastFragmentSize, uMACfragNum,
590 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
591 return buf->duration;
594 struct vnt_tx_datahead_ab *buf = pTxDataHead;
595 /* Get SignalField, ServiceField & Length */
596 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
597 byPktType, &buf->ab);
600 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
604 /* Get Duration and TimeStampOff */
606 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
607 wCurrentRate, bNeedAck, uFragIdx,
608 cbLastFragmentSize, uMACfragNum,
612 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
613 return buf->duration;
621 struct vnt_private *pDevice,
622 unsigned char byPktType,
624 unsigned int cbFrameLength,
627 struct ieee80211_hdr *hdr,
628 unsigned short wCurrentRate,
629 unsigned char byFBOption
632 unsigned int uRTSFrameLen = 20;
638 /* When CRCDIS bit is on, H/W forgot to generate FCS for
639 * RTS frame, in this case we need to decrease its length by 4.
644 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
645 * so we don't need to take them into account.
646 * Otherwise, we need to modify codes for them.
648 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
649 if (byFBOption == AUTO_FB_NONE) {
650 struct vnt_rts_g *buf = pvRTS;
651 /* Get SignalField, ServiceField & Length */
652 vnt_get_phy_field(pDevice, uRTSFrameLen,
653 pDevice->byTopCCKBasicRate,
654 PK_TYPE_11B, &buf->b);
656 vnt_get_phy_field(pDevice, uRTSFrameLen,
657 pDevice->byTopOFDMBasicRate,
661 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
662 cbFrameLength, PK_TYPE_11B,
663 pDevice->byTopCCKBasicRate,
664 bNeedAck, byFBOption);
666 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
667 cbFrameLength, byPktType,
668 wCurrentRate, bNeedAck,
671 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
672 cbFrameLength, byPktType,
673 wCurrentRate, bNeedAck,
676 buf->data.duration = buf->duration_aa;
677 /* Get RTS Frame body */
678 buf->data.frame_control =
679 cpu_to_le16(IEEE80211_FTYPE_CTL |
680 IEEE80211_STYPE_RTS);
682 ether_addr_copy(buf->data.ra, hdr->addr1);
683 ether_addr_copy(buf->data.ta, hdr->addr2);
685 struct vnt_rts_g_fb *buf = pvRTS;
686 /* Get SignalField, ServiceField & Length */
687 vnt_get_phy_field(pDevice, uRTSFrameLen,
688 pDevice->byTopCCKBasicRate,
689 PK_TYPE_11B, &buf->b);
691 vnt_get_phy_field(pDevice, uRTSFrameLen,
692 pDevice->byTopOFDMBasicRate,
696 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
697 cbFrameLength, PK_TYPE_11B,
698 pDevice->byTopCCKBasicRate,
699 bNeedAck, byFBOption);
701 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
702 cbFrameLength, byPktType,
703 wCurrentRate, bNeedAck,
706 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
707 cbFrameLength, byPktType,
708 wCurrentRate, bNeedAck,
710 buf->rts_duration_ba_f0 =
711 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
712 cbFrameLength, byPktType,
713 wCurrentRate, bNeedAck,
715 buf->rts_duration_aa_f0 =
716 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
717 cbFrameLength, byPktType,
718 wCurrentRate, bNeedAck,
720 buf->rts_duration_ba_f1 =
721 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
722 cbFrameLength, byPktType,
723 wCurrentRate, bNeedAck,
725 buf->rts_duration_aa_f1 =
726 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
727 cbFrameLength, byPktType,
728 wCurrentRate, bNeedAck,
730 buf->data.duration = buf->duration_aa;
731 /* Get RTS Frame body */
732 buf->data.frame_control =
733 cpu_to_le16(IEEE80211_FTYPE_CTL |
734 IEEE80211_STYPE_RTS);
736 ether_addr_copy(buf->data.ra, hdr->addr1);
737 ether_addr_copy(buf->data.ta, hdr->addr2);
738 } /* if (byFBOption == AUTO_FB_NONE) */
739 } else if (byPktType == PK_TYPE_11A) {
740 if (byFBOption == AUTO_FB_NONE) {
741 struct vnt_rts_ab *buf = pvRTS;
742 /* Get SignalField, ServiceField & Length */
743 vnt_get_phy_field(pDevice, uRTSFrameLen,
744 pDevice->byTopOFDMBasicRate,
745 byPktType, &buf->ab);
748 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
749 cbFrameLength, byPktType,
750 wCurrentRate, bNeedAck,
752 buf->data.duration = buf->duration;
753 /* Get RTS Frame body */
754 buf->data.frame_control =
755 cpu_to_le16(IEEE80211_FTYPE_CTL |
756 IEEE80211_STYPE_RTS);
758 ether_addr_copy(buf->data.ra, hdr->addr1);
759 ether_addr_copy(buf->data.ta, hdr->addr2);
761 struct vnt_rts_a_fb *buf = pvRTS;
762 /* Get SignalField, ServiceField & Length */
763 vnt_get_phy_field(pDevice, uRTSFrameLen,
764 pDevice->byTopOFDMBasicRate,
768 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
769 cbFrameLength, byPktType,
770 wCurrentRate, bNeedAck,
772 buf->rts_duration_f0 =
773 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
774 cbFrameLength, byPktType,
775 wCurrentRate, bNeedAck,
777 buf->rts_duration_f1 =
778 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
779 cbFrameLength, byPktType,
780 wCurrentRate, bNeedAck,
782 buf->data.duration = buf->duration;
783 /* Get RTS Frame body */
784 buf->data.frame_control =
785 cpu_to_le16(IEEE80211_FTYPE_CTL |
786 IEEE80211_STYPE_RTS);
788 ether_addr_copy(buf->data.ra, hdr->addr1);
789 ether_addr_copy(buf->data.ta, hdr->addr2);
791 } else if (byPktType == PK_TYPE_11B) {
792 struct vnt_rts_ab *buf = pvRTS;
793 /* Get SignalField, ServiceField & Length */
794 vnt_get_phy_field(pDevice, uRTSFrameLen,
795 pDevice->byTopCCKBasicRate,
796 PK_TYPE_11B, &buf->ab);
799 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
800 byPktType, wCurrentRate, bNeedAck,
803 buf->data.duration = buf->duration;
804 /* Get RTS Frame body */
805 buf->data.frame_control =
806 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
808 ether_addr_copy(buf->data.ra, hdr->addr1);
809 ether_addr_copy(buf->data.ta, hdr->addr2);
816 struct vnt_private *pDevice,
817 unsigned int uDMAIdx,
818 unsigned char byPktType,
820 unsigned int cbFrameLength,
823 unsigned short wCurrentRate,
824 unsigned char byFBOption
827 unsigned int uCTSFrameLen = 14;
833 /* When CRCDIS bit is on, H/W forgot to generate FCS for
834 * CTS frame, in this case we need to decrease its length by 4.
839 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
840 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
842 struct vnt_cts_fb *buf = pvCTS;
843 /* Get SignalField, ServiceField & Length */
844 vnt_get_phy_field(pDevice, uCTSFrameLen,
845 pDevice->byTopCCKBasicRate,
846 PK_TYPE_11B, &buf->b);
849 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
850 cbFrameLength, byPktType,
851 wCurrentRate, bNeedAck,
854 /* Get CTSDuration_ba_f0 */
855 buf->cts_duration_ba_f0 =
856 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
857 cbFrameLength, byPktType,
858 wCurrentRate, bNeedAck,
861 /* Get CTSDuration_ba_f1 */
862 buf->cts_duration_ba_f1 =
863 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
864 cbFrameLength, byPktType,
865 wCurrentRate, bNeedAck,
868 /* Get CTS Frame body */
869 buf->data.duration = buf->duration_ba;
871 buf->data.frame_control =
872 cpu_to_le16(IEEE80211_FTYPE_CTL |
873 IEEE80211_STYPE_CTS);
875 buf->reserved2 = 0x0;
877 ether_addr_copy(buf->data.ra,
878 pDevice->abyCurrentNetAddr);
879 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
880 struct vnt_cts *buf = pvCTS;
881 /* Get SignalField, ServiceField & Length */
882 vnt_get_phy_field(pDevice, uCTSFrameLen,
883 pDevice->byTopCCKBasicRate,
884 PK_TYPE_11B, &buf->b);
886 /* Get CTSDuration_ba */
888 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
889 cbFrameLength, byPktType,
890 wCurrentRate, bNeedAck,
893 /* Get CTS Frame body */
894 buf->data.duration = buf->duration_ba;
896 buf->data.frame_control =
897 cpu_to_le16(IEEE80211_FTYPE_CTL |
898 IEEE80211_STYPE_CTS);
900 buf->reserved2 = 0x0;
901 ether_addr_copy(buf->data.ra,
902 pDevice->abyCurrentNetAddr);
910 * Generate FIFO control for MAC & Baseband controller
914 * pDevice - Pointer to adapter
915 * pTxDataHead - Transmit Data Buffer
916 * pTxBufHead - pTxBufHead
917 * pvRrvTime - pvRrvTime
920 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
921 * bNeedACK - If need ACK
922 * uDescIdx - Desc Index
929 * unsigned int cbFrameSize, Hdr+Payload+FCS
933 s_vGenerateTxParameter(
934 struct vnt_private *pDevice,
935 unsigned char byPktType,
936 struct vnt_tx_fifo_head *tx_buffer_head,
940 unsigned int cbFrameSize,
942 unsigned int uDMAIdx,
944 unsigned short wCurrentRate
947 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
948 bool bDisCRC = false;
949 unsigned char byFBOption = AUTO_FB_NONE;
951 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
953 if (fifo_ctl & FIFOCTL_CRCDIS)
956 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
957 byFBOption = AUTO_FB_0;
958 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
959 byFBOption = AUTO_FB_1;
964 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
965 if (pvRTS) { /* RTS_need */
967 struct vnt_rrv_time_rts *buf = pvRrvTime;
969 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
970 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
971 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
972 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
973 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
975 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
976 } else {/* RTS_needless, PCF mode */
977 struct vnt_rrv_time_cts *buf = pvRrvTime;
979 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
980 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
981 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
984 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
986 } else if (byPktType == PK_TYPE_11A) {
987 if (pvRTS) {/* RTS_need, non PCF mode */
988 struct vnt_rrv_time_ab *buf = pvRrvTime;
990 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
991 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
994 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
995 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
996 struct vnt_rrv_time_ab *buf = pvRrvTime;
998 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
1000 } else if (byPktType == PK_TYPE_11B) {
1001 if (pvRTS) {/* RTS_need, non PCF mode */
1002 struct vnt_rrv_time_ab *buf = pvRrvTime;
1004 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1005 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1008 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
1009 } else { /* RTS_needless, non PCF mode */
1010 struct vnt_rrv_time_ab *buf = pvRrvTime;
1012 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1018 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
1019 unsigned char *pbyTxBufferAddr,
1020 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
1021 unsigned int is_pspoll)
1023 struct vnt_td_info *td_info = pHeadTD->td_info;
1024 struct sk_buff *skb = td_info->skb;
1025 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1026 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1027 struct vnt_tx_fifo_head *tx_buffer_head =
1028 (struct vnt_tx_fifo_head *)td_info->buf;
1029 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
1030 unsigned int cbFrameSize;
1032 unsigned char *pbyBuffer;
1033 unsigned int uLength = 0;
1034 unsigned int cbMICHDR = 0;
1035 unsigned int uMACfragNum = 1;
1036 unsigned int uPadding = 0;
1037 unsigned int cbReqCount = 0;
1038 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1039 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
1040 struct vnt_tx_desc *ptdCurr;
1041 unsigned int cbHeaderLength = 0;
1043 struct vnt_mic_hdr *pMICHDR;
1047 unsigned short wTxBufSize; /* FFinfo size */
1048 unsigned char byFBOption = AUTO_FB_NONE;
1050 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
1052 cbFrameSize = skb->len + 4;
1054 if (info->control.hw_key) {
1055 switch (info->control.hw_key->cipher) {
1056 case WLAN_CIPHER_SUITE_CCMP:
1057 cbMICHDR = sizeof(struct vnt_mic_hdr);
1062 cbFrameSize += info->control.hw_key->icv_len;
1064 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1065 /* MAC Header should be padding 0 to DW alignment. */
1066 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1072 * Use for AUTO FALL BACK
1074 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1075 byFBOption = AUTO_FB_0;
1076 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1077 byFBOption = AUTO_FB_1;
1079 /* Set RrvTime/RTS/CTS Buffer */
1080 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1081 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1083 if (byFBOption == AUTO_FB_NONE) {
1084 if (bRTS) {/* RTS_need */
1085 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1086 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1087 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1089 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1090 cbMICHDR + sizeof(struct vnt_rts_g));
1091 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1092 cbMICHDR + sizeof(struct vnt_rts_g) +
1093 sizeof(struct vnt_tx_datahead_g);
1094 } else { /* RTS_needless */
1095 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1096 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1098 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1099 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1100 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1101 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1102 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1105 /* Auto Fall Back */
1106 if (bRTS) {/* RTS_need */
1107 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1108 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1109 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1111 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1112 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1113 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1114 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1115 } else { /* RTS_needless */
1116 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1117 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1119 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1120 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1121 cbMICHDR + sizeof(struct vnt_cts_fb));
1122 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1123 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1125 } /* Auto Fall Back */
1126 } else {/* 802.11a/b packet */
1128 if (byFBOption == AUTO_FB_NONE) {
1130 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1131 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1132 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1134 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1135 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1136 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1137 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1138 } else { /* RTS_needless, need MICHDR */
1139 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1140 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1143 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1144 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1145 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1148 /* Auto Fall Back */
1149 if (bRTS) { /* RTS_need */
1150 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1151 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1152 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1154 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1155 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1156 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1157 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1158 } else { /* RTS_needless */
1159 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1160 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1163 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1164 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1165 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1167 } /* Auto Fall Back */
1170 td_info->mic_hdr = pMICHDR;
1172 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1174 /* Fill FIFO,RrvTime,RTS,and CTS */
1175 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1176 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1178 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1179 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1181 hdr->duration_id = uDuration;
1183 cbReqCount = cbHeaderLength + uPadding + skb->len;
1184 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1185 uLength = cbHeaderLength + uPadding;
1187 /* Copy the Packet into a tx Buffer */
1188 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1192 ptdCurr->td_info->req_count = (u16)cbReqCount;
1194 return cbHeaderLength;
1197 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1198 struct ieee80211_key_conf *tx_key,
1199 struct sk_buff *skb, u16 payload_len,
1200 struct vnt_mic_hdr *mic_hdr)
1203 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1205 /* strip header and icv len from payload */
1206 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1207 payload_len -= tx_key->icv_len;
1209 switch (tx_key->cipher) {
1210 case WLAN_CIPHER_SUITE_WEP40:
1211 case WLAN_CIPHER_SUITE_WEP104:
1212 memcpy(key_buffer, iv, 3);
1213 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1215 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1216 memcpy(key_buffer + 8, iv, 3);
1217 memcpy(key_buffer + 11,
1218 tx_key->key, WLAN_KEY_LEN_WEP40);
1222 case WLAN_CIPHER_SUITE_TKIP:
1223 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1226 case WLAN_CIPHER_SUITE_CCMP:
1232 mic_hdr->payload_len = cpu_to_be16(payload_len);
1233 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1235 pn64 = atomic64_read(&tx_key->tx_pn);
1236 mic_hdr->ccmp_pn[5] = pn64;
1237 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1238 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1239 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1240 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1241 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1243 if (ieee80211_has_a4(hdr->frame_control))
1244 mic_hdr->hlen = cpu_to_be16(28);
1246 mic_hdr->hlen = cpu_to_be16(22);
1248 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1249 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1250 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1252 mic_hdr->frame_control = cpu_to_le16(
1253 le16_to_cpu(hdr->frame_control) & 0xc78f);
1254 mic_hdr->seq_ctrl = cpu_to_le16(
1255 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1257 if (ieee80211_has_a4(hdr->frame_control))
1258 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1260 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1268 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1269 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1271 struct vnt_td_info *td_info = head_td->td_info;
1272 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1273 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1274 struct ieee80211_rate *rate;
1275 struct ieee80211_key_conf *tx_key;
1276 struct ieee80211_hdr *hdr;
1277 struct vnt_tx_fifo_head *tx_buffer_head =
1278 (struct vnt_tx_fifo_head *)td_info->buf;
1279 u16 tx_body_size = skb->len, current_rate;
1281 bool is_pspoll = false;
1283 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1285 hdr = (struct ieee80211_hdr *)(skb->data);
1287 rate = ieee80211_get_tx_rate(priv->hw, info);
1289 current_rate = rate->hw_value;
1290 if (priv->wCurrentRate != current_rate &&
1291 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1292 priv->wCurrentRate = current_rate;
1294 RFbSetPower(priv, priv->wCurrentRate,
1295 priv->hw->conf.chandef.chan->hw_value);
1298 if (current_rate > RATE_11M) {
1299 if (info->band == NL80211_BAND_5GHZ) {
1300 pkt_type = PK_TYPE_11A;
1302 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1303 pkt_type = PK_TYPE_11GB;
1305 pkt_type = PK_TYPE_11GA;
1308 pkt_type = PK_TYPE_11B;
1311 /*Set fifo controls */
1312 if (pkt_type == PK_TYPE_11A)
1313 tx_buffer_head->fifo_ctl = 0;
1314 else if (pkt_type == PK_TYPE_11B)
1315 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1316 else if (pkt_type == PK_TYPE_11GB)
1317 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1318 else if (pkt_type == PK_TYPE_11GA)
1319 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1321 /* generate interrupt */
1322 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1324 if (!ieee80211_is_data(hdr->frame_control)) {
1325 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1326 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1327 tx_buffer_head->time_stamp =
1328 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1330 tx_buffer_head->time_stamp =
1331 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1334 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1335 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1337 if (ieee80211_has_retry(hdr->frame_control))
1338 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1340 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1341 priv->byPreambleType = PREAMBLE_SHORT;
1343 priv->byPreambleType = PREAMBLE_LONG;
1345 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1346 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1348 if (ieee80211_has_a4(hdr->frame_control)) {
1349 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1350 priv->bLongHeader = true;
1353 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1356 tx_buffer_head->frag_ctl =
1357 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1359 if (info->control.hw_key) {
1360 tx_key = info->control.hw_key;
1362 switch (info->control.hw_key->cipher) {
1363 case WLAN_CIPHER_SUITE_WEP40:
1364 case WLAN_CIPHER_SUITE_WEP104:
1365 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1367 case WLAN_CIPHER_SUITE_TKIP:
1368 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1370 case WLAN_CIPHER_SUITE_CCMP:
1371 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1377 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1379 /* legacy rates TODO use ieee80211_tx_rate */
1380 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1381 if (priv->byAutoFBCtrl == AUTO_FB_0)
1382 tx_buffer_head->fifo_ctl |=
1383 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1384 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1385 tx_buffer_head->fifo_ctl |=
1386 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1389 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1391 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1392 dma_idx, head_td, is_pspoll);
1394 if (info->control.hw_key) {
1395 tx_key = info->control.hw_key;
1396 if (tx_key->keylen > 0)
1397 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1398 tx_key, skb, tx_body_size, td_info->mic_hdr);
1404 static int vnt_beacon_xmit(struct vnt_private *priv,
1405 struct sk_buff *skb)
1407 struct vnt_tx_short_buf_head *short_head =
1408 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1409 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1410 (priv->tx_beacon_bufs + sizeof(*short_head));
1411 struct ieee80211_tx_info *info;
1412 u32 frame_size = skb->len + 4;
1415 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1417 if (priv->byBBType == BB_TYPE_11A) {
1418 current_rate = RATE_6M;
1420 /* Get SignalField,ServiceField,Length */
1421 vnt_get_phy_field(priv, frame_size, current_rate,
1422 PK_TYPE_11A, &short_head->ab);
1424 /* Get Duration and TimeStampOff */
1425 short_head->duration =
1426 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1427 frame_size, PK_TYPE_11A, current_rate,
1428 false, 0, 0, 1, AUTO_FB_NONE));
1430 short_head->time_stamp_off =
1431 vnt_time_stamp_off(priv, current_rate);
1433 current_rate = RATE_1M;
1434 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1436 /* Get SignalField,ServiceField,Length */
1437 vnt_get_phy_field(priv, frame_size, current_rate,
1438 PK_TYPE_11B, &short_head->ab);
1440 /* Get Duration and TimeStampOff */
1441 short_head->duration =
1442 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1443 frame_size, PK_TYPE_11B, current_rate,
1444 false, 0, 0, 1, AUTO_FB_NONE));
1446 short_head->time_stamp_off =
1447 vnt_time_stamp_off(priv, current_rate);
1450 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1453 memcpy(mgmt_hdr, skb->data, skb->len);
1455 /* time stamp always 0 */
1456 mgmt_hdr->u.beacon.timestamp = 0;
1458 info = IEEE80211_SKB_CB(skb);
1459 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1460 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1462 hdr->duration_id = 0;
1463 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1466 priv->wSeqCounter++;
1467 if (priv->wSeqCounter > 0x0fff)
1468 priv->wSeqCounter = 0;
1470 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1472 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1474 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1475 /* Set auto Transmit on */
1476 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1477 /* Poll Transmit the adapter */
1478 MACvTransmitBCN(priv->PortOffset);
1483 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1485 struct sk_buff *beacon;
1487 beacon = ieee80211_beacon_get(priv->hw, vif);
1491 if (vnt_beacon_xmit(priv, beacon)) {
1492 ieee80211_free_txskb(priv->hw, beacon);
1499 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1500 struct ieee80211_bss_conf *conf)
1502 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1504 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1506 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1508 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1510 return vnt_beacon_make(priv, vif);