1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
6 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
13 * s_vGenerateTxParameter - Generate tx dma required parameter.
14 * vGenerateMACHeader - Translate 802.3 to 802.11 header
15 * cbGetFragCount - Calculate fragment number count
16 * csBeacon_xmit - beacon tx function
17 * csMgmt_xmit - management tx function
18 * s_cbFillTxBufHead - fulfill tx dma buffer header
19 * s_uGetDataDuration - get tx data required duration
20 * s_uFillDataHead- fulfill tx data duration header
21 * s_uGetRTSCTSDuration- get rtx/cts required duration
22 * get_rtscts_time- get rts/cts reserved time
23 * s_uGetTxRsvTime- get frame reserved time
24 * s_vFillCTSHead- fulfill CTS ctl header
25 * s_vFillFragParameter- Set fragment ctl parameter.
26 * s_vFillRTSHead- fulfill RTS ctl header
27 * s_vFillTxKey- fulfill tx encrypt key
28 * s_vSWencryption- Software encrypt header
29 * vDMA0_tx_80211- tx 802.11 frame via dma0
30 * vGenerateFIFOHeader- Generate tx FIFO ctl header
43 /*--------------------- Static Definitions -------------------------*/
45 /*--------------------- Static Classes ----------------------------*/
47 /*--------------------- Static Variables --------------------------*/
49 /*--------------------- Static Functions --------------------------*/
51 /*--------------------- Static Definitions -------------------------*/
52 /* if packet size < 256 -> in-direct send
53 * vpacket size >= 256 -> direct send
55 #define CRITICAL_PACKET_LEN 256
57 static const unsigned short time_stamp_off[2][MAX_RATE] = {
58 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
59 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
62 static const unsigned short fb_opt0[2][5] = {
63 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
64 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
67 static const unsigned short fb_opt1[2][5] = {
68 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
69 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
76 #define RTSDUR_BA_F0 4
77 #define RTSDUR_AA_F0 5
78 #define RTSDUR_BA_F1 6
79 #define RTSDUR_AA_F1 7
80 #define CTSDUR_BA_F0 8
81 #define CTSDUR_BA_F1 9
84 #define DATADUR_A_F0 12
85 #define DATADUR_A_F1 13
87 /*--------------------- Static Functions --------------------------*/
91 struct vnt_private *pDevice,
92 unsigned char byPktType,
94 unsigned int cbFrameLength,
97 struct ieee80211_hdr *hdr,
98 unsigned short wCurrentRate,
99 unsigned char byFBOption
104 s_vGenerateTxParameter(
105 struct vnt_private *pDevice,
106 unsigned char byPktType,
107 struct vnt_tx_fifo_head *,
111 unsigned int cbFrameSize,
113 unsigned int uDMAIdx,
115 unsigned short wCurrentRate
119 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
120 unsigned char *pbyTxBufferAddr,
121 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
122 unsigned int uNodeIndex);
127 struct vnt_private *pDevice,
128 unsigned char byPktType,
130 unsigned int cbFrameLength,
131 unsigned int uDMAIdx,
133 unsigned int uFragIdx,
134 unsigned int cbLastFragmentSize,
135 unsigned int uMACfragNum,
136 unsigned char byFBOption,
137 unsigned short wCurrentRate,
141 /*--------------------- Export Variables --------------------------*/
143 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
145 return cpu_to_le16(time_stamp_off[priv->preamble_type % 2]
149 /* byPktType : PK_TYPE_11A 0
157 struct vnt_private *pDevice,
158 unsigned char byPktType,
159 unsigned int cbFrameLength,
160 unsigned short wRate,
164 unsigned int uDataTime, uAckTime;
166 uDataTime = bb_get_frame_time(pDevice->preamble_type, byPktType, cbFrameLength, wRate);
173 * OFDM mode - 11g 2.4G & 11a 5G
175 uAckTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14,
176 byPktType == PK_TYPE_11B ?
177 pDevice->byTopCCKBasicRate :
178 pDevice->byTopOFDMBasicRate);
180 return uDataTime + pDevice->uSIFS + uAckTime;
183 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
184 u32 frame_length, u16 rate, bool need_ack)
186 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
187 frame_length, rate, need_ack));
190 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
191 static __le16 get_rtscts_time(struct vnt_private *priv,
192 unsigned char rts_rsvtype,
193 unsigned char pkt_type,
194 unsigned int frame_length,
195 unsigned short current_rate)
197 unsigned int rrv_time = 0;
198 unsigned int rts_time = 0;
199 unsigned int cts_time = 0;
200 unsigned int ack_time = 0;
201 unsigned int data_time = 0;
203 data_time = bb_get_frame_time(priv->preamble_type, pkt_type, frame_length, current_rate);
204 if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */
205 rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);
206 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
208 } else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
209 rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopCCKBasicRate);
210 cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
211 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
212 } else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */
213 rts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 20, priv->byTopOFDMBasicRate);
214 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
216 } else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
217 cts_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopCCKBasicRate);
218 ack_time = bb_get_frame_time(priv->preamble_type, pkt_type, 14, priv->byTopOFDMBasicRate);
219 rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;
220 return cpu_to_le16((u16)rrv_time);
224 rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;
225 return cpu_to_le16((u16)rrv_time);
228 /* byFreqType 0: 5GHz, 1:2.4Ghz */
232 struct vnt_private *pDevice,
233 unsigned char byDurType,
234 unsigned int cbFrameLength,
235 unsigned char byPktType,
236 unsigned short wRate,
238 unsigned int uFragIdx,
239 unsigned int cbLastFragmentSize,
240 unsigned int uMACfragNum,
241 unsigned char byFBOption
244 bool bLastFrag = false;
245 unsigned int uAckTime = 0, uNextPktTime = 0, len;
247 if (uFragIdx == (uMACfragNum - 1))
250 if (uFragIdx == (uMACfragNum - 2))
251 len = cbLastFragmentSize;
256 case DATADUR_B: /* DATADUR_B */
258 uAckTime = bb_get_frame_time(pDevice->preamble_type,
260 pDevice->byTopCCKBasicRate);
262 /* Non Frag or Last Frag */
263 if ((uMACfragNum == 1) || bLastFrag) {
267 /* First Frag or Mid Frag */
268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
269 len, wRate, bNeedAck);
272 return pDevice->uSIFS + uAckTime + uNextPktTime;
274 case DATADUR_A: /* DATADUR_A */
276 uAckTime = bb_get_frame_time(pDevice->preamble_type,
278 pDevice->byTopOFDMBasicRate);
280 /* Non Frag or Last Frag */
281 if ((uMACfragNum == 1) || bLastFrag) {
285 /* First Frag or Mid Frag */
286 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
287 len, wRate, bNeedAck);
290 return pDevice->uSIFS + uAckTime + uNextPktTime;
292 case DATADUR_A_F0: /* DATADUR_A_F0 */
293 case DATADUR_A_F1: /* DATADUR_A_F1 */
295 uAckTime = bb_get_frame_time(pDevice->preamble_type,
297 pDevice->byTopOFDMBasicRate);
299 /* Non Frag or Last Frag */
300 if ((uMACfragNum == 1) || bLastFrag) {
304 /* First Frag or Mid Frag */
305 if (wRate < RATE_18M)
307 else if (wRate > RATE_54M)
312 if (byFBOption == AUTO_FB_0)
313 wRate = fb_opt0[FB_RATE0][wRate];
315 wRate = fb_opt1[FB_RATE0][wRate];
317 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
318 len, wRate, bNeedAck);
321 return pDevice->uSIFS + uAckTime + uNextPktTime;
330 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
333 s_uGetRTSCTSDuration(
334 struct vnt_private *pDevice,
335 unsigned char byDurType,
336 unsigned int cbFrameLength,
337 unsigned char byPktType,
338 unsigned short wRate,
340 unsigned char byFBOption
343 unsigned int uCTSTime = 0, uDurTime = 0;
346 case RTSDUR_BB: /* RTSDuration_bb */
347 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
348 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
351 case RTSDUR_BA: /* RTSDuration_ba */
352 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
353 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
356 case RTSDUR_AA: /* RTSDuration_aa */
357 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
358 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
361 case CTSDUR_BA: /* CTSDuration_ba */
362 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
365 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
366 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
367 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
368 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
369 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
370 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
374 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
375 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
376 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
377 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
378 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
379 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
383 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
384 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopCCKBasicRate);
385 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
386 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
387 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
388 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
392 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
393 uCTSTime = bb_get_frame_time(pDevice->preamble_type, byPktType, 14, pDevice->byTopOFDMBasicRate);
394 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
395 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
396 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
397 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
401 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
402 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
403 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
404 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
405 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
409 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
410 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
411 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
412 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
413 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, fb_opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
421 return cpu_to_le16((u16)uDurTime);
427 struct vnt_private *pDevice,
428 unsigned char byPktType,
430 unsigned int cbFrameLength,
431 unsigned int uDMAIdx,
433 unsigned int uFragIdx,
434 unsigned int cbLastFragmentSize,
435 unsigned int uMACfragNum,
436 unsigned char byFBOption,
437 unsigned short wCurrentRate,
441 struct vnt_tx_datahead_ab *buf = pTxDataHead;
446 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
448 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
450 if (byFBOption == AUTO_FB_NONE) {
451 struct vnt_tx_datahead_g *buf = pTxDataHead;
452 /* Get SignalField, ServiceField & Length */
453 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
456 vnt_get_phy_field(pDevice, cbFrameLength,
457 pDevice->byTopCCKBasicRate,
458 PK_TYPE_11B, &buf->b);
461 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
463 buf->duration_a = dur;
464 buf->duration_b = dur;
466 /* Get Duration and TimeStamp */
468 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
469 byPktType, wCurrentRate, bNeedAck, uFragIdx,
470 cbLastFragmentSize, uMACfragNum,
473 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
474 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
475 bNeedAck, uFragIdx, cbLastFragmentSize,
476 uMACfragNum, byFBOption));
479 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
480 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
482 return buf->duration_a;
485 /* Get SignalField, ServiceField & Length */
486 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
489 vnt_get_phy_field(pDevice, cbFrameLength,
490 pDevice->byTopCCKBasicRate,
491 PK_TYPE_11B, &buf->b);
492 /* Get Duration and TimeStamp */
493 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
494 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
495 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
496 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
497 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
498 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
499 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
500 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
502 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
503 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
505 return buf->duration_a;
506 /* if (byFBOption == AUTO_FB_NONE) */
507 } else if (byPktType == PK_TYPE_11A) {
508 struct vnt_tx_datahead_ab *buf = pTxDataHead;
510 if (byFBOption != AUTO_FB_NONE) {
512 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
513 /* Get SignalField, ServiceField & Length */
514 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
517 /* Get Duration and TimeStampOff */
518 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
519 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
520 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
521 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
522 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
523 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
524 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
525 return buf->duration;
528 /* Get SignalField, ServiceField & Length */
529 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
530 byPktType, &buf->ab);
533 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
537 /* Get Duration and TimeStampOff */
539 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
540 wCurrentRate, bNeedAck, uFragIdx,
541 cbLastFragmentSize, uMACfragNum,
545 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
546 return buf->duration;
549 /* Get SignalField, ServiceField & Length */
550 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
551 byPktType, &buf->ab);
554 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
558 /* Get Duration and TimeStampOff */
560 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
561 wCurrentRate, bNeedAck, uFragIdx,
562 cbLastFragmentSize, uMACfragNum,
566 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
567 return buf->duration;
573 struct vnt_private *pDevice,
574 unsigned char byPktType,
576 unsigned int cbFrameLength,
579 struct ieee80211_hdr *hdr,
580 unsigned short wCurrentRate,
581 unsigned char byFBOption
584 unsigned int uRTSFrameLen = 20;
590 /* When CRCDIS bit is on, H/W forgot to generate FCS for
591 * RTS frame, in this case we need to decrease its length by 4.
596 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
597 * so we don't need to take them into account.
598 * Otherwise, we need to modify codes for them.
600 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
601 if (byFBOption == AUTO_FB_NONE) {
602 struct vnt_rts_g *buf = pvRTS;
603 /* Get SignalField, ServiceField & Length */
604 vnt_get_phy_field(pDevice, uRTSFrameLen,
605 pDevice->byTopCCKBasicRate,
606 PK_TYPE_11B, &buf->b);
608 vnt_get_phy_field(pDevice, uRTSFrameLen,
609 pDevice->byTopOFDMBasicRate,
613 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
614 cbFrameLength, PK_TYPE_11B,
615 pDevice->byTopCCKBasicRate,
616 bNeedAck, byFBOption);
618 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
619 cbFrameLength, byPktType,
620 wCurrentRate, bNeedAck,
623 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
624 cbFrameLength, byPktType,
625 wCurrentRate, bNeedAck,
628 buf->data.duration = buf->duration_aa;
629 /* Get RTS Frame body */
630 buf->data.frame_control =
631 cpu_to_le16(IEEE80211_FTYPE_CTL |
632 IEEE80211_STYPE_RTS);
634 ether_addr_copy(buf->data.ra, hdr->addr1);
635 ether_addr_copy(buf->data.ta, hdr->addr2);
637 struct vnt_rts_g_fb *buf = pvRTS;
638 /* Get SignalField, ServiceField & Length */
639 vnt_get_phy_field(pDevice, uRTSFrameLen,
640 pDevice->byTopCCKBasicRate,
641 PK_TYPE_11B, &buf->b);
643 vnt_get_phy_field(pDevice, uRTSFrameLen,
644 pDevice->byTopOFDMBasicRate,
648 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
649 cbFrameLength, PK_TYPE_11B,
650 pDevice->byTopCCKBasicRate,
651 bNeedAck, byFBOption);
653 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
654 cbFrameLength, byPktType,
655 wCurrentRate, bNeedAck,
658 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
659 cbFrameLength, byPktType,
660 wCurrentRate, bNeedAck,
662 buf->rts_duration_ba_f0 =
663 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
664 cbFrameLength, byPktType,
665 wCurrentRate, bNeedAck,
667 buf->rts_duration_aa_f0 =
668 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
669 cbFrameLength, byPktType,
670 wCurrentRate, bNeedAck,
672 buf->rts_duration_ba_f1 =
673 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
674 cbFrameLength, byPktType,
675 wCurrentRate, bNeedAck,
677 buf->rts_duration_aa_f1 =
678 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
679 cbFrameLength, byPktType,
680 wCurrentRate, bNeedAck,
682 buf->data.duration = buf->duration_aa;
683 /* Get RTS Frame body */
684 buf->data.frame_control =
685 cpu_to_le16(IEEE80211_FTYPE_CTL |
686 IEEE80211_STYPE_RTS);
688 ether_addr_copy(buf->data.ra, hdr->addr1);
689 ether_addr_copy(buf->data.ta, hdr->addr2);
690 } /* if (byFBOption == AUTO_FB_NONE) */
691 } else if (byPktType == PK_TYPE_11A) {
692 if (byFBOption == AUTO_FB_NONE) {
693 struct vnt_rts_ab *buf = pvRTS;
694 /* Get SignalField, ServiceField & Length */
695 vnt_get_phy_field(pDevice, uRTSFrameLen,
696 pDevice->byTopOFDMBasicRate,
697 byPktType, &buf->ab);
700 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
701 cbFrameLength, byPktType,
702 wCurrentRate, bNeedAck,
704 buf->data.duration = buf->duration;
705 /* Get RTS Frame body */
706 buf->data.frame_control =
707 cpu_to_le16(IEEE80211_FTYPE_CTL |
708 IEEE80211_STYPE_RTS);
710 ether_addr_copy(buf->data.ra, hdr->addr1);
711 ether_addr_copy(buf->data.ta, hdr->addr2);
713 struct vnt_rts_a_fb *buf = pvRTS;
714 /* Get SignalField, ServiceField & Length */
715 vnt_get_phy_field(pDevice, uRTSFrameLen,
716 pDevice->byTopOFDMBasicRate,
720 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
721 cbFrameLength, byPktType,
722 wCurrentRate, bNeedAck,
724 buf->rts_duration_f0 =
725 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
726 cbFrameLength, byPktType,
727 wCurrentRate, bNeedAck,
729 buf->rts_duration_f1 =
730 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
731 cbFrameLength, byPktType,
732 wCurrentRate, bNeedAck,
734 buf->data.duration = buf->duration;
735 /* Get RTS Frame body */
736 buf->data.frame_control =
737 cpu_to_le16(IEEE80211_FTYPE_CTL |
738 IEEE80211_STYPE_RTS);
740 ether_addr_copy(buf->data.ra, hdr->addr1);
741 ether_addr_copy(buf->data.ta, hdr->addr2);
743 } else if (byPktType == PK_TYPE_11B) {
744 struct vnt_rts_ab *buf = pvRTS;
745 /* Get SignalField, ServiceField & Length */
746 vnt_get_phy_field(pDevice, uRTSFrameLen,
747 pDevice->byTopCCKBasicRate,
748 PK_TYPE_11B, &buf->ab);
751 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
752 byPktType, wCurrentRate, bNeedAck,
755 buf->data.duration = buf->duration;
756 /* Get RTS Frame body */
757 buf->data.frame_control =
758 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
760 ether_addr_copy(buf->data.ra, hdr->addr1);
761 ether_addr_copy(buf->data.ta, hdr->addr2);
768 struct vnt_private *pDevice,
769 unsigned int uDMAIdx,
770 unsigned char byPktType,
772 unsigned int cbFrameLength,
775 unsigned short wCurrentRate,
776 unsigned char byFBOption
779 unsigned int uCTSFrameLen = 14;
785 /* When CRCDIS bit is on, H/W forgot to generate FCS for
786 * CTS frame, in this case we need to decrease its length by 4.
791 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
792 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
794 struct vnt_cts_fb *buf = pvCTS;
795 /* Get SignalField, ServiceField & Length */
796 vnt_get_phy_field(pDevice, uCTSFrameLen,
797 pDevice->byTopCCKBasicRate,
798 PK_TYPE_11B, &buf->b);
801 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
802 cbFrameLength, byPktType,
803 wCurrentRate, bNeedAck,
806 /* Get CTSDuration_ba_f0 */
807 buf->cts_duration_ba_f0 =
808 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
809 cbFrameLength, byPktType,
810 wCurrentRate, bNeedAck,
813 /* Get CTSDuration_ba_f1 */
814 buf->cts_duration_ba_f1 =
815 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
816 cbFrameLength, byPktType,
817 wCurrentRate, bNeedAck,
820 /* Get CTS Frame body */
821 buf->data.duration = buf->duration_ba;
823 buf->data.frame_control =
824 cpu_to_le16(IEEE80211_FTYPE_CTL |
825 IEEE80211_STYPE_CTS);
827 buf->reserved2 = 0x0;
829 ether_addr_copy(buf->data.ra,
830 pDevice->abyCurrentNetAddr);
831 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
832 struct vnt_cts *buf = pvCTS;
833 /* Get SignalField, ServiceField & Length */
834 vnt_get_phy_field(pDevice, uCTSFrameLen,
835 pDevice->byTopCCKBasicRate,
836 PK_TYPE_11B, &buf->b);
838 /* Get CTSDuration_ba */
840 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
841 cbFrameLength, byPktType,
842 wCurrentRate, bNeedAck,
845 /* Get CTS Frame body */
846 buf->data.duration = buf->duration_ba;
848 buf->data.frame_control =
849 cpu_to_le16(IEEE80211_FTYPE_CTL |
850 IEEE80211_STYPE_CTS);
852 buf->reserved2 = 0x0;
853 ether_addr_copy(buf->data.ra,
854 pDevice->abyCurrentNetAddr);
862 * Generate FIFO control for MAC & Baseband controller
866 * pDevice - Pointer to adapter
867 * pTxDataHead - Transmit Data Buffer
868 * pTxBufHead - pTxBufHead
869 * pvRrvTime - pvRrvTime
872 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
873 * bNeedACK - If need ACK
874 * uDescIdx - Desc Index
881 * unsigned int cbFrameSize, Hdr+Payload+FCS
885 s_vGenerateTxParameter(
886 struct vnt_private *pDevice,
887 unsigned char byPktType,
888 struct vnt_tx_fifo_head *tx_buffer_head,
892 unsigned int cbFrameSize,
894 unsigned int uDMAIdx,
896 unsigned short wCurrentRate
899 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
900 bool bDisCRC = false;
901 unsigned char byFBOption = AUTO_FB_NONE;
903 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
905 if (fifo_ctl & FIFOCTL_CRCDIS)
908 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
909 byFBOption = AUTO_FB_0;
910 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
911 byFBOption = AUTO_FB_1;
916 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
917 if (pvRTS) { /* RTS_need */
919 struct vnt_rrv_time_rts *buf = pvRrvTime;
921 buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
922 buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
923 buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
924 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
925 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
927 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
928 } else {/* RTS_needless, PCF mode */
929 struct vnt_rrv_time_cts *buf = pvRrvTime;
931 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
932 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
933 buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
936 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
938 } else if (byPktType == PK_TYPE_11A) {
939 if (pvRTS) {/* RTS_need, non PCF mode */
940 struct vnt_rrv_time_ab *buf = pvRrvTime;
942 buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
943 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
946 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
947 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
948 struct vnt_rrv_time_ab *buf = pvRrvTime;
950 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
952 } else if (byPktType == PK_TYPE_11B) {
953 if (pvRTS) {/* RTS_need, non PCF mode */
954 struct vnt_rrv_time_ab *buf = pvRrvTime;
956 buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
957 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
960 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
961 } else { /* RTS_needless, non PCF mode */
962 struct vnt_rrv_time_ab *buf = pvRrvTime;
964 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
970 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
971 unsigned char *pbyTxBufferAddr,
972 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
973 unsigned int is_pspoll)
975 struct vnt_td_info *td_info = pHeadTD->td_info;
976 struct sk_buff *skb = td_info->skb;
977 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
978 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
979 struct vnt_tx_fifo_head *tx_buffer_head =
980 (struct vnt_tx_fifo_head *)td_info->buf;
981 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
982 unsigned int cbFrameSize;
984 unsigned char *pbyBuffer;
985 unsigned int uLength = 0;
986 unsigned int cbMICHDR = 0;
987 unsigned int uMACfragNum = 1;
988 unsigned int uPadding = 0;
989 unsigned int cbReqCount = 0;
990 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
991 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
992 struct vnt_tx_desc *ptdCurr;
993 unsigned int cbHeaderLength = 0;
994 void *pvRrvTime = NULL;
995 struct vnt_mic_hdr *pMICHDR = NULL;
998 void *pvTxDataHd = NULL;
999 unsigned short wTxBufSize; /* FFinfo size */
1000 unsigned char byFBOption = AUTO_FB_NONE;
1002 cbFrameSize = skb->len + 4;
1004 if (info->control.hw_key) {
1005 switch (info->control.hw_key->cipher) {
1006 case WLAN_CIPHER_SUITE_CCMP:
1007 cbMICHDR = sizeof(struct vnt_mic_hdr);
1013 cbFrameSize += info->control.hw_key->icv_len;
1015 if (pDevice->local_id > REV_ID_VT3253_A1) {
1016 /* MAC Header should be padding 0 to DW alignment. */
1017 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1023 * Use for AUTO FALL BACK
1025 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1026 byFBOption = AUTO_FB_0;
1027 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1028 byFBOption = AUTO_FB_1;
1030 /* Set RrvTime/RTS/CTS Buffer */
1031 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1032 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1034 if (byFBOption == AUTO_FB_NONE) {
1035 if (bRTS) {/* RTS_need */
1036 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1037 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1038 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1040 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1041 cbMICHDR + sizeof(struct vnt_rts_g));
1042 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1043 cbMICHDR + sizeof(struct vnt_rts_g) +
1044 sizeof(struct vnt_tx_datahead_g);
1045 } else { /* RTS_needless */
1046 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1047 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1049 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1050 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1051 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1052 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1053 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1056 /* Auto Fall Back */
1057 if (bRTS) {/* RTS_need */
1058 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1059 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1060 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1062 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1063 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1064 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1065 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1066 } else { /* RTS_needless */
1067 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1068 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1070 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1071 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1072 cbMICHDR + sizeof(struct vnt_cts_fb));
1073 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1074 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1076 } /* Auto Fall Back */
1077 } else {/* 802.11a/b packet */
1079 if (byFBOption == AUTO_FB_NONE) {
1081 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1082 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1083 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1085 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1086 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1087 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1088 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1089 } else { /* RTS_needless, need MICHDR */
1090 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1091 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1094 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1095 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1096 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1099 /* Auto Fall Back */
1100 if (bRTS) { /* RTS_need */
1101 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1102 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1103 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1105 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1106 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1107 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1108 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1109 } else { /* RTS_needless */
1110 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1111 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1114 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1115 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1116 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1118 } /* Auto Fall Back */
1121 td_info->mic_hdr = pMICHDR;
1123 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1125 /* Fill FIFO,RrvTime,RTS,and CTS */
1126 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1127 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1129 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1130 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1132 hdr->duration_id = uDuration;
1134 cbReqCount = cbHeaderLength + uPadding + skb->len;
1135 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1136 uLength = cbHeaderLength + uPadding;
1138 /* Copy the Packet into a tx Buffer */
1139 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1143 ptdCurr->td_info->req_count = (u16)cbReqCount;
1145 return cbHeaderLength;
1148 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1149 struct ieee80211_key_conf *tx_key,
1150 struct sk_buff *skb, u16 payload_len,
1151 struct vnt_mic_hdr *mic_hdr)
1154 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1156 /* strip header and icv len from payload */
1157 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1158 payload_len -= tx_key->icv_len;
1160 switch (tx_key->cipher) {
1161 case WLAN_CIPHER_SUITE_WEP40:
1162 case WLAN_CIPHER_SUITE_WEP104:
1163 memcpy(key_buffer, iv, 3);
1164 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1166 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1167 memcpy(key_buffer + 8, iv, 3);
1168 memcpy(key_buffer + 11,
1169 tx_key->key, WLAN_KEY_LEN_WEP40);
1173 case WLAN_CIPHER_SUITE_TKIP:
1174 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1177 case WLAN_CIPHER_SUITE_CCMP:
1183 mic_hdr->payload_len = cpu_to_be16(payload_len);
1184 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1186 pn64 = atomic64_read(&tx_key->tx_pn);
1187 mic_hdr->ccmp_pn[5] = pn64;
1188 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1189 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1190 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1191 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1192 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1194 if (ieee80211_has_a4(hdr->frame_control))
1195 mic_hdr->hlen = cpu_to_be16(28);
1197 mic_hdr->hlen = cpu_to_be16(22);
1199 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1200 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1201 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1203 mic_hdr->frame_control = cpu_to_le16(
1204 le16_to_cpu(hdr->frame_control) & 0xc78f);
1205 mic_hdr->seq_ctrl = cpu_to_le16(
1206 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1208 if (ieee80211_has_a4(hdr->frame_control))
1209 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1211 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1219 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1220 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1222 struct vnt_td_info *td_info = head_td->td_info;
1223 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1224 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1225 struct ieee80211_rate *rate;
1226 struct ieee80211_key_conf *tx_key;
1227 struct ieee80211_hdr *hdr;
1228 struct vnt_tx_fifo_head *tx_buffer_head =
1229 (struct vnt_tx_fifo_head *)td_info->buf;
1230 u16 tx_body_size = skb->len, current_rate;
1232 bool is_pspoll = false;
1234 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1236 hdr = (struct ieee80211_hdr *)(skb->data);
1238 rate = ieee80211_get_tx_rate(priv->hw, info);
1240 current_rate = rate->hw_value;
1241 if (priv->wCurrentRate != current_rate &&
1242 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1243 priv->wCurrentRate = current_rate;
1245 RFbSetPower(priv, priv->wCurrentRate,
1246 priv->hw->conf.chandef.chan->hw_value);
1249 if (current_rate > RATE_11M) {
1250 if (info->band == NL80211_BAND_5GHZ) {
1251 pkt_type = PK_TYPE_11A;
1253 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1254 pkt_type = PK_TYPE_11GB;
1256 pkt_type = PK_TYPE_11GA;
1259 pkt_type = PK_TYPE_11B;
1262 /*Set fifo controls */
1263 if (pkt_type == PK_TYPE_11A)
1264 tx_buffer_head->fifo_ctl = 0;
1265 else if (pkt_type == PK_TYPE_11B)
1266 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1267 else if (pkt_type == PK_TYPE_11GB)
1268 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1269 else if (pkt_type == PK_TYPE_11GA)
1270 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1272 /* generate interrupt */
1273 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1275 if (!ieee80211_is_data(hdr->frame_control)) {
1276 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1277 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1278 tx_buffer_head->time_stamp =
1279 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1281 tx_buffer_head->time_stamp =
1282 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1285 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1286 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1288 if (ieee80211_has_retry(hdr->frame_control))
1289 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1291 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1292 priv->preamble_type = PREAMBLE_SHORT;
1294 priv->preamble_type = PREAMBLE_LONG;
1296 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1297 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1299 if (ieee80211_has_a4(hdr->frame_control)) {
1300 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1301 priv->bLongHeader = true;
1304 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1307 tx_buffer_head->frag_ctl =
1308 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1310 if (info->control.hw_key) {
1311 switch (info->control.hw_key->cipher) {
1312 case WLAN_CIPHER_SUITE_WEP40:
1313 case WLAN_CIPHER_SUITE_WEP104:
1314 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1316 case WLAN_CIPHER_SUITE_TKIP:
1317 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1319 case WLAN_CIPHER_SUITE_CCMP:
1320 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1327 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1329 /* legacy rates TODO use ieee80211_tx_rate */
1330 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1331 if (priv->byAutoFBCtrl == AUTO_FB_0)
1332 tx_buffer_head->fifo_ctl |=
1333 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1334 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1335 tx_buffer_head->fifo_ctl |=
1336 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1339 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1341 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1342 dma_idx, head_td, is_pspoll);
1344 if (info->control.hw_key) {
1345 tx_key = info->control.hw_key;
1346 if (tx_key->keylen > 0)
1347 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1348 tx_key, skb, tx_body_size,
1355 static int vnt_beacon_xmit(struct vnt_private *priv,
1356 struct sk_buff *skb)
1358 struct vnt_tx_short_buf_head *short_head =
1359 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1360 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1361 (priv->tx_beacon_bufs + sizeof(*short_head));
1362 struct ieee80211_tx_info *info;
1363 u32 frame_size = skb->len + 4;
1366 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1368 if (priv->byBBType == BB_TYPE_11A) {
1369 current_rate = RATE_6M;
1371 /* Get SignalField,ServiceField,Length */
1372 vnt_get_phy_field(priv, frame_size, current_rate,
1373 PK_TYPE_11A, &short_head->ab);
1375 /* Get Duration and TimeStampOff */
1376 short_head->duration =
1377 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1378 frame_size, PK_TYPE_11A, current_rate,
1379 false, 0, 0, 1, AUTO_FB_NONE));
1381 short_head->time_stamp_off =
1382 vnt_time_stamp_off(priv, current_rate);
1384 current_rate = RATE_1M;
1385 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1387 /* Get SignalField,ServiceField,Length */
1388 vnt_get_phy_field(priv, frame_size, current_rate,
1389 PK_TYPE_11B, &short_head->ab);
1391 /* Get Duration and TimeStampOff */
1392 short_head->duration =
1393 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1394 frame_size, PK_TYPE_11B, current_rate,
1395 false, 0, 0, 1, AUTO_FB_NONE));
1397 short_head->time_stamp_off =
1398 vnt_time_stamp_off(priv, current_rate);
1401 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1404 memcpy(mgmt_hdr, skb->data, skb->len);
1406 /* time stamp always 0 */
1407 mgmt_hdr->u.beacon.timestamp = 0;
1409 info = IEEE80211_SKB_CB(skb);
1410 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1411 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1413 hdr->duration_id = 0;
1414 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1417 priv->wSeqCounter++;
1418 if (priv->wSeqCounter > 0x0fff)
1419 priv->wSeqCounter = 0;
1421 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1423 iowrite32((u32)priv->tx_beacon_dma, priv->port_offset + MAC_REG_BCNDMAPTR);
1425 iowrite16(priv->wBCNBufLen, priv->port_offset + MAC_REG_BCNDMACTL + 2);
1426 /* Set auto Transmit on */
1427 vt6655_mac_reg_bits_on(priv->port_offset, MAC_REG_TCR, TCR_AUTOBCNTX);
1428 /* Poll Transmit the adapter */
1429 iowrite8(BEACON_READY, priv->port_offset + MAC_REG_BCNDMACTL);
1434 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1436 struct sk_buff *beacon;
1438 beacon = ieee80211_beacon_get(priv->hw, vif, 0);
1442 if (vnt_beacon_xmit(priv, beacon)) {
1443 ieee80211_free_txskb(priv->hw, beacon);
1450 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1451 struct ieee80211_bss_conf *conf)
1453 iowrite8(TFTCTL_TSFCNTRST, priv->port_offset + MAC_REG_TFTCTL);
1455 iowrite8(TFTCTL_TSFCNTREN, priv->port_offset + MAC_REG_TFTCTL);
1457 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1459 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1461 return vnt_beacon_make(priv, vif);