1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
4 * All rights reserved.
5 *
6 * File: rxtx.c
7 *
8 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
9 *
10 * Author: Lyndon Chen
11 *
12 * Date: May 20, 2003
13 *
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
33 *
34 * Revision History:
35 *
36 */
37
38 #include "device.h"
39 #include "rxtx.h"
40 #include "card.h"
41 #include "mac.h"
42 #include "baseband.h"
43 #include "rf.h"
44
45 /*--------------------- Static Definitions -------------------------*/
46
47 /*--------------------- Static Classes ----------------------------*/
48
49 /*--------------------- Static Variables --------------------------*/
50
51 /*--------------------- Static Functions --------------------------*/
52
53 /*--------------------- Static Definitions -------------------------*/
54 /* if packet size < 256 -> in-direct send
55 * vpacket size >= 256 -> direct send
56 */
57 #define CRITICAL_PACKET_LEN 256
58
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 */
62 };
63
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 */
67 };
68
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 */
72 };
73
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
88
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
102 );
103
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
118 );
119
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);
125
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
141 );
142
143 /*--------------------- Export Variables --------------------------*/
144
vnt_time_stamp_off(struct vnt_private * priv,u16 rate)145 static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
146 {
147 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
148 [rate % MAX_RATE]);
149 }
150
151 /* byPktType : PK_TYPE_11A 0
152 * PK_TYPE_11B 1
153 * PK_TYPE_11GB 2
154 * PK_TYPE_11GA 3
155 */
156 static
157 unsigned int
s_uGetTxRsvTime(struct vnt_private * pDevice,unsigned char byPktType,unsigned int cbFrameLength,unsigned short wRate,bool bNeedAck)158 s_uGetTxRsvTime(
159 struct vnt_private *pDevice,
160 unsigned char byPktType,
161 unsigned int cbFrameLength,
162 unsigned short wRate,
163 bool bNeedAck
164 )
165 {
166 unsigned int uDataTime, uAckTime;
167
168 uDataTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
169
170 if (!bNeedAck)
171 return uDataTime;
172
173 /*
174 * CCK mode - 11b
175 * OFDM mode - 11g 2.4G & 11a 5G
176 */
177 uAckTime = bb_get_frame_time(pDevice->byPreambleType, byPktType, 14,
178 byPktType == PK_TYPE_11B ?
179 pDevice->byTopCCKBasicRate :
180 pDevice->byTopOFDMBasicRate);
181
182 return uDataTime + pDevice->uSIFS + uAckTime;
183 }
184
vnt_rxtx_rsvtime_le16(struct vnt_private * priv,u8 pkt_type,u32 frame_length,u16 rate,bool need_ack)185 static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
186 u32 frame_length, u16 rate, bool need_ack)
187 {
188 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
189 frame_length, rate, need_ack));
190 }
191
192 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
get_rtscts_time(struct vnt_private * priv,unsigned char rts_rsvtype,unsigned char pkt_type,unsigned int frame_length,unsigned short current_rate)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)
198 {
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;
204
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);
223 }
224
225 /* RTSRrvTime */
226 rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;
227 return cpu_to_le16((u16)rrv_time);
228 }
229
230 /* byFreqType 0: 5GHz, 1:2.4Ghz */
231 static
232 unsigned int
s_uGetDataDuration(struct vnt_private * pDevice,unsigned char byDurType,unsigned int cbFrameLength,unsigned char byPktType,unsigned short wRate,bool bNeedAck,unsigned int uFragIdx,unsigned int cbLastFragmentSize,unsigned int uMACfragNum,unsigned char byFBOption)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
244 )
245 {
246 bool bLastFrag = false;
247 unsigned int uAckTime = 0, uNextPktTime = 0, len;
248
249 if (uFragIdx == (uMACfragNum - 1))
250 bLastFrag = true;
251
252 if (uFragIdx == (uMACfragNum - 2))
253 len = cbLastFragmentSize;
254 else
255 len = cbFrameLength;
256
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);
263 }
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);
272 }
273
274 return pDevice->uSIFS + uAckTime + uNextPktTime;
275
276 case DATADUR_A: /* DATADUR_A */
277 if (bNeedAck) {
278 uAckTime = bb_get_frame_time(pDevice->byPreambleType,
279 byPktType, 14,
280 pDevice->byTopOFDMBasicRate);
281 }
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);
290 }
291
292 return pDevice->uSIFS + uAckTime + uNextPktTime;
293
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);
300 }
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;
311
312 wRate -= RATE_18M;
313
314 if (byFBOption == AUTO_FB_0)
315 wRate = wFB_Opt0[FB_RATE0][wRate];
316 else
317 wRate = wFB_Opt1[FB_RATE0][wRate];
318
319 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType,
320 len, wRate, bNeedAck);
321 }
322
323 return pDevice->uSIFS + uAckTime + uNextPktTime;
324
325 default:
326 break;
327 }
328
329 return 0;
330 }
331
332 /* byFreqType: 0=>5GHZ 1=>2.4GHZ */
333 static
334 __le16
s_uGetRTSCTSDuration(struct vnt_private * pDevice,unsigned char byDurType,unsigned int cbFrameLength,unsigned char byPktType,unsigned short wRate,bool bNeedAck,unsigned char byFBOption)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
343 )
344 {
345 unsigned int uCTSTime = 0, uDurTime = 0;
346
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;
352
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;
357
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;
362
363 case CTSDUR_BA: /* CTSDuration_ba */
364 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
365 break;
366
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);
373
374 break;
375
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);
382
383 break;
384
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);
391
392 break;
393
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);
400
401 break;
402
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);
408
409 break;
410
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);
416
417 break;
418
419 default:
420 break;
421 }
422
423 return cpu_to_le16((u16)uDurTime);
424 }
425
426 static
427 __le16
s_uFillDataHead(struct vnt_private * pDevice,unsigned char byPktType,void * pTxDataHead,unsigned int cbFrameLength,unsigned int uDMAIdx,bool bNeedAck,unsigned int uFragIdx,unsigned int cbLastFragmentSize,unsigned int uMACfragNum,unsigned char byFBOption,unsigned short wCurrentRate,bool is_pspoll)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
441 )
442 {
443 if (!pTxDataHead)
444 return 0;
445
446 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
447 if (byFBOption == AUTO_FB_NONE) {
448 struct vnt_tx_datahead_g *buf = pTxDataHead;
449 /* Get SignalField, ServiceField & Length */
450 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
451 byPktType, &buf->a);
452
453 vnt_get_phy_field(pDevice, cbFrameLength,
454 pDevice->byTopCCKBasicRate,
455 PK_TYPE_11B, &buf->b);
456
457 if (is_pspoll) {
458 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
459
460 buf->duration_a = dur;
461 buf->duration_b = dur;
462 } else {
463 /* Get Duration and TimeStamp */
464 buf->duration_a =
465 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
466 byPktType, wCurrentRate, bNeedAck, uFragIdx,
467 cbLastFragmentSize, uMACfragNum,
468 byFBOption));
469 buf->duration_b =
470 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
471 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
472 bNeedAck, uFragIdx, cbLastFragmentSize,
473 uMACfragNum, byFBOption));
474 }
475
476 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
477 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
478
479 return buf->duration_a;
480 } else {
481 /* Auto Fallback */
482 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
483 /* Get SignalField, ServiceField & Length */
484 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
485 byPktType, &buf->a);
486
487 vnt_get_phy_field(pDevice, cbFrameLength,
488 pDevice->byTopCCKBasicRate,
489 PK_TYPE_11B, &buf->b);
490 /* Get Duration and TimeStamp */
491 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
492 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
493 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
494 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
495 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
496 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
497 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
498 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
499
500 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
501 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
502
503 return buf->duration_a;
504 } /* if (byFBOption == AUTO_FB_NONE) */
505 } else if (byPktType == PK_TYPE_11A) {
506 if (byFBOption != AUTO_FB_NONE) {
507 /* Auto Fallback */
508 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
509 /* Get SignalField, ServiceField & Length */
510 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
511 byPktType, &buf->a);
512
513 /* Get Duration and TimeStampOff */
514 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
515 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
516 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
517 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
518 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
519 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
520 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
521 return buf->duration;
522 } else {
523 struct vnt_tx_datahead_ab *buf = pTxDataHead;
524 /* Get SignalField, ServiceField & Length */
525 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
526 byPktType, &buf->ab);
527
528 if (is_pspoll) {
529 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
530
531 buf->duration = dur;
532 } else {
533 /* Get Duration and TimeStampOff */
534 buf->duration =
535 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
536 wCurrentRate, bNeedAck, uFragIdx,
537 cbLastFragmentSize, uMACfragNum,
538 byFBOption));
539 }
540
541 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
542 return buf->duration;
543 }
544 } else {
545 struct vnt_tx_datahead_ab *buf = pTxDataHead;
546 /* Get SignalField, ServiceField & Length */
547 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
548 byPktType, &buf->ab);
549
550 if (is_pspoll) {
551 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
552
553 buf->duration = dur;
554 } else {
555 /* Get Duration and TimeStampOff */
556 buf->duration =
557 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
558 wCurrentRate, bNeedAck, uFragIdx,
559 cbLastFragmentSize, uMACfragNum,
560 byFBOption));
561 }
562
563 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
564 return buf->duration;
565 }
566 return 0;
567 }
568
569 static
570 void
s_vFillRTSHead(struct vnt_private * pDevice,unsigned char byPktType,void * pvRTS,unsigned int cbFrameLength,bool bNeedAck,bool bDisCRC,struct ieee80211_hdr * hdr,unsigned short wCurrentRate,unsigned char byFBOption)571 s_vFillRTSHead(
572 struct vnt_private *pDevice,
573 unsigned char byPktType,
574 void *pvRTS,
575 unsigned int cbFrameLength,
576 bool bNeedAck,
577 bool bDisCRC,
578 struct ieee80211_hdr *hdr,
579 unsigned short wCurrentRate,
580 unsigned char byFBOption
581 )
582 {
583 unsigned int uRTSFrameLen = 20;
584
585 if (!pvRTS)
586 return;
587
588 if (bDisCRC) {
589 /* When CRCDIS bit is on, H/W forgot to generate FCS for
590 * RTS frame, in this case we need to decrease its length by 4.
591 */
592 uRTSFrameLen -= 4;
593 }
594
595 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
596 * so we don't need to take them into account.
597 * Otherwise, we need to modify codes for them.
598 */
599 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
600 if (byFBOption == AUTO_FB_NONE) {
601 struct vnt_rts_g *buf = pvRTS;
602 /* Get SignalField, ServiceField & Length */
603 vnt_get_phy_field(pDevice, uRTSFrameLen,
604 pDevice->byTopCCKBasicRate,
605 PK_TYPE_11B, &buf->b);
606
607 vnt_get_phy_field(pDevice, uRTSFrameLen,
608 pDevice->byTopOFDMBasicRate,
609 byPktType, &buf->a);
610 /* Get Duration */
611 buf->duration_bb =
612 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
613 cbFrameLength, PK_TYPE_11B,
614 pDevice->byTopCCKBasicRate,
615 bNeedAck, byFBOption);
616 buf->duration_aa =
617 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
618 cbFrameLength, byPktType,
619 wCurrentRate, bNeedAck,
620 byFBOption);
621 buf->duration_ba =
622 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
623 cbFrameLength, byPktType,
624 wCurrentRate, bNeedAck,
625 byFBOption);
626
627 buf->data.duration = buf->duration_aa;
628 /* Get RTS Frame body */
629 buf->data.frame_control =
630 cpu_to_le16(IEEE80211_FTYPE_CTL |
631 IEEE80211_STYPE_RTS);
632
633 ether_addr_copy(buf->data.ra, hdr->addr1);
634 ether_addr_copy(buf->data.ta, hdr->addr2);
635 } else {
636 struct vnt_rts_g_fb *buf = pvRTS;
637 /* Get SignalField, ServiceField & Length */
638 vnt_get_phy_field(pDevice, uRTSFrameLen,
639 pDevice->byTopCCKBasicRate,
640 PK_TYPE_11B, &buf->b);
641
642 vnt_get_phy_field(pDevice, uRTSFrameLen,
643 pDevice->byTopOFDMBasicRate,
644 byPktType, &buf->a);
645 /* Get Duration */
646 buf->duration_bb =
647 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
648 cbFrameLength, PK_TYPE_11B,
649 pDevice->byTopCCKBasicRate,
650 bNeedAck, byFBOption);
651 buf->duration_aa =
652 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
653 cbFrameLength, byPktType,
654 wCurrentRate, bNeedAck,
655 byFBOption);
656 buf->duration_ba =
657 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
658 cbFrameLength, byPktType,
659 wCurrentRate, bNeedAck,
660 byFBOption);
661 buf->rts_duration_ba_f0 =
662 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
663 cbFrameLength, byPktType,
664 wCurrentRate, bNeedAck,
665 byFBOption);
666 buf->rts_duration_aa_f0 =
667 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
668 cbFrameLength, byPktType,
669 wCurrentRate, bNeedAck,
670 byFBOption);
671 buf->rts_duration_ba_f1 =
672 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
673 cbFrameLength, byPktType,
674 wCurrentRate, bNeedAck,
675 byFBOption);
676 buf->rts_duration_aa_f1 =
677 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
678 cbFrameLength, byPktType,
679 wCurrentRate, bNeedAck,
680 byFBOption);
681 buf->data.duration = buf->duration_aa;
682 /* Get RTS Frame body */
683 buf->data.frame_control =
684 cpu_to_le16(IEEE80211_FTYPE_CTL |
685 IEEE80211_STYPE_RTS);
686
687 ether_addr_copy(buf->data.ra, hdr->addr1);
688 ether_addr_copy(buf->data.ta, hdr->addr2);
689 } /* if (byFBOption == AUTO_FB_NONE) */
690 } else if (byPktType == PK_TYPE_11A) {
691 if (byFBOption == AUTO_FB_NONE) {
692 struct vnt_rts_ab *buf = pvRTS;
693 /* Get SignalField, ServiceField & Length */
694 vnt_get_phy_field(pDevice, uRTSFrameLen,
695 pDevice->byTopOFDMBasicRate,
696 byPktType, &buf->ab);
697 /* Get Duration */
698 buf->duration =
699 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
700 cbFrameLength, byPktType,
701 wCurrentRate, bNeedAck,
702 byFBOption);
703 buf->data.duration = buf->duration;
704 /* Get RTS Frame body */
705 buf->data.frame_control =
706 cpu_to_le16(IEEE80211_FTYPE_CTL |
707 IEEE80211_STYPE_RTS);
708
709 ether_addr_copy(buf->data.ra, hdr->addr1);
710 ether_addr_copy(buf->data.ta, hdr->addr2);
711 } else {
712 struct vnt_rts_a_fb *buf = pvRTS;
713 /* Get SignalField, ServiceField & Length */
714 vnt_get_phy_field(pDevice, uRTSFrameLen,
715 pDevice->byTopOFDMBasicRate,
716 byPktType, &buf->a);
717 /* Get Duration */
718 buf->duration =
719 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
720 cbFrameLength, byPktType,
721 wCurrentRate, bNeedAck,
722 byFBOption);
723 buf->rts_duration_f0 =
724 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
725 cbFrameLength, byPktType,
726 wCurrentRate, bNeedAck,
727 byFBOption);
728 buf->rts_duration_f1 =
729 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
730 cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck,
732 byFBOption);
733 buf->data.duration = buf->duration;
734 /* Get RTS Frame body */
735 buf->data.frame_control =
736 cpu_to_le16(IEEE80211_FTYPE_CTL |
737 IEEE80211_STYPE_RTS);
738
739 ether_addr_copy(buf->data.ra, hdr->addr1);
740 ether_addr_copy(buf->data.ta, hdr->addr2);
741 }
742 } else if (byPktType == PK_TYPE_11B) {
743 struct vnt_rts_ab *buf = pvRTS;
744 /* Get SignalField, ServiceField & Length */
745 vnt_get_phy_field(pDevice, uRTSFrameLen,
746 pDevice->byTopCCKBasicRate,
747 PK_TYPE_11B, &buf->ab);
748 /* Get Duration */
749 buf->duration =
750 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
751 byPktType, wCurrentRate, bNeedAck,
752 byFBOption);
753
754 buf->data.duration = buf->duration;
755 /* Get RTS Frame body */
756 buf->data.frame_control =
757 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
758
759 ether_addr_copy(buf->data.ra, hdr->addr1);
760 ether_addr_copy(buf->data.ta, hdr->addr2);
761 }
762 }
763
764 static
765 void
s_vFillCTSHead(struct vnt_private * pDevice,unsigned int uDMAIdx,unsigned char byPktType,void * pvCTS,unsigned int cbFrameLength,bool bNeedAck,bool bDisCRC,unsigned short wCurrentRate,unsigned char byFBOption)766 s_vFillCTSHead(
767 struct vnt_private *pDevice,
768 unsigned int uDMAIdx,
769 unsigned char byPktType,
770 void *pvCTS,
771 unsigned int cbFrameLength,
772 bool bNeedAck,
773 bool bDisCRC,
774 unsigned short wCurrentRate,
775 unsigned char byFBOption
776 )
777 {
778 unsigned int uCTSFrameLen = 14;
779
780 if (!pvCTS)
781 return;
782
783 if (bDisCRC) {
784 /* When CRCDIS bit is on, H/W forgot to generate FCS for
785 * CTS frame, in this case we need to decrease its length by 4.
786 */
787 uCTSFrameLen -= 4;
788 }
789
790 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
791 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
792 /* Auto Fall back */
793 struct vnt_cts_fb *buf = pvCTS;
794 /* Get SignalField, ServiceField & Length */
795 vnt_get_phy_field(pDevice, uCTSFrameLen,
796 pDevice->byTopCCKBasicRate,
797 PK_TYPE_11B, &buf->b);
798
799 buf->duration_ba =
800 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
801 cbFrameLength, byPktType,
802 wCurrentRate, bNeedAck,
803 byFBOption);
804
805 /* Get CTSDuration_ba_f0 */
806 buf->cts_duration_ba_f0 =
807 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
808 cbFrameLength, byPktType,
809 wCurrentRate, bNeedAck,
810 byFBOption);
811
812 /* Get CTSDuration_ba_f1 */
813 buf->cts_duration_ba_f1 =
814 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
815 cbFrameLength, byPktType,
816 wCurrentRate, bNeedAck,
817 byFBOption);
818
819 /* Get CTS Frame body */
820 buf->data.duration = buf->duration_ba;
821
822 buf->data.frame_control =
823 cpu_to_le16(IEEE80211_FTYPE_CTL |
824 IEEE80211_STYPE_CTS);
825
826 buf->reserved2 = 0x0;
827
828 ether_addr_copy(buf->data.ra,
829 pDevice->abyCurrentNetAddr);
830 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
831 struct vnt_cts *buf = pvCTS;
832 /* Get SignalField, ServiceField & Length */
833 vnt_get_phy_field(pDevice, uCTSFrameLen,
834 pDevice->byTopCCKBasicRate,
835 PK_TYPE_11B, &buf->b);
836
837 /* Get CTSDuration_ba */
838 buf->duration_ba =
839 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
840 cbFrameLength, byPktType,
841 wCurrentRate, bNeedAck,
842 byFBOption);
843
844 /* Get CTS Frame body */
845 buf->data.duration = buf->duration_ba;
846
847 buf->data.frame_control =
848 cpu_to_le16(IEEE80211_FTYPE_CTL |
849 IEEE80211_STYPE_CTS);
850
851 buf->reserved2 = 0x0;
852 ether_addr_copy(buf->data.ra,
853 pDevice->abyCurrentNetAddr);
854 }
855 }
856 }
857
858 /*
859 *
860 * Description:
861 * Generate FIFO control for MAC & Baseband controller
862 *
863 * Parameters:
864 * In:
865 * pDevice - Pointer to adapter
866 * pTxDataHead - Transmit Data Buffer
867 * pTxBufHead - pTxBufHead
868 * pvRrvTime - pvRrvTime
869 * pvRTS - RTS Buffer
870 * pCTS - CTS Buffer
871 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
872 * bNeedACK - If need ACK
873 * uDescIdx - Desc Index
874 * Out:
875 * none
876 *
877 * Return Value: none
878 *
879 -
880 * unsigned int cbFrameSize, Hdr+Payload+FCS
881 */
882 static
883 void
s_vGenerateTxParameter(struct vnt_private * pDevice,unsigned char byPktType,struct vnt_tx_fifo_head * tx_buffer_head,void * pvRrvTime,void * pvRTS,void * pvCTS,unsigned int cbFrameSize,bool bNeedACK,unsigned int uDMAIdx,void * psEthHeader,unsigned short wCurrentRate)884 s_vGenerateTxParameter(
885 struct vnt_private *pDevice,
886 unsigned char byPktType,
887 struct vnt_tx_fifo_head *tx_buffer_head,
888 void *pvRrvTime,
889 void *pvRTS,
890 void *pvCTS,
891 unsigned int cbFrameSize,
892 bool bNeedACK,
893 unsigned int uDMAIdx,
894 void *psEthHeader,
895 unsigned short wCurrentRate
896 )
897 {
898 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
899 bool bDisCRC = false;
900 unsigned char byFBOption = AUTO_FB_NONE;
901
902 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
903
904 if (fifo_ctl & FIFOCTL_CRCDIS)
905 bDisCRC = true;
906
907 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
908 byFBOption = AUTO_FB_0;
909 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
910 byFBOption = AUTO_FB_1;
911
912 if (!pvRrvTime)
913 return;
914
915 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
916 if (pvRTS) { /* RTS_need */
917 /* Fill RsvTime */
918 struct vnt_rrv_time_rts *buf = pvRrvTime;
919
920 buf->rts_rrv_time_aa = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
921 buf->rts_rrv_time_ba = get_rtscts_time(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
922 buf->rts_rrv_time_bb = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
923 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
924 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
925
926 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
927 } else {/* RTS_needless, PCF mode */
928 struct vnt_rrv_time_cts *buf = pvRrvTime;
929
930 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
931 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
932 buf->cts_rrv_time_ba = get_rtscts_time(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
933
934 /* Fill CTS */
935 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
936 }
937 } else if (byPktType == PK_TYPE_11A) {
938 if (pvRTS) {/* RTS_need, non PCF mode */
939 struct vnt_rrv_time_ab *buf = pvRrvTime;
940
941 buf->rts_rrv_time = get_rtscts_time(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
942 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
943
944 /* Fill RTS */
945 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
946 } else if (!pvRTS) {/* RTS_needless, non PCF mode */
947 struct vnt_rrv_time_ab *buf = pvRrvTime;
948
949 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
950 }
951 } else if (byPktType == PK_TYPE_11B) {
952 if (pvRTS) {/* RTS_need, non PCF mode */
953 struct vnt_rrv_time_ab *buf = pvRrvTime;
954
955 buf->rts_rrv_time = get_rtscts_time(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
956 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
957
958 /* Fill RTS */
959 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
960 } else { /* RTS_needless, non PCF mode */
961 struct vnt_rrv_time_ab *buf = pvRrvTime;
962
963 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
964 }
965 }
966 }
967
968 static unsigned int
s_cbFillTxBufHead(struct vnt_private * pDevice,unsigned char byPktType,unsigned char * pbyTxBufferAddr,unsigned int uDMAIdx,struct vnt_tx_desc * pHeadTD,unsigned int is_pspoll)969 s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
970 unsigned char *pbyTxBufferAddr,
971 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
972 unsigned int is_pspoll)
973 {
974 struct vnt_td_info *td_info = pHeadTD->td_info;
975 struct sk_buff *skb = td_info->skb;
976 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
977 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
978 struct vnt_tx_fifo_head *tx_buffer_head =
979 (struct vnt_tx_fifo_head *)td_info->buf;
980 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
981 unsigned int cbFrameSize;
982 __le16 uDuration;
983 unsigned char *pbyBuffer;
984 unsigned int uLength = 0;
985 unsigned int cbMICHDR = 0;
986 unsigned int uMACfragNum = 1;
987 unsigned int uPadding = 0;
988 unsigned int cbReqCount = 0;
989 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
990 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
991 struct vnt_tx_desc *ptdCurr;
992 unsigned int cbHeaderLength = 0;
993 void *pvRrvTime = NULL;
994 struct vnt_mic_hdr *pMICHDR = NULL;
995 void *pvRTS = NULL;
996 void *pvCTS = NULL;
997 void *pvTxDataHd = NULL;
998 unsigned short wTxBufSize; /* FFinfo size */
999 unsigned char byFBOption = AUTO_FB_NONE;
1000
1001 cbFrameSize = skb->len + 4;
1002
1003 if (info->control.hw_key) {
1004 switch (info->control.hw_key->cipher) {
1005 case WLAN_CIPHER_SUITE_CCMP:
1006 cbMICHDR = sizeof(struct vnt_mic_hdr);
1007 default:
1008 break;
1009 }
1010
1011 cbFrameSize += info->control.hw_key->icv_len;
1012
1013 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
1014 /* MAC Header should be padding 0 to DW alignment. */
1015 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
1016 uPadding %= 4;
1017 }
1018 }
1019
1020 /*
1021 * Use for AUTO FALL BACK
1022 */
1023 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
1024 byFBOption = AUTO_FB_0;
1025 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
1026 byFBOption = AUTO_FB_1;
1027
1028 /* Set RrvTime/RTS/CTS Buffer */
1029 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
1030 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
1031
1032 if (byFBOption == AUTO_FB_NONE) {
1033 if (bRTS) {/* RTS_need */
1034 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1035 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1036 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1037 pvCTS = NULL;
1038 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1039 cbMICHDR + sizeof(struct vnt_rts_g));
1040 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1041 cbMICHDR + sizeof(struct vnt_rts_g) +
1042 sizeof(struct vnt_tx_datahead_g);
1043 } else { /* RTS_needless */
1044 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1045 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1046 pvRTS = NULL;
1047 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1048 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1049 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
1050 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1051 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
1052 }
1053 } else {
1054 /* Auto Fall Back */
1055 if (bRTS) {/* RTS_need */
1056 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1057 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
1058 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
1059 pvCTS = NULL;
1060 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1061 cbMICHDR + sizeof(struct vnt_rts_g_fb));
1062 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1063 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1064 } else { /* RTS_needless */
1065 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1066 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
1067 pvRTS = NULL;
1068 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1069 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1070 cbMICHDR + sizeof(struct vnt_cts_fb));
1071 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1072 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
1073 }
1074 } /* Auto Fall Back */
1075 } else {/* 802.11a/b packet */
1076
1077 if (byFBOption == AUTO_FB_NONE) {
1078 if (bRTS) {
1079 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1080 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1081 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1082 pvCTS = NULL;
1083 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1084 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
1085 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1086 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
1087 } else { /* RTS_needless, need MICHDR */
1088 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1089 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1090 pvRTS = NULL;
1091 pvCTS = NULL;
1092 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1093 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1094 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
1095 }
1096 } else {
1097 /* Auto Fall Back */
1098 if (bRTS) { /* RTS_need */
1099 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1100 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1101 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1102 pvCTS = NULL;
1103 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1104 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
1105 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1106 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
1107 } else { /* RTS_needless */
1108 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1109 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
1110 pvRTS = NULL;
1111 pvCTS = NULL;
1112 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1113 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1114 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
1115 }
1116 } /* Auto Fall Back */
1117 }
1118
1119 td_info->mic_hdr = pMICHDR;
1120
1121 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
1122
1123 /* Fill FIFO,RrvTime,RTS,and CTS */
1124 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1125 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1126 /* Fill DataHead */
1127 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
1128 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
1129
1130 hdr->duration_id = uDuration;
1131
1132 cbReqCount = cbHeaderLength + uPadding + skb->len;
1133 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
1134 uLength = cbHeaderLength + uPadding;
1135
1136 /* Copy the Packet into a tx Buffer */
1137 memcpy((pbyBuffer + uLength), skb->data, skb->len);
1138
1139 ptdCurr = pHeadTD;
1140
1141 ptdCurr->td_info->req_count = (u16)cbReqCount;
1142
1143 return cbHeaderLength;
1144 }
1145
vnt_fill_txkey(struct ieee80211_hdr * hdr,u8 * key_buffer,struct ieee80211_key_conf * tx_key,struct sk_buff * skb,u16 payload_len,struct vnt_mic_hdr * mic_hdr)1146 static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1147 struct ieee80211_key_conf *tx_key,
1148 struct sk_buff *skb, u16 payload_len,
1149 struct vnt_mic_hdr *mic_hdr)
1150 {
1151 u64 pn64;
1152 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1153
1154 /* strip header and icv len from payload */
1155 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1156 payload_len -= tx_key->icv_len;
1157
1158 switch (tx_key->cipher) {
1159 case WLAN_CIPHER_SUITE_WEP40:
1160 case WLAN_CIPHER_SUITE_WEP104:
1161 memcpy(key_buffer, iv, 3);
1162 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1163
1164 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1165 memcpy(key_buffer + 8, iv, 3);
1166 memcpy(key_buffer + 11,
1167 tx_key->key, WLAN_KEY_LEN_WEP40);
1168 }
1169
1170 break;
1171 case WLAN_CIPHER_SUITE_TKIP:
1172 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1173
1174 break;
1175 case WLAN_CIPHER_SUITE_CCMP:
1176
1177 if (!mic_hdr)
1178 return;
1179
1180 mic_hdr->id = 0x59;
1181 mic_hdr->payload_len = cpu_to_be16(payload_len);
1182 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1183
1184 pn64 = atomic64_read(&tx_key->tx_pn);
1185 mic_hdr->ccmp_pn[5] = pn64;
1186 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1187 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1188 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1189 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1190 mic_hdr->ccmp_pn[0] = pn64 >> 40;
1191
1192 if (ieee80211_has_a4(hdr->frame_control))
1193 mic_hdr->hlen = cpu_to_be16(28);
1194 else
1195 mic_hdr->hlen = cpu_to_be16(22);
1196
1197 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1198 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1199 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1200
1201 mic_hdr->frame_control = cpu_to_le16(
1202 le16_to_cpu(hdr->frame_control) & 0xc78f);
1203 mic_hdr->seq_ctrl = cpu_to_le16(
1204 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1205
1206 if (ieee80211_has_a4(hdr->frame_control))
1207 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1208
1209 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1210
1211 break;
1212 default:
1213 break;
1214 }
1215 }
1216
vnt_generate_fifo_header(struct vnt_private * priv,u32 dma_idx,struct vnt_tx_desc * head_td,struct sk_buff * skb)1217 int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1218 struct vnt_tx_desc *head_td, struct sk_buff *skb)
1219 {
1220 struct vnt_td_info *td_info = head_td->td_info;
1221 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1222 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1223 struct ieee80211_rate *rate;
1224 struct ieee80211_key_conf *tx_key;
1225 struct ieee80211_hdr *hdr;
1226 struct vnt_tx_fifo_head *tx_buffer_head =
1227 (struct vnt_tx_fifo_head *)td_info->buf;
1228 u16 tx_body_size = skb->len, current_rate;
1229 u8 pkt_type;
1230 bool is_pspoll = false;
1231
1232 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1233
1234 hdr = (struct ieee80211_hdr *)(skb->data);
1235
1236 rate = ieee80211_get_tx_rate(priv->hw, info);
1237
1238 current_rate = rate->hw_value;
1239 if (priv->wCurrentRate != current_rate &&
1240 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1241 priv->wCurrentRate = current_rate;
1242
1243 RFbSetPower(priv, priv->wCurrentRate,
1244 priv->hw->conf.chandef.chan->hw_value);
1245 }
1246
1247 if (current_rate > RATE_11M) {
1248 if (info->band == NL80211_BAND_5GHZ) {
1249 pkt_type = PK_TYPE_11A;
1250 } else {
1251 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1252 pkt_type = PK_TYPE_11GB;
1253 else
1254 pkt_type = PK_TYPE_11GA;
1255 }
1256 } else {
1257 pkt_type = PK_TYPE_11B;
1258 }
1259
1260 /*Set fifo controls */
1261 if (pkt_type == PK_TYPE_11A)
1262 tx_buffer_head->fifo_ctl = 0;
1263 else if (pkt_type == PK_TYPE_11B)
1264 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1265 else if (pkt_type == PK_TYPE_11GB)
1266 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1267 else if (pkt_type == PK_TYPE_11GA)
1268 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1269
1270 /* generate interrupt */
1271 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1272
1273 if (!ieee80211_is_data(hdr->frame_control)) {
1274 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1275 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1276 tx_buffer_head->time_stamp =
1277 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1278 } else {
1279 tx_buffer_head->time_stamp =
1280 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1281 }
1282
1283 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1284 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1285
1286 if (ieee80211_has_retry(hdr->frame_control))
1287 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1288
1289 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1290 priv->byPreambleType = PREAMBLE_SHORT;
1291 else
1292 priv->byPreambleType = PREAMBLE_LONG;
1293
1294 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1295 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1296
1297 if (ieee80211_has_a4(hdr->frame_control)) {
1298 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1299 priv->bLongHeader = true;
1300 }
1301
1302 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1303 is_pspoll = true;
1304
1305 tx_buffer_head->frag_ctl =
1306 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1307
1308 if (info->control.hw_key) {
1309 tx_key = info->control.hw_key;
1310
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);
1315 break;
1316 case WLAN_CIPHER_SUITE_TKIP:
1317 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1318 break;
1319 case WLAN_CIPHER_SUITE_CCMP:
1320 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1321 default:
1322 break;
1323 }
1324 }
1325
1326 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1327
1328 /* legacy rates TODO use ieee80211_tx_rate */
1329 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1330 if (priv->byAutoFBCtrl == AUTO_FB_0)
1331 tx_buffer_head->fifo_ctl |=
1332 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1333 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1334 tx_buffer_head->fifo_ctl |=
1335 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1336 }
1337
1338 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1339
1340 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
1341 dma_idx, head_td, is_pspoll);
1342
1343 if (info->control.hw_key) {
1344 tx_key = info->control.hw_key;
1345 if (tx_key->keylen > 0)
1346 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1347 tx_key, skb, tx_body_size,
1348 td_info->mic_hdr);
1349 }
1350
1351 return 0;
1352 }
1353
vnt_beacon_xmit(struct vnt_private * priv,struct sk_buff * skb)1354 static int vnt_beacon_xmit(struct vnt_private *priv,
1355 struct sk_buff *skb)
1356 {
1357 struct vnt_tx_short_buf_head *short_head =
1358 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1359 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1360 (priv->tx_beacon_bufs + sizeof(*short_head));
1361 struct ieee80211_tx_info *info;
1362 u32 frame_size = skb->len + 4;
1363 u16 current_rate;
1364
1365 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1366
1367 if (priv->byBBType == BB_TYPE_11A) {
1368 current_rate = RATE_6M;
1369
1370 /* Get SignalField,ServiceField,Length */
1371 vnt_get_phy_field(priv, frame_size, current_rate,
1372 PK_TYPE_11A, &short_head->ab);
1373
1374 /* Get Duration and TimeStampOff */
1375 short_head->duration =
1376 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1377 frame_size, PK_TYPE_11A, current_rate,
1378 false, 0, 0, 1, AUTO_FB_NONE));
1379
1380 short_head->time_stamp_off =
1381 vnt_time_stamp_off(priv, current_rate);
1382 } else {
1383 current_rate = RATE_1M;
1384 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1385
1386 /* Get SignalField,ServiceField,Length */
1387 vnt_get_phy_field(priv, frame_size, current_rate,
1388 PK_TYPE_11B, &short_head->ab);
1389
1390 /* Get Duration and TimeStampOff */
1391 short_head->duration =
1392 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1393 frame_size, PK_TYPE_11B, current_rate,
1394 false, 0, 0, 1, AUTO_FB_NONE));
1395
1396 short_head->time_stamp_off =
1397 vnt_time_stamp_off(priv, current_rate);
1398 }
1399
1400 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1401
1402 /* Copy Beacon */
1403 memcpy(mgmt_hdr, skb->data, skb->len);
1404
1405 /* time stamp always 0 */
1406 mgmt_hdr->u.beacon.timestamp = 0;
1407
1408 info = IEEE80211_SKB_CB(skb);
1409 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1410 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1411
1412 hdr->duration_id = 0;
1413 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1414 }
1415
1416 priv->wSeqCounter++;
1417 if (priv->wSeqCounter > 0x0fff)
1418 priv->wSeqCounter = 0;
1419
1420 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1421
1422 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1423
1424 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1425 /* Set auto Transmit on */
1426 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1427 /* Poll Transmit the adapter */
1428 MACvTransmitBCN(priv->PortOffset);
1429
1430 return 0;
1431 }
1432
vnt_beacon_make(struct vnt_private * priv,struct ieee80211_vif * vif)1433 int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1434 {
1435 struct sk_buff *beacon;
1436
1437 beacon = ieee80211_beacon_get(priv->hw, vif);
1438 if (!beacon)
1439 return -ENOMEM;
1440
1441 if (vnt_beacon_xmit(priv, beacon)) {
1442 ieee80211_free_txskb(priv->hw, beacon);
1443 return -ENODEV;
1444 }
1445
1446 return 0;
1447 }
1448
vnt_beacon_enable(struct vnt_private * priv,struct ieee80211_vif * vif,struct ieee80211_bss_conf * conf)1449 int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1450 struct ieee80211_bss_conf *conf)
1451 {
1452 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1453
1454 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1455
1456 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
1457
1458 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1459
1460 return vnt_beacon_make(priv, vif);
1461 }
1462