WIP FPC-III support
[linux/fpc-iii.git] / drivers / staging / vt6655 / rxtx.c
blobff452067a6177c7531c65a0783a68e5fbfb85005
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4 * All rights reserved.
6 * File: rxtx.c
8 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
10 * Author: Lyndon Chen
12 * Date: May 20, 2003
14 * 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 * get_rtscts_time- 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
34 * Revision History:
38 #include "device.h"
39 #include "rxtx.h"
40 #include "card.h"
41 #include "mac.h"
42 #include "baseband.h"
43 #include "rf.h"
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 */
69 static const unsigned short wFB_Opt1[2][5] = {
70 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
71 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
74 #define RTSDUR_BB 0
75 #define RTSDUR_BA 1
76 #define RTSDUR_AA 2
77 #define CTSDUR_BA 3
78 #define RTSDUR_BA_F0 4
79 #define RTSDUR_AA_F0 5
80 #define RTSDUR_BA_F1 6
81 #define RTSDUR_AA_F1 7
82 #define CTSDUR_BA_F0 8
83 #define CTSDUR_BA_F1 9
84 #define DATADUR_B 10
85 #define DATADUR_A 11
86 #define DATADUR_A_F0 12
87 #define DATADUR_A_F1 13
89 /*--------------------- Static Functions --------------------------*/
90 static
91 void
92 s_vFillRTSHead(
93 struct vnt_private *pDevice,
94 unsigned char byPktType,
95 void *pvRTS,
96 unsigned int cbFrameLength,
97 bool bNeedAck,
98 bool bDisCRC,
99 struct ieee80211_hdr *hdr,
100 unsigned short wCurrentRate,
101 unsigned char byFBOption
104 static
105 void
106 s_vGenerateTxParameter(
107 struct vnt_private *pDevice,
108 unsigned char byPktType,
109 struct vnt_tx_fifo_head *,
110 void *pvRrvTime,
111 void *pvRTS,
112 void *pvCTS,
113 unsigned int cbFrameSize,
114 bool bNeedACK,
115 unsigned int uDMAIdx,
116 void *psEthHeader,
117 unsigned short wCurrentRate
120 static unsigned int
121 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
122 unsigned char *pbyTxBufferAddr,
123 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
124 unsigned int uNodeIndex);
126 static
127 __le16
128 s_uFillDataHead(
129 struct vnt_private *pDevice,
130 unsigned char byPktType,
131 void *pTxDataHead,
132 unsigned int cbFrameLength,
133 unsigned int uDMAIdx,
134 bool bNeedAck,
135 unsigned int uFragIdx,
136 unsigned int cbLastFragmentSize,
137 unsigned int uMACfragNum,
138 unsigned char byFBOption,
139 unsigned short wCurrentRate,
140 bool is_pspoll
143 /*--------------------- Export Variables --------------------------*/
145 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
147 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
148 [rate % MAX_RATE]);
151 /* byPktType : PK_TYPE_11A 0
152 * PK_TYPE_11B 1
153 * PK_TYPE_11GB 2
154 * PK_TYPE_11GA 3
156 static
157 unsigned int
158 s_uGetTxRsvTime(
159 struct vnt_private *pDevice,
160 unsigned char byPktType,
161 unsigned int cbFrameLength,
162 unsigned short wRate,
163 bool bNeedAck
166 unsigned int uDataTime, uAckTime;
168 uDataTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
170 if (!bNeedAck)
171 return uDataTime;
174 * CCK mode - 11b
175 * OFDM mode - 11g 2.4G & 11a 5G
177 uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14,
178 byPktType == PK_TYPE_11B ?
179 pDevice->byTopCCKBasicRate :
180 pDevice->byTopOFDMBasicRate);
182 return uDataTime + pDevice->uSIFS + uAckTime;
185 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
186 u32 frame_length, u16 rate, bool need_ack)
188 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
189 frame_length, rate, need_ack));
192 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
193 static __le16 get_rtscts_time(struct vnt_private *priv,
194 unsigned char rts_rsvtype,
195 unsigned char pkt_type,
196 unsigned int frame_length,
197 unsigned short current_rate)
199 unsigned int rrv_time = 0;
200 unsigned int rts_time = 0;
201 unsigned int cts_time = 0;
202 unsigned int ack_time = 0;
203 unsigned int data_time = 0;
205 data_time = bb_get_frame_time(priv->byPreambleType, pkt_type, frame_length, current_rate);
206 if (rts_rsvtype == 0) { /* RTSTxRrvTime_bb */
207 rts_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 20, priv->byTopCCKBasicRate);
208 ack_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 14, priv->byTopCCKBasicRate);
209 cts_time = ack_time;
210 } else if (rts_rsvtype == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
211 rts_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 20, priv->byTopCCKBasicRate);
212 cts_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 14, priv->byTopCCKBasicRate);
213 ack_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 14, priv->byTopOFDMBasicRate);
214 } else if (rts_rsvtype == 2) { /* RTSTxRrvTime_aa */
215 rts_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 20, priv->byTopOFDMBasicRate);
216 ack_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 14, priv->byTopOFDMBasicRate);
217 cts_time = ack_time;
218 } else if (rts_rsvtype == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
219 cts_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 14, priv->byTopCCKBasicRate);
220 ack_time = bb_get_frame_time(priv->byPreambleType, pkt_type, 14, priv->byTopOFDMBasicRate);
221 rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;
222 return cpu_to_le16((u16)rrv_time);
225 /* RTSRrvTime */
226 rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;
227 return cpu_to_le16((u16)rrv_time);
230 /* byFreqType 0: 5GHz, 1:2.4Ghz */
231 static
232 unsigned int
233 s_uGetDataDuration(
234 struct vnt_private *pDevice,
235 unsigned char byDurType,
236 unsigned int cbFrameLength,
237 unsigned char byPktType,
238 unsigned short wRate,
239 bool bNeedAck,
240 unsigned int uFragIdx,
241 unsigned int cbLastFragmentSize,
242 unsigned int uMACfragNum,
243 unsigned char byFBOption
246 bool bLastFrag = false;
247 unsigned int uAckTime = 0, uNextPktTime = 0, len;
249 if (uFragIdx == (uMACfragNum - 1))
250 bLastFrag = true;
252 if (uFragIdx == (uMACfragNum - 2))
253 len = cbLastFragmentSize;
254 else
255 len = cbFrameLength;
257 switch (byDurType) {
258 case DATADUR_B: /* DATADUR_B */
259 if (bNeedAck) {
260 uAckTime = bb_get_frame_time(pDevice->byPreambleType,
261 byPktType, 14,
262 pDevice->byTopCCKBasicRate);
264 /* Non Frag or Last Frag */
265 if ((uMACfragNum == 1) || bLastFrag) {
266 if (!bNeedAck)
267 return 0;
268 } else {
269 /* First Frag or Mid Frag */
270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
271 len, wRate, bNeedAck);
274 return pDevice->uSIFS + uAckTime + uNextPktTime;
276 case DATADUR_A: /* DATADUR_A */
277 if (bNeedAck) {
278 uAckTime = bb_get_frame_time(pDevice->byPreambleType,
279 byPktType, 14,
280 pDevice->byTopOFDMBasicRate);
282 /* Non Frag or Last Frag */
283 if ((uMACfragNum == 1) || bLastFrag) {
284 if (!bNeedAck)
285 return 0;
286 } else {
287 /* First Frag or Mid Frag */
288 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
289 len, wRate, bNeedAck);
292 return pDevice->uSIFS + uAckTime + uNextPktTime;
294 case DATADUR_A_F0: /* DATADUR_A_F0 */
295 case DATADUR_A_F1: /* DATADUR_A_F1 */
296 if (bNeedAck) {
297 uAckTime = bb_get_frame_time(pDevice->byPreambleType,
298 byPktType, 14,
299 pDevice->byTopOFDMBasicRate);
301 /* Non Frag or Last Frag */
302 if ((uMACfragNum == 1) || bLastFrag) {
303 if (!bNeedAck)
304 return 0;
305 } else {
306 /* First Frag or Mid Frag */
307 if (wRate < RATE_18M)
308 wRate = RATE_18M;
309 else if (wRate > RATE_54M)
310 wRate = RATE_54M;
312 wRate -= RATE_18M;
314 if (byFBOption == AUTO_FB_0)
315 wRate = wFB_Opt0[FB_RATE0][wRate];
316 else
317 wRate = wFB_Opt1[FB_RATE0][wRate];
319 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
320 len, wRate, bNeedAck);
323 return pDevice->uSIFS + uAckTime + uNextPktTime;
325 default:
326 break;
329 return 0;
332 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
333 static
334 __le16
335 s_uGetRTSCTSDuration(
336 struct vnt_private *pDevice,
337 unsigned char byDurType,
338 unsigned int cbFrameLength,
339 unsigned char byPktType,
340 unsigned short wRate,
341 bool bNeedAck,
342 unsigned char byFBOption
345 unsigned int uCTSTime = 0, uDurTime = 0;
347 switch (byDurType) {
348 case RTSDUR_BB: /* RTSDuration_bb */
349 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
350 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
351 break;
353 case RTSDUR_BA: /* RTSDuration_ba */
354 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
355 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
356 break;
358 case RTSDUR_AA: /* RTSDuration_aa */
359 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
360 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
361 break;
363 case CTSDUR_BA: /* CTSDuration_ba */
364 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
365 break;
367 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
368 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
369 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
370 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
371 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
372 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
374 break;
376 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
377 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
378 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
379 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
380 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
381 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
383 break;
385 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
386 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
387 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
388 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
389 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
390 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
392 break;
394 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
395 uCTSTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
396 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
397 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
398 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
399 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
401 break;
403 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
404 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
405 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate - RATE_18M], bNeedAck);
406 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
407 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate - RATE_18M], bNeedAck);
409 break;
411 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
412 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
413 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate - RATE_18M], bNeedAck);
414 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
415 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate - RATE_18M], bNeedAck);
417 break;
419 default:
420 break;
423 return cpu_to_le16((u16)uDurTime);
426 static
427 __le16
428 s_uFillDataHead(
429 struct vnt_private *pDevice,
430 unsigned char byPktType,
431 void *pTxDataHead,
432 unsigned int cbFrameLength,
433 unsigned int uDMAIdx,
434 bool bNeedAck,
435 unsigned int uFragIdx,
436 unsigned int cbLastFragmentSize,
437 unsigned int uMACfragNum,
438 unsigned char byFBOption,
439 unsigned short wCurrentRate,
440 bool is_pspoll
443 struct vnt_tx_datahead_ab *buf = pTxDataHead;
445 if (!pTxDataHead)
446 return 0;
448 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
449 /* Auto Fallback */
450 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
452 if (byFBOption == AUTO_FB_NONE) {
453 struct vnt_tx_datahead_g *buf = pTxDataHead;
454 /* Get SignalField, ServiceField & Length */
455 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
456 byPktType, &buf->a);
458 vnt_get_phy_field(pDevice, cbFrameLength,
459 pDevice->byTopCCKBasicRate,
460 PK_TYPE_11B, &buf->b);
462 if (is_pspoll) {
463 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
465 buf->duration_a = dur;
466 buf->duration_b = dur;
467 } else {
468 /* Get Duration and TimeStamp */
469 buf->duration_a =
470 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
471 byPktType, wCurrentRate, bNeedAck, uFragIdx,
472 cbLastFragmentSize, uMACfragNum,
473 byFBOption));
474 buf->duration_b =
475 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
476 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
477 bNeedAck, uFragIdx, cbLastFragmentSize,
478 uMACfragNum, byFBOption));
481 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
482 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
484 return buf->duration_a;
487 /* Get SignalField, ServiceField & Length */
488 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
489 byPktType, &buf->a);
491 vnt_get_phy_field(pDevice, cbFrameLength,
492 pDevice->byTopCCKBasicRate,
493 PK_TYPE_11B, &buf->b);
494 /* Get Duration and TimeStamp */
495 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
496 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
497 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
498 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
499 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
500 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
501 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
502 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
504 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
505 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
507 return buf->duration_a;
508 /* if (byFBOption == AUTO_FB_NONE) */
509 } else if (byPktType == PK_TYPE_11A) {
510 struct vnt_tx_datahead_ab *buf = pTxDataHead;
512 if (byFBOption != AUTO_FB_NONE) {
513 /* Auto Fallback */
514 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
515 /* Get SignalField, ServiceField & Length */
516 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
517 byPktType, &buf->a);
519 /* Get Duration and TimeStampOff */
520 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
521 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
522 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
523 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
524 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
525 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
526 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
527 return buf->duration;
530 /* Get SignalField, ServiceField & Length */
531 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
532 byPktType, &buf->ab);
534 if (is_pspoll) {
535 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
537 buf->duration = dur;
538 } else {
539 /* Get Duration and TimeStampOff */
540 buf->duration =
541 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
542 wCurrentRate, bNeedAck, uFragIdx,
543 cbLastFragmentSize, uMACfragNum,
544 byFBOption));
547 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
548 return buf->duration;
551 /* Get SignalField, ServiceField & Length */
552 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
553 byPktType, &buf->ab);
555 if (is_pspoll) {
556 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
558 buf->duration = dur;
559 } else {
560 /* Get Duration and TimeStampOff */
561 buf->duration =
562 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
563 wCurrentRate, bNeedAck, uFragIdx,
564 cbLastFragmentSize, uMACfragNum,
565 byFBOption));
568 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
569 return buf->duration;
572 static
573 void
574 s_vFillRTSHead(
575 struct vnt_private *pDevice,
576 unsigned char byPktType,
577 void *pvRTS,
578 unsigned int cbFrameLength,
579 bool bNeedAck,
580 bool bDisCRC,
581 struct ieee80211_hdr *hdr,
582 unsigned short wCurrentRate,
583 unsigned char byFBOption
586 unsigned int uRTSFrameLen = 20;
588 if (!pvRTS)
589 return;
591 if (bDisCRC) {
592 /* When CRCDIS bit is on, H/W forgot to generate FCS for
593 * RTS frame, in this case we need to decrease its length by 4.
595 uRTSFrameLen -= 4;
598 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
599 * so we don't need to take them into account.
600 * Otherwise, we need to modify codes for them.
602 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
603 if (byFBOption == AUTO_FB_NONE) {
604 struct vnt_rts_g *buf = pvRTS;
605 /* Get SignalField, ServiceField & Length */
606 vnt_get_phy_field(pDevice, uRTSFrameLen,
607 pDevice->byTopCCKBasicRate,
608 PK_TYPE_11B, &buf->b);
610 vnt_get_phy_field(pDevice, uRTSFrameLen,
611 pDevice->byTopOFDMBasicRate,
612 byPktType, &buf->a);
613 /* Get Duration */
614 buf->duration_bb =
615 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
616 cbFrameLength, PK_TYPE_11B,
617 pDevice->byTopCCKBasicRate,
618 bNeedAck, byFBOption);
619 buf->duration_aa =
620 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
621 cbFrameLength, byPktType,
622 wCurrentRate, bNeedAck,
623 byFBOption);
624 buf->duration_ba =
625 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
626 cbFrameLength, byPktType,
627 wCurrentRate, bNeedAck,
628 byFBOption);
630 buf->data.duration = buf->duration_aa;
631 /* Get RTS Frame body */
632 buf->data.frame_control =
633 cpu_to_le16(IEEE80211_FTYPE_CTL |
634 IEEE80211_STYPE_RTS);
636 ether_addr_copy(buf->data.ra, hdr->addr1);
637 ether_addr_copy(buf->data.ta, hdr->addr2);
638 } else {
639 struct vnt_rts_g_fb *buf = pvRTS;
640 /* Get SignalField, ServiceField & Length */
641 vnt_get_phy_field(pDevice, uRTSFrameLen,
642 pDevice->byTopCCKBasicRate,
643 PK_TYPE_11B, &buf->b);
645 vnt_get_phy_field(pDevice, uRTSFrameLen,
646 pDevice->byTopOFDMBasicRate,
647 byPktType, &buf->a);
648 /* Get Duration */
649 buf->duration_bb =
650 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
651 cbFrameLength, PK_TYPE_11B,
652 pDevice->byTopCCKBasicRate,
653 bNeedAck, byFBOption);
654 buf->duration_aa =
655 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
656 cbFrameLength, byPktType,
657 wCurrentRate, bNeedAck,
658 byFBOption);
659 buf->duration_ba =
660 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
661 cbFrameLength, byPktType,
662 wCurrentRate, bNeedAck,
663 byFBOption);
664 buf->rts_duration_ba_f0 =
665 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
666 cbFrameLength, byPktType,
667 wCurrentRate, bNeedAck,
668 byFBOption);
669 buf->rts_duration_aa_f0 =
670 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
671 cbFrameLength, byPktType,
672 wCurrentRate, bNeedAck,
673 byFBOption);
674 buf->rts_duration_ba_f1 =
675 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
676 cbFrameLength, byPktType,
677 wCurrentRate, bNeedAck,
678 byFBOption);
679 buf->rts_duration_aa_f1 =
680 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
681 cbFrameLength, byPktType,
682 wCurrentRate, bNeedAck,
683 byFBOption);
684 buf->data.duration = buf->duration_aa;
685 /* Get RTS Frame body */
686 buf->data.frame_control =
687 cpu_to_le16(IEEE80211_FTYPE_CTL |
688 IEEE80211_STYPE_RTS);
690 ether_addr_copy(buf->data.ra, hdr->addr1);
691 ether_addr_copy(buf->data.ta, hdr->addr2);
692 } /* if (byFBOption == AUTO_FB_NONE) */
693 } else if (byPktType == PK_TYPE_11A) {
694 if (byFBOption == AUTO_FB_NONE) {
695 struct vnt_rts_ab *buf = pvRTS;
696 /* Get SignalField, ServiceField & Length */
697 vnt_get_phy_field(pDevice, uRTSFrameLen,
698 pDevice->byTopOFDMBasicRate,
699 byPktType, &buf->ab);
700 /* Get Duration */
701 buf->duration =
702 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
703 cbFrameLength, byPktType,
704 wCurrentRate, bNeedAck,
705 byFBOption);
706 buf->data.duration = buf->duration;
707 /* Get RTS Frame body */
708 buf->data.frame_control =
709 cpu_to_le16(IEEE80211_FTYPE_CTL |
710 IEEE80211_STYPE_RTS);
712 ether_addr_copy(buf->data.ra, hdr->addr1);
713 ether_addr_copy(buf->data.ta, hdr->addr2);
714 } else {
715 struct vnt_rts_a_fb *buf = pvRTS;
716 /* Get SignalField, ServiceField & Length */
717 vnt_get_phy_field(pDevice, uRTSFrameLen,
718 pDevice->byTopOFDMBasicRate,
719 byPktType, &buf->a);
720 /* Get Duration */
721 buf->duration =
722 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
723 cbFrameLength, byPktType,
724 wCurrentRate, bNeedAck,
725 byFBOption);
726 buf->rts_duration_f0 =
727 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
728 cbFrameLength, byPktType,
729 wCurrentRate, bNeedAck,
730 byFBOption);
731 buf->rts_duration_f1 =
732 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
733 cbFrameLength, byPktType,
734 wCurrentRate, bNeedAck,
735 byFBOption);
736 buf->data.duration = buf->duration;
737 /* Get RTS Frame body */
738 buf->data.frame_control =
739 cpu_to_le16(IEEE80211_FTYPE_CTL |
740 IEEE80211_STYPE_RTS);
742 ether_addr_copy(buf->data.ra, hdr->addr1);
743 ether_addr_copy(buf->data.ta, hdr->addr2);
745 } else if (byPktType == PK_TYPE_11B) {
746 struct vnt_rts_ab *buf = pvRTS;
747 /* Get SignalField, ServiceField & Length */
748 vnt_get_phy_field(pDevice, uRTSFrameLen,
749 pDevice->byTopCCKBasicRate,
750 PK_TYPE_11B, &buf->ab);
751 /* Get Duration */
752 buf->duration =
753 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
754 byPktType, wCurrentRate, bNeedAck,
755 byFBOption);
757 buf->data.duration = buf->duration;
758 /* Get RTS Frame body */
759 buf->data.frame_control =
760 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
762 ether_addr_copy(buf->data.ra, hdr->addr1);
763 ether_addr_copy(buf->data.ta, hdr->addr2);
767 static
768 void
769 s_vFillCTSHead(
770 struct vnt_private *pDevice,
771 unsigned int uDMAIdx,
772 unsigned char byPktType,
773 void *pvCTS,
774 unsigned int cbFrameLength,
775 bool bNeedAck,
776 bool bDisCRC,
777 unsigned short wCurrentRate,
778 unsigned char byFBOption
781 unsigned int uCTSFrameLen = 14;
783 if (!pvCTS)
784 return;
786 if (bDisCRC) {
787 /* When CRCDIS bit is on, H/W forgot to generate FCS for
788 * CTS frame, in this case we need to decrease its length by 4.
790 uCTSFrameLen -= 4;
793 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
794 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
795 /* Auto Fall back */
796 struct vnt_cts_fb *buf = pvCTS;
797 /* Get SignalField, ServiceField & Length */
798 vnt_get_phy_field(pDevice, uCTSFrameLen,
799 pDevice->byTopCCKBasicRate,
800 PK_TYPE_11B, &buf->b);
802 buf->duration_ba =
803 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
804 cbFrameLength, byPktType,
805 wCurrentRate, bNeedAck,
806 byFBOption);
808 /* Get CTSDuration_ba_f0 */
809 buf->cts_duration_ba_f0 =
810 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
811 cbFrameLength, byPktType,
812 wCurrentRate, bNeedAck,
813 byFBOption);
815 /* Get CTSDuration_ba_f1 */
816 buf->cts_duration_ba_f1 =
817 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
818 cbFrameLength, byPktType,
819 wCurrentRate, bNeedAck,
820 byFBOption);
822 /* Get CTS Frame body */
823 buf->data.duration = buf->duration_ba;
825 buf->data.frame_control =
826 cpu_to_le16(IEEE80211_FTYPE_CTL |
827 IEEE80211_STYPE_CTS);
829 buf->reserved2 = 0x0;
831 ether_addr_copy(buf->data.ra,
832 pDevice->abyCurrentNetAddr);
833 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
834 struct vnt_cts *buf = pvCTS;
835 /* Get SignalField, ServiceField & Length */
836 vnt_get_phy_field(pDevice, uCTSFrameLen,
837 pDevice->byTopCCKBasicRate,
838 PK_TYPE_11B, &buf->b);
840 /* Get CTSDuration_ba */
841 buf->duration_ba =
842 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
843 cbFrameLength, byPktType,
844 wCurrentRate, bNeedAck,
845 byFBOption);
847 /* Get CTS Frame body */
848 buf->data.duration = buf->duration_ba;
850 buf->data.frame_control =
851 cpu_to_le16(IEEE80211_FTYPE_CTL |
852 IEEE80211_STYPE_CTS);
854 buf->reserved2 = 0x0;
855 ether_addr_copy(buf->data.ra,
856 pDevice->abyCurrentNetAddr);
863 * Description:
864 * Generate FIFO control for MAC & Baseband controller
866 * Parameters:
867 * In:
868 * pDevice - Pointer to adapter
869 * pTxDataHead - Transmit Data Buffer
870 * pTxBufHead - pTxBufHead
871 * pvRrvTime - pvRrvTime
872 * pvRTS - RTS Buffer
873 * pCTS - CTS Buffer
874 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
875 * bNeedACK - If need ACK
876 * uDescIdx - Desc Index
877 * Out:
878 * none
880 * Return Value: none
883 * unsigned int cbFrameSize, Hdr+Payload+FCS
885 static
886 void
887 s_vGenerateTxParameter(
888 struct vnt_private *pDevice,
889 unsigned char byPktType,
890 struct vnt_tx_fifo_head *tx_buffer_head,
891 void *pvRrvTime,
892 void *pvRTS,
893 void *pvCTS,
894 unsigned int cbFrameSize,
895 bool bNeedACK,
896 unsigned int uDMAIdx,
897 void *psEthHeader,
898 unsigned short wCurrentRate
901 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
902 bool bDisCRC = false;
903 unsigned char byFBOption = AUTO_FB_NONE;
905 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
907 if (fifo_ctl & FIFOCTL_CRCDIS)
908 bDisCRC = true;
910 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
911 byFBOption = AUTO_FB_0;
912 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
913 byFBOption = AUTO_FB_1;
915 if (!pvRrvTime)
916 return;
918 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
919 if (pvRTS) { /* RTS_need */
920 /* Fill RsvTime */
921 struct vnt_rrv_time_rts *buf = pvRrvTime;
923 buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
924 buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
925 buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
926 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
927 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
929 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
930 } else {/* RTS_needless, PCF mode */
931 struct vnt_rrv_time_cts *buf = pvRrvTime;
933 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
934 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
935 buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
937 /* Fill CTS */
938 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
940 } else if (byPktType == PK_TYPE_11A) {
941 if (pvRTS) {/* RTS_need, non PCF mode */
942 struct vnt_rrv_time_ab *buf = pvRrvTime;
944 buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
945 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
947 /* Fill RTS */
948 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
949 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
950 struct vnt_rrv_time_ab *buf = pvRrvTime;
952 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
954 } else if (byPktType == PK_TYPE_11B) {
955 if (pvRTS) {/* RTS_need, non PCF mode */
956 struct vnt_rrv_time_ab *buf = pvRrvTime;
958 buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
959 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
961 /* Fill RTS */
962 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
963 } else { /* RTS_needless, non PCF mode */
964 struct vnt_rrv_time_ab *buf = pvRrvTime;
966 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
971 static unsigned int
972 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
973 unsigned char *pbyTxBufferAddr,
974 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
975 unsigned int is_pspoll)
977 struct vnt_td_info *td_info = pHeadTD->td_info;
978 struct sk_buff *skb = td_info->skb;
979 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
980 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
981 struct vnt_tx_fifo_head *tx_buffer_head =
982 (struct vnt_tx_fifo_head *)td_info->buf;
983 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
984 unsigned int cbFrameSize;
985 __le16 uDuration;
986 unsigned char *pbyBuffer;
987 unsigned int uLength = 0;
988 unsigned int cbMICHDR = 0;
989 unsigned int uMACfragNum = 1;
990 unsigned int uPadding = 0;
991 unsigned int cbReqCount = 0;
992 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
993 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
994 struct vnt_tx_desc *ptdCurr;
995 unsigned int cbHeaderLength = 0;
996 void *pvRrvTime = NULL;
997 struct vnt_mic_hdr *pMICHDR = NULL;
998 void *pvRTS = NULL;
999 void *pvCTS = NULL;
1000 void *pvTxDataHd = NULL;
1001 unsigned short wTxBufSize; /* FFinfo size */
1002 unsigned char byFBOption = AUTO_FB_NONE;
1004 cbFrameSize = skb->len + 4;
1006 if (info->control.hw_key) {
1007 switch (info->control.hw_key->cipher) {
1008 case WLAN_CIPHER_SUITE_CCMP:
1009 cbMICHDR = sizeof(struct vnt_mic_hdr);
1010 break;
1011 default:
1012 break;
1015 cbFrameSize += info->control.hw_key->icv_len;
1017 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1018 /* MAC Header should be padding 0 to DW alignment. */
1019 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1020 uPadding %= 4;
1025 * Use for AUTO FALL BACK
1027 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1028 byFBOption = AUTO_FB_0;
1029 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1030 byFBOption = AUTO_FB_1;
1032 /* Set RrvTime/RTS/CTS Buffer */
1033 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1034 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1036 if (byFBOption == AUTO_FB_NONE) {
1037 if (bRTS) {/* RTS_need */
1038 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1039 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1040 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1041 pvCTS = NULL;
1042 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1043 cbMICHDR + sizeof(struct vnt_rts_g));
1044 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1045 cbMICHDR + sizeof(struct vnt_rts_g) +
1046 sizeof(struct vnt_tx_datahead_g);
1047 } else { /* RTS_needless */
1048 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1049 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1050 pvRTS = NULL;
1051 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1052 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1053 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1054 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1055 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1057 } else {
1058 /* Auto Fall Back */
1059 if (bRTS) {/* RTS_need */
1060 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1061 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1062 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1063 pvCTS = NULL;
1064 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1065 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1066 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1067 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1068 } else { /* RTS_needless */
1069 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1070 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1071 pvRTS = NULL;
1072 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1073 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1074 cbMICHDR + sizeof(struct vnt_cts_fb));
1075 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1076 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1078 } /* Auto Fall Back */
1079 } else {/* 802.11a/b packet */
1081 if (byFBOption == AUTO_FB_NONE) {
1082 if (bRTS) {
1083 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1084 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1085 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1086 pvCTS = NULL;
1087 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1088 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1089 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1090 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1091 } else { /* RTS_needless, need MICHDR */
1092 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1093 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1094 pvRTS = NULL;
1095 pvCTS = NULL;
1096 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1097 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1098 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1100 } else {
1101 /* Auto Fall Back */
1102 if (bRTS) { /* RTS_need */
1103 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1104 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1105 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1106 pvCTS = NULL;
1107 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1108 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1109 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1110 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1111 } else { /* RTS_needless */
1112 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1113 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1114 pvRTS = NULL;
1115 pvCTS = NULL;
1116 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1117 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1118 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1120 } /* Auto Fall Back */
1123 td_info->mic_hdr = pMICHDR;
1125 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1127 /* Fill FIFO,RrvTime,RTS,and CTS */
1128 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1129 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1130 /* Fill DataHead */
1131 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1132 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1134 hdr->duration_id = uDuration;
1136 cbReqCount = cbHeaderLength + uPadding + skb->len;
1137 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1138 uLength = cbHeaderLength + uPadding;
1140 /* Copy the Packet into a tx Buffer */
1141 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1143 ptdCurr = pHeadTD;
1145 ptdCurr->td_info->req_count = (u16)cbReqCount;
1147 return cbHeaderLength;
1150 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1151 struct ieee80211_key_conf *tx_key,
1152 struct sk_buff *skb, u16 payload_len,
1153 struct vnt_mic_hdr *mic_hdr)
1155 u64 pn64;
1156 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1158 /* strip header and icv len from payload */
1159 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1160 payload_len -= tx_key->icv_len;
1162 switch (tx_key->cipher) {
1163 case WLAN_CIPHER_SUITE_WEP40:
1164 case WLAN_CIPHER_SUITE_WEP104:
1165 memcpy(key_buffer, iv, 3);
1166 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1168 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1169 memcpy(key_buffer + 8, iv, 3);
1170 memcpy(key_buffer + 11,
1171 tx_key->key, WLAN_KEY_LEN_WEP40);
1174 break;
1175 case WLAN_CIPHER_SUITE_TKIP:
1176 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1178 break;
1179 case WLAN_CIPHER_SUITE_CCMP:
1181 if (!mic_hdr)
1182 return;
1184 mic_hdr->id = 0x59;
1185 mic_hdr->payload_len = cpu_to_be16(payload_len);
1186 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1188 pn64 = atomic64_read(&tx_key->tx_pn);
1189 mic_hdr->ccmp_pn[5] = pn64;
1190 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1191 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1192 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1193 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1194 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1196 if (ieee80211_has_a4(hdr->frame_control))
1197 mic_hdr->hlen = cpu_to_be16(28);
1198 else
1199 mic_hdr->hlen = cpu_to_be16(22);
1201 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1202 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1203 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1205 mic_hdr->frame_control = cpu_to_le16(
1206 le16_to_cpu(hdr->frame_control) & 0xc78f);
1207 mic_hdr->seq_ctrl = cpu_to_le16(
1208 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1210 if (ieee80211_has_a4(hdr->frame_control))
1211 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1213 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1215 break;
1216 default:
1217 break;
1221 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1222 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1224 struct vnt_td_info *td_info = head_td->td_info;
1225 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1226 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1227 struct ieee80211_rate *rate;
1228 struct ieee80211_key_conf *tx_key;
1229 struct ieee80211_hdr *hdr;
1230 struct vnt_tx_fifo_head *tx_buffer_head =
1231 (struct vnt_tx_fifo_head *)td_info->buf;
1232 u16 tx_body_size = skb->len, current_rate;
1233 u8 pkt_type;
1234 bool is_pspoll = false;
1236 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1238 hdr = (struct ieee80211_hdr *)(skb->data);
1240 rate = ieee80211_get_tx_rate(priv->hw, info);
1242 current_rate = rate->hw_value;
1243 if (priv->wCurrentRate != current_rate &&
1244 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1245 priv->wCurrentRate = current_rate;
1247 RFbSetPower(priv, priv->wCurrentRate,
1248 priv->hw->conf.chandef.chan->hw_value);
1251 if (current_rate > RATE_11M) {
1252 if (info->band == NL80211_BAND_5GHZ) {
1253 pkt_type = PK_TYPE_11A;
1254 } else {
1255 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1256 pkt_type = PK_TYPE_11GB;
1257 else
1258 pkt_type = PK_TYPE_11GA;
1260 } else {
1261 pkt_type = PK_TYPE_11B;
1264 /*Set fifo controls */
1265 if (pkt_type == PK_TYPE_11A)
1266 tx_buffer_head->fifo_ctl = 0;
1267 else if (pkt_type == PK_TYPE_11B)
1268 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1269 else if (pkt_type == PK_TYPE_11GB)
1270 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1271 else if (pkt_type == PK_TYPE_11GA)
1272 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1274 /* generate interrupt */
1275 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1277 if (!ieee80211_is_data(hdr->frame_control)) {
1278 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1279 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1280 tx_buffer_head->time_stamp =
1281 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1282 } else {
1283 tx_buffer_head->time_stamp =
1284 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1287 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1288 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1290 if (ieee80211_has_retry(hdr->frame_control))
1291 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1293 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1294 priv->byPreambleType = PREAMBLE_SHORT;
1295 else
1296 priv->byPreambleType = PREAMBLE_LONG;
1298 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1299 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1301 if (ieee80211_has_a4(hdr->frame_control)) {
1302 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1303 priv->bLongHeader = true;
1306 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1307 is_pspoll = true;
1309 tx_buffer_head->frag_ctl =
1310 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1312 if (info->control.hw_key) {
1313 tx_key = info->control.hw_key;
1315 switch (info->control.hw_key->cipher) {
1316 case WLAN_CIPHER_SUITE_WEP40:
1317 case WLAN_CIPHER_SUITE_WEP104:
1318 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1319 break;
1320 case WLAN_CIPHER_SUITE_TKIP:
1321 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1322 break;
1323 case WLAN_CIPHER_SUITE_CCMP:
1324 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1325 break;
1326 default:
1327 break;
1331 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1333 /* legacy rates TODO use ieee80211_tx_rate */
1334 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1335 if (priv->byAutoFBCtrl == AUTO_FB_0)
1336 tx_buffer_head->fifo_ctl |=
1337 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1338 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1339 tx_buffer_head->fifo_ctl |=
1340 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1343 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1345 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1346 dma_idx, head_td, is_pspoll);
1348 if (info->control.hw_key) {
1349 tx_key = info->control.hw_key;
1350 if (tx_key->keylen > 0)
1351 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1352 tx_key, skb, tx_body_size,
1353 td_info->mic_hdr);
1356 return 0;
1359 static int vnt_beacon_xmit(struct vnt_private *priv,
1360 struct sk_buff *skb)
1362 struct vnt_tx_short_buf_head *short_head =
1363 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1364 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1365 (priv->tx_beacon_bufs + sizeof(*short_head));
1366 struct ieee80211_tx_info *info;
1367 u32 frame_size = skb->len + 4;
1368 u16 current_rate;
1370 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1372 if (priv->byBBType == BB_TYPE_11A) {
1373 current_rate = RATE_6M;
1375 /* Get SignalField,ServiceField,Length */
1376 vnt_get_phy_field(priv, frame_size, current_rate,
1377 PK_TYPE_11A, &short_head->ab);
1379 /* Get Duration and TimeStampOff */
1380 short_head->duration =
1381 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1382 frame_size, PK_TYPE_11A, current_rate,
1383 false, 0, 0, 1, AUTO_FB_NONE));
1385 short_head->time_stamp_off =
1386 vnt_time_stamp_off(priv, current_rate);
1387 } else {
1388 current_rate = RATE_1M;
1389 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1391 /* Get SignalField,ServiceField,Length */
1392 vnt_get_phy_field(priv, frame_size, current_rate,
1393 PK_TYPE_11B, &short_head->ab);
1395 /* Get Duration and TimeStampOff */
1396 short_head->duration =
1397 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1398 frame_size, PK_TYPE_11B, current_rate,
1399 false, 0, 0, 1, AUTO_FB_NONE));
1401 short_head->time_stamp_off =
1402 vnt_time_stamp_off(priv, current_rate);
1405 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1407 /* Copy Beacon */
1408 memcpy(mgmt_hdr, skb->data, skb->len);
1410 /* time stamp always 0 */
1411 mgmt_hdr->u.beacon.timestamp = 0;
1413 info = IEEE80211_SKB_CB(skb);
1414 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1415 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1417 hdr->duration_id = 0;
1418 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1421 priv->wSeqCounter++;
1422 if (priv->wSeqCounter > 0x0fff)
1423 priv->wSeqCounter = 0;
1425 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1427 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1429 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1430 /* Set auto Transmit on */
1431 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1432 /* Poll Transmit the adapter */
1433 MACvTransmitBCN(priv->PortOffset);
1435 return 0;
1438 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1440 struct sk_buff *beacon;
1442 beacon = ieee80211_beacon_get(priv->hw, vif);
1443 if (!beacon)
1444 return -ENOMEM;
1446 if (vnt_beacon_xmit(priv, beacon)) {
1447 ieee80211_free_txskb(priv->hw, beacon);
1448 return -ENODEV;
1451 return 0;
1454 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1455 struct ieee80211_bss_conf *conf)
1457 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1459 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1461 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1463 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1465 return vnt_beacon_make(priv, vif);