blob: 7e69bc99d60fd671a62f3a0c832a0893217812cf [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 -------------------------*/
Anson Jacobf46e0412016-08-22 17:12:35 -040067/* if packet size < 256 -> in-direct send
68 * vpacket size >= 256 -> direct send
69 */
70#define CRITICAL_PACKET_LEN 256
Forest Bond5449c682009-04-25 10:30:44 -040071
Anton Protopopov83e771f2014-07-01 21:06:29 +040072static const unsigned short wTimeStampOff[2][MAX_RATE] = {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020073 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, /* Long Preamble */
74 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, /* Short Preamble */
Joe Perches547f1cf2013-03-18 10:45:01 -070075};
Forest Bond5449c682009-04-25 10:30:44 -040076
Anton Protopopov83e771f2014-07-01 21:06:29 +040077static const unsigned short wFB_Opt0[2][5] = {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020078 {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
79 {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
Joe Perches547f1cf2013-03-18 10:45:01 -070080};
Anton Protopopov83e771f2014-07-01 21:06:29 +040081static const unsigned short wFB_Opt1[2][5] = {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +020082 {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
Shivani Bhardwajb2d44fe2015-10-12 00:49:08 +053083 {RATE_6M, RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
Joe Perches547f1cf2013-03-18 10:45:01 -070084};
Forest Bond5449c682009-04-25 10:30:44 -040085
Forest Bond5449c682009-04-25 10:30:44 -040086#define RTSDUR_BB 0
87#define RTSDUR_BA 1
88#define RTSDUR_AA 2
89#define CTSDUR_BA 3
90#define RTSDUR_BA_F0 4
91#define RTSDUR_AA_F0 5
92#define RTSDUR_BA_F1 6
93#define RTSDUR_AA_F1 7
94#define CTSDUR_BA_F0 8
95#define CTSDUR_BA_F1 9
96#define DATADUR_B 10
97#define DATADUR_A 11
98#define DATADUR_A_F0 12
99#define DATADUR_A_F1 13
100
101/*--------------------- Static Functions --------------------------*/
Forest Bond5449c682009-04-25 10:30:44 -0400102static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700103void
Forest Bond5449c682009-04-25 10:30:44 -0400104s_vFillRTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100105 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700106 unsigned char byPktType,
107 void *pvRTS,
108 unsigned int cbFrameLength,
109 bool bNeedAck,
110 bool bDisCRC,
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000111 struct ieee80211_hdr *hdr,
Joe Perches547f1cf2013-03-18 10:45:01 -0700112 unsigned short wCurrentRate,
113 unsigned char byFBOption
114);
Forest Bond5449c682009-04-25 10:30:44 -0400115
116static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700117void
Forest Bond5449c682009-04-25 10:30:44 -0400118s_vGenerateTxParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100119 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700120 unsigned char byPktType,
Malcolm Priestleydf184802015-04-01 22:32:51 +0100121 struct vnt_tx_fifo_head *,
Joe Perches547f1cf2013-03-18 10:45:01 -0700122 void *pvRrvTime,
123 void *pvRTS,
124 void *pvCTS,
125 unsigned int cbFrameSize,
126 bool bNeedACK,
127 unsigned int uDMAIdx,
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +0000128 void *psEthHeader,
Joe Perches547f1cf2013-03-18 10:45:01 -0700129 unsigned short wCurrentRate
130);
Forest Bond5449c682009-04-25 10:30:44 -0400131
Charles Clémentfe4f34b2010-06-25 10:48:53 -0700132static unsigned int
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100133s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
Malcolm Priestley19f3ed32014-11-29 00:02:03 +0000134 unsigned char *pbyTxBufferAddr,
Malcolm Priestleye2357272015-08-14 22:58:51 +0100135 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
Malcolm Priestley154bb8b2014-11-29 00:02:02 +0000136 unsigned int uNodeIndex);
Forest Bond5449c682009-04-25 10:30:44 -0400137
Forest Bond5449c682009-04-25 10:30:44 -0400138static
Malcolm Priestleya479ffc2014-08-30 22:25:38 +0100139__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700140s_uFillDataHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100141 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700142 unsigned char byPktType,
143 void *pTxDataHead,
144 unsigned int cbFrameLength,
145 unsigned int uDMAIdx,
146 bool bNeedAck,
147 unsigned int uFragIdx,
148 unsigned int cbLastFragmentSize,
149 unsigned int uMACfragNum,
150 unsigned char byFBOption,
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000151 unsigned short wCurrentRate,
152 bool is_pspoll
Joe Perches547f1cf2013-03-18 10:45:01 -0700153);
Forest Bond5449c682009-04-25 10:30:44 -0400154
Forest Bond5449c682009-04-25 10:30:44 -0400155/*--------------------- Export Variables --------------------------*/
156
Malcolm Priestleyd6b95c02014-08-30 22:25:33 +0100157static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
158{
159 return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
160 [rate % MAX_RATE]);
161}
162
Anson Jacobf46e0412016-08-22 17:12:35 -0400163/* byPktType : PK_TYPE_11A 0
164 * PK_TYPE_11B 1
165 * PK_TYPE_11GB 2
166 * PK_TYPE_11GA 3
167 */
Forest Bond5449c682009-04-25 10:30:44 -0400168static
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700169unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -0700170s_uGetTxRsvTime(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100171 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700172 unsigned char byPktType,
173 unsigned int cbFrameLength,
174 unsigned short wRate,
175 bool bNeedAck
176)
Forest Bond5449c682009-04-25 10:30:44 -0400177{
Joe Perches547f1cf2013-03-18 10:45:01 -0700178 unsigned int uDataTime, uAckTime;
Forest Bond5449c682009-04-25 10:30:44 -0400179
Joe Perches547f1cf2013-03-18 10:45:01 -0700180 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200181 if (byPktType == PK_TYPE_11B) /* llb,CCK mode */
Joe Perches547f1cf2013-03-18 10:45:01 -0700182 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopCCKBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200183 else /* 11g 2.4G OFDM mode & 11a 5G OFDM mode */
Joe Perches547f1cf2013-03-18 10:45:01 -0700184 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (unsigned short)pDevice->byTopOFDMBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400185
Guido Martínezbc5cf652014-04-19 16:45:00 -0300186 if (bNeedAck)
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700187 return uDataTime + pDevice->uSIFS + uAckTime;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300188 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700189 return uDataTime;
Forest Bond5449c682009-04-25 10:30:44 -0400190}
191
Malcolm Priestleye7a3481b2014-08-30 22:25:30 +0100192static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
193 u32 frame_length, u16 rate, bool need_ack)
194{
195 return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
196 frame_length, rate, need_ack));
197}
198
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200199/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
Forest Bond5449c682009-04-25 10:30:44 -0400200static
Malcolm Priestley853532d2014-08-30 22:25:31 +0100201__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700202s_uGetRTSCTSRsvTime(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100203 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700204 unsigned char byRTSRsvType,
205 unsigned char byPktType,
206 unsigned int cbFrameLength,
207 unsigned short wCurrentRate
208)
Forest Bond5449c682009-04-25 10:30:44 -0400209{
Piotr Kubusbc22b492015-01-10 15:35:45 +0100210 unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
Forest Bond5449c682009-04-25 10:30:44 -0400211
Joe Perches547f1cf2013-03-18 10:45:01 -0700212 uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400213
Joe Perches547f1cf2013-03-18 10:45:01 -0700214 uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200215 if (byRTSRsvType == 0) { /* RTSTxRrvTime_bb */
Joe Perches547f1cf2013-03-18 10:45:01 -0700216 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
217 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200218 } else if (byRTSRsvType == 1) { /* RTSTxRrvTime_ba, only in 2.4GHZ */
Joe Perches547f1cf2013-03-18 10:45:01 -0700219 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
220 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
221 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200222 } else if (byRTSRsvType == 2) { /* RTSTxRrvTime_aa */
Joe Perches547f1cf2013-03-18 10:45:01 -0700223 uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
224 uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200225 } else if (byRTSRsvType == 3) { /* CTSTxRrvTime_ba, only in 2.4GHZ */
Joe Perches547f1cf2013-03-18 10:45:01 -0700226 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
227 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
228 uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
Malcolm Priestley853532d2014-08-30 22:25:31 +0100229 return cpu_to_le16((u16)uRrvTime);
Joe Perches547f1cf2013-03-18 10:45:01 -0700230 }
Forest Bond5449c682009-04-25 10:30:44 -0400231
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200232 /* RTSRrvTime */
Joe Perches547f1cf2013-03-18 10:45:01 -0700233 uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
Malcolm Priestley853532d2014-08-30 22:25:31 +0100234 return cpu_to_le16((u16)uRrvTime);
Forest Bond5449c682009-04-25 10:30:44 -0400235}
236
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200237/* byFreqType 0: 5GHz, 1:2.4Ghz */
Forest Bond5449c682009-04-25 10:30:44 -0400238static
Charles Clémentb6e95cd2010-06-02 09:52:01 -0700239unsigned int
Joe Perches547f1cf2013-03-18 10:45:01 -0700240s_uGetDataDuration(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100241 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700242 unsigned char byDurType,
243 unsigned int cbFrameLength,
244 unsigned char byPktType,
245 unsigned short wRate,
246 bool bNeedAck,
247 unsigned int uFragIdx,
248 unsigned int cbLastFragmentSize,
249 unsigned int uMACfragNum,
250 unsigned char byFBOption
251)
Forest Bond5449c682009-04-25 10:30:44 -0400252{
Cristina Opriceana19cd2292015-03-04 12:37:28 +0200253 bool bLastFrag = false;
Joe Perches547f1cf2013-03-18 10:45:01 -0700254 unsigned int uAckTime = 0, uNextPktTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400255
Guido Martínezbc5cf652014-04-19 16:45:00 -0300256 if (uFragIdx == (uMACfragNum-1))
Cristina Opriceana19cd2292015-03-04 12:37:28 +0200257 bLastFrag = true;
Forest Bond5449c682009-04-25 10:30:44 -0400258
Joe Perches547f1cf2013-03-18 10:45:01 -0700259 switch (byDurType) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200260 case DATADUR_B: /* DATADUR_B */
261 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700262 if (bNeedAck) {
263 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700264 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700265 } else {
266 return 0;
267 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200268 } else {/* First Frag or Mid Frag */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300269 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700270 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300271 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700272 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300273
Joe Perches547f1cf2013-03-18 10:45:01 -0700274 if (bNeedAck) {
275 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700276 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700277 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700278 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700279 }
280 }
281 break;
Forest Bond5449c682009-04-25 10:30:44 -0400282
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200283 case DATADUR_A: /* DATADUR_A */
284 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700285 if (bNeedAck) {
286 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700287 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700288 } else {
289 return 0;
290 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200291 } else {/* First Frag or Mid Frag */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300292 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700293 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300294 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700295 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300296
Joe Perches547f1cf2013-03-18 10:45:01 -0700297 if (bNeedAck) {
298 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700299 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700300 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700301 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700302 }
303 }
304 break;
Forest Bond5449c682009-04-25 10:30:44 -0400305
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200306 case DATADUR_A_F0: /* DATADUR_A_F0 */
307 if (((uMACfragNum == 1)) || bLastFrag) {/* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700308 if (bNeedAck) {
309 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700310 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700311 } else {
312 return 0;
313 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200314 } else { /* First Frag or Mid Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700315 if (byFBOption == AUTO_FB_0) {
316 if (wRate < RATE_18M)
317 wRate = RATE_18M;
318 else if (wRate > RATE_54M)
319 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400320
Guido Martínezbc5cf652014-04-19 16:45:00 -0300321 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700322 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300323 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700324 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300325
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200326 } else { /* (byFBOption == AUTO_FB_1) */
Joe Perches547f1cf2013-03-18 10:45:01 -0700327 if (wRate < RATE_18M)
328 wRate = RATE_18M;
329 else if (wRate > RATE_54M)
330 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400331
Guido Martínezbc5cf652014-04-19 16:45:00 -0300332 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700333 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300334 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700335 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300336
Joe Perches547f1cf2013-03-18 10:45:01 -0700337 }
Forest Bond5449c682009-04-25 10:30:44 -0400338
Joe Perches547f1cf2013-03-18 10:45:01 -0700339 if (bNeedAck) {
340 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700341 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700342 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700343 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700344 }
345 }
346 break;
Forest Bond5449c682009-04-25 10:30:44 -0400347
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200348 case DATADUR_A_F1: /* DATADUR_A_F1 */
349 if (((uMACfragNum == 1)) || bLastFrag) { /* Non Frag or Last Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700350 if (bNeedAck) {
351 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700352 return pDevice->uSIFS + uAckTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700353 } else {
354 return 0;
355 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200356 } else { /* First Frag or Mid Frag */
Joe Perches547f1cf2013-03-18 10:45:01 -0700357 if (byFBOption == AUTO_FB_0) {
358 if (wRate < RATE_18M)
359 wRate = RATE_18M;
360 else if (wRate > RATE_54M)
361 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400362
Guido Martínezbc5cf652014-04-19 16:45:00 -0300363 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700364 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300365 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700366 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Forest Bond5449c682009-04-25 10:30:44 -0400367
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200368 } else { /* (byFBOption == AUTO_FB_1) */
Joe Perches547f1cf2013-03-18 10:45:01 -0700369 if (wRate < RATE_18M)
370 wRate = RATE_18M;
371 else if (wRate > RATE_54M)
372 wRate = RATE_54M;
Forest Bond5449c682009-04-25 10:30:44 -0400373
Guido Martínezbc5cf652014-04-19 16:45:00 -0300374 if (uFragIdx == (uMACfragNum-2))
Joe Perches547f1cf2013-03-18 10:45:01 -0700375 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300376 else
Joe Perches547f1cf2013-03-18 10:45:01 -0700377 uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Joe Perches547f1cf2013-03-18 10:45:01 -0700378 }
379 if (bNeedAck) {
380 uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700381 return pDevice->uSIFS + uAckTime + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700382 } else {
Joe Perchesa4ef27a2013-03-18 20:55:38 -0700383 return pDevice->uSIFS + uNextPktTime;
Joe Perches547f1cf2013-03-18 10:45:01 -0700384 }
385 }
386 break;
Forest Bond5449c682009-04-25 10:30:44 -0400387
Joe Perches547f1cf2013-03-18 10:45:01 -0700388 default:
389 break;
390 }
Forest Bond5449c682009-04-25 10:30:44 -0400391
Forest Bond5449c682009-04-25 10:30:44 -0400392 return 0;
393}
394
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200395/* byFreqType: 0=>5GHZ 1=>2.4GHZ */
Forest Bond5449c682009-04-25 10:30:44 -0400396static
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100397__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700398s_uGetRTSCTSDuration(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100399 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700400 unsigned char byDurType,
401 unsigned int cbFrameLength,
402 unsigned char byPktType,
403 unsigned short wRate,
404 bool bNeedAck,
405 unsigned char byFBOption
406)
Forest Bond5449c682009-04-25 10:30:44 -0400407{
Joe Perches547f1cf2013-03-18 10:45:01 -0700408 unsigned int uCTSTime = 0, uDurTime = 0;
Forest Bond5449c682009-04-25 10:30:44 -0400409
Joe Perches547f1cf2013-03-18 10:45:01 -0700410 switch (byDurType) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200411 case RTSDUR_BB: /* RTSDuration_bb */
Joe Perches547f1cf2013-03-18 10:45:01 -0700412 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
413 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
414 break;
Forest Bond5449c682009-04-25 10:30:44 -0400415
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200416 case RTSDUR_BA: /* RTSDuration_ba */
Joe Perches547f1cf2013-03-18 10:45:01 -0700417 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
418 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
419 break;
Forest Bond5449c682009-04-25 10:30:44 -0400420
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200421 case RTSDUR_AA: /* RTSDuration_aa */
Joe Perches547f1cf2013-03-18 10:45:01 -0700422 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
423 uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
424 break;
Forest Bond5449c682009-04-25 10:30:44 -0400425
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200426 case CTSDUR_BA: /* CTSDuration_ba */
Joe Perches547f1cf2013-03-18 10:45:01 -0700427 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
428 break;
Forest Bond5449c682009-04-25 10:30:44 -0400429
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200430 case RTSDUR_BA_F0: /* RTSDuration_ba_f0 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700431 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300432 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700433 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 -0300434 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700435 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 -0300436
Joe Perches547f1cf2013-03-18 10:45:01 -0700437 break;
Forest Bond5449c682009-04-25 10:30:44 -0400438
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200439 case RTSDUR_AA_F0: /* RTSDuration_aa_f0 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700440 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300441 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700442 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 -0300443 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700444 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 -0300445
Joe Perches547f1cf2013-03-18 10:45:01 -0700446 break;
Forest Bond5449c682009-04-25 10:30:44 -0400447
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200448 case RTSDUR_BA_F1: /* RTSDuration_ba_f1 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700449 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300450 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700451 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 -0300452 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700453 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 -0300454
Joe Perches547f1cf2013-03-18 10:45:01 -0700455 break;
Forest Bond5449c682009-04-25 10:30:44 -0400456
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200457 case RTSDUR_AA_F1: /* RTSDuration_aa_f1 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700458 uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300459 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700460 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 -0300461 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700462 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 -0300463
Joe Perches547f1cf2013-03-18 10:45:01 -0700464 break;
Forest Bond5449c682009-04-25 10:30:44 -0400465
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200466 case CTSDUR_BA_F0: /* CTSDuration_ba_f0 */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300467 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700468 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300469 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700470 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300471
Joe Perches547f1cf2013-03-18 10:45:01 -0700472 break;
Forest Bond5449c682009-04-25 10:30:44 -0400473
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200474 case CTSDUR_BA_F1: /* CTSDuration_ba_f1 */
Guido Martínezbc5cf652014-04-19 16:45:00 -0300475 if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700476 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300477 else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <= RATE_54M))
Joe Perches547f1cf2013-03-18 10:45:01 -0700478 uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
Guido Martínezbc5cf652014-04-19 16:45:00 -0300479
Joe Perches547f1cf2013-03-18 10:45:01 -0700480 break;
Forest Bond5449c682009-04-25 10:30:44 -0400481
Joe Perches547f1cf2013-03-18 10:45:01 -0700482 default:
483 break;
484 }
Forest Bond5449c682009-04-25 10:30:44 -0400485
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100486 return cpu_to_le16((u16)uDurTime);
Forest Bond5449c682009-04-25 10:30:44 -0400487}
488
Forest Bond5449c682009-04-25 10:30:44 -0400489static
Malcolm Priestleya479ffc2014-08-30 22:25:38 +0100490__le16
Joe Perches547f1cf2013-03-18 10:45:01 -0700491s_uFillDataHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100492 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700493 unsigned char byPktType,
494 void *pTxDataHead,
495 unsigned int cbFrameLength,
496 unsigned int uDMAIdx,
497 bool bNeedAck,
498 unsigned int uFragIdx,
499 unsigned int cbLastFragmentSize,
500 unsigned int uMACfragNum,
501 unsigned char byFBOption,
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000502 unsigned short wCurrentRate,
503 bool is_pspoll
Joe Perches547f1cf2013-03-18 10:45:01 -0700504)
Forest Bond5449c682009-04-25 10:30:44 -0400505{
Forest Bond5449c682009-04-25 10:30:44 -0400506
shyam saini4d932502016-09-29 04:22:20 +0530507 if (!pTxDataHead)
Joe Perches547f1cf2013-03-18 10:45:01 -0700508 return 0;
Guido Martínezbc5cf652014-04-19 16:45:00 -0300509
Forest Bond5449c682009-04-25 10:30:44 -0400510
Joe Perches547f1cf2013-03-18 10:45:01 -0700511 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
512 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100513 struct vnt_tx_datahead_g *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100514 /* Get SignalField, ServiceField & Length */
515 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100516 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100517
518 vnt_get_phy_field(pDevice, cbFrameLength,
519 pDevice->byTopCCKBasicRate,
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100520 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100521
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000522 if (is_pspoll) {
523 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
524
525 buf->duration_a = dur;
526 buf->duration_b = dur;
527 } else {
528 /* Get Duration and TimeStamp */
529 buf->duration_a =
530 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
531 byPktType, wCurrentRate, bNeedAck, uFragIdx,
532 cbLastFragmentSize, uMACfragNum,
533 byFBOption));
534 buf->duration_b =
535 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
536 PK_TYPE_11B, pDevice->byTopCCKBasicRate,
537 bNeedAck, uFragIdx, cbLastFragmentSize,
538 uMACfragNum, byFBOption));
539 }
Forest Bond5449c682009-04-25 10:30:44 -0400540
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100541 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
542 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400543
Malcolm Priestley72edb7e2014-08-30 22:25:34 +0100544 return buf->duration_a;
Joe Perches547f1cf2013-03-18 10:45:01 -0700545 } else {
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100546 /* Auto Fallback */
547 struct vnt_tx_datahead_g_fb *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100548 /* Get SignalField, ServiceField & Length */
549 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100550 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100551
552 vnt_get_phy_field(pDevice, cbFrameLength,
553 pDevice->byTopCCKBasicRate,
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100554 PK_TYPE_11B, &buf->b);
555 /* Get Duration and TimeStamp */
556 buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
557 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
558 buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
559 pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
560 buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
561 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
562 buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
563 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
Forest Bond5449c682009-04-25 10:30:44 -0400564
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100565 buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate);
566 buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate);
Forest Bond5449c682009-04-25 10:30:44 -0400567
Malcolm Priestley2dd76672014-08-30 22:25:35 +0100568 return buf->duration_a;
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200569 } /* if (byFBOption == AUTO_FB_NONE) */
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700570 } else if (byPktType == PK_TYPE_11A) {
Shivani Bhardwaj45e68e42015-10-12 00:49:34 +0530571 if (byFBOption != AUTO_FB_NONE) {
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100572 /* Auto Fallback */
573 struct vnt_tx_datahead_a_fb *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100574 /* Get SignalField, ServiceField & Length */
575 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100576 byPktType, &buf->a);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100577
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +0100578 /* Get Duration and TimeStampOff */
579 buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
580 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
581 buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
582 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
583 buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
584 wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption));
585 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
586 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700587 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100588 struct vnt_tx_datahead_ab *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100589 /* Get SignalField, ServiceField & Length */
590 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100591 byPktType, &buf->ab);
Forest Bond5449c682009-04-25 10:30:44 -0400592
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000593 if (is_pspoll) {
594 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
595
596 buf->duration = dur;
597 } else {
598 /* Get Duration and TimeStampOff */
599 buf->duration =
600 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100601 wCurrentRate, bNeedAck, uFragIdx,
602 cbLastFragmentSize, uMACfragNum,
603 byFBOption));
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000604 }
Forest Bond5449c682009-04-25 10:30:44 -0400605
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100606 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
607 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700608 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700609 } else {
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100610 struct vnt_tx_datahead_ab *buf = pTxDataHead;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100611 /* Get SignalField, ServiceField & Length */
612 vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100613 byPktType, &buf->ab);
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000614
615 if (is_pspoll) {
616 __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15));
617
618 buf->duration = dur;
619 } else {
620 /* Get Duration and TimeStampOff */
621 buf->duration =
622 cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100623 wCurrentRate, bNeedAck, uFragIdx,
624 cbLastFragmentSize, uMACfragNum,
625 byFBOption));
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000626 }
627
Malcolm Priestley9ce842a2014-08-30 22:25:36 +0100628 buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate);
629 return buf->duration;
Joe Perches547f1cf2013-03-18 10:45:01 -0700630 }
631 return 0;
Forest Bond5449c682009-04-25 10:30:44 -0400632}
633
Malcolm Priestley89cf9be2014-10-29 17:43:42 +0000634
Forest Bond5449c682009-04-25 10:30:44 -0400635static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700636void
Joe Perches547f1cf2013-03-18 10:45:01 -0700637s_vFillRTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100638 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700639 unsigned char byPktType,
640 void *pvRTS,
641 unsigned int cbFrameLength,
642 bool bNeedAck,
643 bool bDisCRC,
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000644 struct ieee80211_hdr *hdr,
Joe Perches547f1cf2013-03-18 10:45:01 -0700645 unsigned short wCurrentRate,
646 unsigned char byFBOption
647)
Forest Bond5449c682009-04-25 10:30:44 -0400648{
Joe Perches547f1cf2013-03-18 10:45:01 -0700649 unsigned int uRTSFrameLen = 20;
Forest Bond5449c682009-04-25 10:30:44 -0400650
shyam saini4d932502016-09-29 04:22:20 +0530651 if (!pvRTS)
Joe Perches547f1cf2013-03-18 10:45:01 -0700652 return;
Forest Bond5449c682009-04-25 10:30:44 -0400653
Joe Perches547f1cf2013-03-18 10:45:01 -0700654 if (bDisCRC) {
Anson Jacobf46e0412016-08-22 17:12:35 -0400655 /* When CRCDIS bit is on, H/W forgot to generate FCS for
656 * RTS frame, in this case we need to decrease its length by 4.
657 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700658 uRTSFrameLen -= 4;
659 }
Forest Bond5449c682009-04-25 10:30:44 -0400660
Anson Jacobf46e0412016-08-22 17:12:35 -0400661 /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA,
662 * so we don't need to take them into account.
663 * Otherwise, we need to modify codes for them.
664 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700665 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
666 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestley17434f02014-08-30 22:25:41 +0100667 struct vnt_rts_g *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100668 /* Get SignalField, ServiceField & Length */
669 vnt_get_phy_field(pDevice, uRTSFrameLen,
670 pDevice->byTopCCKBasicRate,
Malcolm Priestley17434f02014-08-30 22:25:41 +0100671 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100672
673 vnt_get_phy_field(pDevice, uRTSFrameLen,
674 pDevice->byTopOFDMBasicRate,
Malcolm Priestley17434f02014-08-30 22:25:41 +0100675 byPktType, &buf->a);
676 /* Get Duration */
677 buf->duration_bb =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100678 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
679 cbFrameLength, PK_TYPE_11B,
680 pDevice->byTopCCKBasicRate,
681 bNeedAck, byFBOption);
Malcolm Priestley17434f02014-08-30 22:25:41 +0100682 buf->duration_aa =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100683 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
684 cbFrameLength, byPktType,
685 wCurrentRate, bNeedAck,
686 byFBOption);
Malcolm Priestley17434f02014-08-30 22:25:41 +0100687 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100688 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
689 cbFrameLength, byPktType,
690 wCurrentRate, bNeedAck,
691 byFBOption);
Forest Bond5449c682009-04-25 10:30:44 -0400692
Malcolm Priestley17434f02014-08-30 22:25:41 +0100693 buf->data.duration = buf->duration_aa;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100694 /* Get RTS Frame body */
Malcolm Priestley17434f02014-08-30 22:25:41 +0100695 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100696 cpu_to_le16(IEEE80211_FTYPE_CTL |
697 IEEE80211_STYPE_RTS);
698
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000699 ether_addr_copy(buf->data.ra, hdr->addr1);
700 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700701 } else {
Malcolm Priestley9587b092014-08-30 22:25:42 +0100702 struct vnt_rts_g_fb *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100703 /* Get SignalField, ServiceField & Length */
704 vnt_get_phy_field(pDevice, uRTSFrameLen,
705 pDevice->byTopCCKBasicRate,
Malcolm Priestley9587b092014-08-30 22:25:42 +0100706 PK_TYPE_11B, &buf->b);
Forest Bond5449c682009-04-25 10:30:44 -0400707
Malcolm Priestley429a2472014-08-20 22:30:29 +0100708 vnt_get_phy_field(pDevice, uRTSFrameLen,
709 pDevice->byTopOFDMBasicRate,
Malcolm Priestley9587b092014-08-30 22:25:42 +0100710 byPktType, &buf->a);
711 /* Get Duration */
712 buf->duration_bb =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100713 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB,
714 cbFrameLength, PK_TYPE_11B,
715 pDevice->byTopCCKBasicRate,
716 bNeedAck, byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100717 buf->duration_aa =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100718 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
719 cbFrameLength, byPktType,
720 wCurrentRate, bNeedAck,
721 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100722 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100723 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA,
724 cbFrameLength, byPktType,
725 wCurrentRate, bNeedAck,
726 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100727 buf->rts_duration_ba_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100728 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0,
729 cbFrameLength, byPktType,
730 wCurrentRate, bNeedAck,
731 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100732 buf->rts_duration_aa_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100733 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
734 cbFrameLength, byPktType,
735 wCurrentRate, bNeedAck,
736 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100737 buf->rts_duration_ba_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100738 s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1,
739 cbFrameLength, byPktType,
740 wCurrentRate, bNeedAck,
741 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100742 buf->rts_duration_aa_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100743 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
744 cbFrameLength, byPktType,
745 wCurrentRate, bNeedAck,
746 byFBOption);
Malcolm Priestley9587b092014-08-30 22:25:42 +0100747 buf->data.duration = buf->duration_aa;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100748 /* Get RTS Frame body */
Malcolm Priestley9587b092014-08-30 22:25:42 +0100749 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100750 cpu_to_le16(IEEE80211_FTYPE_CTL |
751 IEEE80211_STYPE_RTS);
752
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000753 ether_addr_copy(buf->data.ra, hdr->addr1);
754 ether_addr_copy(buf->data.ta, hdr->addr2);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200755 } /* if (byFBOption == AUTO_FB_NONE) */
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700756 } else if (byPktType == PK_TYPE_11A) {
Joe Perches547f1cf2013-03-18 10:45:01 -0700757 if (byFBOption == AUTO_FB_NONE) {
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100758 struct vnt_rts_ab *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100759 /* Get SignalField, ServiceField & Length */
760 vnt_get_phy_field(pDevice, uRTSFrameLen,
761 pDevice->byTopOFDMBasicRate,
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100762 byPktType, &buf->ab);
763 /* Get Duration */
764 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100765 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
766 cbFrameLength, byPktType,
767 wCurrentRate, bNeedAck,
768 byFBOption);
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100769 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100770 /* Get RTS Frame body */
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100771 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100772 cpu_to_le16(IEEE80211_FTYPE_CTL |
773 IEEE80211_STYPE_RTS);
774
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000775 ether_addr_copy(buf->data.ra, hdr->addr1);
776 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700777 } else {
Malcolm Priestley8e448042014-08-30 22:25:44 +0100778 struct vnt_rts_a_fb *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100779 /* Get SignalField, ServiceField & Length */
780 vnt_get_phy_field(pDevice, uRTSFrameLen,
781 pDevice->byTopOFDMBasicRate,
Malcolm Priestley8e448042014-08-30 22:25:44 +0100782 byPktType, &buf->a);
783 /* Get Duration */
784 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100785 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA,
786 cbFrameLength, byPktType,
787 wCurrentRate, bNeedAck,
788 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100789 buf->rts_duration_f0 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100790 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0,
791 cbFrameLength, byPktType,
792 wCurrentRate, bNeedAck,
793 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100794 buf->rts_duration_f1 =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100795 s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1,
796 cbFrameLength, byPktType,
797 wCurrentRate, bNeedAck,
798 byFBOption);
Malcolm Priestley8e448042014-08-30 22:25:44 +0100799 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100800 /* Get RTS Frame body */
Malcolm Priestley8e448042014-08-30 22:25:44 +0100801 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100802 cpu_to_le16(IEEE80211_FTYPE_CTL |
803 IEEE80211_STYPE_RTS);
804
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000805 ether_addr_copy(buf->data.ra, hdr->addr1);
806 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches547f1cf2013-03-18 10:45:01 -0700807 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -0700808 } else if (byPktType == PK_TYPE_11B) {
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100809 struct vnt_rts_ab *buf = pvRTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100810 /* Get SignalField, ServiceField & Length */
811 vnt_get_phy_field(pDevice, uRTSFrameLen,
812 pDevice->byTopCCKBasicRate,
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100813 PK_TYPE_11B, &buf->ab);
814 /* Get Duration */
815 buf->duration =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100816 s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength,
817 byPktType, wCurrentRate, bNeedAck,
818 byFBOption);
819
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100820 buf->data.duration = buf->duration;
Malcolm Priestley52c41302014-08-30 22:25:39 +0100821 /* Get RTS Frame body */
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +0100822 buf->data.frame_control =
Malcolm Priestley52c41302014-08-30 22:25:39 +0100823 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
Forest Bond5449c682009-04-25 10:30:44 -0400824
Malcolm Priestley7c0496d2014-10-29 17:43:41 +0000825 ether_addr_copy(buf->data.ra, hdr->addr1);
826 ether_addr_copy(buf->data.ta, hdr->addr2);
Joe Perches547f1cf2013-03-18 10:45:01 -0700827 }
Forest Bond5449c682009-04-25 10:30:44 -0400828}
829
830static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700831void
Joe Perches547f1cf2013-03-18 10:45:01 -0700832s_vFillCTSHead(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100833 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700834 unsigned int uDMAIdx,
835 unsigned char byPktType,
836 void *pvCTS,
837 unsigned int cbFrameLength,
838 bool bNeedAck,
839 bool bDisCRC,
840 unsigned short wCurrentRate,
841 unsigned char byFBOption
842)
Forest Bond5449c682009-04-25 10:30:44 -0400843{
Joe Perches547f1cf2013-03-18 10:45:01 -0700844 unsigned int uCTSFrameLen = 14;
Forest Bond5449c682009-04-25 10:30:44 -0400845
shyam saini4d932502016-09-29 04:22:20 +0530846 if (!pvCTS)
Joe Perches547f1cf2013-03-18 10:45:01 -0700847 return;
Forest Bond5449c682009-04-25 10:30:44 -0400848
Joe Perches547f1cf2013-03-18 10:45:01 -0700849 if (bDisCRC) {
Anson Jacobf46e0412016-08-22 17:12:35 -0400850 /* When CRCDIS bit is on, H/W forgot to generate FCS for
851 * CTS frame, in this case we need to decrease its length by 4.
852 */
Joe Perches547f1cf2013-03-18 10:45:01 -0700853 uCTSFrameLen -= 4;
854 }
Forest Bond5449c682009-04-25 10:30:44 -0400855
Joe Perches547f1cf2013-03-18 10:45:01 -0700856 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
857 if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200858 /* Auto Fall back */
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100859 struct vnt_cts_fb *buf = pvCTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100860 /* Get SignalField, ServiceField & Length */
861 vnt_get_phy_field(pDevice, uCTSFrameLen,
862 pDevice->byTopCCKBasicRate,
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100863 PK_TYPE_11B, &buf->b);
Forest Bond5449c682009-04-25 10:30:44 -0400864
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100865 buf->duration_ba =
866 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
867 cbFrameLength, byPktType,
868 wCurrentRate, bNeedAck,
869 byFBOption);
870
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100871 /* Get CTSDuration_ba_f0 */
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100872 buf->cts_duration_ba_f0 =
873 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0,
874 cbFrameLength, byPktType,
875 wCurrentRate, bNeedAck,
876 byFBOption);
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100877
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100878 /* Get CTSDuration_ba_f1 */
879 buf->cts_duration_ba_f1 =
880 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1,
881 cbFrameLength, byPktType,
882 wCurrentRate, bNeedAck,
883 byFBOption);
Malcolm Priestley0864db12014-08-30 22:25:40 +0100884
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100885 /* Get CTS Frame body */
886 buf->data.duration = buf->duration_ba;
887
888 buf->data.frame_control =
Malcolm Priestley0864db12014-08-30 22:25:40 +0100889 cpu_to_le16(IEEE80211_FTYPE_CTL |
890 IEEE80211_STYPE_CTS);
891
Malcolm Priestleydb1afd12014-08-30 22:25:46 +0100892 buf->reserved2 = 0x0;
Forest Bond5449c682009-04-25 10:30:44 -0400893
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200894 ether_addr_copy(buf->data.ra,
895 pDevice->abyCurrentNetAddr);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200896 } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100897 struct vnt_cts *buf = pvCTS;
Malcolm Priestley429a2472014-08-20 22:30:29 +0100898 /* Get SignalField, ServiceField & Length */
899 vnt_get_phy_field(pDevice, uCTSFrameLen,
900 pDevice->byTopCCKBasicRate,
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100901 PK_TYPE_11B, &buf->b);
Malcolm Priestley429a2472014-08-20 22:30:29 +0100902
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100903 /* Get CTSDuration_ba */
904 buf->duration_ba =
Malcolm Priestley96372bd2014-08-30 22:25:48 +0100905 s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
906 cbFrameLength, byPktType,
907 wCurrentRate, bNeedAck,
908 byFBOption);
Forest Bond5449c682009-04-25 10:30:44 -0400909
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100910 /* Get CTS Frame body */
911 buf->data.duration = buf->duration_ba;
Malcolm Priestley0864db12014-08-30 22:25:40 +0100912
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100913 buf->data.frame_control =
Malcolm Priestley0864db12014-08-30 22:25:40 +0100914 cpu_to_le16(IEEE80211_FTYPE_CTL |
915 IEEE80211_STYPE_CTS);
916
Malcolm Priestleyf5172b02014-08-30 22:25:45 +0100917 buf->reserved2 = 0x0;
Aya Mahfouz2359b5c2014-10-11 02:42:45 +0200918 ether_addr_copy(buf->data.ra,
919 pDevice->abyCurrentNetAddr);
Joe Perches547f1cf2013-03-18 10:45:01 -0700920 }
921 }
Forest Bond5449c682009-04-25 10:30:44 -0400922}
923
Anson Jacobf46e0412016-08-22 17:12:35 -0400924/*
Forest Bond5449c682009-04-25 10:30:44 -0400925 *
926 * Description:
927 * Generate FIFO control for MAC & Baseband controller
928 *
929 * Parameters:
930 * In:
Gilles Espinassef77f13e2010-03-29 15:41:47 +0200931 * pDevice - Pointer to adapter
Forest Bond5449c682009-04-25 10:30:44 -0400932 * pTxDataHead - Transmit Data Buffer
933 * pTxBufHead - pTxBufHead
934 * pvRrvTime - pvRrvTime
935 * pvRTS - RTS Buffer
936 * pCTS - CTS Buffer
937 * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
938 * bNeedACK - If need ACK
939 * uDescIdx - Desc Index
940 * Out:
941 * none
942 *
943 * Return Value: none
944 *
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200945 -
Anson Jacobf46e0412016-08-22 17:12:35 -0400946 * unsigned int cbFrameSize, Hdr+Payload+FCS
947 */
Forest Bond5449c682009-04-25 10:30:44 -0400948static
Charles Clément6b35b7b2010-05-07 12:30:19 -0700949void
Joe Perches547f1cf2013-03-18 10:45:01 -0700950s_vGenerateTxParameter(
Malcolm Priestleycf76dc42014-08-10 15:46:59 +0100951 struct vnt_private *pDevice,
Joe Perches547f1cf2013-03-18 10:45:01 -0700952 unsigned char byPktType,
Malcolm Priestleydf184802015-04-01 22:32:51 +0100953 struct vnt_tx_fifo_head *tx_buffer_head,
Joe Perches547f1cf2013-03-18 10:45:01 -0700954 void *pvRrvTime,
955 void *pvRTS,
956 void *pvCTS,
957 unsigned int cbFrameSize,
958 bool bNeedACK,
959 unsigned int uDMAIdx,
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +0000960 void *psEthHeader,
Joe Perches547f1cf2013-03-18 10:45:01 -0700961 unsigned short wCurrentRate
962)
Forest Bond5449c682009-04-25 10:30:44 -0400963{
Malcolm Priestleydf184802015-04-01 22:32:51 +0100964 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
Joe Perches547f1cf2013-03-18 10:45:01 -0700965 bool bDisCRC = false;
966 unsigned char byFBOption = AUTO_FB_NONE;
Forest Bond5449c682009-04-25 10:30:44 -0400967
Malcolm Priestleydf184802015-04-01 22:32:51 +0100968 tx_buffer_head->current_rate = cpu_to_le16(wCurrentRate);
Guillaume Clement6b711272014-07-25 01:06:16 +0200969
Malcolm Priestleydf184802015-04-01 22:32:51 +0100970 if (fifo_ctl & FIFOCTL_CRCDIS)
Joe Perches547f1cf2013-03-18 10:45:01 -0700971 bDisCRC = true;
Forest Bond5449c682009-04-25 10:30:44 -0400972
Malcolm Priestleydf184802015-04-01 22:32:51 +0100973 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -0700974 byFBOption = AUTO_FB_0;
Malcolm Priestleydf184802015-04-01 22:32:51 +0100975 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -0700976 byFBOption = AUTO_FB_1;
Forest Bond5449c682009-04-25 10:30:44 -0400977
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100978 if (!pvRrvTime)
979 return;
980
Joe Perches547f1cf2013-03-18 10:45:01 -0700981 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
Anson Jacobf46e0412016-08-22 17:12:35 -0400982 if (pvRTS != NULL) { /* RTS_need */
983 /* Fill RsvTime */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100984 struct vnt_rrv_time_rts *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +0200985
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100986 buf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
987 buf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate);
988 buf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
989 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
990 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
991
Joe Perches547f1cf2013-03-18 10:45:01 -0700992 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +0200993 } else {/* RTS_needless, PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100994 struct vnt_rrv_time_cts *buf = pvRrvTime;
Forest Bond5449c682009-04-25 10:30:44 -0400995
Malcolm Priestleyc00a3782014-08-30 22:25:32 +0100996 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
997 buf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK);
998 buf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate);
Forest Bond5449c682009-04-25 10:30:44 -0400999
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001000 /* Fill CTS */
Joe Perches547f1cf2013-03-18 10:45:01 -07001001 s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
1002 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001003 } else if (byPktType == PK_TYPE_11A) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001004 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001005 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001006
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001007 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate);
1008 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK);
1009
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001010 /* Fill RTS */
Joe Perches547f1cf2013-03-18 10:45:01 -07001011 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
shyam saini4d932502016-09-29 04:22:20 +05301012 } else if (!pvRTS) {/* RTS_needless, 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->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK);
Joe Perches547f1cf2013-03-18 10:45:01 -07001016 }
Joe Perches5e0cc8a2013-03-18 20:55:37 -07001017 } else if (byPktType == PK_TYPE_11B) {
Shivani Bhardwaj45e68e42015-10-12 00:49:34 +05301018 if (pvRTS != NULL) {/* RTS_need, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001019 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001020
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001021 buf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate);
1022 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
1023
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001024 /* Fill RTS */
Joe Perches547f1cf2013-03-18 10:45:01 -07001025 s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001026 } else { /* RTS_needless, non PCF mode */
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001027 struct vnt_rrv_time_ab *buf = pvRrvTime;
Guillaume Clement6b711272014-07-25 01:06:16 +02001028
Malcolm Priestleyc00a3782014-08-30 22:25:32 +01001029 buf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK);
Joe Perches547f1cf2013-03-18 10:45:01 -07001030 }
1031 }
Forest Bond5449c682009-04-25 10:30:44 -04001032}
Guido Martínez4e8a7e52014-04-19 16:44:59 -03001033
Charles Clémentfe4f34b2010-06-25 10:48:53 -07001034static unsigned int
Malcolm Priestleycf76dc42014-08-10 15:46:59 +01001035s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001036 unsigned char *pbyTxBufferAddr,
Malcolm Priestleye2357272015-08-14 22:58:51 +01001037 unsigned int uDMAIdx, struct vnt_tx_desc *pHeadTD,
Malcolm Priestley154bb8b2014-11-29 00:02:02 +00001038 unsigned int is_pspoll)
Forest Bond5449c682009-04-25 10:30:44 -04001039{
Malcolm Priestley54382852015-08-14 22:58:50 +01001040 struct vnt_td_info *td_info = pHeadTD->td_info;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001041 struct sk_buff *skb = td_info->skb;
1042 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1043 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1044 struct vnt_tx_fifo_head *tx_buffer_head =
1045 (struct vnt_tx_fifo_head *)td_info->buf;
1046 u16 fifo_ctl = le16_to_cpu(tx_buffer_head->fifo_ctl);
Joe Perches547f1cf2013-03-18 10:45:01 -07001047 unsigned int cbFrameSize;
Malcolm Priestleya479ffc2014-08-30 22:25:38 +01001048 __le16 uDuration;
Joe Perches547f1cf2013-03-18 10:45:01 -07001049 unsigned char *pbyBuffer;
Joe Perches547f1cf2013-03-18 10:45:01 -07001050 unsigned int uLength = 0;
Joe Perches547f1cf2013-03-18 10:45:01 -07001051 unsigned int cbMICHDR = 0;
Joe Perches547f1cf2013-03-18 10:45:01 -07001052 unsigned int uMACfragNum = 1;
1053 unsigned int uPadding = 0;
1054 unsigned int cbReqCount = 0;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001055 bool bNeedACK = (bool)(fifo_ctl & FIFOCTL_NEEDACK);
1056 bool bRTS = (bool)(fifo_ctl & FIFOCTL_RTS);
Malcolm Priestleye2357272015-08-14 22:58:51 +01001057 struct vnt_tx_desc *ptdCurr;
Joe Perches547f1cf2013-03-18 10:45:01 -07001058 unsigned int cbHeaderLength = 0;
1059 void *pvRrvTime;
Malcolm Priestley11a72e52014-08-09 20:15:56 +01001060 struct vnt_mic_hdr *pMICHDR;
Joe Perches547f1cf2013-03-18 10:45:01 -07001061 void *pvRTS;
1062 void *pvCTS;
1063 void *pvTxDataHd;
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001064 unsigned short wTxBufSize; /* FFinfo size */
Joe Perches547f1cf2013-03-18 10:45:01 -07001065 unsigned char byFBOption = AUTO_FB_NONE;
Forest Bond5449c682009-04-25 10:30:44 -04001066
Joe Perches547f1cf2013-03-18 10:45:01 -07001067 pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
Forest Bond5449c682009-04-25 10:30:44 -04001068
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001069 cbFrameSize = skb->len + 4;
Forest Bond5449c682009-04-25 10:30:44 -04001070
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001071 if (info->control.hw_key) {
1072 switch (info->control.hw_key->cipher) {
1073 case WLAN_CIPHER_SUITE_CCMP:
Malcolm Priestley11a72e52014-08-09 20:15:56 +01001074 cbMICHDR = sizeof(struct vnt_mic_hdr);
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001075 default:
1076 break;
Joe Perches547f1cf2013-03-18 10:45:01 -07001077 }
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001078
1079 cbFrameSize += info->control.hw_key->icv_len;
1080
Joe Perches547f1cf2013-03-18 10:45:01 -07001081 if (pDevice->byLocalID > REV_ID_VT3253_A1) {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001082 /* MAC Header should be padding 0 to DW alignment. */
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001083 uPadding = 4 - (ieee80211_get_hdrlen_from_skb(skb) % 4);
Joe Perches547f1cf2013-03-18 10:45:01 -07001084 uPadding %= 4;
1085 }
1086 }
Forest Bond5449c682009-04-25 10:30:44 -04001087
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001088 /*
1089 * Use for AUTO FALL BACK
1090 */
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001091 if (fifo_ctl & FIFOCTL_AUTO_FB_0)
Joe Perches547f1cf2013-03-18 10:45:01 -07001092 byFBOption = AUTO_FB_0;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001093 else if (fifo_ctl & FIFOCTL_AUTO_FB_1)
Joe Perches547f1cf2013-03-18 10:45:01 -07001094 byFBOption = AUTO_FB_1;
Forest Bond5449c682009-04-25 10:30:44 -04001095
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001096
1097 /* Set RrvTime/RTS/CTS Buffer */
Malcolm Priestleyc5c7bd22015-07-22 19:16:46 +01001098 wTxBufSize = sizeof(struct vnt_tx_fifo_head);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001099 if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {/* 802.11g packet */
Forest Bond5449c682009-04-25 10:30:44 -04001100
Joe Perches547f1cf2013-03-18 10:45:01 -07001101 if (byFBOption == AUTO_FB_NONE) {
Harisangam Sharvari441b3e42015-06-09 04:27:35 +00001102 if (bRTS) {/* RTS_need */
Malcolm Priestleya9e6a2d2014-08-30 22:25:27 +01001103 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1104 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
Malcolm Priestley17434f02014-08-30 22:25:41 +01001105 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001106 pvCTS = NULL;
Malcolm Priestley17434f02014-08-30 22:25:41 +01001107 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1108 cbMICHDR + sizeof(struct vnt_rts_g));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01001109 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley17434f02014-08-30 22:25:41 +01001110 cbMICHDR + sizeof(struct vnt_rts_g) +
1111 sizeof(struct vnt_tx_datahead_g);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001112 } else { /* RTS_needless */
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01001113 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1114 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07001115 pvRTS = NULL;
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001116 pvCTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1117 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1118 sizeof(struct vnt_rrv_time_cts) + cbMICHDR + sizeof(struct vnt_cts));
Malcolm Priestley72edb7e2014-08-30 22:25:34 +01001119 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleyf5172b02014-08-30 22:25:45 +01001120 cbMICHDR + sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
Joe Perches547f1cf2013-03-18 10:45:01 -07001121 }
1122 } else {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001123 /* Auto Fall Back */
Harisangam Sharvari441b3e42015-06-09 04:27:35 +00001124 if (bRTS) {/* RTS_need */
Malcolm Priestleya9e6a2d2014-08-30 22:25:27 +01001125 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1126 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts));
Malcolm Priestley9587b092014-08-30 22:25:42 +01001127 pvRTS = (void *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001128 pvCTS = NULL;
Malcolm Priestley9587b092014-08-30 22:25:42 +01001129 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
1130 cbMICHDR + sizeof(struct vnt_rts_g_fb));
Malcolm Priestley2dd76672014-08-30 22:25:35 +01001131 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
Malcolm Priestley9587b092014-08-30 22:25:42 +01001132 cbMICHDR + sizeof(struct vnt_rts_g_fb) + sizeof(struct vnt_tx_datahead_g_fb);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001133 } else { /* RTS_needless */
Malcolm Priestleyd66a5a72014-08-30 22:25:28 +01001134 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1135 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts));
Joe Perches547f1cf2013-03-18 10:45:01 -07001136 pvRTS = NULL;
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001137 pvCTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
1138 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
1139 cbMICHDR + sizeof(struct vnt_cts_fb));
Malcolm Priestley2dd76672014-08-30 22:25:35 +01001140 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
Malcolm Priestleydb1afd12014-08-30 22:25:46 +01001141 cbMICHDR + sizeof(struct vnt_cts_fb) + sizeof(struct vnt_tx_datahead_g_fb);
Joe Perches547f1cf2013-03-18 10:45:01 -07001142 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001143 } /* Auto Fall Back */
1144 } else {/* 802.11a/b packet */
Forest Bond5449c682009-04-25 10:30:44 -04001145
Joe Perches547f1cf2013-03-18 10:45:01 -07001146 if (byFBOption == AUTO_FB_NONE) {
Harisangam Sharvari441b3e42015-06-09 04:27:35 +00001147 if (bRTS) {
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001148 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1149 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001150 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001151 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001152 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001153 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_ab));
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001154 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestleye21eb1c2014-08-30 22:25:43 +01001155 cbMICHDR + sizeof(struct vnt_rts_ab) + sizeof(struct vnt_tx_datahead_ab);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001156 } else { /* RTS_needless, need MICHDR */
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001157 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1158 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07001159 pvRTS = NULL;
1160 pvCTS = NULL;
Malcolm Priestley9ce842a2014-08-30 22:25:36 +01001161 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1162 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1163 cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
Joe Perches547f1cf2013-03-18 10:45:01 -07001164 }
1165 } else {
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001166 /* Auto Fall Back */
Harisangam Sharvari441b3e42015-06-09 04:27:35 +00001167 if (bRTS) { /* RTS_need */
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001168 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1169 pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Malcolm Priestley8e448042014-08-30 22:25:44 +01001170 pvRTS = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
Joe Perches547f1cf2013-03-18 10:45:01 -07001171 pvCTS = NULL;
Malcolm Priestley8e448042014-08-30 22:25:44 +01001172 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize +
1173 sizeof(struct vnt_rrv_time_ab) + cbMICHDR + sizeof(struct vnt_rts_a_fb));
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +01001174 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
Malcolm Priestley8e448042014-08-30 22:25:44 +01001175 cbMICHDR + sizeof(struct vnt_rts_a_fb) + sizeof(struct vnt_tx_datahead_a_fb);
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001176 } else { /* RTS_needless */
Malcolm Priestleyf6a634c2014-08-30 22:25:29 +01001177 pvRrvTime = (void *)(pbyTxBufferAddr + wTxBufSize);
1178 pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab));
Joe Perches547f1cf2013-03-18 10:45:01 -07001179 pvRTS = NULL;
1180 pvCTS = NULL;
Malcolm Priestley9c62c7a2014-08-30 22:25:37 +01001181 pvTxDataHd = (void *)(pbyTxBufferAddr + wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
1182 cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
1183 cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
Joe Perches547f1cf2013-03-18 10:45:01 -07001184 }
Hatice ERTÜRK7a48a092015-03-19 23:09:43 +02001185 } /* Auto Fall Back */
Joe Perches547f1cf2013-03-18 10:45:01 -07001186 }
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001187
1188 td_info->mic_hdr = pMICHDR;
1189
Joe Perches547f1cf2013-03-18 10:45:01 -07001190 memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
Forest Bond5449c682009-04-25 10:30:44 -04001191
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001192 /* Fill FIFO,RrvTime,RTS,and CTS */
1193 s_vGenerateTxParameter(pDevice, byPktType, tx_buffer_head, pvRrvTime, pvRTS, pvCTS,
1194 cbFrameSize, bNeedACK, uDMAIdx, hdr, pDevice->wCurrentRate);
1195 /* Fill DataHead */
1196 uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
Malcolm Priestley89cf9be2014-10-29 17:43:42 +00001197 0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate, is_pspoll);
Forest Bond5449c682009-04-25 10:30:44 -04001198
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001199 hdr->duration_id = uDuration;
Forest Bond5449c682009-04-25 10:30:44 -04001200
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001201 cbReqCount = cbHeaderLength + uPadding + skb->len;
Malcolm Priestley54382852015-08-14 22:58:50 +01001202 pbyBuffer = (unsigned char *)pHeadTD->td_info->buf;
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001203 uLength = cbHeaderLength + uPadding;
Forest Bond5449c682009-04-25 10:30:44 -04001204
Malcolm Priestleycfd9f0d2014-10-29 17:43:39 +00001205 /* Copy the Packet into a tx Buffer */
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001206 memcpy((pbyBuffer + uLength), skb->data, skb->len);
Guido Martínezbc5cf652014-04-19 16:45:00 -03001207
Malcolm Priestleye2357272015-08-14 22:58:51 +01001208 ptdCurr = pHeadTD;
Forest Bond5449c682009-04-25 10:30:44 -04001209
Malcolm Priestley54382852015-08-14 22:58:50 +01001210 ptdCurr->td_info->req_count = (u16)cbReqCount;
Forest Bond5449c682009-04-25 10:30:44 -04001211
Joe Perches547f1cf2013-03-18 10:45:01 -07001212 return cbHeaderLength;
Forest Bond5449c682009-04-25 10:30:44 -04001213}
1214
Malcolm Priestley01eec152014-10-29 17:43:38 +00001215static void vnt_fill_txkey(struct ieee80211_hdr *hdr, u8 *key_buffer,
1216 struct ieee80211_key_conf *tx_key,
1217 struct sk_buff *skb, u16 payload_len,
1218 struct vnt_mic_hdr *mic_hdr)
1219{
Eliad Pellerca48ebb2016-02-15 12:34:10 +02001220 u64 pn64;
Malcolm Priestley01eec152014-10-29 17:43:38 +00001221 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
1222
1223 /* strip header and icv len from payload */
1224 payload_len -= ieee80211_get_hdrlen_from_skb(skb);
1225 payload_len -= tx_key->icv_len;
1226
1227 switch (tx_key->cipher) {
1228 case WLAN_CIPHER_SUITE_WEP40:
1229 case WLAN_CIPHER_SUITE_WEP104:
1230 memcpy(key_buffer, iv, 3);
1231 memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
1232
1233 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
1234 memcpy(key_buffer + 8, iv, 3);
1235 memcpy(key_buffer + 11,
1236 tx_key->key, WLAN_KEY_LEN_WEP40);
1237 }
1238
1239 break;
1240 case WLAN_CIPHER_SUITE_TKIP:
1241 ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
1242
1243 break;
1244 case WLAN_CIPHER_SUITE_CCMP:
1245
1246 if (!mic_hdr)
1247 return;
1248
1249 mic_hdr->id = 0x59;
1250 mic_hdr->payload_len = cpu_to_be16(payload_len);
1251 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
1252
Eliad Pellerca48ebb2016-02-15 12:34:10 +02001253 pn64 = atomic64_read(&tx_key->tx_pn);
1254 mic_hdr->ccmp_pn[5] = pn64;
1255 mic_hdr->ccmp_pn[4] = pn64 >> 8;
1256 mic_hdr->ccmp_pn[3] = pn64 >> 16;
1257 mic_hdr->ccmp_pn[2] = pn64 >> 24;
1258 mic_hdr->ccmp_pn[1] = pn64 >> 32;
1259 mic_hdr->ccmp_pn[0] = pn64 >> 40;
Malcolm Priestley01eec152014-10-29 17:43:38 +00001260
1261 if (ieee80211_has_a4(hdr->frame_control))
1262 mic_hdr->hlen = cpu_to_be16(28);
1263 else
1264 mic_hdr->hlen = cpu_to_be16(22);
1265
1266 ether_addr_copy(mic_hdr->addr1, hdr->addr1);
1267 ether_addr_copy(mic_hdr->addr2, hdr->addr2);
1268 ether_addr_copy(mic_hdr->addr3, hdr->addr3);
1269
1270 mic_hdr->frame_control = cpu_to_le16(
1271 le16_to_cpu(hdr->frame_control) & 0xc78f);
1272 mic_hdr->seq_ctrl = cpu_to_le16(
1273 le16_to_cpu(hdr->seq_ctrl) & 0xf);
1274
1275 if (ieee80211_has_a4(hdr->frame_control))
1276 ether_addr_copy(mic_hdr->addr4, hdr->addr4);
1277
1278 memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
1279
1280 break;
1281 default:
1282 break;
1283 }
1284}
1285
1286int vnt_generate_fifo_header(struct vnt_private *priv, u32 dma_idx,
Malcolm Priestleye2357272015-08-14 22:58:51 +01001287 struct vnt_tx_desc *head_td, struct sk_buff *skb)
Malcolm Priestley01eec152014-10-29 17:43:38 +00001288{
Malcolm Priestley54382852015-08-14 22:58:50 +01001289 struct vnt_td_info *td_info = head_td->td_info;
Malcolm Priestley01eec152014-10-29 17:43:38 +00001290 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1291 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
1292 struct ieee80211_rate *rate;
1293 struct ieee80211_key_conf *tx_key;
1294 struct ieee80211_hdr *hdr;
1295 struct vnt_tx_fifo_head *tx_buffer_head =
1296 (struct vnt_tx_fifo_head *)td_info->buf;
Malcolm Priestley01eec152014-10-29 17:43:38 +00001297 u16 tx_body_size = skb->len, current_rate;
1298 u8 pkt_type;
1299 bool is_pspoll = false;
1300
1301 memset(tx_buffer_head, 0, sizeof(*tx_buffer_head));
1302
1303 hdr = (struct ieee80211_hdr *)(skb->data);
1304
1305 rate = ieee80211_get_tx_rate(priv->hw, info);
1306
1307 current_rate = rate->hw_value;
1308 if (priv->wCurrentRate != current_rate &&
1309 !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
1310 priv->wCurrentRate = current_rate;
1311
1312 RFbSetPower(priv, priv->wCurrentRate,
1313 priv->hw->conf.chandef.chan->hw_value);
1314 }
1315
Malcolm Priestleya6388e62015-04-01 22:32:52 +01001316 if (current_rate > RATE_11M) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02001317 if (info->band == NL80211_BAND_5GHZ) {
Malcolm Priestleya6388e62015-04-01 22:32:52 +01001318 pkt_type = PK_TYPE_11A;
1319 } else {
1320 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
1321 pkt_type = PK_TYPE_11GB;
1322 else
1323 pkt_type = PK_TYPE_11GA;
1324 }
1325 } else {
Malcolm Priestley01eec152014-10-29 17:43:38 +00001326 pkt_type = PK_TYPE_11B;
Malcolm Priestleya6388e62015-04-01 22:32:52 +01001327 }
Malcolm Priestley01eec152014-10-29 17:43:38 +00001328
1329 /*Set fifo controls */
1330 if (pkt_type == PK_TYPE_11A)
1331 tx_buffer_head->fifo_ctl = 0;
1332 else if (pkt_type == PK_TYPE_11B)
1333 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
1334 else if (pkt_type == PK_TYPE_11GB)
1335 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
1336 else if (pkt_type == PK_TYPE_11GA)
1337 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
1338
1339 /* generate interrupt */
1340 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1341
1342 if (!ieee80211_is_data(hdr->frame_control)) {
1343 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
1344 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_ISDMA0);
1345 tx_buffer_head->time_stamp =
1346 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
1347 } else {
1348 tx_buffer_head->time_stamp =
1349 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
1350 }
1351
1352 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
1353 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
1354
1355 if (ieee80211_has_retry(hdr->frame_control))
1356 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
1357
1358 if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
1359 priv->byPreambleType = PREAMBLE_SHORT;
1360 else
1361 priv->byPreambleType = PREAMBLE_LONG;
1362
1363 if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
1364 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
1365
1366 if (ieee80211_has_a4(hdr->frame_control)) {
1367 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
1368 priv->bLongHeader = true;
1369 }
1370
1371 if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
1372 is_pspoll = true;
1373
1374 tx_buffer_head->frag_ctl =
1375 cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
1376
1377 if (info->control.hw_key) {
1378 tx_key = info->control.hw_key;
1379
1380 switch (info->control.hw_key->cipher) {
1381 case WLAN_CIPHER_SUITE_WEP40:
1382 case WLAN_CIPHER_SUITE_WEP104:
1383 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
1384 break;
1385 case WLAN_CIPHER_SUITE_TKIP:
1386 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
1387 break;
1388 case WLAN_CIPHER_SUITE_CCMP:
1389 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
1390 default:
1391 break;
1392 }
1393 }
1394
1395 tx_buffer_head->current_rate = cpu_to_le16(current_rate);
1396
1397 /* legacy rates TODO use ieee80211_tx_rate */
1398 if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
1399 if (priv->byAutoFBCtrl == AUTO_FB_0)
1400 tx_buffer_head->fifo_ctl |=
1401 cpu_to_le16(FIFOCTL_AUTO_FB_0);
1402 else if (priv->byAutoFBCtrl == AUTO_FB_1)
1403 tx_buffer_head->fifo_ctl |=
1404 cpu_to_le16(FIFOCTL_AUTO_FB_1);
1405
1406 }
1407
1408 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
1409
Malcolm Priestley19f3ed32014-11-29 00:02:03 +00001410 s_cbFillTxBufHead(priv, pkt_type, (u8 *)tx_buffer_head,
Malcolm Priestley154bb8b2014-11-29 00:02:02 +00001411 dma_idx, head_td, is_pspoll);
Malcolm Priestley01eec152014-10-29 17:43:38 +00001412
1413 if (info->control.hw_key) {
1414 tx_key = info->control.hw_key;
1415 if (tx_key->keylen > 0)
1416 vnt_fill_txkey(hdr, tx_buffer_head->tx_key,
1417 tx_key, skb, tx_body_size, td_info->mic_hdr);
1418 }
1419
1420 return 0;
1421}
1422
1423static int vnt_beacon_xmit(struct vnt_private *priv,
1424 struct sk_buff *skb)
1425{
1426 struct vnt_tx_short_buf_head *short_head =
1427 (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs;
1428 struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *)
1429 (priv->tx_beacon_bufs + sizeof(*short_head));
1430 struct ieee80211_tx_info *info;
1431 u32 frame_size = skb->len + 4;
1432 u16 current_rate;
1433
1434 memset(priv->tx_beacon_bufs, 0, sizeof(*short_head));
1435
1436 if (priv->byBBType == BB_TYPE_11A) {
1437 current_rate = RATE_6M;
1438
1439 /* Get SignalField,ServiceField,Length */
1440 vnt_get_phy_field(priv, frame_size, current_rate,
1441 PK_TYPE_11A, &short_head->ab);
1442
1443 /* Get Duration and TimeStampOff */
1444 short_head->duration =
1445 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1446 frame_size, PK_TYPE_11A, current_rate,
1447 false, 0, 0, 1, AUTO_FB_NONE));
1448
1449 short_head->time_stamp_off =
1450 vnt_time_stamp_off(priv, current_rate);
1451 } else {
1452 current_rate = RATE_1M;
1453 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
1454
1455 /* Get SignalField,ServiceField,Length */
1456 vnt_get_phy_field(priv, frame_size, current_rate,
1457 PK_TYPE_11B, &short_head->ab);
1458
1459 /* Get Duration and TimeStampOff */
1460 short_head->duration =
1461 cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B,
1462 frame_size, PK_TYPE_11B, current_rate,
1463 false, 0, 0, 1, AUTO_FB_NONE));
1464
1465 short_head->time_stamp_off =
1466 vnt_time_stamp_off(priv, current_rate);
1467 }
1468
1469 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT);
1470
1471 /* Copy Beacon */
1472 memcpy(mgmt_hdr, skb->data, skb->len);
1473
1474 /* time stamp always 0 */
1475 mgmt_hdr->u.beacon.timestamp = 0;
1476
1477 info = IEEE80211_SKB_CB(skb);
1478 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1479 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
1480
1481 hdr->duration_id = 0;
1482 hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4);
1483 }
1484
1485 priv->wSeqCounter++;
1486 if (priv->wSeqCounter > 0x0fff)
1487 priv->wSeqCounter = 0;
1488
1489 priv->wBCNBufLen = sizeof(*short_head) + skb->len;
1490
1491 MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma);
1492
1493 MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen);
1494 /* Set auto Transmit on */
1495 MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
1496 /* Poll Transmit the adapter */
1497 MACvTransmitBCN(priv->PortOffset);
1498
1499 return 0;
1500}
1501
1502int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
1503{
1504 struct sk_buff *beacon;
1505
1506 beacon = ieee80211_beacon_get(priv->hw, vif);
1507 if (!beacon)
1508 return -ENOMEM;
1509
1510 if (vnt_beacon_xmit(priv, beacon)) {
1511 ieee80211_free_txskb(priv->hw, beacon);
1512 return -ENODEV;
1513 }
1514
1515 return 0;
1516}
1517
1518int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
1519 struct ieee80211_bss_conf *conf)
1520{
Malcolm Priestley01eec152014-10-29 17:43:38 +00001521 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
1522
1523 VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
1524
Malcolm Priestley738487f2014-11-12 21:11:09 +00001525 CARDvSetFirstNextTBTT(priv, conf->beacon_int);
Malcolm Priestley01eec152014-10-29 17:43:38 +00001526
1527 CARDbSetBeaconPeriod(priv, conf->beacon_int);
1528
Aya Mahfouz0c596a32015-02-27 14:51:29 +02001529 return vnt_beacon_make(priv, vif);
Malcolm Priestley01eec152014-10-29 17:43:38 +00001530}