blob: 33c4aa49946d33185a78d484d6fcc17cbc7235f6 [file] [log] [blame]
Forest Bond5449c682009-04-25 10:30:44 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * File: rxtx.c
20 *
21 * Purpose: handle WMAC/802.3/802.11 rx & tx functions
22 *
23 * Author: Lyndon Chen
24 *
25 * Date: May 20, 2003
26 *
27 * Functions:
Gilles Espinassef77f13e2010-03-29 15:41:47 +020028 * s_vGenerateTxParameter - Generate tx dma required parameter.
Forest Bond5449c682009-04-25 10:30:44 -040029 * vGenerateMACHeader - Translate 802.3 to 802.11 header
Justin P. Mattock7664ec82012-08-20 08:43:15 -070030 * cbGetFragCount - Calculate fragment number count
Forest Bond5449c682009-04-25 10:30:44 -040031 * csBeacon_xmit - beacon tx function
32 * csMgmt_xmit - management tx function
33 * s_cbFillTxBufHead - fulfill tx dma buffer header
34 * s_uGetDataDuration - get tx data required duration
35 * s_uFillDataHead- fulfill tx data duration header
Gilles Espinassef77f13e2010-03-29 15:41:47 +020036 * s_uGetRTSCTSDuration- get rtx/cts required duration
Forest Bond5449c682009-04-25 10:30:44 -040037 * s_uGetRTSCTSRsvTime- get rts/cts reserved time
38 * s_uGetTxRsvTime- get frame reserved time
39 * s_vFillCTSHead- fulfill CTS ctl header
Gilles Espinassef77f13e2010-03-29 15:41:47 +020040 * s_vFillFragParameter- Set fragment ctl parameter.
Forest Bond5449c682009-04-25 10:30:44 -040041 * s_vFillRTSHead- fulfill RTS ctl header
42 * s_vFillTxKey- fulfill tx encrypt key
43 * s_vSWencryption- Software encrypt header
44 * vDMA0_tx_80211- tx 802.11 frame via dma0
45 * vGenerateFIFOHeader- Generate tx FIFO ctl header
46 *
47 * Revision History:
48 *
49 */
50
Forest Bond5449c682009-04-25 10:30:44 -040051#include "device.h"
Forest Bond5449c682009-04-25 10:30:44 -040052#include "rxtx.h"
Forest Bond5449c682009-04-25 10:30:44 -040053#include "card.h"
Forest Bond5449c682009-04-25 10:30:44 -040054#include "mac.h"
Forest Bond5449c682009-04-25 10:30:44 -040055#include "baseband.h"
Forest Bond5449c682009-04-25 10:30:44 -040056#include "rf.h"
Forest Bond5449c682009-04-25 10:30:44 -040057
58/*--------------------- Static Definitions -------------------------*/
59
60/*--------------------- Static Classes ----------------------------*/
61
62/*--------------------- Static Variables --------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -040063
Forest Bond5449c682009-04-25 10:30:44 -040064/*--------------------- Static Functions --------------------------*/
65
66/*--------------------- Static Definitions -------------------------*/
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020067#define CRITICAL_PACKET_LEN 256 /* if packet size < 256 -> in-direct send
68 packet size >= 256 -> direct send */
Forest Bond5449c682009-04-25 10:30:44 -040069
Anton Protopopov83e771f2014-07-01 21:06:29 +040070static const unsigned short wTimeStampOff[2][MAX_RATE] = {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020071 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
72 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
Joe Perches547f1cf2013-03-18 10:45:01 -070073};
Forest Bond5449c682009-04-25 10:30:44 -040074
Anton Protopopov83e771f2014-07-01 21:06:29 +040075static const unsigned short wFB_Opt0[2][5] = {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020076 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
77 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
Joe Perches547f1cf2013-03-18 10:45:01 -070078};
Anton Protopopov83e771f2014-07-01 21:06:29 +040079static const unsigned short wFB_Opt1[2][5] = {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020080 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
81 {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
Joe Perches547f1cf2013-03-18 10:45:01 -070082};
Forest Bond5449c682009-04-25 10:30:44 -040083
Forest Bond5449c682009-04-25 10:30:44 -040084#define RTSDUR_BB 0
85#define RTSDUR_BA 1
86#define RTSDUR_AA 2
87#define CTSDUR_BA 3
88#define RTSDUR_BA_F0 4
89#define RTSDUR_AA_F0 5
90#define RTSDUR_BA_F1 6
91#define RTSDUR_AA_F1 7
92#define CTSDUR_BA_F0 8
93#define CTSDUR_BA_F1 9
94#define DATADUR_B 10
95#define DATADUR_A 11
96#define DATADUR_A_F0 12
97#define DATADUR_A_F1 13
98
99/*--------------------- Static Functions --------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -0400100static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700101void
Forest Bond5449c682009-04-25 10:30:44 -0400102s_vFillRTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100103 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700104 unsigned char byPktType,
105 void *pvRTS,
106 unsigned int cbFrameLength,
107 bool bNeedAck,
108 bool bDisCRC,
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000109 struct ieee80211_hdr *hdr,
Joe Perches547f1cf2013-03-18 10:45:01 -0700110 unsigned short wCurrentRate,
111 unsigned char byFBOption
112);
Forest Bond5449c682009-04-25 10:30:44 -0400113
114static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700115void
Forest Bond5449c682009-04-25 10:30:44 -0400116s_vGenerateTxParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100117 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700118 unsigned char byPktType,
Malcolm Priestleydf184802015-04-01 22:32:51 +0100119 struct vnt_tx_fifo_head *,
Joe Perches547f1cf2013-03-18 10:45:01 -0700120 void *pvRrvTime,
121 void *pvRTS,
122 void *pvCTS,
123 unsigned int cbFrameSize,
124 bool bNeedACK,
125 unsigned int uDMAIdx,
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +0000126 void *psEthHeader,
Joe Perches547f1cf2013-03-18 10:45:01 -0700127 unsigned short wCurrentRate
128);
Forest Bond5449c682009-04-25 10:30:44 -0400129
Charles Clémentfe4f34b2010-06-25 10:48:53 -0700130static unsigned int
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100131s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
Malcolm Priestley19f3ed32014-11-29 00:02:03 +0000132 unsigned char *pbyTxBufferAddr,
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100133 unsigned int uDMAIdx, PSTxDesc pHeadTD,
Malcolm Priestley154bb8b2014-11-29 00:02:02 +0000134 unsigned int uNodeIndex);
Forest Bond5449c682009-04-25 10:30:44 -0400135
Forest Bond5449c682009-04-25 10:30:44 -0400136static
Malcolm Priestleya479ffc2014-08-30 22:25:38 +0100137__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700138s_uFillDataHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100139 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700140 unsigned char byPktType,
141 void *pTxDataHead,
142 unsigned int cbFrameLength,
143 unsigned int uDMAIdx,
144 bool bNeedAck,
145 unsigned int uFragIdx,
146 unsigned int cbLastFragmentSize,
147 unsigned int uMACfragNum,
148 unsigned char byFBOption,
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000149 unsigned short wCurrentRate,
150 bool is_pspoll
Joe Perches547f1cf2013-03-18 10:45:01 -0700151);
Forest Bond5449c682009-04-25 10:30:44 -0400152
Forest Bond5449c682009-04-25 10:30:44 -0400153/*--------------------- Export Variables --------------------------*/
154
Malcolm Priestleyd6b95c02014-08-30 22:25:33 +0100155static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
156{
157 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
158 [rate % MAX_RATE]);
159}
160
Jim Lieb7e809a92009-07-30 10:27:21 -0700161/*byPktType : PK_TYPE_11A 0
Joe Perches547f1cf2013-03-18 10:45:01 -0700162 PK_TYPE_11B 1
163 PK_TYPE_11GB 2
164 PK_TYPE_11GA 3
Forest Bond5449c682009-04-25 10:30:44 -0400165*/
166static
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700167unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -0700168s_uGetTxRsvTime(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100169 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700170 unsigned char byPktType,
171 unsigned int cbFrameLength,
172 unsigned short wRate,
173 bool bNeedAck
174)
Forest Bond5449c682009-04-25 10:30:44 -0400175{
Joe Perches547f1cf2013-03-18 10:45:01 -0700176 unsigned int uDataTime, uAckTime;
Forest Bond5449c682009-04-25 10:30:44 -0400177
Joe Perches547f1cf2013-03-18 10:45:01 -0700178 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200179 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
Joe Perches547f1cf2013-03-18 10:45:01 -0700180 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200181 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
Joe Perches547f1cf2013-03-18 10:45:01 -0700182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400183
Guido Martínezbc5cf652014-04-19 16:45:00 -0300184 if (bNeedAck)
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700185 return uDataTime + pDevice->uSIFS + uAckTime;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300186 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700187 return uDataTime;
Forest Bond5449c682009-04-25 10:30:44 -0400188}
189
Malcolm Priestleye7a3481b2014-08-30 22:25:30 +0100190static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
191 u32 frame_length, u16 rate, bool need_ack)
192{
193 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
194 frame_length, rate, need_ack));
195}
196
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200197/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
Forest Bond5449c682009-04-25 10:30:44 -0400198static
Malcolm Priestley853532d2014-08-30 22:25:31 +0100199__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700200s_uGetRTSCTSRsvTime(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100201 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700202 unsigned char byRTSRsvType,
203 unsigned char byPktType,
204 unsigned int cbFrameLength,
205 unsigned short wCurrentRate
206)
Forest Bond5449c682009-04-25 10:30:44 -0400207{
Piotr Kubusbc22b492015-01-10 15:35:45 +0100208 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond5449c682009-04-25 10:30:44 -0400209
Joe Perches547f1cf2013-03-18 10:45:01 -0700210 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400211
Joe Perches547f1cf2013-03-18 10:45:01 -0700212 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200213 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
Joe Perches547f1cf2013-03-18 10:45:01 -0700214 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
215 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200216 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
Joe Perches547f1cf2013-03-18 10:45:01 -0700217 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
218 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
219 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200220 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
Joe Perches547f1cf2013-03-18 10:45:01 -0700221 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
222 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200223 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
Joe Perches547f1cf2013-03-18 10:45:01 -0700224 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
225 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
226 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
Malcolm Priestley853532d2014-08-30 22:25:31 +0100227 return cpu_to_le16((u16)uRrvTime);
Joe Perches547f1cf2013-03-18 10:45:01 -0700228 }
Forest Bond5449c682009-04-25 10:30:44 -0400229
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200230 /* RTSRrvTime */
Joe Perches547f1cf2013-03-18 10:45:01 -0700231 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
Malcolm Priestley853532d2014-08-30 22:25:31 +0100232 return cpu_to_le16((u16)uRrvTime);
Forest Bond5449c682009-04-25 10:30:44 -0400233}
234
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200235/* byFreqType 0: 5GHz, 1:2.4Ghz */
Forest Bond5449c682009-04-25 10:30:44 -0400236static
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700237unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -0700238s_uGetDataDuration(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100239 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700240 unsigned char byDurType,
241 unsigned int cbFrameLength,
242 unsigned char byPktType,
243 unsigned short wRate,
244 bool bNeedAck,
245 unsigned int uFragIdx,
246 unsigned int cbLastFragmentSize,
247 unsigned int uMACfragNum,
248 unsigned char byFBOption
249)
Forest Bond5449c682009-04-25 10:30:44 -0400250{
Cristina Opriceana19cd2292015-03-04 12:37:28 +0200251 bool bLastFrag = false;
Joe Perches547f1cf2013-03-18 10:45:01 -0700252 unsigned int uAckTime = 0, uNextPktTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400253
Guido Martínezbc5cf652014-04-19 16:45:00 -0300254 if (uFragIdx == (uMACfragNum-1))
Cristina Opriceana19cd2292015-03-04 12:37:28 +0200255 bLastFrag = true;
Forest Bond5449c682009-04-25 10:30:44 -0400256
Joe Perches547f1cf2013-03-18 10:45:01 -0700257 switch (byDurType) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200258 case DATADUR_B: /* DATADUR_B */
259 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700260 if (bNeedAck) {
261 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700262 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700263 } else {
264 return 0;
265 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200266 } else {/* First Frag or Mid Frag */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300267 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700268 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300269 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300271
Joe Perches547f1cf2013-03-18 10:45:01 -0700272 if (bNeedAck) {
273 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700274 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700275 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700276 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700277 }
278 }
279 break;
Forest Bond5449c682009-04-25 10:30:44 -0400280
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200281 case DATADUR_A: /* DATADUR_A */
282 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700283 if (bNeedAck) {
284 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700285 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700286 } else {
287 return 0;
288 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200289 } else {/* First Frag or Mid Frag */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300290 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700291 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300292 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300294
Joe Perches547f1cf2013-03-18 10:45:01 -0700295 if (bNeedAck) {
296 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700297 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700298 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700299 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700300 }
301 }
302 break;
Forest Bond5449c682009-04-25 10:30:44 -0400303
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200304 case DATADUR_A_F0: /* DATADUR_A_F0 */
305 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700306 if (bNeedAck) {
307 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700308 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700309 } else {
310 return 0;
311 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200312 } else { /* First Frag or Mid Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700313 if (byFBOption == AUTO_FB_0) {
314 if (wRate < RATE_18M)
315 wRate = RATE_18M;
316 else if (wRate > RATE_54M)
317 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400318
Guido Martínezbc5cf652014-04-19 16:45:00 -0300319 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700320 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300321 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300323
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200324 } else { /* (byFBOption == AUTO_FB_1) */
Joe Perches547f1cf2013-03-18 10:45:01 -0700325 if (wRate < RATE_18M)
326 wRate = RATE_18M;
327 else if (wRate > RATE_54M)
328 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400329
Guido Martínezbc5cf652014-04-19 16:45:00 -0300330 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700331 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300332 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300334
Joe Perches547f1cf2013-03-18 10:45:01 -0700335 }
Forest Bond5449c682009-04-25 10:30:44 -0400336
Joe Perches547f1cf2013-03-18 10:45:01 -0700337 if (bNeedAck) {
338 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700339 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700340 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700341 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700342 }
343 }
344 break;
Forest Bond5449c682009-04-25 10:30:44 -0400345
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200346 case DATADUR_A_F1: /* DATADUR_A_F1 */
347 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700348 if (bNeedAck) {
349 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700350 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700351 } else {
352 return 0;
353 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200354 } else { /* First Frag or Mid Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700355 if (byFBOption == AUTO_FB_0) {
356 if (wRate < RATE_18M)
357 wRate = RATE_18M;
358 else if (wRate > RATE_54M)
359 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400360
Guido Martínezbc5cf652014-04-19 16:45:00 -0300361 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700362 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300363 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Forest Bond5449c682009-04-25 10:30:44 -0400365
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200366 } else { /* (byFBOption == AUTO_FB_1) */
Joe Perches547f1cf2013-03-18 10:45:01 -0700367 if (wRate < RATE_18M)
368 wRate = RATE_18M;
369 else if (wRate > RATE_54M)
370 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400371
Guido Martínezbc5cf652014-04-19 16:45:00 -0300372 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700373 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300374 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Joe Perches547f1cf2013-03-18 10:45:01 -0700376 }
377 if (bNeedAck) {
378 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700379 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700380 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700381 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700382 }
383 }
384 break;
Forest Bond5449c682009-04-25 10:30:44 -0400385
Joe Perches547f1cf2013-03-18 10:45:01 -0700386 default:
387 break;
388 }
Forest Bond5449c682009-04-25 10:30:44 -0400389
Charles Clément5a5a2a62010-08-01 17:15:49 +0200390 ASSERT(false);
Forest Bond5449c682009-04-25 10:30:44 -0400391 return 0;
392}
393
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200394/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
Forest Bond5449c682009-04-25 10:30:44 -0400395static
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100396__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700397s_uGetRTSCTSDuration(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100398 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700399 unsigned char byDurType,
400 unsigned int cbFrameLength,
401 unsigned char byPktType,
402 unsigned short wRate,
403 bool bNeedAck,
404 unsigned char byFBOption
405)
Forest Bond5449c682009-04-25 10:30:44 -0400406{
Joe Perches547f1cf2013-03-18 10:45:01 -0700407 unsigned int uCTSTime = 0, uDurTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400408
Joe Perches547f1cf2013-03-18 10:45:01 -0700409 switch (byDurType) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200410 case RTSDUR_BB: /* RTSDuration_bb */
Joe Perches547f1cf2013-03-18 10:45:01 -0700411 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
412 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
413 break;
Forest Bond5449c682009-04-25 10:30:44 -0400414
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200415 case RTSDUR_BA: /* RTSDuration_ba */
Joe Perches547f1cf2013-03-18 10:45:01 -0700416 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
417 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
418 break;
Forest Bond5449c682009-04-25 10:30:44 -0400419
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200420 case RTSDUR_AA: /* RTSDuration_aa */
Joe Perches547f1cf2013-03-18 10:45:01 -0700421 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
422 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
423 break;
Forest Bond5449c682009-04-25 10:30:44 -0400424
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200425 case CTSDUR_BA: /* CTSDuration_ba */
Joe Perches547f1cf2013-03-18 10:45:01 -0700426 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
427 break;
Forest Bond5449c682009-04-25 10:30:44 -0400428
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200429 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700430 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300431 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700432 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300433 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700434 uDurTime = uCTSTime + 2 * pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300435
Joe Perches547f1cf2013-03-18 10:45:01 -0700436 break;
Forest Bond5449c682009-04-25 10:30:44 -0400437
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200438 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700439 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300440 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700441 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300442 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700443 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300444
Joe Perches547f1cf2013-03-18 10:45:01 -0700445 break;
Forest Bond5449c682009-04-25 10:30:44 -0400446
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200447 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700448 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300449 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700450 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300451 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700452 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300453
Joe Perches547f1cf2013-03-18 10:45:01 -0700454 break;
Forest Bond5449c682009-04-25 10:30:44 -0400455
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200456 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700457 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300458 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700459 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300460 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700461 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300462
Joe Perches547f1cf2013-03-18 10:45:01 -0700463 break;
Forest Bond5449c682009-04-25 10:30:44 -0400464
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200465 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300466 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700467 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300468 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700469 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300470
Joe Perches547f1cf2013-03-18 10:45:01 -0700471 break;
Forest Bond5449c682009-04-25 10:30:44 -0400472
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200473 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300474 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700475 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300476 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700477 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300478
Joe Perches547f1cf2013-03-18 10:45:01 -0700479 break;
Forest Bond5449c682009-04-25 10:30:44 -0400480
Joe Perches547f1cf2013-03-18 10:45:01 -0700481 default:
482 break;
483 }
Forest Bond5449c682009-04-25 10:30:44 -0400484
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100485 return cpu_to_le16((u16)uDurTime);
Forest Bond5449c682009-04-25 10:30:44 -0400486}
487
Forest Bond5449c682009-04-25 10:30:44 -0400488static
Malcolm Priestleya479ffc2014-08-30 22:25:38 +0100489__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700490s_uFillDataHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100491 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700492 unsigned char byPktType,
493 void *pTxDataHead,
494 unsigned int cbFrameLength,
495 unsigned int uDMAIdx,
496 bool bNeedAck,
497 unsigned int uFragIdx,
498 unsigned int cbLastFragmentSize,
499 unsigned int uMACfragNum,
500 unsigned char byFBOption,
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000501 unsigned short wCurrentRate,
502 bool is_pspoll
Joe Perches547f1cf2013-03-18 10:45:01 -0700503)
Forest Bond5449c682009-04-25 10:30:44 -0400504{
Forest Bond5449c682009-04-25 10:30:44 -0400505
Guido Martínezbc5cf652014-04-19 16:45:00 -0300506 if (pTxDataHead == NULL)
Joe Perches547f1cf2013-03-18 10:45:01 -0700507 return 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300508
Forest Bond5449c682009-04-25 10:30:44 -0400509
Joe Perches547f1cf2013-03-18 10:45:01 -0700510 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
511 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100512 struct vnt_tx_datahead_g *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100513 /* Get SignalField, ServiceField & Length */
514 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100515 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100516
517 vnt_get_phy_field(pDevice, cbFrameLength,
518 pDevice->byTopCCKBasicRate,
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100519 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100520
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000521 if (is_pspoll) {
522 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
523
524 buf->duration_a = dur;
525 buf->duration_b = dur;
526 } else {
527 /* Get Duration and TimeStamp */
528 buf->duration_a =
529 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
530 byPktType, wCurrentRate, bNeedAck, uFragIdx,
531 cbLastFragmentSize, uMACfragNum,
532 byFBOption));
533 buf->duration_b =
534 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
535 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
536 bNeedAck, uFragIdx, cbLastFragmentSize,
537 uMACfragNum, byFBOption));
538 }
Forest Bond5449c682009-04-25 10:30:44 -0400539
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100540 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
541 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400542
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100543 return buf->duration_a;
Joe Perches547f1cf2013-03-18 10:45:01 -0700544 } else {
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100545 /* Auto Fallback */
546 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100547 /* Get SignalField, ServiceField & Length */
548 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100549 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100550
551 vnt_get_phy_field(pDevice, cbFrameLength,
552 pDevice->byTopCCKBasicRate,
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100553 PK_TYPE_11B, &buf->b);
554 /* Get Duration and TimeStamp */
555 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
556 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
557 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
558 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
559 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
560 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
561 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
562 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
Forest Bond5449c682009-04-25 10:30:44 -0400563
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100564 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
565 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400566
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100567 return buf->duration_a;
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200568 } /* if (byFBOption == AUTO_FB_NONE) */
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700569 } else if (byPktType == PK_TYPE_11A) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700570 if ((byFBOption != AUTO_FB_NONE)) {
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100571 /* Auto Fallback */
572 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100573 /* Get SignalField, ServiceField & Length */
574 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100575 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100576
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100577 /* Get Duration and TimeStampOff */
578 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
579 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
580 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
581 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
582 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
583 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
584 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
585 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700586 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100587 struct vnt_tx_datahead_ab *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100588 /* Get SignalField, ServiceField & Length */
589 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100590 byPktType, &buf->ab);
Forest Bond5449c682009-04-25 10:30:44 -0400591
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000592 if (is_pspoll) {
593 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
594
595 buf->duration = dur;
596 } else {
597 /* Get Duration and TimeStampOff */
598 buf->duration =
599 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100600 wCurrentRate, bNeedAck, uFragIdx,
601 cbLastFragmentSize, uMACfragNum,
602 byFBOption));
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000603 }
Forest Bond5449c682009-04-25 10:30:44 -0400604
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100605 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
606 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700607 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700608 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100609 struct vnt_tx_datahead_ab *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100610 /* Get SignalField, ServiceField & Length */
611 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100612 byPktType, &buf->ab);
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000613
614 if (is_pspoll) {
615 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
616
617 buf->duration = dur;
618 } else {
619 /* Get Duration and TimeStampOff */
620 buf->duration =
621 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100622 wCurrentRate, bNeedAck, uFragIdx,
623 cbLastFragmentSize, uMACfragNum,
624 byFBOption));
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000625 }
626
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100627 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
628 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700629 }
630 return 0;
Forest Bond5449c682009-04-25 10:30:44 -0400631}
632
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000633
Forest Bond5449c682009-04-25 10:30:44 -0400634static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700635void
Joe Perches547f1cf2013-03-18 10:45:01 -0700636s_vFillRTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100637 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700638 unsigned char byPktType,
639 void *pvRTS,
640 unsigned int cbFrameLength,
641 bool bNeedAck,
642 bool bDisCRC,
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000643 struct ieee80211_hdr *hdr,
Joe Perches547f1cf2013-03-18 10:45:01 -0700644 unsigned short wCurrentRate,
645 unsigned char byFBOption
646)
Forest Bond5449c682009-04-25 10:30:44 -0400647{
Joe Perches547f1cf2013-03-18 10:45:01 -0700648 unsigned int uRTSFrameLen = 20;
Forest Bond5449c682009-04-25 10:30:44 -0400649
Joe Perches547f1cf2013-03-18 10:45:01 -0700650 if (pvRTS == NULL)
651 return;
Forest Bond5449c682009-04-25 10:30:44 -0400652
Joe Perches547f1cf2013-03-18 10:45:01 -0700653 if (bDisCRC) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200654 /* When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
655 in this case we need to decrease its length by 4. */
Joe Perches547f1cf2013-03-18 10:45:01 -0700656 uRTSFrameLen -= 4;
657 }
Forest Bond5449c682009-04-25 10:30:44 -0400658
Carlos E. Garcia69e98df2015-04-24 09:40:42 -0400659 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, so we don't need to take them into account.
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200660 Otherwise, we need to modify codes for them. */
Joe Perches547f1cf2013-03-18 10:45:01 -0700661 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
662 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley17434f02014-08-30 22:25:41 +0100663 struct vnt_rts_g *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100664 /* Get SignalField, ServiceField & Length */
665 vnt_get_phy_field(pDevice, uRTSFrameLen,
666 pDevice->byTopCCKBasicRate,
Malcolm Priestley17434f02014-08-30 22:25:41 +0100667 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100668
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopOFDMBasicRate,
Malcolm Priestley17434f02014-08-30 22:25:41 +0100671 byPktType, &buf->a);
672 /* Get Duration */
673 buf->duration_bb =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100674 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
675 cbFrameLength, PK_TYPE_11B,
676 pDevice->byTopCCKBasicRate,
677 bNeedAck, byFBOption);
Malcolm Priestley17434f02014-08-30 22:25:41 +0100678 buf->duration_aa =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100679 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
680 cbFrameLength, byPktType,
681 wCurrentRate, bNeedAck,
682 byFBOption);
Malcolm Priestley17434f02014-08-30 22:25:41 +0100683 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100684 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
685 cbFrameLength, byPktType,
686 wCurrentRate, bNeedAck,
687 byFBOption);
Forest Bond5449c682009-04-25 10:30:44 -0400688
Malcolm Priestley17434f02014-08-30 22:25:41 +0100689 buf->data.duration = buf->duration_aa;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100690 /* Get RTS Frame body */
Malcolm Priestley17434f02014-08-30 22:25:41 +0100691 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100692 cpu_to_le16(IEEE80211_FTYPE_CTL |
693 IEEE80211_STYPE_RTS);
694
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000695 ether_addr_copy(buf->data.ra, hdr->addr1);
696 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700697 } else {
Malcolm Priestley9587b092014-08-30 22:25:42 +0100698 struct vnt_rts_g_fb *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100699 /* Get SignalField, ServiceField & Length */
700 vnt_get_phy_field(pDevice, uRTSFrameLen,
701 pDevice->byTopCCKBasicRate,
Malcolm Priestley9587b092014-08-30 22:25:42 +0100702 PK_TYPE_11B, &buf->b);
Forest Bond5449c682009-04-25 10:30:44 -0400703
Malcolm Priestley429a2472014-08-20 22:30:29 +0100704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopOFDMBasicRate,
Malcolm Priestley9587b092014-08-30 22:25:42 +0100706 byPktType, &buf->a);
707 /* Get Duration */
708 buf->duration_bb =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100709 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
710 cbFrameLength, PK_TYPE_11B,
711 pDevice->byTopCCKBasicRate,
712 bNeedAck, byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100713 buf->duration_aa =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100714 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
715 cbFrameLength, byPktType,
716 wCurrentRate, bNeedAck,
717 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100718 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100719 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
720 cbFrameLength, byPktType,
721 wCurrentRate, bNeedAck,
722 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100723 buf->rts_duration_ba_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100724 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
725 cbFrameLength, byPktType,
726 wCurrentRate, bNeedAck,
727 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100728 buf->rts_duration_aa_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100729 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
730 cbFrameLength, byPktType,
731 wCurrentRate, bNeedAck,
732 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100733 buf->rts_duration_ba_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100734 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
735 cbFrameLength, byPktType,
736 wCurrentRate, bNeedAck,
737 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100738 buf->rts_duration_aa_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100739 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
740 cbFrameLength, byPktType,
741 wCurrentRate, bNeedAck,
742 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100743 buf->data.duration = buf->duration_aa;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100744 /* Get RTS Frame body */
Malcolm Priestley9587b092014-08-30 22:25:42 +0100745 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100746 cpu_to_le16(IEEE80211_FTYPE_CTL |
747 IEEE80211_STYPE_RTS);
748
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000749 ether_addr_copy(buf->data.ra, hdr->addr1);
750 ether_addr_copy(buf->data.ta, hdr->addr2);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200751 } /* if (byFBOption == AUTO_FB_NONE) */
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700752 } else if (byPktType == PK_TYPE_11A) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700753 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100754 struct vnt_rts_ab *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100755 /* Get SignalField, ServiceField & Length */
756 vnt_get_phy_field(pDevice, uRTSFrameLen,
757 pDevice->byTopOFDMBasicRate,
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100758 byPktType, &buf->ab);
759 /* Get Duration */
760 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100761 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
762 cbFrameLength, byPktType,
763 wCurrentRate, bNeedAck,
764 byFBOption);
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100765 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100766 /* Get RTS Frame body */
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100767 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100768 cpu_to_le16(IEEE80211_FTYPE_CTL |
769 IEEE80211_STYPE_RTS);
770
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000771 ether_addr_copy(buf->data.ra, hdr->addr1);
772 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700773 } else {
Malcolm Priestley8e448042014-08-30 22:25:44 +0100774 struct vnt_rts_a_fb *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100775 /* Get SignalField, ServiceField & Length */
776 vnt_get_phy_field(pDevice, uRTSFrameLen,
777 pDevice->byTopOFDMBasicRate,
Malcolm Priestley8e448042014-08-30 22:25:44 +0100778 byPktType, &buf->a);
779 /* Get Duration */
780 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100781 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
782 cbFrameLength, byPktType,
783 wCurrentRate, bNeedAck,
784 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100785 buf->rts_duration_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100786 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
787 cbFrameLength, byPktType,
788 wCurrentRate, bNeedAck,
789 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100790 buf->rts_duration_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100791 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
792 cbFrameLength, byPktType,
793 wCurrentRate, bNeedAck,
794 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100795 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100796 /* Get RTS Frame body */
Malcolm Priestley8e448042014-08-30 22:25:44 +0100797 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100798 cpu_to_le16(IEEE80211_FTYPE_CTL |
799 IEEE80211_STYPE_RTS);
800
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000801 ether_addr_copy(buf->data.ra, hdr->addr1);
802 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches547f1cf2013-03-18 10:45:01 -0700803 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700804 } else if (byPktType == PK_TYPE_11B) {
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100805 struct vnt_rts_ab *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100806 /* Get SignalField, ServiceField & Length */
807 vnt_get_phy_field(pDevice, uRTSFrameLen,
808 pDevice->byTopCCKBasicRate,
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100809 PK_TYPE_11B, &buf->ab);
810 /* Get Duration */
811 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100812 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
813 byPktType, wCurrentRate, bNeedAck,
814 byFBOption);
815
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100816 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100817 /* Get RTS Frame body */
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100818 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100819 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
Forest Bond5449c682009-04-25 10:30:44 -0400820
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000821 ether_addr_copy(buf->data.ra, hdr->addr1);
822 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches547f1cf2013-03-18 10:45:01 -0700823 }
Forest Bond5449c682009-04-25 10:30:44 -0400824}
825
826static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700827void
Joe Perches547f1cf2013-03-18 10:45:01 -0700828s_vFillCTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100829 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700830 unsigned int uDMAIdx,
831 unsigned char byPktType,
832 void *pvCTS,
833 unsigned int cbFrameLength,
834 bool bNeedAck,
835 bool bDisCRC,
836 unsigned short wCurrentRate,
837 unsigned char byFBOption
838)
Forest Bond5449c682009-04-25 10:30:44 -0400839{
Joe Perches547f1cf2013-03-18 10:45:01 -0700840 unsigned int uCTSFrameLen = 14;
Forest Bond5449c682009-04-25 10:30:44 -0400841
Guido Martínezbc5cf652014-04-19 16:45:00 -0300842 if (pvCTS == NULL)
Joe Perches547f1cf2013-03-18 10:45:01 -0700843 return;
Forest Bond5449c682009-04-25 10:30:44 -0400844
Joe Perches547f1cf2013-03-18 10:45:01 -0700845 if (bDisCRC) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200846 /* When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
847 in this case we need to decrease its length by 4. */
Joe Perches547f1cf2013-03-18 10:45:01 -0700848 uCTSFrameLen -= 4;
849 }
Forest Bond5449c682009-04-25 10:30:44 -0400850
Joe Perches547f1cf2013-03-18 10:45:01 -0700851 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
852 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200853 /* Auto Fall back */
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100854 struct vnt_cts_fb *buf = pvCTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100855 /* Get SignalField, ServiceField & Length */
856 vnt_get_phy_field(pDevice, uCTSFrameLen,
857 pDevice->byTopCCKBasicRate,
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100858 PK_TYPE_11B, &buf->b);
Forest Bond5449c682009-04-25 10:30:44 -0400859
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100860 buf->duration_ba =
861 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
862 cbFrameLength, byPktType,
863 wCurrentRate, bNeedAck,
864 byFBOption);
865
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100866 /* Get CTSDuration_ba_f0 */
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100867 buf->cts_duration_ba_f0 =
868 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
869 cbFrameLength, byPktType,
870 wCurrentRate, bNeedAck,
871 byFBOption);
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100872
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100873 /* Get CTSDuration_ba_f1 */
874 buf->cts_duration_ba_f1 =
875 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
876 cbFrameLength, byPktType,
877 wCurrentRate, bNeedAck,
878 byFBOption);
Malcolm Priestley0864db12014-08-30 22:25:40 +0100879
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100880 /* Get CTS Frame body */
881 buf->data.duration = buf->duration_ba;
882
883 buf->data.frame_control =
Malcolm Priestley0864db12014-08-30 22:25:40 +0100884 cpu_to_le16(IEEE80211_FTYPE_CTL |
885 IEEE80211_STYPE_CTS);
886
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100887 buf->reserved2 = 0x0;
Forest Bond5449c682009-04-25 10:30:44 -0400888
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200889 ether_addr_copy(buf->data.ra,
890 pDevice->abyCurrentNetAddr);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200891 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100892 struct vnt_cts *buf = pvCTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100893 /* Get SignalField, ServiceField & Length */
894 vnt_get_phy_field(pDevice, uCTSFrameLen,
895 pDevice->byTopCCKBasicRate,
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100896 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100897
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100898 /* Get CTSDuration_ba */
899 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100900 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
901 cbFrameLength, byPktType,
902 wCurrentRate, bNeedAck,
903 byFBOption);
Forest Bond5449c682009-04-25 10:30:44 -0400904
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100905 /* Get CTS Frame body */
906 buf->data.duration = buf->duration_ba;
Malcolm Priestley0864db12014-08-30 22:25:40 +0100907
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100908 buf->data.frame_control =
Malcolm Priestley0864db12014-08-30 22:25:40 +0100909 cpu_to_le16(IEEE80211_FTYPE_CTL |
910 IEEE80211_STYPE_CTS);
911
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100912 buf->reserved2 = 0x0;
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200913 ether_addr_copy(buf->data.ra,
914 pDevice->abyCurrentNetAddr);
Joe Perches547f1cf2013-03-18 10:45:01 -0700915 }
916 }
Forest Bond5449c682009-04-25 10:30:44 -0400917}
918
Forest Bond5449c682009-04-25 10:30:44 -0400919/*+
920 *
921 * Description:
922 * Generate FIFO control for MAC & Baseband controller
923 *
924 * Parameters:
925 * In:
Gilles Espinassef77f13e2010-03-29 15:41:47 +0200926 * pDevice - Pointer to adapter
Forest Bond5449c682009-04-25 10:30:44 -0400927 * pTxDataHead - Transmit Data Buffer
928 * pTxBufHead - pTxBufHead
929 * pvRrvTime - pvRrvTime
930 * pvRTS - RTS Buffer
931 * pCTS - CTS Buffer
932 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
933 * bNeedACK - If need ACK
934 * uDescIdx - Desc Index
935 * Out:
936 * none
937 *
938 * Return Value: none
939 *
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200940 -
941 * unsigned int cbFrameSize, Hdr+Payload+FCS */
Forest Bond5449c682009-04-25 10:30:44 -0400942static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700943void
Joe Perches547f1cf2013-03-18 10:45:01 -0700944s_vGenerateTxParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100945 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700946 unsigned char byPktType,
Malcolm Priestleydf184802015-04-01 22:32:51 +0100947 struct vnt_tx_fifo_head *tx_buffer_head,
Joe Perches547f1cf2013-03-18 10:45:01 -0700948 void *pvRrvTime,
949 void *pvRTS,
950 void *pvCTS,
951 unsigned int cbFrameSize,
952 bool bNeedACK,
953 unsigned int uDMAIdx,
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +0000954 void *psEthHeader,
Joe Perches547f1cf2013-03-18 10:45:01 -0700955 unsigned short wCurrentRate
956)
Forest Bond5449c682009-04-25 10:30:44 -0400957{
Malcolm Priestleydf184802015-04-01 22:32:51 +0100958 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
Joe Perches547f1cf2013-03-18 10:45:01 -0700959 bool bDisCRC = false;
960 unsigned char byFBOption = AUTO_FB_NONE;
Forest Bond5449c682009-04-25 10:30:44 -0400961
Malcolm Priestleydf184802015-04-01 22:32:51 +0100962 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
Guillaume Clement6b711272014-07-25 01:06:16 +0200963
Malcolm Priestleydf184802015-04-01 22:32:51 +0100964 if (fifo_ctl & FIFOCTL_CRCDIS)
Joe Perches547f1cf2013-03-18 10:45:01 -0700965 bDisCRC = true;
Forest Bond5449c682009-04-25 10:30:44 -0400966
Malcolm Priestleydf184802015-04-01 22:32:51 +0100967 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -0700968 byFBOption = AUTO_FB_0;
Malcolm Priestleydf184802015-04-01 22:32:51 +0100969 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -0700970 byFBOption = AUTO_FB_1;
Forest Bond5449c682009-04-25 10:30:44 -0400971
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100972 if (!pvRrvTime)
973 return;
974
Joe Perches547f1cf2013-03-18 10:45:01 -0700975 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200976 if (pvRTS != NULL) { /* RTS_need
977 Fill RsvTime */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100978 struct vnt_rrv_time_rts *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +0200979
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100980 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
981 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
982 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
983 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
984 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
985
Joe Perches547f1cf2013-03-18 10:45:01 -0700986 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200987 } else {/* RTS_needless, PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100988 struct vnt_rrv_time_cts *buf = pvRrvTime;
Forest Bond5449c682009-04-25 10:30:44 -0400989
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100990 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
991 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
992 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -0400993
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200994 /* Fill CTS */
Joe Perches547f1cf2013-03-18 10:45:01 -0700995 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
996 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700997 } else if (byPktType == PK_TYPE_11A) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200998 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100999 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001000
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001001 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1002 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1003
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001004 /* Fill RTS */
Joe Perches547f1cf2013-03-18 10:45:01 -07001005 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001006 } else if (pvRTS == NULL) {/* RTS_needless, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001007 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001008
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001009 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
Joe Perches547f1cf2013-03-18 10:45:01 -07001010 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001011 } else if (byPktType == PK_TYPE_11B) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001012 if ((pvRTS != NULL)) {/* RTS_need, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001013 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001014
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001015 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1016 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1017
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001018 /* Fill RTS */
Joe Perches547f1cf2013-03-18 10:45:01 -07001019 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001020 } else { /* RTS_needless, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001021 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001022
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001023 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
Joe Perches547f1cf2013-03-18 10:45:01 -07001024 }
1025 }
Forest Bond5449c682009-04-25 10:30:44 -04001026}
Guido Martínez4e8a7e52014-04-19 16:44:59 -03001027
Charles Clémentfe4f34b2010-06-25 10:48:53 -07001028static unsigned int
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001029s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001030 unsigned char *pbyTxBufferAddr,
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001031 unsigned int uDMAIdx, PSTxDesc pHeadTD,
Malcolm Priestley154bb8b2014-11-29 00:02:02 +00001032 unsigned int is_pspoll)
Forest Bond5449c682009-04-25 10:30:44 -04001033{
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001034 PDEVICE_TD_INFO td_info = pHeadTD->pTDInfo;
1035 struct sk_buff *skb = td_info->skb;
1036 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1037 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1038 struct vnt_tx_fifo_head *tx_buffer_head =
1039 (struct vnt_tx_fifo_head *)td_info->buf;
1040 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
Joe Perches547f1cf2013-03-18 10:45:01 -07001041 unsigned int cbFrameSize;
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001042 __le16 uDuration;
Joe Perches547f1cf2013-03-18 10:45:01 -07001043 unsigned char *pbyBuffer;
Joe Perches547f1cf2013-03-18 10:45:01 -07001044 unsigned int uLength = 0;
Joe Perches547f1cf2013-03-18 10:45:01 -07001045 unsigned int cbMICHDR = 0;
Joe Perches547f1cf2013-03-18 10:45:01 -07001046 unsigned int uMACfragNum = 1;
1047 unsigned int uPadding = 0;
1048 unsigned int cbReqCount = 0;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001049 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1050 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
Joe Perches547f1cf2013-03-18 10:45:01 -07001051 PSTxDesc ptdCurr;
Joe Perches547f1cf2013-03-18 10:45:01 -07001052 unsigned int cbHeaderLength = 0;
1053 void *pvRrvTime;
Malcolm Priestley11a72e52014-08-09 20:15:56 +01001054 struct vnt_mic_hdr *pMICHDR;
Joe Perches547f1cf2013-03-18 10:45:01 -07001055 void *pvRTS;
1056 void *pvCTS;
1057 void *pvTxDataHd;
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001058 unsigned short wTxBufSize; /* FFinfo size */
Joe Perches547f1cf2013-03-18 10:45:01 -07001059 unsigned char byFBOption = AUTO_FB_NONE;
Forest Bond5449c682009-04-25 10:30:44 -04001060
Joe Perches547f1cf2013-03-18 10:45:01 -07001061 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond5449c682009-04-25 10:30:44 -04001062
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001063 cbFrameSize = skb->len + 4;
Forest Bond5449c682009-04-25 10:30:44 -04001064
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001065 if (info->control.hw_key) {
1066 switch (info->control.hw_key->cipher) {
1067 case WLAN_CIPHER_SUITE_CCMP:
Malcolm Priestley11a72e52014-08-09 20:15:56 +01001068 cbMICHDR = sizeof(struct vnt_mic_hdr);
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001069 default:
1070 break;
Joe Perches547f1cf2013-03-18 10:45:01 -07001071 }
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001072
1073 cbFrameSize += info->control.hw_key->icv_len;
1074
Joe Perches547f1cf2013-03-18 10:45:01 -07001075 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001076 /* MAC Header should be padding 0 to DW alignment. */
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001077 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
Joe Perches547f1cf2013-03-18 10:45:01 -07001078 uPadding %= 4;
1079 }
1080 }
Forest Bond5449c682009-04-25 10:30:44 -04001081
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001082 /*
1083 * Use for AUTO FALL BACK
1084 */
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001085 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -07001086 byFBOption = AUTO_FB_0;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001087 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -07001088 byFBOption = AUTO_FB_1;
Forest Bond5449c682009-04-25 10:30:44 -04001089
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001090
1091 /* Set RrvTime/RTS/CTS Buffer */
Joe Perches547f1cf2013-03-18 10:45:01 -07001092 wTxBufSize = sizeof(STxBufHead);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001093 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
Forest Bond5449c682009-04-25 10:30:44 -04001094
Joe Perches547f1cf2013-03-18 10:45:01 -07001095 if (byFBOption == AUTO_FB_NONE) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001096 if (bRTS == true) {/* RTS_need */
Malcolm Priestleya9e6a2d2014-08-30 22:25:27 +01001097 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1098 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
Malcolm Priestley17434f02014-08-30 22:25:41 +01001099 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001100 pvCTS = NULL;
Malcolm Priestley17434f02014-08-30 22:25:41 +01001101 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1102 cbMICHDR + sizeof(struct vnt_rts_g));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01001103 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley17434f02014-08-30 22:25:41 +01001104 cbMICHDR + sizeof(struct vnt_rts_g) +
1105 sizeof(struct vnt_tx_datahead_g);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001106 } else { /* RTS_needless */
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01001107 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1108 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07001109 pvRTS = NULL;
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001110 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1111 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1112 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01001113 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001114 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Joe Perches547f1cf2013-03-18 10:45:01 -07001115 }
1116 } else {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001117 /* Auto Fall Back */
1118 if (bRTS == true) {/* RTS_need */
Malcolm Priestleya9e6a2d2014-08-30 22:25:27 +01001119 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1120 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
Malcolm Priestley9587b092014-08-30 22:25:42 +01001121 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001122 pvCTS = NULL;
Malcolm Priestley9587b092014-08-30 22:25:42 +01001123 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1124 cbMICHDR + sizeof(struct vnt_rts_g_fb));
Malcolm Priestley2dd76672014-08-30 22:25:35 +01001125 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley9587b092014-08-30 22:25:42 +01001126 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001127 } else { /* RTS_needless */
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01001128 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1129 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07001130 pvRTS = NULL;
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001131 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1132 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1133 cbMICHDR + sizeof(struct vnt_cts_fb));
Malcolm Priestley2dd76672014-08-30 22:25:35 +01001134 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001135 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
Joe Perches547f1cf2013-03-18 10:45:01 -07001136 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001137 } /* Auto Fall Back */
1138 } else {/* 802.11a/b packet */
Forest Bond5449c682009-04-25 10:30:44 -04001139
Joe Perches547f1cf2013-03-18 10:45:01 -07001140 if (byFBOption == AUTO_FB_NONE) {
1141 if (bRTS == true) {
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001142 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1143 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001144 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001145 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001146 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001147 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001148 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001149 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001150 } else { /* RTS_needless, need MICHDR */
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001151 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1152 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07001153 pvRTS = NULL;
1154 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001155 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1156 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1157 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
Joe Perches547f1cf2013-03-18 10:45:01 -07001158 }
1159 } else {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001160 /* Auto Fall Back */
1161 if (bRTS == true) { /* RTS_need */
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001162 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1163 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestley8e448042014-08-30 22:25:44 +01001164 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001165 pvCTS = NULL;
Malcolm Priestley8e448042014-08-30 22:25:44 +01001166 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1167 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +01001168 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley8e448042014-08-30 22:25:44 +01001169 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001170 } else { /* RTS_needless */
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001171 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1172 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07001173 pvRTS = NULL;
1174 pvCTS = NULL;
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +01001175 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1176 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1177 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
Joe Perches547f1cf2013-03-18 10:45:01 -07001178 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001179 } /* Auto Fall Back */
Joe Perches547f1cf2013-03-18 10:45:01 -07001180 }
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001181
1182 td_info->mic_hdr = pMICHDR;
1183
Joe Perches547f1cf2013-03-18 10:45:01 -07001184 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
Forest Bond5449c682009-04-25 10:30:44 -04001185
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001186 /* Fill FIFO,RrvTime,RTS,and CTS */
1187 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1188 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1189 /* Fill DataHead */
1190 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
Malcolm Priestley89cf9be2014-10-29 17:43:42 +00001191 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
Forest Bond5449c682009-04-25 10:30:44 -04001192
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001193 hdr->duration_id = uDuration;
Forest Bond5449c682009-04-25 10:30:44 -04001194
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001195 cbReqCount = cbHeaderLength + uPadding + skb->len;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001196 pbyBuffer = (unsigned char *)pHeadTD->pTDInfo->buf;
1197 uLength = cbHeaderLength + uPadding;
Forest Bond5449c682009-04-25 10:30:44 -04001198
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001199 /* Copy the Packet into a tx Buffer */
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001200 memcpy((pbyBuffer + uLength), skb->data, skb->len);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001201
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001202 ptdCurr = (PSTxDesc)pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001203
Malcolm Priestleyb5745292014-12-21 12:56:34 +00001204 ptdCurr->pTDInfo->dwReqCount = cbReqCount;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001205 ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
1206 ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
Forest Bond5449c682009-04-25 10:30:44 -04001207
Joe Perches547f1cf2013-03-18 10:45:01 -07001208 return cbHeaderLength;
Forest Bond5449c682009-04-25 10:30:44 -04001209}
1210
Malcolm Priestley01eec152014-10-29 17:43:38 +00001211static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1212 struct ieee80211_key_conf *tx_key,
1213 struct sk_buff *skb, u16 payload_len,
1214 struct vnt_mic_hdr *mic_hdr)
1215{
1216 struct ieee80211_key_seq seq;
1217 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1218
1219 /* strip header and icv len from payload */
1220 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1221 payload_len -= tx_key->icv_len;
1222
1223 switch (tx_key->cipher) {
1224 case WLAN_CIPHER_SUITE_WEP40:
1225 case WLAN_CIPHER_SUITE_WEP104:
1226 memcpy(key_buffer, iv, 3);
1227 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1228
1229 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1230 memcpy(key_buffer + 8, iv, 3);
1231 memcpy(key_buffer + 11,
1232 tx_key->key, WLAN_KEY_LEN_WEP40);
1233 }
1234
1235 break;
1236 case WLAN_CIPHER_SUITE_TKIP:
1237 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1238
1239 break;
1240 case WLAN_CIPHER_SUITE_CCMP:
1241
1242 if (!mic_hdr)
1243 return;
1244
1245 mic_hdr->id = 0x59;
1246 mic_hdr->payload_len = cpu_to_be16(payload_len);
1247 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1248
1249 ieee80211_get_key_tx_seq(tx_key, &seq);
1250
1251 memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
1252
1253 if (ieee80211_has_a4(hdr->frame_control))
1254 mic_hdr->hlen = cpu_to_be16(28);
1255 else
1256 mic_hdr->hlen = cpu_to_be16(22);
1257
1258 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1259 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1260 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1261
1262 mic_hdr->frame_control = cpu_to_le16(
1263 le16_to_cpu(hdr->frame_control) & 0xc78f);
1264 mic_hdr->seq_ctrl = cpu_to_le16(
1265 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1266
1267 if (ieee80211_has_a4(hdr->frame_control))
1268 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1269
1270 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1271
1272 break;
1273 default:
1274 break;
1275 }
1276}
1277
1278int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
1279 PSTxDesc head_td, struct sk_buff *skb)
1280{
1281 PDEVICE_TD_INFO td_info = head_td->pTDInfo;
1282 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1283 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1284 struct ieee80211_rate *rate;
1285 struct ieee80211_key_conf *tx_key;
1286 struct ieee80211_hdr *hdr;
1287 struct vnt_tx_fifo_head *tx_buffer_head =
1288 (struct vnt_tx_fifo_head *)td_info->buf;
Malcolm Priestley01eec152014-10-29 17:43:38 +00001289 u16 tx_body_size = skb->len, current_rate;
1290 u8 pkt_type;
1291 bool is_pspoll = false;
1292
1293 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1294
1295 hdr = (struct ieee80211_hdr *)(skb->data);
1296
1297 rate = ieee80211_get_tx_rate(priv->hw, info);
1298
1299 current_rate = rate->hw_value;
1300 if (priv->wCurrentRate != current_rate &&
1301 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1302 priv->wCurrentRate = current_rate;
1303
1304 RFbSetPower(priv, priv->wCurrentRate,
1305 priv->hw->conf.chandef.chan->hw_value);
1306 }
1307
Malcolm Priestleya6388e62015-04-01 22:32:52 +01001308 if (current_rate > RATE_11M) {
1309 if (info->band == IEEE80211_BAND_5GHZ) {
1310 pkt_type = PK_TYPE_11A;
1311 } else {
1312 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1313 pkt_type = PK_TYPE_11GB;
1314 else
1315 pkt_type = PK_TYPE_11GA;
1316 }
1317 } else {
Malcolm Priestley01eec152014-10-29 17:43:38 +00001318 pkt_type = PK_TYPE_11B;
Malcolm Priestleya6388e62015-04-01 22:32:52 +01001319 }
Malcolm Priestley01eec152014-10-29 17:43:38 +00001320
1321 /*Set fifo controls */
1322 if (pkt_type == PK_TYPE_11A)
1323 tx_buffer_head->fifo_ctl = 0;
1324 else if (pkt_type == PK_TYPE_11B)
1325 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1326 else if (pkt_type == PK_TYPE_11GB)
1327 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1328 else if (pkt_type == PK_TYPE_11GA)
1329 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1330
1331 /* generate interrupt */
1332 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1333
1334 if (!ieee80211_is_data(hdr->frame_control)) {
1335 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1336 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1337 tx_buffer_head->time_stamp =
1338 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1339 } else {
1340 tx_buffer_head->time_stamp =
1341 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1342 }
1343
1344 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1345 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1346
1347 if (ieee80211_has_retry(hdr->frame_control))
1348 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1349
1350 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1351 priv->byPreambleType = PREAMBLE_SHORT;
1352 else
1353 priv->byPreambleType = PREAMBLE_LONG;
1354
1355 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1356 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1357
1358 if (ieee80211_has_a4(hdr->frame_control)) {
1359 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1360 priv->bLongHeader = true;
1361 }
1362
1363 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1364 is_pspoll = true;
1365
1366 tx_buffer_head->frag_ctl =
1367 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1368
1369 if (info->control.hw_key) {
1370 tx_key = info->control.hw_key;
1371
1372 switch (info->control.hw_key->cipher) {
1373 case WLAN_CIPHER_SUITE_WEP40:
1374 case WLAN_CIPHER_SUITE_WEP104:
1375 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1376 break;
1377 case WLAN_CIPHER_SUITE_TKIP:
1378 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1379 break;
1380 case WLAN_CIPHER_SUITE_CCMP:
1381 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1382 default:
1383 break;
1384 }
1385 }
1386
1387 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1388
1389 /* legacy rates TODO use ieee80211_tx_rate */
1390 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1391 if (priv->byAutoFBCtrl == AUTO_FB_0)
1392 tx_buffer_head->fifo_ctl |=
1393 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1394 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1395 tx_buffer_head->fifo_ctl |=
1396 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1397
1398 }
1399
1400 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1401
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001402 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
Malcolm Priestley154bb8b2014-11-29 00:02:02 +00001403 dma_idx, head_td, is_pspoll);
Malcolm Priestley01eec152014-10-29 17:43:38 +00001404
1405 if (info->control.hw_key) {
1406 tx_key = info->control.hw_key;
1407 if (tx_key->keylen > 0)
1408 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1409 tx_key, skb, tx_body_size, td_info->mic_hdr);
1410 }
1411
1412 return 0;
1413}
1414
1415static int vnt_beacon_xmit(struct vnt_private *priv,
1416 struct sk_buff *skb)
1417{
1418 struct vnt_tx_short_buf_head *short_head =
1419 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1420 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1421 (priv->tx_beacon_bufs + sizeof(*short_head));
1422 struct ieee80211_tx_info *info;
1423 u32 frame_size = skb->len + 4;
1424 u16 current_rate;
1425
1426 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1427
1428 if (priv->byBBType == BB_TYPE_11A) {
1429 current_rate = RATE_6M;
1430
1431 /* Get SignalField,ServiceField,Length */
1432 vnt_get_phy_field(priv, frame_size, current_rate,
1433 PK_TYPE_11A, &short_head->ab);
1434
1435 /* Get Duration and TimeStampOff */
1436 short_head->duration =
1437 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1438 frame_size, PK_TYPE_11A, current_rate,
1439 false, 0, 0, 1, AUTO_FB_NONE));
1440
1441 short_head->time_stamp_off =
1442 vnt_time_stamp_off(priv, current_rate);
1443 } else {
1444 current_rate = RATE_1M;
1445 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1446
1447 /* Get SignalField,ServiceField,Length */
1448 vnt_get_phy_field(priv, frame_size, current_rate,
1449 PK_TYPE_11B, &short_head->ab);
1450
1451 /* Get Duration and TimeStampOff */
1452 short_head->duration =
1453 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1454 frame_size, PK_TYPE_11B, current_rate,
1455 false, 0, 0, 1, AUTO_FB_NONE));
1456
1457 short_head->time_stamp_off =
1458 vnt_time_stamp_off(priv, current_rate);
1459 }
1460
1461 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1462
1463 /* Copy Beacon */
1464 memcpy(mgmt_hdr, skb->data, skb->len);
1465
1466 /* time stamp always 0 */
1467 mgmt_hdr->u.beacon.timestamp = 0;
1468
1469 info = IEEE80211_SKB_CB(skb);
1470 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1471 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1472
1473 hdr->duration_id = 0;
1474 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1475 }
1476
1477 priv->wSeqCounter++;
1478 if (priv->wSeqCounter > 0x0fff)
1479 priv->wSeqCounter = 0;
1480
1481 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1482
1483 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1484
1485 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1486 /* Set auto Transmit on */
1487 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1488 /* Poll Transmit the adapter */
1489 MACvTransmitBCN(priv->PortOffset);
1490
1491 return 0;
1492}
1493
1494int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1495{
1496 struct sk_buff *beacon;
1497
1498 beacon = ieee80211_beacon_get(priv->hw, vif);
1499 if (!beacon)
1500 return -ENOMEM;
1501
1502 if (vnt_beacon_xmit(priv, beacon)) {
1503 ieee80211_free_txskb(priv->hw, beacon);
1504 return -ENODEV;
1505 }
1506
1507 return 0;
1508}
1509
1510int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1511 struct ieee80211_bss_conf *conf)
1512{
Malcolm Priestley01eec152014-10-29 17:43:38 +00001513 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1514
1515 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1516
Malcolm Priestley738487f2014-11-12 21:11:09 +00001517 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
Malcolm Priestley01eec152014-10-29 17:43:38 +00001518
1519 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1520
Aya Mahfouz0c596a32015-02-27 14:51:29 +02001521 return vnt_beacon_make(priv, vif);
Malcolm Priestley01eec152014-10-29 17:43:38 +00001522}