blob: f99adc155ecef17c52a98cc94bf18e1ece2949e9 [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_dxe.c
45
46 @brief
47
48 This file contains the external API exposed by the wlan data transfer abstraction layer module.
49 Copyright (c) 2010-2011 QUALCOMM Incorporated.
50 All Rights Reserved.
51 Qualcomm Confidential and Proprietary
52========================================================================*/
53
54/*===========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66when who what, where, why
67-------- --- ----------------------------------------------------------
6808/03/10 schang Created module.
69
70===========================================================================*/
71
72/*===========================================================================
73
74 INCLUDE FILES FOR MODULE
75
76===========================================================================*/
77
78/*----------------------------------------------------------------------------
79 * Include Files
80 * -------------------------------------------------------------------------*/
81#include "wlan_qct_dxe.h"
82#include "wlan_qct_dxe_i.h"
83#include "wlan_qct_pal_device.h"
84#ifdef FEATURE_R33D
85#include "wlan_qct_pal_bus.h"
86#endif /* FEATURE_R33D */
87
88/*----------------------------------------------------------------------------
89 * Local Definitions
90 * -------------------------------------------------------------------------*/
91//#define WLANDXE_DEBUG_CH_INFO_DUMP
92
93/* Temporary configuration defines
94 * Have to find out permanent solution */
95#define T_WLANDXE_MAX_DESCRIPTOR_COUNT 40
96#define T_WLANDXE_MAX_FRAME_SIZE 2000
97#define T_WLANDXE_TX_INT_ENABLE_FCOUNT 1
98#define T_WLANDXE_MEMDUMP_BYTE_PER_LINE 16
99#define T_WLANDXE_MAX_RX_PACKET_WAIT 6000
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700100#define T_WLANDXE_PERIODIC_HEALTH_M_TIME 1500
101#define T_WLANDXE_MAX_HW_ACCESS_WAIT 2000
Jeff Johnsone7245742012-09-05 17:12:55 -0700102#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104/* This is temporary fot the compile
105 * WDI will release official version
106 * This must be removed */
107#define WDI_GET_PAL_CTX() NULL
108
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700109
Jeff Johnson295189b2012-06-20 16:38:30 -0700110/*-------------------------------------------------------------------------
111 * Local Varables
112 *-------------------------------------------------------------------------*/
113/* This is temp, someone have to allocate for me, and must be part of global context */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700114static WLANDXE_CtrlBlkType *tempDxeCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -0700115static char *channelType[WDTS_CHANNEL_MAX] =
116 {
117 "TX_LOW_PRI",
118 "TX_HIGH_PRI",
119 "RX_LOW_PRI",
120#ifndef WLANDXE_TEST_CHANNEL_ENABLE
121 "RX_HIGH_PRI",
122#else
123 "H2H_TEST_TX",
124 "H2H_TEST_RX"
125#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
126 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700127static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129/*-------------------------------------------------------------------------
130 * External Function Proto Type
131 *-------------------------------------------------------------------------*/
132
133/*-------------------------------------------------------------------------
134 * Local Function Proto Type
135 *-------------------------------------------------------------------------*/
136static wpt_status dxeRXFrameSingleBufferAlloc
137(
138 WLANDXE_CtrlBlkType *dxeCtxt,
139 WLANDXE_ChannelCBType *channelEntry,
140 WLANDXE_DescCtrlBlkType *currentCtrlBlock
141);
142
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700143static wpt_status dxeNotifySmsm
144(
145 wpt_boolean kickDxe,
146 wpt_boolean ringEmpty
147);
148
Jeff Johnson295189b2012-06-20 16:38:30 -0700149/*-------------------------------------------------------------------------
150 * Local Function
151 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700152/*==========================================================================
153 @ Function Name
154 dxeChannelMonitor
155
156 @ Description
157
158 @ Parameters
159 WLANDXE_ChannelCBType *channelEntry
160 Channel specific control block
161
162 @ Return
163 wpt_status
164
165===========================================================================*/
166static wpt_status dxeChannelMonitor
167(
168 char *monitorDescription,
169 WLANDXE_ChannelCBType *channelEntry
170)
171{
172 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
173
Jeff Johnsone7245742012-09-05 17:12:55 -0700174 if((NULL == monitorDescription) || (NULL == channelEntry))
175 {
176 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
177 "INVALID Input ARG");
178 return eWLAN_PAL_STATUS_E_INVAL;
179 }
180
181 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
182 {
183 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
184 "INVALID Channel type");
185 return eWLAN_PAL_STATUS_E_INVAL;
186 }
187
188 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700189 "=== %s Channel Number %d, Channel Type %s",
190 monitorDescription, channelEntry->assignedDMAChannel, channelType[channelEntry->channelType]);
Jeff Johnsone7245742012-09-05 17:12:55 -0700191 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700192 "numDesc %d, numFreeDesc %d, numResvDesc %d",
193 channelEntry->numDesc, channelEntry->numFreeDesc, channelEntry->numRsvdDesc);
Jeff Johnsone7245742012-09-05 17:12:55 -0700194 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 "headCB 0x%x, next 0x%x, DESC 0x%x",
196 channelEntry->headCtrlBlk, channelEntry->headCtrlBlk->nextCtrlBlk, channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700197 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700198 "tailCB 0x%x, next 0x%x, DESC 0x%x",
199 channelEntry->tailCtrlBlk, channelEntry->tailCtrlBlk->nextCtrlBlk, channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700200 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 "headCB Order %d, tailCB Order %d",
202 channelEntry->headCtrlBlk->ctrlBlkOrder, channelEntry->tailCtrlBlk->ctrlBlkOrder);
Jeff Johnsone7245742012-09-05 17:12:55 -0700203 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 "numFragmentCurrentChain %d, numTotalFrame %d ===",
205 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
206
207 return status;
208}
209
Jeff Johnsone7245742012-09-05 17:12:55 -0700210#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700211/*==========================================================================
212 @ Function Name
213 dxeMemoryDump
214
215 @ Description
216
217 @ Parameters
218 WLANDXE_ChannelCBType *channelEntry
219 Channel specific control block
220
221 @ Return
222 wpt_status
223
224===========================================================================*/
225static wpt_status dxeMemoryDump
226(
227 wpt_uint8 *dumpPointer,
228 wpt_uint32 dumpSize,
229 char *dumpTarget
230)
231{
232 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
233 wpt_uint32 numBytes = 0;
234 wpt_uint32 idx;
235
Jeff Johnsone7245742012-09-05 17:12:55 -0700236 if((NULL == dumpPointer) ||
237 (NULL == dumpTarget))
238 {
239 return status;
240 }
241
Jeff Johnson295189b2012-06-20 16:38:30 -0700242 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
243 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
244 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
245 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
246
247 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
248 for(idx = 0; idx < dumpSize; idx++)
249 {
250 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
251 "0x%2x ", dumpPointer[idx]);
252 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
253 {
254 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
255 }
256 }
257 if(0 != numBytes)
258 {
259 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
260 }
261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
262 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
263
264 return status;
265}
Jeff Johnsone7245742012-09-05 17:12:55 -0700266#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700267
268/*==========================================================================
269 @ Function Name
270 dxeDescriptorDump
271
272 @ Description
273
274 @ Parameters
275 WLANDXE_ChannelCBType *channelEntry
276 Channel specific control block
277
278 @ Return
279 wpt_status
280
281===========================================================================*/
282wpt_status dxeDescriptorDump
283(
284 WLANDXE_ChannelCBType *channelEntry,
285 WLANDXE_DescType *targetDesc,
286 wpt_uint32 fragmentOrder
287)
288{
289 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
290
291
Jeff Johnsone7245742012-09-05 17:12:55 -0700292 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700294 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700295 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700296 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700297 fragmentOrder + 1,
298 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700299
Jeff Johnsone7245742012-09-05 17:12:55 -0700300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 "CTRL WORD 0x%x, TransferSize %d",
302 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
303 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700304 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
306 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
307 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
308 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700309 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
311
312 return status;
313}
314
315/*==========================================================================
316 @ Function Name
317 dxeChannelRegisterDump
318
319 @ Description
320
321 @ Parameters
322 WLANDXE_ChannelCBType *channelEntry
323 Channel specific control block
324
325 @ Return
326 wpt_status
327
328===========================================================================*/
329wpt_status dxeChannelRegisterDump
330(
331 WLANDXE_ChannelCBType *channelEntry,
332 char *dumpTarget
333)
334{
335 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
336 wpt_uint32 regValue = 0;
337
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700338 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
339 {
340 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
341 "INVALID Channel type");
342 return eWLAN_PAL_STATUS_E_INVAL;
343 }
344
Jeff Johnsone7245742012-09-05 17:12:55 -0700345 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700346 "%s Channel register dump for %s, base address 0x%x",
347 channelType[channelEntry->channelType],
348 dumpTarget,
349 channelEntry->channelRegister.chDXEBaseAddr);
350 regValue = 0;
351 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 "Control Register 0x%x", regValue);
354
355 regValue = 0;
356 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700357 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700358 "Status Register 0x%x", regValue);
359 regValue = 0;
360
361 wpalReadRegister(channelEntry->channelRegister.chDXESadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700362 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700363 "Source Address Register 0x%x", regValue);
364 regValue = 0;
365
366 wpalReadRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700367 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700368 "Destination Address Register 0x%x", regValue);
369 regValue = 0;
370
371 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700373 "Last Descriptor Address Register 0x%x", regValue);
374
375 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &regValue);
376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
377 "Next Descriptor Address Register 0x%x", regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378
379 return status;
380}
Jeff Johnsone7245742012-09-05 17:12:55 -0700381
382/*==========================================================================
383 @ Function Name
384 dxeChannelAllDescDump
385
386 @ Description
387 Dump all DXE descriptors within assigned channe;
388
389 @ Parameters
390 WLANDXE_ChannelCBType *channelEntry
391
392 @ Return
393 NONE
394
395===========================================================================*/
396void dxeChannelAllDescDump
397(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700398 WLANDXE_ChannelCBType *channelEntry,
399 WDTS_ChannelType channel
Jeff Johnsone7245742012-09-05 17:12:55 -0700400)
401{
402 wpt_uint32 channelLoop;
403 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700404 wpt_uint32 previousCtrlValue = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700405
406 targetCtrlBlk = channelEntry->headCtrlBlk;
407
408 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700409 "%s %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700410 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700411 channelEntry->numDesc,
412 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700413 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
414
415 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
416 (WDTS_CHANNEL_RX_HIGH_PRI == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700417 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700418 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700419 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700420 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
421 {
422 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
423 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
424 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
425 }
426 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
427 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700428 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700429 }
430 else
431 {
432 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
433 {
434 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
435 {
436 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
437 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
438 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
439 }
440 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
441 }
442 }
443 return;
444}
445
446/*==========================================================================
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700447 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700448 dxeTxThreadChannelDebugHandler
449
450 @ Description
451 Dump TX channel information
452
453 @ Parameters
454 Wwpt_msg *msgPtr
455
456 @ Return
457 NONE
458
459===========================================================================*/
460void dxeTxThreadChannelDebugHandler
461(
462 wpt_msg *msgPtr
463)
464{
465 wpt_uint8 channelLoop;
466
467 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700468 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700469
470 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
471 * This will not simply wakeup RIVA
472 * Just incase TX not wanted stuck, Trigger TX again */
473 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
474 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
475 {
476 dxeChannelMonitor("******** Get Descriptor Snapshot ",
477 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
478 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700479 tempDxeCtrlBlk->dxeChannel[channelLoop].tailCtrlBlk->linkedDesc,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700480 0);
481 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
482 "Abnormal successive empty interrupt");
483 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700484 }
485
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700486 wpalMemoryFree(msgPtr);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700487 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700488 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700489 return;
490}
491
492/*==========================================================================
493 @ Function Name
494 dxeRxThreadChannelDebugHandler
495
496 @ Description
497 Dump RX channel information
498
499 @ Parameters
500 Wwpt_msg *msgPtr
501
502 @ Return
503 NONE
504
505===========================================================================*/
506void dxeRxThreadChannelDebugHandler
507(
508 wpt_msg *msgPtr
509)
510{
511 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
512 wpt_uint8 channelLoop;
513
514 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700515 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700516
517 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
518 * This will not simply wakeup RIVA
519 * Just incase TX not wanted stuck, Trigger TX again */
520 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
521 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
522 {
523 dxeChannelMonitor("******** Get Descriptor Snapshot ",
524 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
525 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
526 tempDxeCtrlBlk->dxeChannel[channelLoop].headCtrlBlk->linkedDesc,
527 0);
528 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
529 "Abnormal successive empty interrupt");
530 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
531 }
532
533 /* Now serialise the message through Tx thread also to make sure
534 * no register access when RIVA is in powersave */
535 /*Use the same message pointer just change the call back function */
536 msgPtr->callback = dxeTxThreadChannelDebugHandler;
537 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
538 msgPtr);
539 if ( eWLAN_PAL_STATUS_SUCCESS != status )
540 {
541 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700542 "Tx thread state dump req serialize fail status=%d",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700543 status, 0, 0);
544 }
545
546 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700547 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700548 return;
549}
Jeff Johnson295189b2012-06-20 16:38:30 -0700550
551/*==========================================================================
552 @ Function Name
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700553 dxeRXHealthMonitor
554
555 @ Description
556 Monitoring RX channel healthy stataus
557 If detect any problem, try to recover
558
559 @ Parameters
560 healthMonitorMsg MSG pointer.
561 will have low resource TX channel context
562
563 @ Return
564 NONE
565
566===========================================================================*/
567void dxeRXHealthMonitor
568(
569 wpt_msg *healthMonitorMsg
570)
571{
572 WLANDXE_ChannelCBType *channelCtrlBlk;
573 WLANDXE_ChannelCBType *testCHCtrlBlk;
574 wpt_uint32 regValue;
575 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
576 wpt_uint32 hwWakeLoop, chLoop;
577
578 if(NULL == healthMonitorMsg)
579 {
580 return;
581 }
582
583 /* Make wake up HW */
584 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
585 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
586
587 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
588 {
589 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
590 if(0 != regValue)
591 {
592 break;
593 }
594 }
595
596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
597 "Scheduled RX, num free BD/PDU %d, loop Count %d",
598 regValue, hwWakeLoop, 0);
599
600 for(chLoop = WDTS_CHANNEL_RX_LOW_PRI; chLoop < WDTS_CHANNEL_MAX; chLoop++)
601 {
602 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
603 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
604 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
605 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
606 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
607
608 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
609 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
610 channelType[chLoop],
611 chControlReg, chStatusReg, chDescReg, chLDescReg,
612 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
613 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
614 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
615 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
616
617 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
618 (chLDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
619 {
620 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
621 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
622 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
623 channelType[chLoop],
624 chControlReg, chStatusReg, chDescReg, chLDescReg,
625 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
626 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
627 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
628 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
629 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
630 "%11s : RX CH EN Descriptor Async, resync it", channelType[chLoop], 0, 0);
631 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
632 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
633 }
634 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
635 (chDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
636 {
637 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
638 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
639 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
640 channelType[chLoop],
641 chControlReg, chStatusReg, chDescReg, chLDescReg,
642 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
643 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
644 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
645 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
647 "%11s : RX CH DIS Descriptor Async, resync it", channelType[chLoop], 0, 0);
648 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
649 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
650 }
651 }
652
653 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
654 if(channelCtrlBlk->hitLowResource)
655 {
656 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
657 "%11s : Still Low Resource, kick DXE TX and restart timer",
658 channelType[channelCtrlBlk->channelType], 0, 0);
659 /* Still Low Resource, Kick DXE again and start timer again */
660 wpalTimerStart(&channelCtrlBlk->healthMonitorTimer,
661 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
662 }
663 else
664 {
665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
666 "%11s : Out from Low resource condition, do nothing",
667 channelType[channelCtrlBlk->channelType], 0, 0);
668 /* Recovered from low resource condition
669 * Not need to do anything */
670 }
671
672 return;
673}
674
675/*==========================================================================
676 @ Function Name
677 dxeTXHealthMonitor
678
679 @ Description
680 Monitoring TX channel healthy stataus
681 If detect any problem, try to recover
682
683 @ Parameters
684 healthMonitorMsg MSG pointer.
685 will have low resource TX channel context
686
687 @ Return
688 NONE
689
690===========================================================================*/
691void dxeTXHealthMonitor
692(
693 wpt_msg *healthMonitorMsg
694)
695{
696 WLANDXE_ChannelCBType *channelCtrlBlk;
697 WLANDXE_ChannelCBType *testCHCtrlBlk;
698 wpt_uint32 regValue;
699 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
700 wpt_uint32 hwWakeLoop, chLoop;
701 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
702
703 if(NULL == healthMonitorMsg)
704 {
705 return;
706 }
707
708 /* First of all kick TX channel
709 * This will fix if there is any problem with SMSM state */
710 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
711 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
712
713 /* Wait till RIVA up */
714 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
715 {
716 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
717 if(0 != regValue)
718 {
719 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
720 "num free BD/PDU %d, loop Count %d",
721 regValue, hwWakeLoop, 0);
722 break;
723 }
724 }
725
726 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
727 "Scheduled TX, num free BD/PDU %d, loop Count %d",
728 regValue, hwWakeLoop, 0);
729
730 for(chLoop = 0; chLoop < WDTS_CHANNEL_RX_LOW_PRI; chLoop++)
731 {
732 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
733 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
734 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
735 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
736 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
737
738 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
739 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
740 channelType[chLoop],
741 chControlReg, chStatusReg, chDescReg, chLDescReg,
742 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
743 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
744 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
745 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
746
747 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
748 (chLDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
749 {
750 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
751 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
752 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
753 channelType[chLoop],
754 chControlReg, chStatusReg, chDescReg, chLDescReg,
755 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
756 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
757 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
758 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
759 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
760 "%11s : TX CH EN Descriptor Async, resync it", channelType[chLoop], 0, 0);
761 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
762 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
763 }
764 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
765 (chDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
766 {
767 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
768 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
769 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
770 channelType[chLoop],
771 chControlReg, chStatusReg, chDescReg, chLDescReg,
772 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
773 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
774 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
775 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
776 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
777 "%11s : TX CH DIS Descriptor Async, resync it", channelType[chLoop], 0, 0);
778 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
779 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
780 }
781 }
782
783 /* TX channel test done, test RX channels */
784 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
785 channelCtrlBlk->healthMonitorMsg->callback = dxeRXHealthMonitor;
786 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
787 channelCtrlBlk->healthMonitorMsg);
788 if (eWLAN_PAL_STATUS_SUCCESS != status)
789 {
790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
791 "TX Low resource Kick DXE MSG Serialize fail",
792 status, 0, 0);
793 }
794
795 return;
796}
797
798/*==========================================================================
799 @ Function Name
800 dxeHealthMonitorTimeout
801
802 @ Description
803 Health Monitor timer started when TX channel low resource condition
804 And if reciovered from low resource condition, timer would not fired
805 Timer fired means during certain time, TX CH could not be recovered
806
807 @ Parameters
808 channelCtxt Low resource condition happen Channel context
809
810 @ Return
811 NONE
812
813===========================================================================*/
814void dxeHealthMonitorTimeout
815(
816 void *channelCtxt
817)
818{
819 WLANDXE_ChannelCBType *channelCtrlBlk;
820 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
821
822 if(NULL == channelCtxt)
823 {
824 return;
825 }
826
827 /* Timeout Fired, DXE TX should kick on TX thread
828 * Serailize to TX Thread */
829 channelCtrlBlk = (WLANDXE_ChannelCBType *)channelCtxt;
830 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
831 "%11s : Health Monitor timer expired",
832 channelType[channelCtrlBlk->channelType], 0, 0);
833
834 channelCtrlBlk->healthMonitorMsg->callback = dxeTXHealthMonitor;
835 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
836 channelCtrlBlk->healthMonitorMsg);
837 if (eWLAN_PAL_STATUS_SUCCESS != status)
838 {
839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
840 "TX Low resource Kick DXE MSG Serialize fail",
841 status, 0, 0);
842 }
843
844 return;
845}
846
847/*==========================================================================
848 @ Function Name
Jeff Johnson295189b2012-06-20 16:38:30 -0700849 dxeCtrlBlkAlloc
850
851 @ Description
852 Allocate DXE Control block
853 DXE control block will used by Host DXE driver only, internal structure
854 Will make ring linked list
855
856 @ Parameters
857 WLANDXE_CtrlBlkType *dxeCtrlBlk,
858 DXE host driver main control block
859 WLANDXE_ChannelCBType *channelEntry
860 Channel specific control block
861
862 @ Return
863 wpt_status
864
865===========================================================================*/
866static wpt_status dxeCtrlBlkAlloc
867(
868 WLANDXE_CtrlBlkType *dxeCtrlBlk,
869 WLANDXE_ChannelCBType *channelEntry
870)
871{
872 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
873 unsigned int idx, fIdx;
874 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
875 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
876 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
877 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
878
879 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700880 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700881
882 /* Sanity check */
883 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
884 {
885 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
886 "dxeCtrlBlkAlloc Channel Entry is not valid");
887 return eWLAN_PAL_STATUS_E_INVAL;
888 }
889
890 /* Allocate pre asigned number of control blocks */
891 for(idx = 0; idx < channelEntry->numDesc; idx++)
892 {
893 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
894 if(NULL == currentCtrlBlk)
895 {
896 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
897 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
898 channelEntry->channelType);
899 freeCtrlBlk = channelEntry->headCtrlBlk;
900 for(fIdx = 0; fIdx < idx; fIdx++)
901 {
902 if(NULL == freeCtrlBlk)
903 {
904 break;
905 }
906
907 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
908 wpalMemoryFree((void *)freeCtrlBlk);
909 freeCtrlBlk = nextCtrlBlk;
910 }
911 return eWLAN_PAL_STATUS_E_FAULT;
912 }
913
914 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
915 /* Initialize common elements first */
916 currentCtrlBlk->xfrFrame = NULL;
917 currentCtrlBlk->linkedDesc = NULL;
918 currentCtrlBlk->linkedDescPhyAddr = 0;
919 currentCtrlBlk->ctrlBlkOrder = idx;
920
921 /* This is the first control block allocated
922 * Next Control block is not allocated yet
923 * head and tail must be first control block */
924 if(0 == idx)
925 {
926 currentCtrlBlk->nextCtrlBlk = NULL;
927 channelEntry->headCtrlBlk = currentCtrlBlk;
928 channelEntry->tailCtrlBlk = currentCtrlBlk;
929 }
930 /* This is not first, not last control block
931 * previous control block may has next linked block */
932 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
933 {
934 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
935 }
936 /* This is last control blocl
937 * next control block for the last control block is head, first control block
938 * then whole linked list made RING */
939 else if((channelEntry->numDesc - 1) == idx)
940 {
941 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
942 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
943 }
944 else
945 {
946 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
947 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
948 channelEntry->channelType);
949 wpalMemoryFree(currentCtrlBlk);
950 return eWLAN_PAL_STATUS_E_FAULT;
951 }
952
953 prevCtrlBlk = currentCtrlBlk;
954 channelEntry->numFreeDesc++;
955 }
956
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700957 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700958 return status;
959}
960
961/*==========================================================================
962 @ Function Name
963 dxeDescLinkAlloc
964
965 @ Description
966 Allocate DXE descriptor
967 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
968 Will make RING linked list
969 Will be linked with Descriptor control block one by one
970
971 @ Parameters
972 WLANDXE_CtrlBlkType *dxeCtrlBlk,
973 DXE host driver main control block
974 WLANDXE_ChannelCBType *channelEntry
975 Channel specific control block
976 @ Return
977 wpt_status
978
979===========================================================================*/
980static wpt_status dxeDescAllocAndLink
981(
982 WLANDXE_CtrlBlkType *dxeCtrlBlk,
983 WLANDXE_ChannelCBType *channelEntry
984)
985{
986 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
987 WLANDXE_DescType *currentDesc = NULL;
988 WLANDXE_DescType *prevDesc = NULL;
989 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
990 unsigned int idx;
991 void *physAddress = NULL;
992#ifdef WLANDXE_TEST_CHANNEL_ENABLE
993 WLANDXE_ChannelCBType *testTXChannelCB = &dxeCtrlBlk->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
994 WLANDXE_DescCtrlBlkType *currDescCtrlBlk = testTXChannelCB->headCtrlBlk;
995#endif /* WLANDXE_TEST_CHANNEL_ENABLE*/
996
997 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700998 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700999
1000 /* Sanity Check */
1001 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1002 {
1003 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1004 "dxeDescLinkAlloc Channel Entry is not valid");
1005 return eWLAN_PAL_STATUS_E_INVAL;
1006 }
1007
1008 currentCtrlBlk = channelEntry->headCtrlBlk;
1009
1010#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1011 /* allocate all DXE descriptors for this channel in one chunk */
1012 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
1013 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
1014 &physAddress);
1015 if(NULL == channelEntry->descriptorAllocation)
1016 {
1017 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1018 "dxeDescLinkAlloc Descriptor Alloc Fail");
1019 return eWLAN_PAL_STATUS_E_RESOURCES;
1020 }
1021 currentDesc = channelEntry->descriptorAllocation;
1022#endif
1023
1024 /* Allocate pre asigned number of descriptor */
1025 for(idx = 0; idx < channelEntry->numDesc; idx++)
1026 {
1027#ifndef FEATURE_R33D
1028#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1029 // descriptors were allocated in a chunk -- use the current one
1030 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1031 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1032 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1033#else
1034 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1035 {
1036 // allocate a descriptor
1037 currentDesc = (WLANDXE_DescType *)wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType),
1038 &physAddress);
1039 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1040 }
1041 else
1042 {
1043 currentDesc = currDescCtrlBlk->linkedDesc;
1044 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
1045 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1046 }
1047#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1048#else
1049#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1050 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
1051 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1052 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1053 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1054#else
1055 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1056 {
1057 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
1058 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1059 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1060 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1061 }
1062 else
1063 {
1064 currentDesc = currDescCtrlBlk->linkedDesc;
1065 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
1066 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1067 }
1068#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1069#endif /* FEATURE_R33D */
1070 if(NULL == currentDesc)
1071 {
1072 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1073 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
1074 channelEntry->channelType);
1075 return eWLAN_PAL_STATUS_E_FAULT;
1076 }
1077
1078 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1079 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1080 {
1081 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1082 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1083 }
1084 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1085 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1086 {
1087 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1088 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1089 }
1090 else
1091 {
1092 /* Just in case. H2H Test RX channel, do nothing
1093 * By Definition this must not happen */
1094 }
1095
1096 currentCtrlBlk->linkedDesc = currentDesc;
1097 currentCtrlBlk->linkedDescPhyAddr = (unsigned int)physAddress;
1098 /* First descriptor, next none
1099 * descriptor bottom location is first descriptor address */
1100 if(0 == idx)
1101 {
1102 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
1103 channelEntry->DescBottomLoc = currentDesc;
1104 channelEntry->descBottomLocPhyAddr = (unsigned int)physAddress;
1105 }
1106 /* Not first, not last descriptor
1107 * may make link for previous descriptor with current descriptor
1108 * ENDIAN SWAP needed ????? */
1109 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
1110 {
1111 prevDesc->dxedesc.dxe_short_desc.phyNextL =
1112 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
1113 }
1114 /* Last descriptor
1115 * make a ring by asign next pointer as first descriptor
1116 * ENDIAN SWAP NEEDED ??? */
1117 else if((channelEntry->numDesc - 1) == idx)
1118 {
1119 prevDesc->dxedesc.dxe_short_desc.phyNextL =
1120 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
1121 currentDesc->dxedesc.dxe_short_desc.phyNextL =
1122 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)channelEntry->headCtrlBlk->linkedDescPhyAddr);
1123 }
1124
1125 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
1126 * Pre allocated and physical address must be assigned into
1127 * Corresponding DXE Descriptor */
1128#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1129 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1130 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1131 (WDTS_CHANNEL_H2H_TEST_RX == channelEntry->channelType))
1132#else
1133 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1134 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1135#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1136 {
1137 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
1138 channelEntry,
1139 currentCtrlBlk);
1140 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1141 {
1142 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1143 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1144 channelEntry->channelType);
1145 return status;
1146 }
1147 --channelEntry->numFreeDesc;
1148 }
1149
1150 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1151 prevDesc = currentDesc;
1152
1153#ifndef FEATURE_R33D
1154#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1155 // advance to the next pre-allocated descriptor in the chunk
1156 currentDesc++;
1157 physAddress = ((wpt_int8 *)physAddress) + sizeof(WLANDXE_DescType);
1158#endif
1159#endif
1160 }
1161
1162 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001163 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001164 return status;
1165}
1166
1167/*==========================================================================
1168 @ Function Name
1169
1170 @ Description
1171
1172 @ Parameters
1173
1174 @ Return
1175 wpt_status
1176
1177===========================================================================*/
1178static wpt_status dxeSetInterruptPath
1179(
1180 WLANDXE_CtrlBlkType *dxeCtrlBlk
1181)
1182{
1183 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1184 wpt_uint32 interruptPath = 0;
1185 wpt_uint32 idx;
1186 WLANDXE_ChannelCBType *channelEntry = NULL;
1187
1188 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001189 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001190
1191 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
1192 {
1193 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
1194#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1195 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1196 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) ||
1197 (WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType))
1198#else
1199 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1200 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1201#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1202 {
1203 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1204 }
1205 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1206 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1207 {
1208 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1209 }
1210 else
1211 {
1212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1213 "H2H TEST RX???? %d", channelEntry->channelType);
1214 }
1215 }
1216 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1217 "Interrupt Path Must be 0x%x", interruptPath);
1218 dxeCtrlBlk->interruptPath = interruptPath;
1219 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1220
1221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001222 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001223 return status;
1224}
1225
1226/*==========================================================================
1227 @ Function Name
1228 dxeEngineCoreStart
1229
1230 @ Description
1231 Trigger to start RIVA DXE Hardware
1232
1233 @ Parameters
1234 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1235 DXE host driver main control block
1236
1237 @ Return
1238 wpt_status
1239
1240===========================================================================*/
1241static wpt_status dxeEngineCoreStart
1242(
1243 WLANDXE_CtrlBlkType *dxeCtrlBlk
1244)
1245{
1246 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1247 wpt_uint32 registerData = 0;
1248
1249 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001250 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001251
1252 /* START This core init is not needed for the integrated system */
1253 /* Reset First */
1254 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1255 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1256 registerData);
1257
1258 registerData = WLANDXE_DMA_CSR_EN_MASK;
1259 registerData |= WLANDXE_DMA_CSR_ECTR_EN_MASK;
1260 registerData |= WLANDXE_DMA_CSR_TSTMP_EN_MASK;
1261 registerData |= WLANDXE_DMA_CSR_H2H_SYNC_EN_MASK;
1262
1263 registerData = 0x00005c89;
1264 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1265 registerData);
1266
1267 /* Is This needed?
1268 * Not sure, revisit with integrated system */
1269 /* END This core init is not needed for the integrated system */
1270
1271 dxeSetInterruptPath(dxeCtrlBlk);
1272 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001273 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001274 return status;
1275}
1276
1277/*==========================================================================
1278 @ Function Name
1279 dxeChannelInitProgram
1280
1281 @ Description
1282 Program RIVA DXE engine register with initial value
1283 What must be programmed
1284 - Source Address (SADRL, chDXESadrlRegAddr)
1285 - Destination address (DADRL, chDXEDadrlRegAddr)
1286 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1287 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1288
1289 Not need to program now
1290 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1291 TX : Have to program to trigger send out frame
1292 RX : programmed by DXE engine
1293
1294 @ Parameters
1295 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1296 DXE host driver main control block
1297 WLANDXE_ChannelCBType *channelEntry
1298 Channel specific control block
1299 @ Return
1300 wpt_status
1301
1302===========================================================================*/
1303static wpt_status dxeChannelInitProgram
1304(
1305 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1306 WLANDXE_ChannelCBType *channelEntry
1307)
1308{
1309 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1310 wpt_uint32 idx;
1311 WLANDXE_DescType *currentDesc = NULL;
1312 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1313
1314 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001315 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001316
1317 /* Sanity Check */
1318 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1319 {
1320 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1321 "dxeChannelInitProgram Channel Entry is not valid");
1322 return eWLAN_PAL_STATUS_E_INVAL;
1323 }
1324
1325 /* Program Source address and destination adderss */
1326 if(!channelEntry->channelConfig.useShortDescFmt)
1327 {
1328 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1329 "dxeChannelInitProgram Long Descriptor not support yet");
1330 return eWLAN_PAL_STATUS_E_FAILURE;
1331 }
1332
1333 /* Common register area */
1334 /* Next linked list Descriptor pointer */
1335 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1336 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1337 if(eWLAN_PAL_STATUS_SUCCESS != status)
1338 {
1339 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1340 "dxeChannelInitProgram Write DESC Address register fail");
1341 return status;
1342 }
1343
1344 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1345 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1346 {
1347 /* Program default registers */
1348 /* TX DMA channel, DMA destination address is work Q */
1349 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1350 channelEntry->channelConfig.refWQ);
1351 if(eWLAN_PAL_STATUS_SUCCESS != status)
1352 {
1353 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1354 "dxeChannelInitProgram Write TX DAddress register fail");
1355 return status;
1356 }
1357 }
1358 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1359 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1360 {
1361 /* Initialize Descriptor control Word First */
1362 currentCtrlBlk = channelEntry->headCtrlBlk;
1363 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1364 {
1365 currentDesc = currentCtrlBlk->linkedDesc;
1366 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1367 }
1368
1369 /* RX DMA channel, DMA source address is work Q */
1370 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1371 channelEntry->channelConfig.refWQ);
1372 if(eWLAN_PAL_STATUS_SUCCESS != status)
1373 {
1374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1375 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1376 return status;
1377 }
1378
1379 /* RX DMA channel, Program pre allocated destination Address */
1380 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1381 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1382 if(eWLAN_PAL_STATUS_SUCCESS != status)
1383 {
1384 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1385 "dxeChannelInitProgram Write RX DAddress register fail");
1386 return status;
1387 }
1388
1389 /* RX Channels, default Control registers MUST BE ENABLED */
1390 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1391 channelEntry->extraConfig.chan_mask);
1392 if(eWLAN_PAL_STATUS_SUCCESS != status)
1393 {
1394 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1395 "dxeChannelInitProgram Write RX Control register fail");
1396 return status;
1397 }
1398 }
1399 else
1400 {
1401 /* H2H test channel, not use work Q */
1402 /* Program pre allocated destination Address */
1403 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1404 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1405 if(eWLAN_PAL_STATUS_SUCCESS != status)
1406 {
1407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1408 "dxeChannelInitProgram Write RX DAddress register fail");
1409 return status;
1410 }
1411 }
1412
1413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001414 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001415 return status;
1416}
1417
1418
1419/*==========================================================================
1420 @ Function Name
1421 dxeChannelStart
1422
1423 @ Description
1424 Start Specific Channel
1425
1426 @ Parameters
1427 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1428 DXE host driver main control block
1429 WLANDXE_ChannelCBType *channelEntry
1430 Channel specific control block
1431
1432 @ Return
1433 wpt_status
1434
1435===========================================================================*/
1436static wpt_status dxeChannelStart
1437(
1438 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1439 WLANDXE_ChannelCBType *channelEntry
1440)
1441{
1442 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1443 wpt_uint32 regValue = 0;
1444 wpt_uint32 intMaskVal = 0;
1445
1446 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001447 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001448
1449 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1450 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1451
1452 /* Enable individual channel
1453 * not to break current channel setup, first read register */
1454 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1455 &regValue);
1456 if(eWLAN_PAL_STATUS_SUCCESS != status)
1457 {
1458 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1459 "dxeChannelStart Read Channel Enable register fail");
1460 return status;
1461 }
1462
1463 /* Enable Channel specific Interrupt */
1464 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1465 &intMaskVal);
1466 if(eWLAN_PAL_STATUS_SUCCESS != status)
1467 {
1468 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1469 "dxeChannelStart Read INT_MASK register fail");
1470 return status;
1471 }
1472 intMaskVal |= channelEntry->extraConfig.intMask;
1473 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1474 intMaskVal);
1475 if(eWLAN_PAL_STATUS_SUCCESS != status)
1476 {
1477 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1478 "dxeChannelStart Write INT_MASK register fail");
1479 return status;
1480 }
1481
1482 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001483 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 return status;
1485}
1486
1487/*==========================================================================
1488 @ Function Name
1489 dxeChannelStop
1490
1491 @ Description
1492 Stop Specific Channel
1493
1494 @ Parameters
1495 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1496 DXE host driver main control block
1497 WLANDXE_ChannelCBType *channelEntry
1498 Channel specific control block
1499
1500 @ Return
1501 wpt_status
1502
1503===========================================================================*/
1504static wpt_status dxeChannelStop
1505(
1506 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1507 WLANDXE_ChannelCBType *channelEntry
1508)
1509{
1510 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1511 wpt_uint32 intMaskVal = 0;
1512
1513 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001514 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001515
1516 /* Sanity */
1517 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1518 {
1519 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1520 "dxeChannelStop Invalid arg input");
1521 return eWLAN_PAL_STATUS_E_INVAL;
1522 }
1523
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001524 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1525 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1526 {
1527 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1528 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001529 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001531 /* Maskout interrupt */
1532 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1533 &intMaskVal);
1534 if(eWLAN_PAL_STATUS_SUCCESS != status)
1535 {
1536 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1537 "dxeChannelStop Read INT_MASK register fail");
1538 return status;
1539 }
1540 intMaskVal ^= channelEntry->extraConfig.intMask;
1541 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1542 intMaskVal);
1543 if(eWLAN_PAL_STATUS_SUCCESS != status)
1544 {
1545 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1546 "dxeChannelStop Write INT_MASK register fail");
1547 return status;
1548 }
1549
1550 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1551
1552 /* Stop Channel ??? */
1553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001554 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001555 return status;
1556}
1557
1558/*==========================================================================
1559 @ Function Name
1560 dxeChannelClose
1561
1562 @ Description
1563 Close Specific Channel
1564 Free pre allocated RX frame buffer if RX channel
1565 Free DXE descriptor for each channel
1566 Free Descriptor control block for each channel
1567
1568 @ Parameters
1569 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1570 DXE host driver main control block
1571 WLANDXE_ChannelCBType *channelEntry
1572 Channel specific control block
1573
1574 @ Return
1575 wpt_status
1576
1577===========================================================================*/
1578static wpt_status dxeChannelClose
1579(
1580 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1581 WLANDXE_ChannelCBType *channelEntry
1582)
1583{
1584 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1585 wpt_uint32 idx;
1586 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1587 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1588 WLANDXE_DescType *currentDescriptor = NULL;
1589 WLANDXE_DescType *nextDescriptor = NULL;
1590
1591 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001592 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001593
1594 /* Sanity */
1595 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1596 {
1597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1598 "dxeChannelStop Invalid arg input");
1599 return eWLAN_PAL_STATUS_E_INVAL;
1600 }
1601
1602 currentCtrlBlk = channelEntry->headCtrlBlk;
1603 if(NULL != currentCtrlBlk)
1604 {
1605 currentDescriptor = currentCtrlBlk->linkedDesc;
1606 for(idx = 0; idx < channelEntry->numDesc; idx++)
1607 {
1608 if (idx + 1 != channelEntry->numDesc)
1609 {
1610 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1611 nextDescriptor = nextCtrlBlk->linkedDesc;
1612 }
1613 else
1614 {
1615 nextCtrlBlk = NULL;
1616 nextDescriptor = NULL;
1617 }
1618 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1619 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1620 {
1621 if (NULL != currentCtrlBlk->xfrFrame)
1622 {
1623 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1624 wpalPacketFree(currentCtrlBlk->xfrFrame);
1625 }
1626 }
1627 /*
1628 * It is the responsibility of DXE to walk through the
1629 * descriptor chain and unlock any pending packets (if
1630 * locked).
1631 */
1632 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1633 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1634 {
1635 if((NULL != currentCtrlBlk->xfrFrame) &&
1636 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1637 {
1638 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1639 wpalPacketFree(currentCtrlBlk->xfrFrame);
1640 }
1641 }
1642#if (defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1643 // descriptors allocated individually so free them individually
1644 wpalDmaMemoryFree(currentDescriptor);
1645#endif
1646 wpalMemoryFree(currentCtrlBlk);
1647
1648 currentCtrlBlk = nextCtrlBlk;
1649 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001650 if(NULL == currentCtrlBlk)
1651 {
1652 /* Already reach last of the control block
1653 * Not need to process anymore, break */
1654 break;
1655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 }
1657 }
1658
1659#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1660 // descriptors were allocated as a single chunk so free the chunk
1661 if(NULL != channelEntry->descriptorAllocation)
1662 {
1663 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1664 }
1665#endif
1666
1667 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001668 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 return status;
1670}
1671
1672/*==========================================================================
1673 @ Function Name
1674 dxeChannelCleanInt
1675
1676 @ Description
1677 Clean up interrupt from RIVA HW
1678 After Host finish to handle interrupt, interrupt signal must be cleaned up
1679 Otherwise next interrupt will not be generated
1680
1681 @ Parameters
1682 WLANDXE_ChannelCBType *channelEntry
1683 Channel specific control block
1684 wpt_uint32 *chStat
1685 Channel Status register value
1686
1687 @ Return
1688 wpt_status
1689
1690===========================================================================*/
1691static wpt_status dxeChannelCleanInt
1692(
1693 WLANDXE_ChannelCBType *channelEntry,
1694 wpt_uint32 *chStat
1695)
1696{
1697 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1698
1699 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001700 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001701
1702 /* Read Channel Status Register to know why INT Happen */
1703 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1704 chStat);
1705 if(eWLAN_PAL_STATUS_SUCCESS != status)
1706 {
1707 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1708 "dxeChannelCleanInt Read CH STAT register fail");
1709 return eWLAN_PAL_STATUS_E_FAULT;
1710 }
1711 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1712 "%s Channel INT Clean, Status 0x%x",
1713 channelType[channelEntry->channelType], *chStat);
1714
1715 /* Clean up all the INT within this channel */
1716 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1717 (1 << channelEntry->assignedDMAChannel));
1718 if(eWLAN_PAL_STATUS_SUCCESS != status)
1719 {
1720 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1721 "dxeChannelCleanInt Write CH Clean register fail");
1722 return eWLAN_PAL_STATUS_E_FAULT;
1723 }
1724
Jeff Johnsone7245742012-09-05 17:12:55 -07001725 /* Clean up Error INT Bit */
1726 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1727 {
1728 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1729 (1 << channelEntry->assignedDMAChannel));
1730 if(eWLAN_PAL_STATUS_SUCCESS != status)
1731 {
1732 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1733 "dxeChannelCleanInt Read CH STAT register fail");
1734 return eWLAN_PAL_STATUS_E_FAULT;
1735 }
1736 }
1737
1738 /* Clean up DONE INT Bit */
1739 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1740 {
1741 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1742 (1 << channelEntry->assignedDMAChannel));
1743 if(eWLAN_PAL_STATUS_SUCCESS != status)
1744 {
1745 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1746 "dxeChannelCleanInt Read CH STAT register fail");
1747 return eWLAN_PAL_STATUS_E_FAULT;
1748 }
1749 }
1750
1751 /* Clean up ED INT Bit */
1752 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1753 {
1754 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1755 (1 << channelEntry->assignedDMAChannel));
1756 if(eWLAN_PAL_STATUS_SUCCESS != status)
1757 {
1758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1759 "dxeChannelCleanInt Read CH STAT register fail");
1760 return eWLAN_PAL_STATUS_E_FAULT;
1761 }
1762 }
1763
Jeff Johnson295189b2012-06-20 16:38:30 -07001764 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001765 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001766 return status;
1767}
1768
1769/*==========================================================================
1770 @ Function Name
1771 dxeRXPacketAvailableCB
1772
1773 @ Description
1774 If RX frame handler encounts RX buffer pool empty condition,
1775 DXE RX handle loop will be blocked till get available RX buffer pool.
1776 When new RX buffer pool available, Packet available CB function will
1777 be called.
1778
1779 @ Parameters
1780 wpt_packet *freePacket
1781 Newly allocated RX buffer
1782 v_VOID_t *usrData
1783 DXE context
1784
1785 @ Return
1786 NONE
1787
1788===========================================================================*/
1789void dxeRXPacketAvailableCB
1790(
1791 wpt_packet *freePacket,
1792 v_VOID_t *usrData
1793)
1794{
1795 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1796 wpt_status status;
1797
1798 /* Simple Sanity */
1799 if((NULL == freePacket) || (NULL == usrData))
1800 {
1801 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1802 "Get Free RX Buffer fail, Critical Error");
1803 HDXE_ASSERT(0);
1804 return;
1805 }
1806
1807 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1808
1809 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1810 {
1811 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1812 "DXE Context data corrupted, Critical Error");
1813 HDXE_ASSERT(0);
1814 return;
1815 }
1816
1817 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1818 "DXE RX packet available, post MSG to RX Thread");
1819
1820 dxeCtxt->freeRXPacket = freePacket;
1821
1822 /* Serialize RX Packet Available message upon RX thread */
1823 HDXE_ASSERT(NULL != dxeCtxt->rxPktAvailMsg);
1824
1825 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1826 dxeCtxt->rxPktAvailMsg);
1827 if(eWLAN_PAL_STATUS_SUCCESS != status)
1828 {
1829 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
1830 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1831 "dxeRXPacketAvailableCB serialize fail");
1832 }
1833
1834 return;
1835}
1836
1837/*==========================================================================
1838 @ Function Name
1839 dxeRXFrameSingleBufferAlloc
1840
1841 @ Description
1842 Allocate Platform packet buffer to prepare RX frame
1843 RX frame memory space must be pre allocted and must be asigned to
1844 descriptor
1845 then whenever DMA engine want to tranfer frame from BMU,
1846 buffer must be ready
1847
1848 @ Parameters
1849 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1850 DXE host driver main control block
1851 WLANDXE_ChannelCBType *channelEntry
1852 Channel specific control block
1853 WLANDXE_DescCtrlBlkType currentCtrlBlock
1854 current control block which have to be asigned
1855 frame buffer
1856
1857 @ Return
1858 wpt_status
1859
1860===========================================================================*/
1861static wpt_status dxeRXFrameSingleBufferAlloc
1862(
1863 WLANDXE_CtrlBlkType *dxeCtxt,
1864 WLANDXE_ChannelCBType *channelEntry,
1865 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1866)
1867{
1868 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1869 wpt_packet *currentPalPacketBuffer = NULL;
1870 WLANDXE_DescType *currentDesc = NULL;
1871#ifdef FEATURE_R33D
1872 wpt_uint32 virtualAddressPCIe;
1873 wpt_uint32 physicalAddressPCIe;
1874#else
1875 wpt_iterator iterator;
1876 wpt_uint32 allocatedSize = 0;
1877 void *physAddress = NULL;
1878#endif /* FEATURE_R33D */
1879
Jeff Johnson295189b2012-06-20 16:38:30 -07001880
1881 currentDesc = currentCtrlBlock->linkedDesc;
1882
1883 /* First check if a packet pointer has already been provided by a previously
1884 invoked Rx packet available callback. If so use that packet. */
1885 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1886 {
1887 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1888 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1889 dxeCtxt->freeRXPacket = NULL;
1890 }
1891 else if(!dxeCtxt->rxPalPacketUnavailable)
1892 {
1893 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1894 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
1895 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1896 dxeRXPacketAvailableCB,
1897 (void *)dxeCtxt);
1898
1899 if(NULL == currentPalPacketBuffer)
1900 {
1901 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
1902 }
1903 }
1904
1905 if(NULL == currentPalPacketBuffer)
1906 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001907 return eWLAN_PAL_STATUS_E_RESOURCES;
1908 }
1909
1910 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1911 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1912 currentPalPacketBuffer->pBD = NULL;
1913 currentPalPacketBuffer->pBDPhys = NULL;
1914 currentPalPacketBuffer->BDLength = 0;
1915#ifdef FEATURE_R33D
1916 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
1917 &physicalAddressPCIe,
1918 &virtualAddressPCIe);
1919 HDXE_ASSERT(0 != physicalAddressPCIe);
1920 HDXE_ASSERT(0 != virtualAddressPCIe);
1921 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
1922 "RX Shadow Memory Va 0x%x, Pa 0x%x",
1923 virtualAddressPCIe, physicalAddressPCIe);
1924 if(eWLAN_PAL_STATUS_SUCCESS != status)
1925 {
1926 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1927 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
1928 return status;
1929 }
1930 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
1931 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
1932 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1933#else
1934 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
1935 if(eWLAN_PAL_STATUS_SUCCESS != status)
1936 {
1937 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1938 "dxeRXFrameBufferAlloc unable to lock packet");
1939 return status;
1940 }
1941
1942 /* Init iterator to get physical os buffer address */
1943 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1944 if(eWLAN_PAL_STATUS_SUCCESS != status)
1945 {
1946 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1947 "dxeRXFrameBufferAlloc iterator init fail");
1948 return status;
1949 }
1950 status = wpalIteratorNext(&iterator,
1951 currentPalPacketBuffer,
1952 &physAddress,
1953 &allocatedSize);
1954 if(eWLAN_PAL_STATUS_SUCCESS != status)
1955 {
1956 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1957 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1958 return status;
1959 }
1960 currentPalPacketBuffer->pBDPhys = physAddress;
1961#endif /* FEATURE_R33D */
1962
1963 /* DXE descriptor must have SWAPPED addres in it's structure
1964 * !!! SWAPPED !!! */
1965 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
1966 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)currentPalPacketBuffer->pBDPhys);
1967
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 return status;
1969}
1970
1971/*==========================================================================
1972 @ Function Name
1973 dxeRXFrameRefillRing
1974
1975 @ Description
1976 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1977
1978 @ Parameters
1979 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1980 DXE host driver main control block
1981 WLANDXE_ChannelCBType *channelEntry
1982 Channel specific control block
1983
1984 @ Return
1985 wpt_status
1986
1987===========================================================================*/
1988static wpt_status dxeRXFrameRefillRing
1989(
1990 WLANDXE_CtrlBlkType *dxeCtxt,
1991 WLANDXE_ChannelCBType *channelEntry
1992)
1993{
1994 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1995 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
1996 WLANDXE_DescType *currentDesc = NULL;
1997
1998 while(channelEntry->numFreeDesc > 0)
1999 {
2000 /* Current Control block is free
2001 * and associated frame buffer is not linked with control block anymore
2002 * allocate new frame buffer for current control block */
2003 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2004 channelEntry,
2005 currentCtrlBlk);
2006
2007 if(eWLAN_PAL_STATUS_SUCCESS != status)
2008 {
2009 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2010 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2011 break;
2012 }
2013
2014 currentDesc = currentCtrlBlk->linkedDesc;
2015 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2016
2017 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2018 that any posted writes are reflected in memory before DXE looks at
2019 the descriptor. */
2020 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2021 {
2022 //HDXE_ASSERT(0);
2023 }
2024
2025 /* Kick off the DXE ring, if not in any power save mode */
2026 if((WLANDXE_POWER_STATE_IMPS != dxeCtxt->hostPowerState) &&
2027 (WLANDXE_POWER_STATE_DOWN != dxeCtxt->hostPowerState))
2028 {
2029 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2030 1 << channelEntry->assignedDMAChannel);
2031 }
2032 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2033 --channelEntry->numFreeDesc;
2034 }
2035
2036 channelEntry->tailCtrlBlk = currentCtrlBlk;
2037
2038 return status;
2039}
2040
2041/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002042 @ Function Name
2043 dxeRXFrameRouteUpperLayer
2044
2045 @ Description
2046 Test DXE descriptors and if any RX frame pending within RING,
2047 Route to upper layer
2048
2049 @ Parameters
2050 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2051 DXE host driver main control block
2052 WLANDXE_ChannelCBType *channelEntry
2053 Channel specific control block
2054 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002055 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002056 0 No frame pulled from RX RING
2057 int number of RX frames pulled from RX ring
2058
2059===========================================================================*/
2060static wpt_int32 dxeRXFrameRouteUpperLayer
2061(
2062 WLANDXE_CtrlBlkType *dxeCtxt,
2063 WLANDXE_ChannelCBType *channelEntry
2064)
2065{
2066 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2067 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2068 WLANDXE_DescType *currentDesc = NULL;
2069 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002070 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002071
2072 currentCtrlBlk = channelEntry->headCtrlBlk;
2073 currentDesc = currentCtrlBlk->linkedDesc;
2074
2075 /* Descriptoe should be SWAPPED ???? */
2076 descCtrl = currentDesc->descCtrl.ctrl;
2077
2078 /* Get frames while VALID bit is not set (DMA complete) and a data
2079 * associated with it */
2080 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2081 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2082 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2083 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2084 {
2085 channelEntry->numTotalFrame++;
2086 channelEntry->numFreeDesc++;
2087#ifdef FEATURE_R33D
2088 /* Transfer Size should be */
2089 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2090 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
2091 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
2092 currentCtrlBlk->shadowBufferVa,
2093 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2094 if(eWLAN_PAL_STATUS_SUCCESS != status)
2095 {
2096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2097 "dxeRXFrameReady Prepare RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002098 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002099 }
2100 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
2101 if(eWLAN_PAL_STATUS_SUCCESS != status)
2102 {
2103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2104 "dxeRXFrameReady Free Shadow RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002105 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002106 }
2107
2108#else /* FEATURE_R33D */
2109 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
2110 if (eWLAN_PAL_STATUS_SUCCESS != status)
2111 {
2112 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2113 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002114 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002115 }
2116#endif /* FEATURE_R33D */
2117 /* This Descriptor is valid, so linked Control block is also valid
2118 * Linked Control block has pre allocated packet buffer
2119 * So, just let upper layer knows preallocated frame pointer will be OK */
2120 /* Reap Rx frames */
2121 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2122 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002123 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002124
2125 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2126 dxeRXFrameRefillRing(dxeCtxt,channelEntry);
2127
2128 /* Test next contorl block
2129 * if valid, this control block also has new RX frame must be handled */
2130 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2131 currentDesc = currentCtrlBlk->linkedDesc;
2132 descCtrl = currentDesc->descCtrl.ctrl;
2133 }
2134
2135 /* Update head control block
2136 * current control block's valid bit was 0
2137 * next trial first control block must be current control block */
2138 channelEntry->headCtrlBlk = currentCtrlBlk;
2139
2140 /* Deliver all the reaped RX frames to upper layers */
2141 i = 0;
2142 while(i < frameCount) {
2143 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2144 i++;
2145 }
2146
2147 return frameCount;
2148}
2149
2150/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002151 @ Function Name
2152 dxeRXFrameReady
2153
2154 @ Description
2155 Pop frame from descriptor and route frame to upper transport layer
2156 Assign new platform packet buffer into used descriptor
2157 Actual frame pop and resource realloc
2158
2159 @ Parameters
2160 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2161 DXE host driver main control block
2162 WLANDXE_ChannelCBType *channelEntry
2163 Channel specific control block
2164
2165 @ Return
2166 wpt_status
2167
2168===========================================================================*/
2169static wpt_status dxeRXFrameReady
2170(
2171 WLANDXE_CtrlBlkType *dxeCtxt,
2172 WLANDXE_ChannelCBType *channelEntry
2173)
2174{
2175 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2176 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2177 WLANDXE_DescType *currentDesc = NULL;
2178 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002179 wpt_int32 frameCount = 0;
2180
2181 wpt_uint32 descLoop;
2182 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002183
2184 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002185 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002186
2187 /* Sanity Check */
2188 if((NULL == dxeCtxt) || (NULL == channelEntry))
2189 {
2190 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2191 "dxeRXFrameReady Channel Entry is not valid");
2192 return eWLAN_PAL_STATUS_E_INVAL;
2193 }
2194
Jeff Johnsone7245742012-09-05 17:12:55 -07002195 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002196
Jeff Johnsone7245742012-09-05 17:12:55 -07002197 if(0 > frameCount)
Jeff Johnson295189b2012-06-20 16:38:30 -07002198 {
2199 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 "dxeRXFrameReady RX frame route fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 return eWLAN_PAL_STATUS_E_INVAL;
2202 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002203
Jeff Johnsone7245742012-09-05 17:12:55 -07002204 if((0 == frameCount) &&
2205 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2206 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2207 {
2208 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 currentDesc = currentCtrlBlk->linkedDesc;
2210 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002211
2212 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2213 {
2214 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2215 "RX ISR called but no frame handled PWS %d, channel %s",
2216 (int)dxeCtxt->hostPowerState,
2217 channelType[channelEntry->channelType]);
2218 }
2219
2220 /* Current interupt empty and previous interrupt also empty
2221 * detected successive empty interrupt
2222 * or first interrupt empty, this should not happen */
2223 if(0 == channelEntry->numFragmentCurrentChain)
2224 {
2225 dxeChannelMonitor("RX Ready", channelEntry);
2226 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2227 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt");
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07002228 dxeChannelAllDescDump(channelEntry, channelEntry->channelType);
Jeff Johnsone7245742012-09-05 17:12:55 -07002229
2230 /* Abnormal interrupt detected, try to find not validated descriptor */
2231 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2232 {
2233 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2234 {
2235 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2236 "Found Invalidated Descriptor %d", (int)descLoop);
2237 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2238 {
2239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2240 "Packet locked, Resync Host and HW");
2241 channelEntry->headCtrlBlk = currentCtrlBlk;
2242 invalidatedFound = 1;
2243 break;
2244 }
2245 else
2246 {
2247 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2248 "Packet Not Locked, cannot transfer frame");
2249 }
2250 }
2251 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2252 currentDesc = currentCtrlBlk->linkedDesc;
2253 descCtrl = currentDesc->descCtrl.ctrl;
2254 }
2255
Jeff Johnson32d95a32012-09-10 13:15:23 -07002256 /* Invalidated descriptor found, and that is not head descriptor
2257 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2258 * Try re-sync here */
2259 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002260 {
2261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2262 "Found New Sync location with HW, handle frames from there");
2263 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2264 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2265 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002266 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002267 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002268 /* Successive Empty interrupt
2269 * But this case, first descriptor also invalidated, then it means head descriptor
2270 * is linked with already handled RX frame, then could not unlock RX frame
2271 * This is just Out of RX buffer pool, not need to anything here */
2272 else if((invalidatedFound) && (0 == descLoop))
2273 {
2274 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2275 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2276 }
2277 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002278 else
2279 {
2280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2281 "Could not found invalidated descriptor");
2282 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2283 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2284 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2285 wpalWlanReload();
2286 }
2287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002288 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002289 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002290 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002291 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002292 return status;
2293}
2294
2295/*==========================================================================
2296 @ Function Name
2297 dxeNotifySmsm
2298
2299 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2300 buffer
2301
2302 @ Parameters
2303
2304 @ Return
2305 wpt_status
2306
2307===========================================================================*/
2308static wpt_status dxeNotifySmsm
2309(
2310 wpt_boolean kickDxe,
2311 wpt_boolean ringEmpty
2312)
2313{
2314 wpt_uint32 clrSt = 0;
2315 wpt_uint32 setSt = 0;
2316
2317 if(kickDxe)
2318 {
2319 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2320
2321 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2322 {
2323 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2324 tempDxeCtrlBlk->lastKickOffDxe = 1;
2325 }
2326 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2327 {
2328 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2329 tempDxeCtrlBlk->lastKickOffDxe = 0;
2330 }
2331 else
2332 {
2333 HDXE_ASSERT(0);
2334 }
2335 }
2336 else
2337 {
2338 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2339 }
2340
2341 if(ringEmpty)
2342 {
2343 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2344 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2345 }
2346 else
2347 {
2348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2349 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2350 }
2351
2352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2353
2354 wpalNotifySmsm(clrSt, setSt);
2355
2356 return eWLAN_PAL_STATUS_SUCCESS;
2357}
2358
2359/*==========================================================================
2360 @ Function Name
2361 dxePsComplete
2362
2363 @ Description: Utility function to check the resv desc to deside if we can
2364 get into Power Save mode now
2365
2366 @ Parameters
2367
2368 @ Return
2369 None
2370
2371===========================================================================*/
2372static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2373{
2374 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2375 {
2376 return;
2377 }
2378
2379 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2380 //must have been consumed by RIVA, OK to get into BMPS
2381 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2382 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2383 {
2384 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2385 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2386 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2387 {
2388 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2389 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2390 }
2391 }
2392 else //still more pkts to be served by RIVA
2393 {
2394 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2395
2396 switch(dxeCtxt->rivaPowerState)
2397 {
2398 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2399 //NOP
2400 break;
2401 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2402 if(intr_based)
2403 {
2404 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2405 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2406 }
2407 break;
2408 default:
2409 //assert
2410 break;
2411 }
2412 }
2413}
2414
2415/*==========================================================================
2416 @ Function Name
2417 dxeRXEventHandler
2418
2419 @ Description
2420 Handle serailized RX frame ready event
2421 First disable interrupt then pick up frame from pre allocated buffer
2422 Since frame handle is doen, clear interrupt bit to ready next interrupt
2423 Finally re enable interrupt
2424
2425 @ Parameters
2426 wpt_msg *rxReadyMsg
2427 RX frame ready MSG pointer
2428 include DXE control context
2429
2430 @ Return
2431 NONE
2432
2433===========================================================================*/
2434void dxeRXEventHandler
2435(
2436 wpt_msg *rxReadyMsg
2437)
2438{
2439 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2440 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2441 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2442 wpt_uint32 intSrc = 0;
2443 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002444 wpt_uint32 chHighStat = 0;
2445 wpt_uint32 chLowStat = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002446
Jeff Johnsone7245742012-09-05 17:12:55 -07002447 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002448
Jeff Johnsone7245742012-09-05 17:12:55 -07002449 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002450 {
2451 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002452 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002453 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002454 }
2455
Jeff Johnsone7245742012-09-05 17:12:55 -07002456 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2457 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2458 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
2459
Jeff Johnson295189b2012-06-20 16:38:30 -07002460 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2461
2462 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
2463 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
2464 {
2465 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2466 "DXE already stopped in RX event handler. Just return");
2467 return;
2468 }
2469
2470 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2471 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2472 {
2473 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2474 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002475 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002476
2477 /* Not to touch any register, just pull frame directly from chain ring
2478 * First high priority */
2479 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2480 status = dxeRXFrameReady(dxeCtxt,
2481 channelCb);
2482 if(eWLAN_PAL_STATUS_SUCCESS != status)
2483 {
2484 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2485 "dxeRXEventHandler Pull from RX high channel fail");
2486 }
2487
2488 /* Second low priority */
2489 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2490 status = dxeRXFrameReady(dxeCtxt,
2491 channelCb);
2492 if(eWLAN_PAL_STATUS_SUCCESS != status)
2493 {
2494 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2495 "dxeRXEventHandler Pull from RX low channel fail");
2496 }
2497
2498 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2499 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2500
2501 return;
2502 }
2503
2504 /* Disable device interrupt */
2505 /* Read whole interrupt mask register and exclusive only this channel int */
2506 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2507 &intSrc);
2508 if(eWLAN_PAL_STATUS_SUCCESS != status)
2509 {
2510 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2511 "dxeRXEventHandler Read INT_SRC register fail");
2512 return;
2513 }
2514 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2515 "RX Event Handler INT Source 0x%x", intSrc);
2516
2517#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2518 /* Test High Priority Channel interrupt is enabled or not */
2519 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2520 if(intSrc & (1 << channelCb->assignedDMAChannel))
2521 {
2522 status = dxeChannelCleanInt(channelCb, &chHighStat);
2523 if(eWLAN_PAL_STATUS_SUCCESS != status)
2524 {
2525 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2526 "dxeRXEventHandler INT Clean up fail");
2527 return;
2528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2530 {
2531 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002532 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2533 "%11s : 0x%x Error Reported, Reload Driver",
2534 channelType[channelCb->channelType], chHighStat);
2535 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2536 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002537 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002538 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2539 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002540 {
2541 /* Handle RX Ready for high priority channel */
2542 status = dxeRXFrameReady(dxeCtxt,
2543 channelCb);
2544 }
2545 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2546 {
2547 status = dxeRXFrameReady(dxeCtxt,
2548 channelCb);
2549 }
2550 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2551 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002552 /* Update the Rx DONE histogram */
2553 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2554 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2555 {
2556 channelCb->rxDoneHistogram |= 1;
2557 }
2558 else
2559 {
2560 channelCb->rxDoneHistogram &= ~1;
2561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002562 }
2563#else
2564 /* Test H2H Test interrupt is enabled or not */
2565 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2566 if(intSrc & (1 << channelCb->assignedDMAChannel))
2567 {
2568 status = dxeChannelCleanInt(channelCb, &chStat);
2569 if(eWLAN_PAL_STATUS_SUCCESS != status)
2570 {
2571 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2572 "dxeRXEventHandler INT Clean up fail");
2573 return;
2574 }
2575
2576 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2577 {
2578 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002579 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2580 "%11s : 0x%x Error Reported, Reload Driver",
2581 channelType[channelCb->channelType], chStat);
2582 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2583 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 }
2585 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2586 {
2587 /* Handle RX Ready for high priority channel */
2588 status = dxeRXFrameReady(dxeCtxt,
2589 channelCb);
2590 }
2591 /* Update the Rx DONE histogram */
2592 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2593 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2594 {
2595 channelCb->rxDoneHistogram |= 1;
2596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2597 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2598 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2599 }
2600 else
2601 {
2602 channelCb->rxDoneHistogram &= ~1;
2603 }
2604 }
2605#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2606
2607 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002608 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002609 if(intSrc & (1 << channelCb->assignedDMAChannel))
2610 {
2611 status = dxeChannelCleanInt(channelCb, &chLowStat);
2612 if(eWLAN_PAL_STATUS_SUCCESS != status)
2613 {
2614 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2615 "dxeRXEventHandler INT Clean up fail");
2616 return;
2617 }
2618
2619 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2620 {
2621 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002622 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2623 "%11s : 0x%x Error Reported, Reload Driver",
2624 channelType[channelCb->channelType], chLowStat);
2625 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2626 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002627 }
2628 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2629 {
2630 /* Handle RX Ready for low priority channel */
2631 status = dxeRXFrameReady(dxeCtxt,
2632 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07002633 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002634
2635 /* Update the Rx DONE histogram */
2636 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2637 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2638 {
2639 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002640 }
2641 else
2642 {
2643 channelCb->rxDoneHistogram &= ~1;
2644 }
2645 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2646 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2647 }
2648 if(eWLAN_PAL_STATUS_SUCCESS != status)
2649 {
2650 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2651 "dxeRXEventHandler Handle Frame Ready Fail");
2652 return;
2653 }
2654
2655 /* Enable system level ISR */
2656 /* Enable RX ready Interrupt at here */
2657 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2658 if(eWLAN_PAL_STATUS_SUCCESS != status)
2659 {
2660 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2661 "dxeRXEventHandler Enable RX Ready interrupt fail");
2662 return;
2663 }
2664
2665 /* Prepare Control Register EN Channel */
2666 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2667 {
2668 HDXE_ASSERT(0);
2669 }
2670 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
2671 {
2672 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2673 "dxeRXEventHandler RX High, Not yet ED, re-enable CH");
2674 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
2675 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
2676 }
2677 else
2678 {
2679 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2680 "dxeRXEventHandler RX High, CH STAT = ED_MASK, will RIVA PC");
2681 }
2682
2683 /* Prepare Control Register EN Channel */
2684 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2685 {
2686 HDXE_ASSERT(0);
2687 }
2688 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat))
2689 {
2690 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2691 "dxeRXEventHandler RX Low, Not yet ED, re-enable CH");
2692 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
2693 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
2694 }
2695 else
2696 {
2697 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2698 "dxeRXEventHandler RX Low, CH STAT = ED_MASK, will RIVA PC");
2699 }
2700
2701 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002702 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002703 return;
2704}
2705
2706/*==========================================================================
2707 @ Function Name
2708 dxeRXPacketAvailableEventHandler
2709
2710 @ Description
2711 Handle serialized RX Packet Available event when the corresponding callback
2712 is invoked by WPAL.
2713 Try to fill up any completed DXE descriptors with available Rx packet buffer
2714 pointers.
2715
2716 @ Parameters
2717 wpt_msg *rxPktAvailMsg
2718 RX frame ready MSG pointer
2719 include DXE control context
2720
2721 @ Return
2722 NONE
2723
2724===========================================================================*/
2725void dxeRXPacketAvailableEventHandler
2726(
2727 wpt_msg *rxPktAvailMsg
2728)
2729{
2730 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2731 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2732 WLANDXE_ChannelCBType *channelCb = NULL;
2733
2734 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002735 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002736
2737 /* Sanity Check */
2738 if(NULL == rxPktAvailMsg)
2739 {
2740 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2741 "dxeRXPacketAvailableEventHandler Context is not valid");
2742 return;
2743 }
2744
2745 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
2746
2747 do
2748 {
2749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2750 "dxeRXPacketAvailableEventHandler, start refilling ring");
2751
2752 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2753 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2754
2755 // Wait for another callback to indicate when Rx resources are available
2756 // again.
2757 if(eWLAN_PAL_STATUS_SUCCESS != status)
2758 {
2759 break;
2760 }
2761
2762 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2763 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2764 if(eWLAN_PAL_STATUS_SUCCESS != status)
2765 {
2766 break;
2767 }
2768 } while(0);
2769
2770 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2771 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2772 {
2773 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2774 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2775 }
2776}
2777
2778/*==========================================================================
2779 @ Function Name
2780 dxeRXISR
2781
2782 @ Description
2783 RX frame ready interrupt service routine
2784 interrupt entry function, this function called based on ISR context
2785 Must be serialized
2786
2787 @ Parameters
2788 void *hostCtxt
2789 DXE host driver control context,
2790 pre registerd during interrupt registration
2791
2792 @ Return
2793 NONE
2794
2795===========================================================================*/
2796static void dxeRXISR
2797(
2798 void *hostCtxt
2799)
2800{
2801 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2802 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2803#ifdef FEATURE_R33D
2804 wpt_uint32 regValue;
2805#endif /* FEATURE_R33D */
2806
Jeff Johnson295189b2012-06-20 16:38:30 -07002807
2808#ifdef FEATURE_R33D
2809 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2810 &regValue);
2811 if(eWLAN_PAL_STATUS_SUCCESS != status)
2812 {
2813 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2814 "dxeTXCompISR Read INT_SRC_RAW fail");
2815 return;
2816 }
2817 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2818 "INT_SRC_RAW 0x%x", regValue);
2819 if(0 == regValue)
2820 {
2821 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2822 "This is not DXE Interrupt, Reject it 0x%x", regValue);
2823 return;
2824 }
2825#endif /* FEATURE_R33D */
2826
2827 /* Disable interrupt at here
2828 * Disable RX Ready system level Interrupt at here
2829 * Otherwise infinite loop might happen */
2830 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2831 if(eWLAN_PAL_STATUS_SUCCESS != status)
2832 {
2833 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2834 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2835 return;
2836 }
2837
2838 /* Serialize RX Ready interrupt upon RX thread */
2839 HDXE_ASSERT(NULL != dxeCtxt->rxIsrMsg);
2840 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2841 dxeCtxt->rxIsrMsg);
2842 if(eWLAN_PAL_STATUS_SUCCESS != status)
2843 {
2844 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
2845 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2846 "dxeRXFrameReadyISR interrupt serialize fail");
2847 }
2848
Jeff Johnson295189b2012-06-20 16:38:30 -07002849 return;
2850}
2851
2852/*==========================================================================
2853 @ Function Name
2854 dxeTXPushFrame
2855
2856 @ Description
2857 Push TX frame into DXE descriptor and DXE register
2858 Send notification to DXE register that TX frame is ready to transfer
2859
2860 @ Parameters
2861 WLANDXE_ChannelCBType *channelEntry
2862 Channel specific control block
2863 wpt_packet *palPacket
2864 Packet pointer ready to transfer
2865
2866 @ Return
2867 PAL_STATUS_T
2868===========================================================================*/
2869static wpt_status dxeTXPushFrame
2870(
2871 WLANDXE_ChannelCBType *channelEntry,
2872 wpt_packet *palPacket
2873)
2874{
2875 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2876 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2877 WLANDXE_DescType *currentDesc = NULL;
2878 WLANDXE_DescType *firstDesc = NULL;
2879 WLANDXE_DescType *LastDesc = NULL;
2880 void *sourcePhysicalAddress = NULL;
2881 wpt_uint32 xferSize = 0;
2882#ifdef FEATURE_R33D
2883 tx_frm_pcie_vector_t frameVector;
2884 wpt_uint32 Va;
2885 wpt_uint32 fragCount = 0;
2886#else
2887 wpt_iterator iterator;
2888#endif /* FEATURE_R33D */
2889
2890 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002891 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002892
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002893 if(WLANDXE_POWER_STATE_BMPS == tempDxeCtrlBlk->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002894 {
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002895 tempDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2896 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002897 }
2898
2899 channelEntry->numFragmentCurrentChain = 0;
2900 currentCtrlBlk = channelEntry->headCtrlBlk;
2901
2902 /* Initialize interator, TX is fragmented */
2903#ifdef FEATURE_R33D
2904 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2905 status = wpalPrepareTxFrame(palPacket,
2906 &frameVector,
2907 &Va);
2908#else
2909 status = wpalLockPacketForTransfer(palPacket);
2910 if(eWLAN_PAL_STATUS_SUCCESS != status)
2911 {
2912 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2913 "dxeTXPushFrame unable to lock packet");
2914 return status;
2915 }
2916
2917 status = wpalIteratorInit(&iterator, palPacket);
2918#endif /* FEATURE_R33D */
2919 if(eWLAN_PAL_STATUS_SUCCESS != status)
2920 {
2921 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2922 "dxeTXPushFrame iterator init fail");
2923 return status;
2924 }
2925
2926 /* !!!! Revisit break condition !!!!!!! */
2927 while(1)
2928 {
2929 /* Get current descriptor pointer from current control block */
2930 currentDesc = currentCtrlBlk->linkedDesc;
2931 if(NULL == firstDesc)
2932 {
2933 firstDesc = currentCtrlBlk->linkedDesc;
2934 }
2935 /* All control block will have same palPacket Pointer
2936 * to make logic simpler */
2937 currentCtrlBlk->xfrFrame = palPacket;
2938
2939 /* Get next fragment physical address and fragment size
2940 * if this is the first trial, will get first physical address
2941 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2942#ifdef FEATURE_R33D
2943 if(fragCount == frameVector.num_frg)
2944 {
2945 break;
2946 }
2947 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2948 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2949 xferSize = frameVector.frg[fragCount].size;
2950 fragCount++;
2951 HDXE_ASSERT(0 != xferSize);
2952 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2953#else
2954 status = wpalIteratorNext(&iterator,
2955 palPacket,
2956 &sourcePhysicalAddress,
2957 &xferSize);
2958 if((NULL == sourcePhysicalAddress) ||
2959 (0 == xferSize))
2960 {
2961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2962 "dxeTXPushFrame end of current frame");
2963 break;
2964 }
2965 if(eWLAN_PAL_STATUS_SUCCESS != status)
2966 {
2967 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2968 "dxeTXPushFrame Get next frame fail");
2969 return status;
2970 }
2971#endif /* FEATURE_R33D */
2972
2973 /* This is the LAST descriptor valid for this transaction */
2974 LastDesc = currentCtrlBlk->linkedDesc;
2975
2976 /* Program DXE descriptor */
2977 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2978 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2979
2980 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2981 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2982 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2983 {
2984 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
2985 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
2986 }
2987 else
2988 {
2989 /* Test specific H2H transfer, destination address already set
2990 * Do Nothing */
2991 }
2992 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
2993
2994 /* Program channel control register */
2995 /* First frame not set VAL bit, why ??? */
2996 if(0 == channelEntry->numFragmentCurrentChain)
2997 {
2998 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
2999 }
3000 else
3001 {
3002 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3003 }
3004
3005 /* Update statistics */
3006 channelEntry->numFragmentCurrentChain++;
3007 channelEntry->numFreeDesc--;
3008 channelEntry->numRsvdDesc++;
3009
3010 /* Get next control block */
3011 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3012 }
3013 channelEntry->numTotalFrame++;
3014 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3015 "NUM TX FRAG %d, Total Frame %d",
3016 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3017
3018 /* Program Channel control register
3019 * Set as end of packet
3020 * Enable interrupt also for first code lock down
3021 * performace optimization, this will be revisited */
3022 if(NULL == LastDesc)
3023 {
3024 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3025 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3026 return eWLAN_PAL_STATUS_E_FAULT;
3027 }
3028 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3029 /* Now First one also Valid ????
3030 * this procedure will prevent over handle descriptor from previous
3031 * TX trigger */
3032 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3033
3034 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3035 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3036 {
3037 /* Update channel head as next avaliable linked slot */
3038 channelEntry->headCtrlBlk = currentCtrlBlk;
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003039 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3040 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "SMSM_ret LO=%d HI=%d", tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3041 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3042 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3043 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003044 }
3045
3046 /* If DXE use external descriptor, registers are not needed to be programmed
3047 * Just after finish to program descriptor, tirigger to send */
3048 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3049 {
3050 /* Issue a dummy read from the DXE descriptor DDR location to
3051 ensure that any previously posted write to the descriptor
3052 completes. */
3053 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3054 {
3055 //HDXE_ASSERT(0);
3056 }
3057
3058 /* Everything is ready
3059 * Trigger to start DMA */
3060 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3061 channelEntry->extraConfig.chan_mask);
3062 if(eWLAN_PAL_STATUS_SUCCESS != status)
3063 {
3064 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3065 "dxeTXPushFrame Write Channel Ctrl Register fail");
3066 return status;
3067 }
3068
3069 /* Update channel head as next avaliable linked slot */
3070 channelEntry->headCtrlBlk = currentCtrlBlk;
3071
3072 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003073 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003074 return status;
3075 }
3076
3077 /* If DXE not use external descriptor, program each registers */
3078 /* Circular buffer handle not need to program DESC register???
3079 * GEN5 code not programed RING buffer case
3080 * REVISIT THIS !!!!!! */
3081 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3082 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3083 {
3084 /* Destination address, assigned Work Q */
3085 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3086 channelEntry->channelConfig.refWQ);
3087 if(eWLAN_PAL_STATUS_SUCCESS != status)
3088 {
3089 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3090 "dxeTXPushFrame Program dest address register fail");
3091 return status;
3092 }
3093 /* If descriptor format is SHORT */
3094 if(channelEntry->channelConfig.useShortDescFmt)
3095 {
3096 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3097 0);
3098 if(eWLAN_PAL_STATUS_SUCCESS != status)
3099 {
3100 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3101 "dxeTXPushFrame Program dest address register fail");
3102 return status;
3103 }
3104 }
3105 else
3106 {
3107 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3108 "dxeTXPushFrame LONG Descriptor Format!!!");
3109 }
3110 }
3111#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3112 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3113 {
3114 /* Destination address, Physical memory address */
3115 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3116 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3117 if(eWLAN_PAL_STATUS_SUCCESS != status)
3118 {
3119 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3120 "dxeTXPushFrame Program dest address register fail");
3121 return status;
3122 }
3123 /* If descriptor format is SHORT */
3124 if(channelEntry->channelConfig.useShortDescFmt)
3125 {
3126 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3127 0);
3128 if(eWLAN_PAL_STATUS_SUCCESS != status)
3129 {
3130 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3131 "dxeTXPushFrame Program dest address register fail");
3132 return status;
3133 }
3134 }
3135 else
3136 {
3137 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3138 "dxeTXPushFrame LONG Descriptor Format!!!");
3139 }
3140 }
3141#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3142
3143 /* Program Source address register
3144 * This address is already programmed into DXE Descriptor
3145 * But register also upadte */
3146 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3147 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3148 if(eWLAN_PAL_STATUS_SUCCESS != status)
3149 {
3150 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3151 "dxeTXPushFrame Program src address register fail");
3152 return status;
3153 }
3154 /* If descriptor format is SHORT */
3155 if(channelEntry->channelConfig.useShortDescFmt)
3156 {
3157 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3158 0);
3159 if(eWLAN_PAL_STATUS_SUCCESS != status)
3160 {
3161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3162 "dxeTXPushFrame Program dest address register fail");
3163 return status;
3164 }
3165 }
3166 else
3167 {
3168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3169 "dxeTXPushFrame LONG Descriptor Format!!!");
3170 }
3171
3172 /* Linked list Descriptor pointer */
3173 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3174 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3175 if(eWLAN_PAL_STATUS_SUCCESS != status)
3176 {
3177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3178 "dxeTXPushFrame Write DESC Address register fail");
3179 return status;
3180 }
3181 /* If descriptor format is SHORT */
3182 if(channelEntry->channelConfig.useShortDescFmt)
3183 {
3184 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3185 0);
3186 if(eWLAN_PAL_STATUS_SUCCESS != status)
3187 {
3188 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3189 "dxeTXPushFrame Program dest address register fail");
3190 return status;
3191 }
3192 }
3193 else
3194 {
3195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3196 "dxeTXPushFrame LONG Descriptor Format!!!");
3197 }
3198
3199 /* Transfer Size */
3200 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3201 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3202 xferSize);
3203 if(eWLAN_PAL_STATUS_SUCCESS != status)
3204 {
3205 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3206 "dxeTXPushFrame Write DESC Address register fail");
3207 return status;
3208 }
3209
3210 /* Everything is ready
3211 * Trigger to start DMA */
3212 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3213 channelEntry->extraConfig.chan_mask);
3214 if(eWLAN_PAL_STATUS_SUCCESS != status)
3215 {
3216 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3217 "dxeTXPushFrame Write Channel Ctrl Register fail");
3218 return status;
3219 }
3220
3221 /* Update channel head as next avaliable linked slot */
3222 channelEntry->headCtrlBlk = currentCtrlBlk;
3223
3224 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003225 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003226 return status;
3227}
3228
3229/*==========================================================================
3230 @ Function Name
3231 dxeTXCompFrame
3232
3233 @ Description
3234 TX Frame transfer complete event handler
3235
3236 @ Parameters
3237 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3238 DXE host driver main control block
3239 WLANDXE_ChannelCBType *channelEntry
3240 Channel specific control block
3241
3242 @ Return
3243 PAL_STATUS_T
3244===========================================================================*/
3245static wpt_status dxeTXCompFrame
3246(
3247 WLANDXE_CtrlBlkType *hostCtxt,
3248 WLANDXE_ChannelCBType *channelEntry
3249)
3250{
3251 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3252 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3253 WLANDXE_DescType *currentDesc = NULL;
3254 wpt_uint32 descCtrlValue = 0;
3255 unsigned int *lowThreshold = NULL;
3256
3257 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003258 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003259
3260 /* Sanity */
3261 if((NULL == hostCtxt) || (NULL == channelEntry))
3262 {
3263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3264 "dxeTXCompFrame Invalid ARG");
3265 return eWLAN_PAL_STATUS_E_INVAL;
3266 }
3267
3268 if(NULL == hostCtxt->txCompCB)
3269 {
3270 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3271 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003272 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003273 }
3274
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003275 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3276 if(eWLAN_PAL_STATUS_SUCCESS != status)
3277 {
3278 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3279 "dxeTXCompFrame Mutex Acquire fail");
3280 return status;
3281 }
3282
Jeff Johnson295189b2012-06-20 16:38:30 -07003283 currentCtrlBlk = channelEntry->tailCtrlBlk;
3284 currentDesc = currentCtrlBlk->linkedDesc;
3285
3286 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3287 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003288 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3289 if(eWLAN_PAL_STATUS_SUCCESS != status)
3290 {
3291 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3292 "dxeTXCompFrame Mutex Release fail");
3293 return status;
3294 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003295 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003296 }
3297
3298 /* */
3299 while(1)
3300 {
3301// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3302 descCtrlValue = currentDesc->descCtrl.ctrl;
3303 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3304 {
3305 /* caught up with head, bail out */
3306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3307 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3308 break;
3309 }
3310
3311 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
3312 channelEntry->numFreeDesc++;
3313 channelEntry->numRsvdDesc--;
3314
3315 /* Send Frame TX Complete notification with frame start fragment location */
3316 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3317 {
3318 hostCtxt->txCompletedFrames--;
3319#ifdef FEATURE_R33D
3320 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3321#else
3322 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3323 if (eWLAN_PAL_STATUS_SUCCESS != status)
3324 {
3325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3326 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003327 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3328 if(eWLAN_PAL_STATUS_SUCCESS != status)
3329 {
3330 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3331 "dxeTXCompFrame Mutex Release fail");
3332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003333 return status;
3334 }
3335#endif /* FEATURE_R33D */
3336 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3337 currentCtrlBlk->xfrFrame,
3338 eWLAN_PAL_STATUS_SUCCESS);
3339 channelEntry->numFragmentCurrentChain = 0;
3340 }
3341 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3342 currentDesc = currentCtrlBlk->linkedDesc;
3343
3344 /* Break condition
3345 * Head control block is the control block must be programed for the next TX
3346 * so, head control block is not programmed control block yet
3347 * if loop encounte head control block, stop to complete
3348 * in theory, COMP CB must be called already ??? */
3349 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3350 {
3351 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3352 "dxeTXCompFrame caught up with head ptr");
3353 break;
3354 }
3355 /* VALID Bit check ???? */
3356 }
3357
3358 /* Tail and Head Control block must be same */
3359 channelEntry->tailCtrlBlk = currentCtrlBlk;
3360
3361 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3362 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3363 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3364
3365 /* If specific channel hit low resource condition send notification to upper layer */
3366 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3367 (channelEntry->numFreeDesc > *lowThreshold))
3368 {
3369 /* Change it back if we raised it for fetching a remaining packet from TL */
3370 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3371 {
3372 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3373 }
3374
3375 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3376 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3377 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3378 channelEntry->channelType,
3379 eWLAN_PAL_TRUE);
3380 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003381 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003382 }
3383
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003384 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3385 if(eWLAN_PAL_STATUS_SUCCESS != status)
3386 {
3387 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3388 "dxeTXCompFrame Mutex Release fail");
3389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003390
3391 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003392 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003393 return status;
3394}
3395
3396/*==========================================================================
3397 @ Function Name
3398 dxeTXEventHandler
3399
3400 @ Description
3401 If DXE HW sends TX related interrupt, this event handler will be called
3402 Handle higher priority channel first
3403 Figureout why interrupt happen and call appropriate final even handler
3404 TX complete or error happen
3405
3406 @ Parameters
3407 void *msgPtr
3408 Even MSG
3409
3410 @ Return
3411 PAL_STATUS_T
3412===========================================================================*/
3413void dxeTXEventHandler
3414(
3415 wpt_msg *msgPtr
3416)
3417{
3418 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3419 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3420 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3421 wpt_uint32 intSrc = 0;
3422 wpt_uint32 chStat = 0;
3423 WLANDXE_ChannelCBType *channelCb = NULL;
3424
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003425 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003426 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003427
3428 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003429 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003430
3431 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003432 dxeCtxt->ucTxMsgCnt = 0;
3433
3434 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3435 {
3436 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3437 "wlan: TX COMP WLAN Driver re-loading in progress");
3438 return;
3439 }
3440
Jeff Johnson295189b2012-06-20 16:38:30 -07003441 /* Return from here if the RIVA is in IMPS, to avoid register access */
3442 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3443 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003444 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003445 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003446 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003447 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3448 if(eWLAN_PAL_STATUS_SUCCESS != status)
3449 {
3450 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003451 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003452 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003453
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003454 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3455 if(eWLAN_PAL_STATUS_SUCCESS != status)
3456 {
3457 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3458 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3459 }
3460
3461 if(((dxeCtxt->txCompletedFrames) &&
3462 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3463 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003464 {
3465 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3466 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3467 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003468 "TX COMP INT Enabled, remain TX frame count on ring %d",
3469 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003470 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3471 the posibility of a race*/
3472 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3473 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003474 else
3475 {
3476 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3477 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3478 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3479 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003481 return;
3482 }
3483
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003484 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003485 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3486 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3487 {
3488 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3489 "DXE already stopped in TX event handler. Just return");
3490 return;
3491 }
3492
Jeff Johnson295189b2012-06-20 16:38:30 -07003493 /* Disable device interrupt */
3494 /* Read whole interrupt mask register and exclusive only this channel int */
3495 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3496 &intSrc);
3497 if(eWLAN_PAL_STATUS_SUCCESS != status)
3498 {
3499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3500 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3501 return;
3502 }
3503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3504 "TX Event Handler INT Source 0x%x", intSrc);
3505
3506 /* Test High Priority Channel is the INT source or not */
3507 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3508 if(intSrc & (1 << channelCb->assignedDMAChannel))
3509 {
3510 status = dxeChannelCleanInt(channelCb, &chStat);
3511 if(eWLAN_PAL_STATUS_SUCCESS != status)
3512 {
3513 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3514 "dxeTXEventHandler INT Clean up fail");
3515 return;
3516 }
3517
3518 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3519 {
3520 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003521 "%11s : 0x%x Error Reported, Reload Driver",
3522 channelType[channelCb->channelType], chStat);
3523 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3524 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 }
3526 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3527 {
3528 /* Handle TX complete for high priority channel */
3529 status = dxeTXCompFrame(dxeCtxt,
3530 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003531 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003532 }
3533 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3534 {
3535 /* Handle TX complete for high priority channel */
3536 status = dxeTXCompFrame(dxeCtxt,
3537 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003538 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003539 }
3540 else
3541 {
3542 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3543 "dxeTXEventHandler TX HI status=%x", chStat);
3544 }
3545
3546 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3547 {
3548 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3549 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3550 }
3551
3552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3553 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3554 }
3555
3556 /* Test Low Priority Channel interrupt is enabled or not */
3557 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3558 if(intSrc & (1 << channelCb->assignedDMAChannel))
3559 {
3560 status = dxeChannelCleanInt(channelCb, &chStat);
3561 if(eWLAN_PAL_STATUS_SUCCESS != status)
3562 {
3563 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3564 "dxeTXEventHandler INT Clean up fail");
3565 return;
3566 }
3567
3568 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3569 {
3570 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003571 "%11s : 0x%x Error Reported, Reload Driver",
3572 channelType[channelCb->channelType], chStat);
3573 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3574 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003575 }
3576 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3577 {
3578 /* Handle TX complete for low priority channel */
3579 status = dxeTXCompFrame(dxeCtxt,
3580 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003581 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003582 }
3583 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3584 {
3585 /* Handle TX complete for low priority channel */
3586 status = dxeTXCompFrame(dxeCtxt,
3587 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003588 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 }
3590 else
3591 {
3592 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3593 "dxeTXEventHandler TX LO status=%x", chStat);
3594 }
3595
3596 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3597 {
3598 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3599 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3600 }
3601 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3602 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3603 }
3604
3605
3606#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3607 /* Test H2H TX Channel interrupt is enabled or not */
3608 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3609 if(intSrc & (1 << channelCb->assignedDMAChannel))
3610 {
3611 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3612 &chStat);
3613 if(eWLAN_PAL_STATUS_SUCCESS != status)
3614 {
3615 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3616 "dxeChannelCleanInt Read CH STAT register fail");
3617 return;
3618 }
3619
3620 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3621 {
3622 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003623 "%11s : 0x%x Error Reported, Reload Driver",
3624 channelType[channelCb->channelType], chStat);
3625 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3626 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 }
3628 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3629 {
3630 /* Handle TX complete for high priority channel */
3631 status = dxeTXCompFrame(dxeCtxt,
3632 channelCb);
3633 if(eWLAN_PAL_STATUS_SUCCESS != status)
3634 {
3635 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3636 "dxeTXEventHandler INT Clean up fail");
3637 return;
3638 }
3639 }
3640 else
3641 {
3642 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3643 "unexpected channel state %d", chStat);
3644 }
3645 }
3646#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3647
3648 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3649 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3650 {
3651 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3652 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003653 if(0 != dxeCtxt->txCompletedFrames)
3654 {
3655 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3656 "TX COMP INT Enabled, remain TX frame count on ring %d",
3657 dxeCtxt->txCompletedFrames);
3658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 }
3660
3661 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3662 the posibility of a race*/
3663 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3664
3665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003666 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003667 return;
3668}
3669
3670
3671/*==========================================================================
3672 @ Function Name
3673 dxeTXCompleteProcessing
3674
3675 @ Description
3676 If DXE HW sends TX related interrupt, this event handler will be called
3677 Handle higher priority channel first
3678 Figureout why interrupt happen and call appropriate final even handler
3679 TX complete or error happen
3680
3681 @ Parameters
3682 dxeCtxt DXE context
3683
3684 @ Return
3685 PAL_STATUS_T
3686===========================================================================*/
3687void dxeTXCompleteProcessing
3688(
3689 WLANDXE_CtrlBlkType *dxeCtxt
3690)
3691{
3692 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3693 WLANDXE_ChannelCBType *channelCb = NULL;
3694
3695 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003696 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003697
3698 /* Test High Priority Channel is the INT source or not */
3699 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3700
3701 /* Handle TX complete for high priority channel */
3702 status = dxeTXCompFrame(dxeCtxt, channelCb);
3703
3704 /* Test Low Priority Channel interrupt is enabled or not */
3705 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3706
3707 /* Handle TX complete for low priority channel */
3708 status = dxeTXCompFrame(dxeCtxt, channelCb);
3709
3710 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3711 ((dxeCtxt->txCompletedFrames > 0) ||
3712 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3713 {
3714 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3715 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3716 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003717 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003718 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3719 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3720 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3721 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
3722 }
3723
3724 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3725 the posibility of a race*/
3726 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3727
3728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003729 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 return;
3731}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003732
3733/*==========================================================================
3734 @ Function Name
3735 dxeTXReSyncDesc
3736
3737 @ Description
3738 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3739 And HW programmed descriptor.
3740 If any async happen between HW/SW TX stall will happen
3741
3742 @ Parameters
3743 void *msgPtr
3744 Message pointer to sync with TX thread
3745
3746 @ Return
3747 NONE
3748===========================================================================*/
3749void dxeTXReSyncDesc
3750(
3751 wpt_msg *msgPtr
3752)
3753{
3754 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3755 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3756 wpt_uint32 nextDescReg;
3757 WLANDXE_ChannelCBType *channelEntry;
3758 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3759 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003760 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003761
3762 if(NULL == msgContent)
3763 {
3764 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3765 "dxeTXReSyncDesc Invalid Control Block");
3766 return;
3767 }
3768
3769 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3770 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3771 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3772
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003773 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003774 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003775 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3776 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3777 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3778 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3779 &nextDescReg);
3780 /* Async detect without TX pending frame */
3781 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003782 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003783 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003784 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003785 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3786 "TX Async no Pending frame");
3787 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry);
3788 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!");
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003789 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003790 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003791 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003792 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003793 /* Async detect with some TX pending frames
3794 * next descriptor register should sync with first valid descriptor */
3795 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003796 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003797 validCtrlBlk = channelEntry->tailCtrlBlk;
3798 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003799 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003800 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3801 {
3802 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3803 {
3804 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3805 "TX Async");
3806 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3807 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3808 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3809 validCtrlBlk->linkedDescPhyAddr);
3810 }
3811 break;
3812 }
3813 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3814 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3815 {
3816 /* Finished to test till head control blcok, but could not find valid descriptor
3817 * from head to tail all descriptors are invalidated
3818 * host point of view head descriptor is next TX candidate
3819 * So, next descriptor control have to be programmed with head descriptor
3820 * check */
3821 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3822 {
3823 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08003824 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003825 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3826 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3827 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3828 validCtrlBlk->linkedDescPhyAddr);
3829 }
3830 break;
3831 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003832 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003833 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003834 }
3835
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003836 /* HW/SW descriptor resync is done.
3837 * Next if there are any valid descriptor in chain, Push to HW again */
3838 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3839 {
3840 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3841 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3842 {
3843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3844 "%11s : No TX Pending frame",
3845 channelType[channelEntry->channelType]);
3846 /* No Pending frame, Do nothing */
3847 }
3848 else
3849 {
3850 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3851 "%11s : TX Pending frame, process it",
3852 channelType[channelEntry->channelType]);
3853 validCtrlBlk = channelEntry->tailCtrlBlk;
3854 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3855 {
3856 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3857 {
3858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3859 "%11s : when exit IMPS found valid descriptor",
3860 channelType[channelEntry->channelType]);
3861
3862 /* Found valid descriptor, kick DXE */
3863 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3864 channelEntry->extraConfig.chan_mask);
3865 break;
3866 }
3867 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3868 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3869 {
3870 /* Finished to test till head control blcok, but could not find valid descriptor
3871 * from head to tail all descriptors are invalidated */
3872 break;
3873 }
3874 }
3875 }
3876 }
3877
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003878 wpalMemoryFree(msgPtr);
3879 return;
3880}
3881
Jeff Johnson295189b2012-06-20 16:38:30 -07003882/*==========================================================================
3883 @ Function Name
3884 dxeTXISR
3885
3886 @ Description
3887 TX interrupt ISR
3888 Platform will call this function if INT is happen
3889 This function must be registered into platform interrupt module
3890
3891 @ Parameters
3892 void *hostCtxt
3893 DXE host driver control context,
3894 pre registerd during interrupt registration
3895
3896 @ Return
3897 PAL_STATUS_T
3898===========================================================================*/
3899static void dxeTXISR
3900(
3901 void *hostCtxt
3902)
3903{
3904 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3905 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3906#ifdef FEATURE_R33D
3907 wpt_uint32 regValue;
3908#endif /* FEATURE_R33D */
3909
3910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003911 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003912
3913 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003914 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003915 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003916 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003917 /* Disable interrupt at here,
3918 IMPS or IMPS Pending state should not access RIVA register */
3919 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3920 if(eWLAN_PAL_STATUS_SUCCESS != status)
3921 {
3922 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3923 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3924 return;
3925 }
3926 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3927 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003928 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003929 return;
3930 }
3931
3932#ifdef FEATURE_R33D
3933 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3934 &regValue);
3935 if(eWLAN_PAL_STATUS_SUCCESS != status)
3936 {
3937 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3938 "dxeTXCompISR Read INT_SRC_RAW fail");
3939 return;
3940 }
3941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3942 "INT_SRC_RAW 0x%x", regValue);
3943 if(0 == regValue)
3944 {
3945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3946 "This is not DXE Interrupt, Reject it");
3947 return;
3948 }
3949#endif /* FEATURE_R33D */
3950
3951 /* Disable TX Complete Interrupt at here */
3952 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3953 if(eWLAN_PAL_STATUS_SUCCESS != status)
3954 {
3955 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3956 "dxeTXCompISR Disable TX complete interrupt fail");
3957 return;
3958 }
3959 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3960
3961
3962 if( dxeCtxt->ucTxMsgCnt )
3963 {
3964 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3965 "Avoiding serializing TX Complete event");
3966 return;
3967 }
3968
3969 dxeCtxt->ucTxMsgCnt = 1;
3970
3971 /* Serialize TX complete interrupt upon TX thread */
3972 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3973 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3974 dxeCtxt->txIsrMsg);
3975 if(eWLAN_PAL_STATUS_SUCCESS != status)
3976 {
3977 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3978 "dxeTXCompISR interrupt serialize fail status=%d", status);
3979 }
3980
3981 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003982 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003983 return;
3984}
3985
3986/*-------------------------------------------------------------------------
3987 * Global Function
3988 *-------------------------------------------------------------------------*/
3989/*==========================================================================
3990 @ Function Name
3991 WLANDXE_Open
3992
3993 @ Description
3994 Open host DXE driver, allocate DXE resources
3995 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
3996
3997 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08003998 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07003999
4000 @ Return
4001 pVoid DXE local module control block pointer
4002===========================================================================*/
4003void *WLANDXE_Open
4004(
4005 void
4006)
4007{
4008 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4009 unsigned int idx;
4010 WLANDXE_ChannelCBType *currentChannel = NULL;
4011 int smsmInitState;
4012#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4013 wpt_uint32 sIdx;
4014 WLANDXE_ChannelCBType *channel = NULL;
4015 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4016 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4017#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4018
4019 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004020 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004021
4022 /* This is temporary allocation */
4023 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4024 if(NULL == tempDxeCtrlBlk)
4025 {
4026 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4027 "WLANDXE_Open Control Block Alloc Fail");
4028 return NULL;
4029 }
4030 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4031
4032 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4033 if(eWLAN_PAL_STATUS_SUCCESS != status)
4034 {
4035 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4036 "WLANDXE_Open Common Configuration Fail");
4037 WLANDXE_Close(tempDxeCtrlBlk);
4038 return NULL;
4039 }
4040
4041 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4042 {
4043 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4044 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4045 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
4046 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
4047 {
4048 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
4049 }
4050 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
4051 {
4052 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
4053 }
4054 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
4055 {
4056 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
4057 }
4058 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
4059 {
4060 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
4061 }
4062#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4063 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
4064 {
4065 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
4066 }
4067 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
4068 {
4069 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
4070 }
4071#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4072
4073 /* Config individual channels from channel default setup table */
4074 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4075 currentChannel);
4076 if(eWLAN_PAL_STATUS_SUCCESS != status)
4077 {
4078 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4079 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4080 WLANDXE_Close(tempDxeCtrlBlk);
4081 return NULL;
4082 }
4083
4084 /* Allocate DXE Control Block will be used by host DXE driver */
4085 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4086 if(eWLAN_PAL_STATUS_SUCCESS != status)
4087 {
4088 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4089 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4090
4091 WLANDXE_Close(tempDxeCtrlBlk);
4092 return NULL;
4093 }
4094 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4095 if(eWLAN_PAL_STATUS_SUCCESS != status)
4096 {
4097 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4098 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4099 WLANDXE_Close(tempDxeCtrlBlk);
4100 return NULL;
4101 }
4102
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004103 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4104 dxeHealthMonitorTimeout,
4105 (void *)currentChannel);
4106 if(eWLAN_PAL_STATUS_SUCCESS != status)
4107 {
4108 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4109 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4110 WLANDXE_Close(tempDxeCtrlBlk);
4111 return NULL;
4112 }
4113
4114 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4115 if(NULL == currentChannel->healthMonitorMsg)
4116 {
4117 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4118 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4119 WLANDXE_Close(tempDxeCtrlBlk);
4120 return NULL;
4121 }
4122 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4123 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4124 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4125
Jeff Johnson295189b2012-06-20 16:38:30 -07004126 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4127 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4128 }
4129
4130 /* Allocate and Init RX READY ISR Serialize Buffer */
4131 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4132 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4133 {
4134 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4135 "WLANDXE_Open Alloc RX ISR Fail");
4136 WLANDXE_Close(tempDxeCtrlBlk);
4137 return NULL;
4138 }
4139 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4140 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4141 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4142
4143 /* Allocate and Init TX COMP ISR Serialize Buffer */
4144 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4145 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4146 {
4147 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4148 "WLANDXE_Open Alloc TX ISR Fail");
4149 WLANDXE_Close(tempDxeCtrlBlk);
4150 return NULL;
4151 }
4152 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4153 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4154 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4155
4156 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4157 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4158 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4159 {
4160 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4161 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4162 WLANDXE_Close(tempDxeCtrlBlk);
4163 return NULL;
4164 }
4165 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4166 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4167 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4168
4169 tempDxeCtrlBlk->freeRXPacket = NULL;
4170 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4171 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4172 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004173 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004174
4175 /* Initialize SMSM state
4176 * Init State is
4177 * Clear TX Enable
4178 * RING EMPTY STATE */
4179 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4180 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4181 if(0 != smsmInitState)
4182 {
4183 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4184 "SMSM Channel init fail %d", smsmInitState);
4185 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4186 {
4187 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4188 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004189 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4190 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004191 wpalMemoryFree(tempDxeCtrlBlk);
4192 return NULL;
4193 }
4194
4195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4196 "WLANDXE_Open Success");
4197 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004198 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004199 return (void *)tempDxeCtrlBlk;
4200}
4201
4202/*==========================================================================
4203 @ Function Name
4204 WLANDXE_ClientRegistration
4205
4206 @ Description
4207 Make callback functions registration into DXE driver from DXE driver client
4208
4209 @ Parameters
4210 pVoid pDXEContext : DXE module control block
4211 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4212 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4213 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4214 void *userContext : DXE Cliennt control block
4215
4216 @ Return
4217 wpt_status
4218===========================================================================*/
4219wpt_status WLANDXE_ClientRegistration
4220(
4221 void *pDXEContext,
4222 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4223 WLANDXE_TxCompleteCbType txCompleteCB,
4224 WLANDXE_LowResourceCbType lowResourceCB,
4225 void *userContext
4226)
4227{
4228 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4229 WLANDXE_CtrlBlkType *dxeCtxt;
4230
4231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004232 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004233
4234 /* Sanity */
4235 if(NULL == pDXEContext)
4236 {
4237 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4238 "WLANDXE_ClientRegistration Invalid DXE CB");
4239 return eWLAN_PAL_STATUS_E_INVAL;
4240 }
4241
4242 if(NULL == rxFrameReadyCB)
4243 {
4244 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4245 "WLANDXE_ClientRegistration Invalid RX READY CB");
4246 return eWLAN_PAL_STATUS_E_INVAL;
4247 }
4248
4249 if(NULL == txCompleteCB)
4250 {
4251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4252 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4253 return eWLAN_PAL_STATUS_E_INVAL;
4254 }
4255
4256 if(NULL == lowResourceCB)
4257 {
4258 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4259 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4260 return eWLAN_PAL_STATUS_E_INVAL;
4261 }
4262
4263 if(NULL == userContext)
4264 {
4265 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4266 "WLANDXE_ClientRegistration Invalid userContext");
4267 return eWLAN_PAL_STATUS_E_INVAL;
4268 }
4269
4270 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4271
4272 /* Assign */
4273 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4274 dxeCtxt->txCompCB = txCompleteCB;
4275 dxeCtxt->lowResourceCB = lowResourceCB;
4276 dxeCtxt->clientCtxt = userContext;
4277
4278 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004279 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004280 return status;
4281}
4282
4283/*==========================================================================
4284 @ Function Name
4285 WLANDXE_Start
4286
4287 @ Description
4288 Start Host DXE driver
4289 Initialize DXE channels and start channel
4290
4291 @ Parameters
4292 pVoid pDXEContext : DXE module control block
4293
4294 @ Return
4295 wpt_status
4296===========================================================================*/
4297wpt_status WLANDXE_Start
4298(
4299 void *pDXEContext
4300)
4301{
4302 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4303 wpt_uint32 idx;
4304 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4305
4306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004307 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004308
4309 /* Sanity */
4310 if(NULL == pDXEContext)
4311 {
4312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4313 "WLANDXE_Start Invalid DXE CB");
4314 return eWLAN_PAL_STATUS_E_INVAL;
4315 }
4316 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4317
4318 /* WLANDXE_Start called means DXE engine already initiates
4319 * And DXE HW is reset and init finished
4320 * But here to make sure HW is initialized, reset again */
4321 status = dxeEngineCoreStart(dxeCtxt);
4322 if(eWLAN_PAL_STATUS_SUCCESS != status)
4323 {
4324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4325 "WLANDXE_Start DXE HW init Fail");
4326 return status;
4327 }
4328
4329 /* Individual Channel Start */
4330 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4331 {
4332 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4333 "WLANDXE_Start Channel %s Start", channelType[idx]);
4334
4335 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4336 /* Make connection between DXE descriptor and DXE control block */
4337 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4338 if(eWLAN_PAL_STATUS_SUCCESS != status)
4339 {
4340 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4341 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4342 return status;
4343 }
4344
4345 /* Program each channel register with configuration arguments */
4346 status = dxeChannelInitProgram(dxeCtxt,
4347 &dxeCtxt->dxeChannel[idx]);
4348 if(eWLAN_PAL_STATUS_SUCCESS != status)
4349 {
4350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4351 "WLANDXE_Start %d Program DMA channel Fail", idx);
4352 return status;
4353 }
4354
4355 /* ??? Trigger to start DMA channel
4356 * This must be seperated from ??? */
4357 status = dxeChannelStart(dxeCtxt,
4358 &dxeCtxt->dxeChannel[idx]);
4359 if(eWLAN_PAL_STATUS_SUCCESS != status)
4360 {
4361 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4362 "WLANDXE_Start %d Channel Start Fail", idx);
4363 return status;
4364 }
4365 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4366 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4367 }
4368
4369 /* Register ISR to OS */
4370 /* Register TX complete interrupt into platform */
4371 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4372 dxeTXISR,
4373 dxeCtxt);
4374 if(eWLAN_PAL_STATUS_SUCCESS != status)
4375 {
4376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4377 "WLANDXE_Start TX comp interrupt registration Fail");
4378 return status;
4379 }
4380
4381 /* Register RX ready interrupt into platform */
4382 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4383 dxeRXISR,
4384 dxeCtxt);
4385 if(eWLAN_PAL_STATUS_SUCCESS != status)
4386 {
4387 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4388 "WLANDXE_Start RX Ready interrupt registration Fail");
4389 return status;
4390 }
4391
4392 /* Enable system level ISR */
4393 /* Enable RX ready Interrupt at here */
4394 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4395 if(eWLAN_PAL_STATUS_SUCCESS != status)
4396 {
4397 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4398 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4399 return status;
4400 }
4401
4402 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004403 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004404 return status;
4405}
4406
4407/*==========================================================================
4408 @ Function Name
4409 WLANDXE_TXFrame
4410
4411 @ Description
4412 Trigger frame transmit from host to RIVA
4413
4414 @ Parameters
4415 pVoid pDXEContext : DXE Control Block
4416 wpt_packet pPacket : transmit packet structure
4417 WDTS_ChannelType channel : TX channel
4418
4419 @ Return
4420 wpt_status
4421===========================================================================*/
4422wpt_status WLANDXE_TxFrame
4423(
4424 void *pDXEContext,
4425 wpt_packet *pPacket,
4426 WDTS_ChannelType channel
4427)
4428{
4429 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4430 WLANDXE_ChannelCBType *currentChannel = NULL;
4431 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4432 unsigned int *lowThreshold = NULL;
4433
4434 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004435 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004436
4437 /* Sanity */
4438 if(NULL == pDXEContext)
4439 {
4440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4441 "WLANDXE_Start Invalid DXE CB");
4442 return eWLAN_PAL_STATUS_E_INVAL;
4443 }
4444
4445 if(NULL == pPacket)
4446 {
4447 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4448 "WLANDXE_Start Invalid pPacket");
4449 return eWLAN_PAL_STATUS_E_INVAL;
4450 }
4451
4452 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4453 {
4454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4455 "WLANDXE_Start Invalid channel");
4456 return eWLAN_PAL_STATUS_E_INVAL;
4457 }
4458
4459 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4460
4461 currentChannel = &dxeCtxt->dxeChannel[channel];
4462
4463
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004464 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4465 if(eWLAN_PAL_STATUS_SUCCESS != status)
4466 {
4467 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4468 "WLANDXE_TxFrame Mutex Acquire fail");
4469 return status;
4470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004471
4472 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4473 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4474 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4475
4476 /* Decide have to activate TX complete event or not */
4477 switch(dxeCtxt->txCompInt.txIntEnable)
4478 {
4479 /* TX complete interrupt will be activated when low DXE resource */
4480 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4481 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4482 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4483 {
4484 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4485 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4486 channel,
4487 eWLAN_PAL_FALSE);
4488 }
4489 break;
4490
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004491 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004492 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4493 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4494 {
4495 currentChannel->numFrameBeforeInt++;
4496 }
4497 break;
4498
4499 /* TX complete interrupt will be activated periodically */
4500 case WLANDXE_TX_COMP_INT_TIMER:
4501 break;
4502 }
4503
4504 dxeCtxt->txCompletedFrames++;
4505
4506 /* Update DXE descriptor, this is frame based
4507 * if a frame consist of N fragments, N Descriptor will be programed */
4508 status = dxeTXPushFrame(currentChannel, pPacket);
4509 if(eWLAN_PAL_STATUS_SUCCESS != status)
4510 {
4511 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4512 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004513 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4514 if(eWLAN_PAL_STATUS_SUCCESS != status)
4515 {
4516 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4517 "WLANDXE_TxFrame Mutex Release fail");
4518 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004519 return status;
4520 }
4521
4522 /* If specific channel hit low resource condition, send notification to upper layer */
4523 if(currentChannel->numFreeDesc <= *lowThreshold)
4524 {
4525 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4526 channel,
4527 eWLAN_PAL_FALSE);
4528 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004529
4530 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4531 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4532 channelType[currentChannel->channelType],
4533 currentChannel->numRsvdDesc);
4534 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4535 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4536 wpalTimerStart(&currentChannel->healthMonitorTimer,
4537 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004538 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004539 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4540 if(eWLAN_PAL_STATUS_SUCCESS != status)
4541 {
4542 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4543 "WLANDXE_TxFrame Mutex Release fail");
4544 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004545
4546 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004547 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004548 return status;
4549}
4550
4551/*==========================================================================
4552 @ Function Name
4553 WLANDXE_CompleteTX
4554
4555 @ Description
4556 Informs DXE that the current series of Tx packets is complete
4557
4558 @ Parameters
4559 pContext pDXEContext : DXE Control Block
4560 ucTxResReq TX resource number required by TL/WDI
4561
4562 @ Return
4563 wpt_status
4564===========================================================================*/
4565wpt_status
4566WLANDXE_CompleteTX
4567(
4568 void* pContext,
4569 wpt_uint32 ucTxResReq
4570)
4571{
4572 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4573 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4574 WLANDXE_ChannelCBType *channelCb = NULL;
4575 wpt_boolean inLowRes;
4576
4577 /* Sanity Check */
4578 if( NULL == pContext )
4579 {
4580 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4581 "WLANDXE_CompleteTX invalid param");
4582 return eWLAN_PAL_STATUS_E_INVAL;
4583 }
4584
4585 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4586 inLowRes = channelCb->hitLowResource;
4587
4588 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4589 {
4590 /* Raise threshold temporarily if necessary */
4591 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4592
4593 if(eWLAN_PAL_FALSE == inLowRes)
4594 {
4595 /* Put the channel to low resource condition */
4596 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4597 WDTS_CHANNEL_TX_LOW_PRI,
4598 eWLAN_PAL_FALSE);
4599 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004600 wpalTimerStart(&channelCb->healthMonitorTimer,
4601 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 }
4603 }
4604
4605 /*Try to reclaim resources*/
4606 dxeTXCompleteProcessing(dxeCtxt);
4607
4608 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4609 because its fragment size is larger than DXE free resource. */
4610 if(0 < ucTxResReq)
4611 {
4612 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4613 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4614 {
4615 /* DXE has not been in low resource condition. DXE forces to kick off
4616 TX tranmit */
4617 if((eWLAN_PAL_FALSE == inLowRes) &&
4618 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4619 {
4620 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4621 WDTS_CHANNEL_TX_LOW_PRI,
4622 eWLAN_PAL_FALSE);
4623 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4624 WDTS_CHANNEL_TX_LOW_PRI,
4625 eWLAN_PAL_TRUE);
4626 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4627 }
4628 }
4629 else
4630 {
4631 /* DXE doesn't have enough free DXE resources. Put the channel
4632 to low resource condition. */
4633 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4634 {
4635 /* Put the channel to low resource condition */
4636 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4637 WDTS_CHANNEL_TX_LOW_PRI,
4638 eWLAN_PAL_FALSE);
4639 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004640 wpalTimerStart(&channelCb->healthMonitorTimer,
4641 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004642 }
4643 }
4644 }
4645
4646 return status;
4647}
4648
4649/*==========================================================================
4650 @ Function Name
4651 WLANDXE_Stop
4652
4653 @ Description
4654 Stop DXE channels and DXE engine operations
4655 Disable all channel interrupt
4656 Stop all channel operation
4657
4658 @ Parameters
4659 pVoid pDXEContext : DXE Control Block
4660
4661 @ Return
4662 wpt_status
4663===========================================================================*/
4664wpt_status WLANDXE_Stop
4665(
4666 void *pDXEContext
4667)
4668{
4669 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4670 wpt_uint32 idx;
4671 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4672
4673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004674 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004675
4676 /* Sanity */
4677 if(NULL == pDXEContext)
4678 {
4679 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4680 "WLANDXE_Stop Invalid DXE CB");
4681 return eWLAN_PAL_STATUS_E_INVAL;
4682 }
4683
4684 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4685 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4686 {
4687 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4688 if(eWLAN_PAL_STATUS_SUCCESS != status)
4689 {
4690 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4691 "WLANDXE_Stop Channel %d Stop Fail", idx);
4692 return status;
4693 }
4694 }
4695
4696 /* During Stop unregister interrupt */
4697 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4698 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4699
4700 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004701 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004702 return status;
4703}
4704
4705/*==========================================================================
4706 @ Function Name
4707 WLANDXE_Close
4708
4709 @ Description
4710 Close DXE channels
4711 Free DXE related resources
4712 DXE descriptor free
4713 Descriptor control block free
4714 Pre allocated RX buffer free
4715
4716 @ Parameters
4717 pVoid pDXEContext : DXE Control Block
4718
4719 @ Return
4720 wpt_status
4721===========================================================================*/
4722wpt_status WLANDXE_Close
4723(
4724 void *pDXEContext
4725)
4726{
4727 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4728 wpt_uint32 idx;
4729 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4730#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4731 wpt_uint32 sIdx;
4732 WLANDXE_ChannelCBType *channel = NULL;
4733 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4734 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4735#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4736
4737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004738 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004739
4740 /* Sanity */
4741 if(NULL == pDXEContext)
4742 {
4743 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4744 "WLANDXE_Stop Invalid DXE CB");
4745 return eWLAN_PAL_STATUS_E_INVAL;
4746 }
4747
4748 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4749 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4750 {
4751 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004752 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4753 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
4754 {
4755 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
4756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004757 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4758#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4759 channel = &dxeCtxt->dxeChannel[idx];
4760 crntDescCB = channel->headCtrlBlk;
4761 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4762 {
4763 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4764 wpalMemoryFree((void *)crntDescCB);
4765 crntDescCB = nextDescCB;
4766 if(NULL == crntDescCB)
4767 {
4768 break;
4769 }
4770 }
4771#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4772 }
4773
4774 if(NULL != dxeCtxt->rxIsrMsg)
4775 {
4776 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4777 }
4778 if(NULL != dxeCtxt->txIsrMsg)
4779 {
4780 wpalMemoryFree(dxeCtxt->txIsrMsg);
4781 }
4782 if(NULL != dxeCtxt->rxPktAvailMsg)
4783 {
4784 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4785 }
4786
4787 wpalMemoryFree(pDXEContext);
4788
4789 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004790 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004791 return status;
4792}
4793
4794/*==========================================================================
4795 @ Function Name
4796 WLANDXE_TriggerTX
4797
4798 @ Description
4799 TBD
4800
4801 @ Parameters
4802 pVoid pDXEContext : DXE Control Block
4803
4804 @ Return
4805 wpt_status
4806===========================================================================*/
4807wpt_status WLANDXE_TriggerTX
4808(
4809 void *pDXEContext
4810)
4811{
4812 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4813
4814 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004815 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004816
4817 /* TBD */
4818
4819 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004820 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 return status;
4822}
4823
4824/*==========================================================================
4825 @ Function Name
4826 dxeTxThreadSetPowerStateEventHandler
4827
4828 @ Description
4829 If WDI sends set power state req, this event handler will be called in Tx
4830 thread context
4831
4832 @ Parameters
4833 void *msgPtr
4834 Event MSG
4835
4836 @ Return
4837 None
4838===========================================================================*/
4839void dxeTxThreadSetPowerStateEventHandler
4840(
4841 wpt_msg *msgPtr
4842)
4843{
4844 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4845 WLANDXE_CtrlBlkType *dxeCtxt;
4846 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4847 WLANDXE_PowerStateType reqPowerState;
4848
4849 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004850 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004851
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4853 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4854 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4855
4856 switch(reqPowerState)
4857 {
4858 case WLANDXE_POWER_STATE_BMPS:
4859 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4860 {
4861 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4862 //based on amount of TX and RX activity - during this time any received
4863 // management frames will remain un-processed consuming RX buffers
4864 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4865 dxeCtxt->hostPowerState = reqPowerState;
4866 }
4867 else
4868 {
4869 status = eWLAN_PAL_STATUS_E_INVAL;
4870 }
4871 break;
4872 case WLANDXE_POWER_STATE_IMPS:
4873 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4874 {
4875 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4876 }
4877 else
4878 {
4879 status = eWLAN_PAL_STATUS_E_INVAL;
4880 }
4881 break;
4882 case WLANDXE_POWER_STATE_FULL:
4883 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4884 {
4885 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4886 }
4887 dxeCtxt->hostPowerState = reqPowerState;
4888 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4889 break;
4890 case WLANDXE_POWER_STATE_DOWN:
4891 WLANDXE_Stop((void *)dxeCtxt);
4892 break;
4893 default:
4894 //assert
4895 break;
4896 }
4897
4898 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4899 {
4900 dxeCtxt->setPowerStateCb(status,
4901 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4902 }
Ravali85acf6b2012-12-12 14:01:38 -08004903 else
4904 {
4905 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4906 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
4907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 /* Free MSG buffer */
4909 wpalMemoryFree(msgPtr);
4910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004911 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004912 return;
4913}
4914
4915
4916/*==========================================================================
4917 @ Function Name
4918 dxeRxThreadSetPowerStateEventHandler
4919
4920 @ Description
4921 If WDI sends set power state req, this event handler will be called in Rx
4922 thread context
4923
4924 @ Parameters
4925 void *msgPtr
4926 Event MSG
4927
4928 @ Return
4929 None
4930===========================================================================*/
4931void dxeRxThreadSetPowerStateEventHandler
4932(
4933 wpt_msg *msgPtr
4934)
4935{
4936 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4937
4938 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004939 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004940
4941 /* Now serialise the message through Tx thread also to make sure
4942 * no register access when RIVA is in powersave */
4943 /*Use the same message pointer just change the call back function */
4944 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4945 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4946 msgPtr);
4947 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4948 {
4949 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4950 "Tx thread Set power state req serialize fail status=%d",
4951 status, 0, 0);
4952 }
4953
4954 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004955 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004956}
4957
4958/*==========================================================================
4959 @ Function Name
4960 WLANDXE_SetPowerState
4961
4962 @ Description
4963 From Client let DXE knows what is the WLAN HW(RIVA) power state
4964
4965 @ Parameters
4966 pVoid pDXEContext : DXE Control Block
4967 WLANDXE_PowerStateType powerState
4968
4969 @ Return
4970 wpt_status
4971===========================================================================*/
4972wpt_status WLANDXE_SetPowerState
4973(
4974 void *pDXEContext,
4975 WDTS_PowerStateType powerState,
4976 WDTS_SetPSCbType cBack
4977)
4978{
4979 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4980 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4981 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004982 wpt_msg *rxCompMsg;
4983 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07004984
4985 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004986 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004987 if(NULL == pDXEContext)
4988 {
4989 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4990 "NULL pDXEContext passed by caller", 0, 0, 0);
4991 return eWLAN_PAL_STATUS_E_FAILURE;
4992 }
4993 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
4994
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 switch(powerState)
4996 {
4997 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004998 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
4999 {
5000 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5001 if(NULL == txDescReSyncMsg)
5002 {
5003 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5004 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5005 }
5006 else
5007 {
5008 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5009 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5010 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5011 txDescReSyncMsg);
5012 if(eWLAN_PAL_STATUS_SUCCESS != status)
5013 {
5014 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5015 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5016 }
5017 }
5018 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005019 hostPowerState = WLANDXE_POWER_STATE_FULL;
5020 break;
5021 case WDTS_POWER_STATE_BMPS:
5022 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5023 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5024 break;
5025 case WDTS_POWER_STATE_IMPS:
5026 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5027 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5028 break;
5029 case WDTS_POWER_STATE_DOWN:
5030 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5031 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5032 break;
5033 default:
5034 hostPowerState = WLANDXE_POWER_STATE_MAX;
5035 }
5036
5037 // A callback i.e. ACK back is needed only when we want to enable BMPS
5038 // and the data/management path is active because we want to ensure
5039 // DXE registers are not accessed when RIVA may be power-collapsed. So
5040 // we need a callback in enter_bmps_req (the request to RIVA is sent
5041 // only after ACK back from TX thread). A callback is not needed in
5042 // finish_scan_req during BMPS since data-path is resumed only in
5043 // finish_scan_rsp and no management frames are sent in between. No
5044 // callback is needed when going from BMPS enabled to BMPS suspended/
5045 // disabled when it is known that RIVA is awake and cannot enter power
5046 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5047 // init_scan_rsp
5048 if ( cBack )
5049 {
5050 //serialize through Rx thread
5051 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5052 if(NULL == rxCompMsg)
5053 {
5054 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5055 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5056 return eWLAN_PAL_STATUS_E_RESOURCES;
5057 }
5058
5059 /* Event type, where it must be defined???? */
5060 /* THIS MUST BE CLEARED ASAP
5061 txCompMsg->type = TX_COMPLETE; */
5062 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5063 rxCompMsg->pContext = pDxeCtrlBlk;
5064 rxCompMsg->val = hostPowerState;
5065 rxCompMsg->ptr = cBack;
5066 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5067 rxCompMsg);
5068 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5069 {
5070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5071 "Rx thread Set power state req serialize fail status=%d",
5072 status, 0, 0);
5073 }
5074 }
5075 else
5076 {
5077 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5078 {
5079 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5080 {
5081 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5082 }
5083 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5084 {
5085 /* Requested Full power from exit IMPS, reenable the interrupts*/
5086 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5087 {
5088 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5089 /* Enable RX interrupt at here, if new PS is not IMPS */
5090 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5091 if(eWLAN_PAL_STATUS_SUCCESS != status)
5092 {
5093 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005094 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 return status;
5096 }
5097 }
5098 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5099 {
5100 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005101 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 /* Enable RX interrupt at here, if new PS is not IMPS */
5103 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5104 if(eWLAN_PAL_STATUS_SUCCESS != status)
5105 {
5106 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005107 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 return status;
5109 }
5110 }
5111 }
5112 pDxeCtrlBlk->hostPowerState = hostPowerState;
5113 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5114 }
5115 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5116 {
5117 pDxeCtrlBlk->hostPowerState = hostPowerState;
5118 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5119 }
5120 else
5121 {
5122 HDXE_ASSERT(0);
5123 }
5124 }
5125
5126 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005127 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005128
5129 return status;
5130}
5131
5132/*==========================================================================
5133 @ Function Name
5134 WLANDXE_GetFreeTxDataResNumber
5135
5136 @ Description
5137 Returns free descriptor numbers for TX data channel (TX high priority)
5138
5139 @ Parameters
5140 pVoid pDXEContext : DXE Control Block
5141
5142 @ Return
5143 wpt_uint32 Free descriptor number of TX high pri ch
5144===========================================================================*/
5145wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5146(
5147 void *pDXEContext
5148)
5149{
5150 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005151 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005152
5153 if(NULL == pDXEContext)
5154 {
5155 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5156 "NULL parameter passed by caller", 0, 0, 0);
5157 return (0);
5158 }
5159
5160 return
5161 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5162}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005163
5164/*==========================================================================
5165 @ Function Name
5166 WLANDXE_ChannelDebug
5167
5168 @ Description
5169 Display DXE Channel debugging information
5170 User may request to display DXE channel snapshot
5171 Or if host driver detects any abnormal stcuk may display
5172
5173 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005174 displaySnapshot : Display DXE snapshot option
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005175 enableStallDetect : Enable stall detect feature
5176 This feature will take effect to data performance
5177 Not integrate till fully verification
5178
5179 @ Return
5180 NONE
5181
5182===========================================================================*/
5183void WLANDXE_ChannelDebug
5184(
5185 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005186 wpt_boolean enableStallDetect
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005187)
5188{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005189 wpt_msg *channelDebugMsg;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005190 wpt_uint32 regValue;
5191 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5192
5193 /* Debug Type 1, Display current snapshot */
5194 if(displaySnapshot)
5195 {
5196 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5197 * This will not simply wakeup RIVA
5198 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005199 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005200 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5201 "Host power state %d, RIVA power state %d",
5202 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
5203 /* Get free BD count */
5204 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
5205 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5206 "TX Pending frames count %d, Current available BD %d",
5207 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005208
5209 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5210 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005211 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5213 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5214 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005215 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005216
5217 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5218 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5219 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005220 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5222 "Tx thread Set power state req serialize fail status=%d",
5223 status, 0, 0);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005224 }
5225 }
5226
5227 /* Debug Type 2, toggling stall detect enable/disable */
5228 if(enableStallDetect)
5229 {
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5231 "DXE TX Stall detect",
5232 0, 0, 0);
5233 /* Start Stall detect timer and detect stall */
5234 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5235 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005236 }
5237 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005238}