blob: 321dcb4411c75a08ab6da6114218077ea0e05fd0 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/**=========================================================================
43 *
44 * \file wlan_qct_wdi_dts.c
45 *
46 * \brief Data Transport Service API
47 *
48 * WLAN Device Abstraction layer External API for Dataservice
49 * DESCRIPTION
50 * This file contains the external API implemntation exposed by the
51 * wlan device abstarction layer module.
52 *
53 * Copyright (c) 2008 QUALCOMM Incorporated. All Rights Reserved.
54 * Qualcomm Confidential and Proprietary
55 */
56
57
58#include "wlan_qct_wdi.h"
59#include "wlan_qct_dxe.h"
60#include "wlan_qct_wdi_ds.h"
61#include "wlan_qct_wdi_ds_i.h"
62#include "wlan_qct_wdi_dts.h"
63#include "wlan_qct_wdi_dp.h"
64#include "wlan_qct_wdi_sta.h"
65
66static WDTS_TransportDriverTrype gTransportDriver = {
67 WLANDXE_Open,
68 WLANDXE_Start,
69 WLANDXE_ClientRegistration,
70 WLANDXE_TxFrame,
71 WLANDXE_CompleteTX,
72 WLANDXE_SetPowerState,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -070073 WLANDXE_ChannelDebug,
Jeff Johnson295189b2012-06-20 16:38:30 -070074 WLANDXE_Stop,
75 WLANDXE_Close,
76 WLANDXE_GetFreeTxDataResNumber
77};
78
79static WDTS_SetPowerStateCbInfoType gSetPowerStateCbInfo;
80
Madan Mohan Koyyalamudi01cba042013-01-10 21:56:05 -080081typedef struct
82{
83 uint32 phyRate; //unit in Mega bits per sec X 10
84 uint32 tputRate; //unit in Mega bits per sec X 10
85 uint32 tputBpms; //unit in Bytes per msec = (tputRateX1024x1024)/(8x10X1000) ~= (tputRate*13)
86 float tputBpus; //unit in Bytes per usec
87}WDTS_RateInfo;
88
89#define WDTS_MAX_RATE_NUM 137
90
91WDTS_RateInfo gRateInfo[WDTS_MAX_RATE_NUM] = {
92 //11b rates
93 { 10, 9, 117, 0.12}, //index 0
94 { 20, 17, 221, 0.22}, //index 1
95 { 55, 41, 533, 0.53}, //index 2
96 { 110, 68, 884, 0.88}, //index 3
97
98 //11b short preamble
99 { 10, 10, 130, 0.13}, //index 4
100 { 20, 18, 234, 0.23}, //index 5
101 { 55, 44, 572, 0.57}, //index 6
102 { 110, 77, 1001, 1.00}, //index 7
103
104 //11ag
105 { 60, 50, 650, 0.65}, //index 8
106 { 90, 70, 910, 0.91}, //index 9
107 { 120, 100, 1300, 1.30}, //index 10
108 { 180, 150, 1950, 1.95}, //index 11
109 { 240, 190, 2470, 2.47}, //index 12
110 { 360, 280, 3640, 3.64}, //index 13
111 { 480, 350, 4550, 4.55}, //index 14
112 { 540, 380, 4940, 4.94}, //index 15
113
114 //11n SIMO
115 { 65, 54, 702, 0.70}, //index 16
116 { 130, 108, 1404, 1.40}, //index 17
117 { 195, 161, 2093, 2.09}, //index 18
118 { 260, 217, 2821, 2.82}, //index 19
119 { 390, 326, 4238, 4.24}, //index 20
120 { 520, 435, 5655, 5.66}, //index 21
121 { 585, 492, 6396, 6.40}, //index 22
122 { 650, 548, 7124, 7.12}, //index 23
123
124 //11n SIMO SGI
125 { 72, 59, 767, 0.77}, //index 24
126 { 144, 118, 1534, 1.53}, //index 25
127 { 217, 180, 2340, 2.34}, //index 26
128 { 289, 243, 3159, 3.16}, //index 27
129 { 434, 363, 4719, 4.72}, //index 28
130 { 578, 486, 6318, 6.32}, //index 29
131 { 650, 548, 7124, 7.12}, //index 30
132 { 722, 606, 7878, 7.88}, //index 31
133
134 //11n GF SIMO
135 { 65, 54, 702, 0.70}, //index 32
136 { 130, 108, 1404, 1.40}, //index 33
137 { 195, 161, 2093, 2.09}, //index 34
138 { 260, 217, 2821, 2.82}, //index 35
139 { 390, 326, 4238, 4.23}, //index 36
140 { 520, 435, 5655, 5.66}, //index 37
141 { 585, 492, 6396, 6.40}, //index 38
142 { 650, 548, 7124, 7.12}, //index 39
143
144 //11n SIMO CB MCS 0 - 7
145 { 135, 110, 1430, 1.43}, //index 40
146 { 270, 223, 2899, 2.90}, //index 41
147 { 405, 337, 4381, 4.38}, //index 42
148 { 540, 454, 5902, 5.90}, //index 43
149 { 810, 679, 8827, 8.83}, //index 44
150 { 1080, 909, 11817, 11.81}, //index 45
151 { 1215, 1022, 13286, 13.29}, //index 46
152 { 1350, 1137, 14781, 14.78}, //index 47
153
154 //11n SIMO CB SGI MCS 0 - 7
155 { 150, 121, 1573, 1.57}, //index 48
156 { 300, 249, 3237, 3.24}, //index 49
157 { 450, 378, 4914, 4.91}, //index 50
158 { 600, 503, 6539, 6.54}, //index 51
159 { 900, 758, 9854, 9.85}, //index 52
160 { 1200, 1010, 13130, 13.13}, //index 53
161 { 1350, 1137, 14781, 14.78}, //index 54
162 { 1500, 1262, 16406, 16.41}, //index 55
163
164 //11n SIMO GF CB MCS 0 - 7
165 { 135, 110, 1430, 1.43}, //index 56
166 { 270, 223, 2899, 2.90}, //index 57
167 { 405, 337, 4381, 4.38}, //index 58
168 { 540, 454, 5902, 5.90}, //index 59
169 { 810, 679, 8827, 8.83}, //index 60
170 { 1080, 909, 11817, 11.81}, //index 61
171 { 1215, 1022, 13286, 13.29}, //index 62
172 { 1350, 1137, 14781, 14.79}, //index 63
173
174 //11AC
175 { 1350, 1137, 14781, 14.78}, //reserved 64
176 { 1350, 1137, 14781, 14.78}, //reserved 65
177 { 65, 65, 845, 0.85}, //index 66
178 { 130, 130, 1690, 1.69}, //index 67
179 { 195, 195, 2535, 2.54}, //index 68
180 { 260, 260, 3380, 3.38}, //index 69
181 { 390, 390, 5070, 5.07}, //index 70
182 { 520, 520, 6760, 6.76}, //index 71
183 { 585, 585, 7605, 7.61}, //index 72
184 { 650, 650, 8450, 8.45}, //index 73
185 { 780, 780, 2340, 2.34}, //index 74
186 { 1350, 1137, 14781, 14.78}, //reserved 75
187 { 1350, 1137, 14781, 14.78}, //reserved 76
188 { 1350, 1137, 14781, 14.78}, //reserved 77
189 { 1350, 1137, 14781, 14.78}, //index 78
190 { 1350, 1137, 14781, 14.78}, //index 79
191 { 1350, 1137, 14781, 14.78}, //index 80
192 { 1350, 1137, 14781, 14.78}, //index 81
193 { 1350, 1137, 14781, 14.78}, //index 82
194 { 1350, 1137, 14781, 14.78}, //index 83
195 { 655, 655, 8515, 8.52}, //index 84
196 { 722, 722, 9386, 9.39}, //index 85
197 { 866, 866, 11258, 11.26}, //index 86
198 { 1350, 1137, 14781, 14.78}, //reserved 87
199 { 1350, 1137, 14781, 14.78}, //reserved 88
200 { 1350, 1137, 14781, 14.78}, //reserved 89
201 { 135, 135, 1755, 1.76}, //index 90
202 { 270, 270, 3510, 3.51}, //index 91
203 { 405, 405, 5265, 5.27}, //index 92
204 { 540, 540, 7020, 7.02}, //index 93
205 { 810, 810, 10530, 10.53}, //index 94
206 { 1080, 1080, 14040, 14.04}, //index 95
207 { 1215, 1215, 15795, 15.80}, //index 96
208 { 1350, 1350, 17550, 17.55}, //index 97
209 { 1350, 1137, 14781, 14.78}, //index 98
210 { 1620, 1620, 21060, 21.06}, //index 99
211 { 1800, 1800, 23400, 23.40}, //index 100
212 { 1350, 1137, 14781, 14.78}, //reserved 101
213 { 1350, 1137, 14781, 14.78}, //index 102
214 { 1350, 1137, 14781, 14.78}, //index 103
215 { 1350, 1137, 14781, 14.78}, //index 104
216 { 1350, 1137, 14781, 14.78}, //index 105
217 { 1350, 1137, 14781, 14.78}, //index 106
218 { 1200, 1200, 15600, 15.60}, //index 107
219 { 1350, 1350, 17550, 17.55}, //index 108
220 { 1500, 1500, 19500, 19.50}, //index 109
221 { 1350, 1137, 14781, 14.78}, //index 110
222 { 1800, 1800, 23400, 23.40}, //index 111
223 { 2000, 2000, 26000, 26.00}, //index 112
224 { 1350, 1137, 14781, 14.78}, //index 113
225 { 292, 292, 3796, 3.80}, //index 114
226 { 585, 585, 7605, 7.61}, //index 115
227 { 877, 877, 11401, 11.40}, //index 116
228 { 1170, 1170, 15210, 15.21}, //index 117
229 { 1755, 1755, 22815, 22.82}, //index 118
230 { 2340, 2340, 30420, 30.42}, //index 119
231 { 2632, 2632, 34216, 34.22}, //index 120
232 { 2925, 2925, 38025, 38.03}, //index 121
233 { 1350, 1137, 14781, 14.78}, //index 122
234 { 3510, 3510, 45630, 45.63}, //index 123
235 { 3900, 3900, 50700, 50.70}, //index 124
236 { 1350, 1137, 14781, 14.78}, //reserved 125
237 { 1350, 1137, 14781, 14.78}, //index 126
238 { 1350, 1137, 14781, 14.78}, //index 127
239 { 1350, 1137, 14781, 14.78}, //index 128
240 { 1350, 1137, 14781, 14.78}, //index 129
241 { 1350, 1137, 14781, 14.78}, //index 130
242 { 1350, 1137, 14781, 14.78}, //index 131
243 { 2925, 2925, 38025, 38.03}, //index 132
244 { 3250, 3250, 42250, 42.25}, //index 133
245 { 1350, 1137, 14781, 14.78}, //index 134
246 { 3900, 3900, 50700, 50.70}, //index 135
247 { 4333, 4333, 56329, 56.33} //index 136
248 };
249
250/* TX stats */
251typedef struct
252{
253 wpt_uint32 txBytesPushed;
254 wpt_uint32 txPacketsPushed; //Can be removed to optimize memory
255}WDI_DTS_TX_TrafficStatsType;
256
257/* RX stats */
258typedef struct
259{
260 wpt_uint32 rxBytesRcvd;
261 wpt_uint32 rxPacketsRcvd; //Can be removed to optimize memory
262}WDI_DTS_RX_TrafficStatsType;
263
264typedef struct {
265 wpt_uint8 running;
266 WDI_DTS_RX_TrafficStatsType rxStats[HAL_NUM_STA][WDTS_MAX_RATE_NUM];
267 WDI_DTS_TX_TrafficStatsType txStats[HAL_NUM_STA];
268 WDI_TrafficStatsType netTxRxStats[HAL_NUM_STA];
269}WDI_DTS_TrafficStatsType;
270
271static WDI_DTS_TrafficStatsType gDsTrafficStats;
272
273#define DTS_RATE_TPUT(x) gRateInfo[x].tputBpms
274
275/* Tx/Rx stats function
276 * This function should be invoked to fetch the current stats
277 * Parameters:
278 * pStats:Pointer to the collected stats
279 * len: length of buffer pointed to by pStats
280 * Return Status: None
281 */
282void WDTS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len)
283{
284 if(gDsTrafficStats.running)
285 {
286 uint8 staIdx, rate;
287 WDI_TrafficStatsType *pNetTxRxStats = gDsTrafficStats.netTxRxStats;
288 wpalMemoryZero(pNetTxRxStats, sizeof(gDsTrafficStats.netTxRxStats));
289
290 for(staIdx = 0; staIdx < HAL_NUM_STA; staIdx++, pNetTxRxStats++)
291 {
292 pNetTxRxStats->txBytesPushed += gDsTrafficStats.txStats[staIdx].txBytesPushed;
293 pNetTxRxStats->txPacketsPushed+= gDsTrafficStats.txStats[staIdx].txPacketsPushed;
294 for (rate = 0; rate < WDTS_MAX_RATE_NUM; rate++)
295 {
296 pNetTxRxStats->rxBytesRcvd +=
297 gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd;
298 pNetTxRxStats->rxPacketsRcvd +=
299 gDsTrafficStats.rxStats[staIdx][rate].rxPacketsRcvd;
300 pNetTxRxStats->rxTimeTotal +=
301 gDsTrafficStats.rxStats[staIdx][rate].rxPacketsRcvd/DTS_RATE_TPUT(rate);
302 }
303 }
304 *pStats = gDsTrafficStats.netTxRxStats;
305 *len = sizeof(gDsTrafficStats.netTxRxStats);
306 }
307 else
308 {
309 *pStats = NULL;
310 *len = 0;
311 }
312}
313
314/* WDTS_DeactivateTrafficStats
315 * This function should be invoked to deactivate traffic stats collection
316 * Parameters: None
317 * Return Status: None
318 */
319void WDTS_DeactivateTrafficStats(void)
320{
321 gDsTrafficStats.running = eWLAN_PAL_FALSE;
322}
323
324/* WDTS_ActivateTrafficStats
325 * This function should be invoked to activate traffic stats collection
326 * Parameters: None
327 * Return Status: None
328 */
329void WDTS_ActivateTrafficStats(void)
330{
331 gDsTrafficStats.running = eWLAN_PAL_TRUE;
332}
333
334/* WDTS_ClearTrafficStats
335 * This function should be invoked to clear traffic stats
336 * Parameters: None
337 * Return Status: None
338 */
339void WDTS_ClearTrafficStats(void)
340{
341 wpalMemoryZero(gDsTrafficStats.rxStats, sizeof(gDsTrafficStats.rxStats));
342 wpalMemoryZero(gDsTrafficStats.txStats, sizeof(gDsTrafficStats.txStats));
343}
344
Jeff Johnson295189b2012-06-20 16:38:30 -0700345/* DTS Tx packet complete function.
346 * This function should be invoked by the transport device to indicate
347 * transmit complete for a frame.
348 * Parameters:
349 * pContext:Cookie that should be passed back to the caller
350 * pFrame:Refernce to PAL frame.
351 * Return Value: SUCCESS Completed successfully.
352 * FAILURE_XXX Request was rejected due XXX Reason.
353 *
354 */
355wpt_status WDTS_TxPacketComplete(void *pContext, wpt_packet *pFrame, wpt_status status)
356{
357 WDI_DS_ClientDataType *pClientData = (WDI_DS_ClientDataType*)(pContext);
358 WDI_DS_TxMetaInfoType *pTxMetadata;
359 void *pvBDHeader, *physBDHeader;
360 wpt_uint8 staIndex;
361
362 // Do Sanity checks
363 if(NULL == pContext || NULL == pFrame){
364 return eWLAN_PAL_STATUS_E_FAILURE;
365 }
366
367
368 // extract metadata from PAL packet
369 pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame);
370 pTxMetadata->txCompleteStatus = status;
371
372 // Free BD header from pool
373 WDI_GetBDPointers(pFrame, &pvBDHeader, &physBDHeader);
374 switch(pTxMetadata->frmType)
375 {
376 case WDI_MAC_DATA_FRAME:
Madan Mohan Koyyalamudi1541a5b2012-10-29 16:18:21 -0700377 /* note that EAPOL frame hasn't incremented ReserveCount. see
378 WDI_DS_TxPacket() in wlan_qct_wdi_ds.c
379 */
380 if(!pTxMetadata->isEapol)
381 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700382 /* SWAP BD header to get STA index for completed frame */
383 WDI_SwapTxBd(pvBDHeader);
384 staIndex = (wpt_uint8)WDI_TX_BD_GET_STA_ID(pvBDHeader);
385 WDI_DS_MemPoolFree(&(pClientData->dataMemPool), pvBDHeader, physBDHeader);
386 WDI_DS_MemPoolDecreaseReserveCount(&(pClientData->dataMemPool), staIndex);
387 break;
Madan Mohan Koyyalamudi1541a5b2012-10-29 16:18:21 -0700388 }
389 // intentional fall-through to handle eapol packet as mgmt
Jeff Johnson295189b2012-06-20 16:38:30 -0700390 case WDI_MAC_MGMT_FRAME:
391 WDI_DS_MemPoolFree(&(pClientData->mgmtMemPool), pvBDHeader, physBDHeader);
392 break;
393 }
394 WDI_SetBDPointers(pFrame, 0, 0);
395
396 // Invoke Tx complete callback
397 pClientData->txCompleteCB(pClientData->pCallbackContext, pFrame);
398 return eWLAN_PAL_STATUS_SUCCESS;
399
400}
401
402
403/*===============================================================================
404 FUNCTION WLANTL_GetReplayCounterFromRxBD
405
406 DESCRIPTION This function extracts 48-bit replay packet number from RX BD
407
408 DEPENDENCIES Validity of replay check must be done before the function
409 is called
410
411 PARAMETERS pucRxHeader pointer to RX BD header
412
413 RETRUN v_U64_t Packet number extarcted from RX BD
414
415 SIDE EFFECTS none
416 ===============================================================================*/
417v_U64_t
418WDTS_GetReplayCounterFromRxBD
419(
420 v_U8_t *pucRxBDHeader
421)
422{
423 v_U64_t ullcurrentReplayCounter = 0;
424 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
425/* 48-bit replay counter is created as follows
426 from RX BD 6 byte PMI command:
427 Addr : AES/TKIP
428 0x38 : pn3/tsc3
429 0x39 : pn2/tsc2
430 0x3a : pn1/tsc1
431 0x3b : pn0/tsc0
432
433 0x3c : pn5/tsc5
434 0x3d : pn4/tsc4 */
435
436#ifdef ANI_BIG_BYTE_ENDIAN
437 /* Getting 48-bit replay counter from the RX BD */
438 ullcurrentReplayCounter = WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader);
439 ullcurrentReplayCounter <<= 16;
440 ullcurrentReplayCounter |= (( WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0xFFFF0000) >> 16);
441 return ullcurrentReplayCounter;
442#else
443 /* Getting 48-bit replay counter from the RX BD */
444 ullcurrentReplayCounter = (WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0x0000FFFF);
445 ullcurrentReplayCounter <<= 32;
446 ullcurrentReplayCounter |= WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader);
447 return ullcurrentReplayCounter;
448#endif
449}
450
451
452/* DTS Rx packet function.
453 * This function should be invoked by the transport device to indicate
454 * reception of a frame.
455 * Parameters:
456 * pContext:Cookie that should be passed back to the caller
457 * pFrame:Refernce to PAL frame.
458 * Return Value: SUCCESS Completed successfully.
459 * FAILURE_XXX Request was rejected due XXX Reason.
460 *
461 */
462wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType channel)
463{
464 WDI_DS_ClientDataType *pClientData =
465 (WDI_DS_ClientDataType*)(pContext);
466 wpt_boolean bASF, bFSF, bLSF, bAEF;
467 wpt_uint8 ucMPDUHOffset, ucMPDUHLen, ucTid;
468 wpt_uint8 *pBDHeader;
469 wpt_uint16 usMPDUDOffset, usMPDULen;
470 WDI_DS_RxMetaInfoType *pRxMetadata;
471 wpt_uint8 isFcBd = 0;
472
473 tpSirMacFrameCtl pMacFrameCtl;
474 // Do Sanity checks
475 if(NULL == pContext || NULL == pFrame){
476 return eWLAN_PAL_STATUS_E_FAILURE;
477 }
478
479 /*------------------------------------------------------------------------
480 Extract BD header and check if valid
481 ------------------------------------------------------------------------*/
482 pBDHeader = (wpt_uint8*)wpalPacketGetRawBuf(pFrame);
483 if(NULL == pBDHeader)
484 {
485 DTI_TRACE( DTI_TRACE_LEVEL_ERROR,
486 "WLAN TL:BD header received NULL - dropping packet");
487 wpalPacketFree(pFrame);
488 return eWLAN_PAL_STATUS_E_FAILURE;
489 }
490 WDI_SwapRxBd(pBDHeader);
491
492 ucMPDUHOffset = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_OFFSET(pBDHeader);
493 usMPDUDOffset = (wpt_uint16)WDI_RX_BD_GET_MPDU_D_OFFSET(pBDHeader);
494 usMPDULen = (wpt_uint16)WDI_RX_BD_GET_MPDU_LEN(pBDHeader);
495 ucMPDUHLen = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_LEN(pBDHeader);
496 ucTid = (wpt_uint8)WDI_RX_BD_GET_TID(pBDHeader);
497
498 /*------------------------------------------------------------------------
499 Gather AMSDU information
500 ------------------------------------------------------------------------*/
501 bASF = WDI_RX_BD_GET_ASF(pBDHeader);
502 bAEF = WDI_RX_BD_GET_AEF(pBDHeader);
503 bFSF = WDI_RX_BD_GET_ESF(pBDHeader);
504 bLSF = WDI_RX_BD_GET_LSF(pBDHeader);
505 isFcBd = WDI_RX_FC_BD_GET_FC(pBDHeader);
506
507 DTI_TRACE( DTI_TRACE_LEVEL_INFO,
508 "WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d"
509 " Tid %d BD %d",
510 ucMPDUHOffset, usMPDUDOffset, usMPDULen, ucMPDUHLen, ucTid,
511 WDI_RX_BD_HEADER_SIZE);
512
513 if(!isFcBd)
514 {
515 if(usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) {
516 DTI_TRACE( DTI_TRACE_LEVEL_ERROR,
517 "WLAN TL:BD header corrupted - dropping packet");
518 /* Drop packet ???? */
519 wpalPacketFree(pFrame);
520 return eWLAN_PAL_STATUS_SUCCESS;
521 }
522
523 if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (!(bASF && !bFSF))){
524 /* AMSDU case, ucMPDUHOffset = 0 it should be hancdled seperatly */
525 /* Drop packet ???? */
526 wpalPacketFree(pFrame);
527 return eWLAN_PAL_STATUS_SUCCESS;
528 }
529
530 /* AMSDU frame, but not first sub-frame
531 * No MPDU header, MPDU header offset is 0
532 * Total frame size is actual frame size + MPDU data offset */
533 if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (bASF && !bFSF)){
534 ucMPDUHOffset = usMPDUDOffset;
535 }
536
537 if(VPKT_SIZE_BUFFER < (usMPDULen+ucMPDUHOffset)){
538 DTI_TRACE( DTI_TRACE_LEVEL_FATAL,
539 "Invalid Frame size, might memory corrupted");
540 wpalPacketFree(pFrame);
541 return eWLAN_PAL_STATUS_SUCCESS;
542 }
543 wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
544 wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);
545
546
547
548 pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame);
549
550 pRxMetadata->fc = isFcBd;
551 pRxMetadata->staId = WDI_RX_BD_GET_STA_ID(pBDHeader);
552 pRxMetadata->addr3Idx = WDI_RX_BD_GET_ADDR3_IDX(pBDHeader);
553 pRxMetadata->rxChannel = WDI_RX_BD_GET_RX_CHANNEL(pBDHeader);
554 pRxMetadata->rtsf = WDI_RX_BD_GET_RTSF(pBDHeader);
555 pRxMetadata->bsf = WDI_RX_BD_GET_BSF(pBDHeader);
556 pRxMetadata->scan = WDI_RX_BD_GET_SCAN(pBDHeader);
557 pRxMetadata->dpuSig = WDI_RX_BD_GET_DPU_SIG(pBDHeader);
558 pRxMetadata->ft = WDI_RX_BD_GET_FT(pBDHeader);
559 pRxMetadata->ne = WDI_RX_BD_GET_NE(pBDHeader);
560 pRxMetadata->llcr = WDI_RX_BD_GET_LLCR(pBDHeader);
561 pRxMetadata->bcast = WDI_RX_BD_GET_UB(pBDHeader);
562 pRxMetadata->tid = ucTid;
563 pRxMetadata->dpuFeedback = WDI_RX_BD_GET_DPU_FEEDBACK(pBDHeader);
564 pRxMetadata->rateIndex = WDI_RX_BD_GET_RATEINDEX(pBDHeader);
565 pRxMetadata->rxpFlags = WDI_RX_BD_GET_RXPFLAGS(pBDHeader);
566 pRxMetadata->mclkRxTimestamp = WDI_RX_BD_GET_TIMESTAMP(pBDHeader);
567
568 /* typeSubtype in BD doesn't look like correct. Fill from frame ctrl
569 TL does it for Volans but TL does not know BD for Prima. WDI should do it */
570 if ( 0 == WDI_RX_BD_GET_FT(pBDHeader) ) {
571 if ( bASF ) {
572 pRxMetadata->subtype = WDI_MAC_DATA_QOS_DATA;
573 pRxMetadata->type = WDI_MAC_DATA_FRAME;
574 } else {
575 pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + ucMPDUHOffset);
576 pRxMetadata->subtype = pMacFrameCtl->subType;
577 pRxMetadata->type = pMacFrameCtl->type;
578 }
579 } else {
580 pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + WDI_RX_BD_HEADER_SIZE);
581 pRxMetadata->subtype = pMacFrameCtl->subType;
582 pRxMetadata->type = pMacFrameCtl->type;
583 }
584
585 pRxMetadata->mpduHeaderPtr = pBDHeader + ucMPDUHOffset;
586 pRxMetadata->mpduDataPtr = pBDHeader + usMPDUDOffset;
587 pRxMetadata->mpduLength = usMPDULen;
588 pRxMetadata->mpduHeaderLength = ucMPDUHLen;
589
590 /*------------------------------------------------------------------------
591 Gather AMPDU information
592 ------------------------------------------------------------------------*/
593 pRxMetadata->ampdu_reorderOpcode = (wpt_uint8)WDI_RX_BD_GET_BA_OPCODE(pBDHeader);
594 pRxMetadata->ampdu_reorderSlotIdx = (wpt_uint8)WDI_RX_BD_GET_BA_SI(pBDHeader);
595 pRxMetadata->ampdu_reorderFwdIdx = (wpt_uint8)WDI_RX_BD_GET_BA_FI(pBDHeader);
596 pRxMetadata->currentPktSeqNo = (wpt_uint8)WDI_RX_BD_GET_BA_CSN(pBDHeader);
597
598
599 /*------------------------------------------------------------------------
600 Gather AMSDU information
601 ------------------------------------------------------------------------*/
602 pRxMetadata->amsdu_asf = bASF;
603 pRxMetadata->amsdu_aef = bAEF;
604 pRxMetadata->amsdu_esf = bFSF;
605 pRxMetadata->amsdu_lsf = bLSF;
606 pRxMetadata->amsdu_size = WDI_RX_BD_GET_AMSDU_SIZE(pBDHeader);
607
608 pRxMetadata->rssi0 = WDI_RX_BD_GET_RSSI0(pBDHeader);
609 pRxMetadata->rssi1 = WDI_RX_BD_GET_RSSI1(pBDHeader);
610
611
612 /* Missing:
613 wpt_uint32 fcSTATxQStatus:8;
614 wpt_uint32 fcSTAThreshIndMask:8;
615 wpt_uint32 fcSTAPwrSaveStateMask:8;
616 wpt_uint32 fcSTAValidMask:8;
617
618 wpt_uint8 fcSTATxQLen[8]; // one byte per STA.
619 wpt_uint8 fcSTACurTxRate[8]; // current Tx rate for each sta.
620 unknownUcastPkt
621 */
622
623 pRxMetadata->replayCount = WDTS_GetReplayCounterFromRxBD(pBDHeader);
624 pRxMetadata->snr = WDI_RX_BD_GET_SNR(pBDHeader);
625
626 /*
627 * PAL BD pointer information needs to be populated
628 */
629 WPAL_PACKET_SET_BD_POINTER(pFrame, pBDHeader);
630 WPAL_PACKET_SET_BD_LENGTH(pFrame, sizeof(WDI_RxBdType));
631
632 // Invoke Rx complete callback
633 pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame);
634 }
635 else
636 {
637 wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
638 wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);
639
640 pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame);
641 //flow control related
642 pRxMetadata->fc = isFcBd;
643 pRxMetadata->fcStaTxDisabledBitmap = WDI_RX_FC_BD_GET_STA_TX_DISABLED_BITMAP(pBDHeader);
644 pRxMetadata->fcSTAValidMask = WDI_RX_FC_BD_GET_STA_VALID_MASK(pBDHeader);
645 // Invoke Rx complete callback
646 pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame);
647 }
Madan Mohan Koyyalamudi01cba042013-01-10 21:56:05 -0800648
649 //Log the RX Stats
650 if(gDsTrafficStats.running && pRxMetadata->staId < HAL_NUM_STA)
651 {
652 if(pRxMetadata->rateIndex < WDTS_MAX_RATE_NUM)
653 {
654 gDsTrafficStats.rxStats[pRxMetadata->staId][pRxMetadata->rateIndex].rxBytesRcvd += pRxMetadata->mpduLength;
655 gDsTrafficStats.rxStats[pRxMetadata->staId][pRxMetadata->rateIndex].rxPacketsRcvd++;
656 }
657 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 return eWLAN_PAL_STATUS_SUCCESS;
659
660}
661
662
663
664/* DTS Out of Resource packet function.
665 * This function should be invoked by the transport device to indicate
666 * the device is out of resources.
667 * Parameters:
668 * pContext:Cookie that should be passed back to the caller
669 * priority: indicates which channel is out of resource.
670 * Return Value: SUCCESS Completed successfully.
671 * FAILURE_XXX Request was rejected due XXX Reason.
672 */
673wpt_status WDTS_OOResourceNotification(void *pContext, WDTS_ChannelType channel, wpt_boolean on)
674{
675 WDI_DS_ClientDataType *pClientData =
676 (WDI_DS_ClientDataType *) pContext;
677 static wpt_uint8 ac_mask = 0x1f;
678
679 // Do Sanity checks
680 if(NULL == pContext){
681 return eWLAN_PAL_STATUS_E_FAILURE;
682 }
683
684 if(on){
685 ac_mask |= channel == WDTS_CHANNEL_TX_LOW_PRI? 0x0f : 0x10;
686 } else {
687 ac_mask &= channel == WDTS_CHANNEL_TX_LOW_PRI? 0x10 : 0x0f;
688 }
689
690
691 // Invoke OOR callback
692 pClientData->txResourceCB(pClientData->pCallbackContext, ac_mask);
693 return eWLAN_PAL_STATUS_SUCCESS;
694
695}
696
697/* DTS open function.
698 * On open the transport device should initialize itself.
699 * Parameters:
700 * pContext:Cookie that should be passed back to the caller along
701 * with the callback.
702 *
703 * Return Value: SUCCESS Completed successfully.
704 * FAILURE_XXX Request was rejected due XXX Reason.
705 *
706 */
707wpt_status WDTS_openTransport( void *pContext)
708{
709 void *pDTDriverContext;
710 WDI_DS_ClientDataType *pClientData;
711 WDI_Status sWdiStatus = WDI_STATUS_SUCCESS;
712
713 pClientData = (WDI_DS_ClientDataType*) wpalMemoryAllocate(sizeof(WDI_DS_ClientDataType));
714 if (!pClientData){
715 return eWLAN_PAL_STATUS_E_NOMEM;
716 }
717
718 pClientData->suspend = 0;
719 WDI_DS_AssignDatapathContext(pContext, (void*)pClientData);
720
721 pDTDriverContext = gTransportDriver.open();
722 if( NULL == pDTDriverContext )
723 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700724 DTI_TRACE( DTI_TRACE_LEVEL_ERROR, " %s fail from transport open", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 return eWLAN_PAL_STATUS_E_FAILURE;
726 }
727 WDT_AssignTransportDriverContext(pContext, pDTDriverContext);
728 gTransportDriver.register_client(pDTDriverContext, WDTS_RxPacket, WDTS_TxPacketComplete,
729 WDTS_OOResourceNotification, (void*)pClientData);
730
731 /* Create a memory pool for Mgmt BDheaders.*/
732 sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->mgmtMemPool, WDI_DS_MAX_CHUNK_SIZE,
733 WDI_DS_HI_PRI_RES_NUM);
734 if (WDI_STATUS_SUCCESS != sWdiStatus){
735 return eWLAN_PAL_STATUS_E_NOMEM;
736 }
737
738 /* Create a memory pool for Data BDheaders.*/
739 sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->dataMemPool, WDI_DS_MAX_CHUNK_SIZE,
740 WDI_DS_LO_PRI_RES_NUM);
741 if (WDI_STATUS_SUCCESS != sWdiStatus){
742 return eWLAN_PAL_STATUS_E_NOMEM;
743 }
744
Madan Mohan Koyyalamudi01cba042013-01-10 21:56:05 -0800745 wpalMemoryZero(&gDsTrafficStats, sizeof(gDsTrafficStats));
746
Jeff Johnson295189b2012-06-20 16:38:30 -0700747 return eWLAN_PAL_STATUS_SUCCESS;
748
749}
750
751
752
753/* DTS start function.
754 * On start the transport device should start running.
755 * Parameters:
756 * pContext:Cookie that should be passed back to the caller along
757 * with the callback.
758 *
759 * Return Value: SUCCESS Completed successfully.
760 * FAILURE_XXX Request was rejected due XXX Reason.
761 *
762 */
763wpt_status WDTS_startTransport( void *pContext)
764{
765 void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
766 gTransportDriver.start(pDTDriverContext);
767 return eWLAN_PAL_STATUS_SUCCESS;
768
769}
770
771
772/* DTS Tx packet function.
773 * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO.
774 * Parameters:
775 * pContext:Cookie that should be passed back to the caller along with the callback.
776 * pFrame:Refernce to PAL frame.
777 * Return Value: SUCCESS Completed successfully.
778 * FAILURE_XXX Request was rejected due XXX Reason.
779 *
780 */
781wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame)
782{
783 void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
784 WDI_DS_TxMetaInfoType *pTxMetadata;
785 WDTS_ChannelType channel = WDTS_CHANNEL_TX_LOW_PRI;
786 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Madan Mohan Koyyalamudi01cba042013-01-10 21:56:05 -0800787 WDI_TxBdType *pvBDHeader;
Jeff Johnson295189b2012-06-20 16:38:30 -0700788
789 // extract metadata from PAL packet
790 pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame);
Madan Mohan Koyyalamudi01cba042013-01-10 21:56:05 -0800791 pvBDHeader = (WDI_TxBdType*)WPAL_PACKET_GET_BD_POINTER(pFrame);
792
793 //Log the TX Stats
794 if(gDsTrafficStats.running && pvBDHeader->staIndex < HAL_NUM_STA)
795 {
796 gDsTrafficStats.txStats[pvBDHeader->staIndex].txBytesPushed +=
797 pvBDHeader->mpduLength;
798 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700799
800 // assign MDPU to correct channel??
801 channel = (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)?
Madan Mohan Koyyalamudi1541a5b2012-10-29 16:18:21 -0700802 /* EAPOL frame uses TX_HIGH_PRIORITY DXE channel
803 To make sure EAPOL (for second session) is pushed even if TX_LO channel
804 already reached to low resource condition
805 This can happen especially in MCC, high data traffic TX in first session
806 */
807 ((pTxMetadata->isEapol) ? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI;
Jeff Johnson295189b2012-06-20 16:38:30 -0700808 // Send packet to Transport Driver.
809 status = gTransportDriver.xmit(pDTDriverContext, pFrame, channel);
810 return status;
811}
812
813/* DTS Tx Complete function.
814 * This function should be invoked by the DAL Dataservice to notify tx completion to DXE/SDIO.
815 * Parameters:
816 * pContext:Cookie that should be passed back to the caller along with the callback.
817 * ucTxResReq:TX resource number required by TL
818 * Return Value: SUCCESS Completed successfully.
819 * FAILURE_XXX Request was rejected due XXX Reason.
820 *
821 */
822wpt_status WDTS_CompleteTx(void *pContext, wpt_uint32 ucTxResReq)
823{
824 void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
825
826 // Notify completion to Transport Driver.
827 return gTransportDriver.txComplete(pDTDriverContext, ucTxResReq);
828}
829
830/* DXE Set power state ACK callback.
831 * This callback function should be invoked by the DXE to notify WDI that set
832 * power state request is complete.
833 * Parameters:
834 * status: status of the set operation
835 * Return Value: None.
836 *
837 */
838void WDTS_SetPowerStateCb(wpt_status status, unsigned int dxePhyAddr)
839{
840 //print a msg
841 if(NULL != gSetPowerStateCbInfo.cback)
842 {
843 gSetPowerStateCbInfo.cback(status, dxePhyAddr, gSetPowerStateCbInfo.pUserData);
844 }
845}
846
847
848/* DTS Set power state function.
849 * This function should be invoked by the DAL to notify the WLAN device power state.
850 * Parameters:
851 * pContext:Cookie that should be passed back to the caller along with the callback.
852 * powerState:Power state of the WLAN device.
853 * Return Value: SUCCESS Set successfully in DXE control blk.
854 * FAILURE_XXX Request was rejected due XXX Reason.
855 *
856 */
857wpt_status WDTS_SetPowerState(void *pContext, WDTS_PowerStateType powerState,
858 WDTS_SetPowerStateCbType cback)
859{
860 void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
861 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
862
863 if( cback )
864 {
865 //save the cback & cookie
866 gSetPowerStateCbInfo.pUserData = pContext;
867 gSetPowerStateCbInfo.cback = cback;
868 status = gTransportDriver.setPowerState(pDTDriverContext, powerState,
869 WDTS_SetPowerStateCb);
870 }
871 else
872 {
873 status = gTransportDriver.setPowerState(pDTDriverContext, powerState,
874 NULL);
875 }
876
877 return status;
878}
879
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700880/* DTS Transport Channel Debug
881 * Display DXE Channel debugging information
882 * User may request to display DXE channel snapshot
883 * Or if host driver detects any abnormal stcuk may display
884 * Parameters:
Jeff Johnsonb88db982012-12-10 13:34:59 -0800885 * displaySnapshot : Display DXE snapshot option
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700886 * enableStallDetect : Enable stall detect feature
887 This feature will take effect to data performance
888 Not integrate till fully verification
889 * Return Value: NONE
890 *
891 */
Jeff Johnsonb88db982012-12-10 13:34:59 -0800892void WDTS_ChannelDebug(wpt_boolean displaySnapshot, wpt_boolean toggleStallDetect)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700893{
Jeff Johnsonb88db982012-12-10 13:34:59 -0800894 gTransportDriver.channelDebug(displaySnapshot, toggleStallDetect);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700895 return;
896}
897
Jeff Johnson295189b2012-06-20 16:38:30 -0700898/* DTS Stop function.
899 * Stop Transport driver, ie DXE, SDIO
900 * Parameters:
901 * pContext:Cookie that should be passed back to the caller along with the callback.
902 * Return Value: SUCCESS Completed successfully.
903 * FAILURE_XXX Request was rejected due XXX Reason.
904 *
905 */
906wpt_status WDTS_Stop(void *pContext)
907{
908 void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
909 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
910
911 status = gTransportDriver.stop(pDTDriverContext);
912
Madan Mohan Koyyalamudi01cba042013-01-10 21:56:05 -0800913 wpalMemoryZero(&gDsTrafficStats, sizeof(gDsTrafficStats));
914
Jeff Johnson295189b2012-06-20 16:38:30 -0700915 return status;
916}
917
918/* DTS Stop function.
919 * Stop Transport driver, ie DXE, SDIO
920 * Parameters:
921 * pContext:Cookie that should be passed back to the caller along with the callback.
922 * Return Value: SUCCESS Completed successfully.
923 * FAILURE_XXX Request was rejected due XXX Reason.
924 *
925 */
926wpt_status WDTS_Close(void *pContext)
927{
928 void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
929 WDI_DS_ClientDataType *pClientData = WDI_DS_GetDatapathContext(pContext);
930 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
931
932 /*Destroy the mem pool for mgmt BD headers*/
933 WDI_DS_MemPoolDestroy(&pClientData->mgmtMemPool);
934
935 /*Destroy the mem pool for mgmt BD headers*/
936 WDI_DS_MemPoolDestroy(&pClientData->dataMemPool);
937
938 status = gTransportDriver.close(pDTDriverContext);
939
940 wpalMemoryFree(pClientData);
941
942 return status;
943}
944
945/* Get free TX data descriptor number from DXE
946 * Parameters:
947 * pContext: Cookie that should be passed back to the caller along with the callback.
948 * Return Value: number of free descriptors for TX data channel
949 *
950 */
951wpt_uint32 WDTS_GetFreeTxDataResNumber(void *pContext)
952{
953 return
954 gTransportDriver.getFreeTxDataResNumber(WDT_GetTransportDriverContext(pContext));
955}