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

source code of linux/drivers/staging/vt6655/rxtx.c