blob: 720d64f257519508d5e773a09ddc95f6e5a8e917 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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
22/**=========================================================================
23
24 @file wlan_qct_dxe.c
25
26 @brief
27
28 This file contains the external API exposed by the wlan data transfer abstraction layer module.
29 Copyright (c) 2010-2011 QUALCOMM Incorporated.
30 All Rights Reserved.
31 Qualcomm Confidential and Proprietary
32========================================================================*/
33
34/*===========================================================================
35
36 EDIT HISTORY FOR FILE
37
38
39 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
41
42
43 $Header:$ $DateTime: $ $Author: $
44
45
46when who what, where, why
47-------- --- ----------------------------------------------------------
4808/03/10 schang Created module.
49
50===========================================================================*/
51
52/*===========================================================================
53
54 INCLUDE FILES FOR MODULE
55
56===========================================================================*/
57
58/*----------------------------------------------------------------------------
59 * Include Files
60 * -------------------------------------------------------------------------*/
61#include "wlan_qct_dxe.h"
62#include "wlan_qct_dxe_i.h"
63#include "wlan_qct_pal_device.h"
64#ifdef FEATURE_R33D
65#include "wlan_qct_pal_bus.h"
66#endif /* FEATURE_R33D */
67
68/*----------------------------------------------------------------------------
69 * Local Definitions
70 * -------------------------------------------------------------------------*/
71//#define WLANDXE_DEBUG_CH_INFO_DUMP
72
73/* Temporary configuration defines
74 * Have to find out permanent solution */
75#define T_WLANDXE_MAX_DESCRIPTOR_COUNT 40
76#define T_WLANDXE_MAX_FRAME_SIZE 2000
77#define T_WLANDXE_TX_INT_ENABLE_FCOUNT 1
78#define T_WLANDXE_MEMDUMP_BYTE_PER_LINE 16
79#define T_WLANDXE_MAX_RX_PACKET_WAIT 6000
Jeff Johnsone7245742012-09-05 17:12:55 -070080#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -070081
82/* This is temporary fot the compile
83 * WDI will release official version
84 * This must be removed */
85#define WDI_GET_PAL_CTX() NULL
86
87/*-------------------------------------------------------------------------
88 * Local Varables
89 *-------------------------------------------------------------------------*/
90/* This is temp, someone have to allocate for me, and must be part of global context */
91static WLANDXE_CtrlBlkType *tempDxeCtrlBlk = NULL;
92static char *channelType[WDTS_CHANNEL_MAX] =
93 {
94 "TX_LOW_PRI",
95 "TX_HIGH_PRI",
96 "RX_LOW_PRI",
97#ifndef WLANDXE_TEST_CHANNEL_ENABLE
98 "RX_HIGH_PRI",
99#else
100 "H2H_TEST_TX",
101 "H2H_TEST_RX"
102#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
103 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700104static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
106/*-------------------------------------------------------------------------
107 * External Function Proto Type
108 *-------------------------------------------------------------------------*/
109
110/*-------------------------------------------------------------------------
111 * Local Function Proto Type
112 *-------------------------------------------------------------------------*/
113static wpt_status dxeRXFrameSingleBufferAlloc
114(
115 WLANDXE_CtrlBlkType *dxeCtxt,
116 WLANDXE_ChannelCBType *channelEntry,
117 WLANDXE_DescCtrlBlkType *currentCtrlBlock
118);
119
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700120static wpt_status dxeNotifySmsm
121(
122 wpt_boolean kickDxe,
123 wpt_boolean ringEmpty
124);
125
Jeff Johnson295189b2012-06-20 16:38:30 -0700126/*-------------------------------------------------------------------------
127 * Local Function
128 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700129/*==========================================================================
130 @ Function Name
131 dxeChannelMonitor
132
133 @ Description
134
135 @ Parameters
136 WLANDXE_ChannelCBType *channelEntry
137 Channel specific control block
138
139 @ Return
140 wpt_status
141
142===========================================================================*/
143static wpt_status dxeChannelMonitor
144(
145 char *monitorDescription,
146 WLANDXE_ChannelCBType *channelEntry
147)
148{
149 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
150
Jeff Johnsone7245742012-09-05 17:12:55 -0700151 if((NULL == monitorDescription) || (NULL == channelEntry))
152 {
153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
154 "INVALID Input ARG");
155 return eWLAN_PAL_STATUS_E_INVAL;
156 }
157
158 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
159 {
160 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
161 "INVALID Channel type");
162 return eWLAN_PAL_STATUS_E_INVAL;
163 }
164
165 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700166 "=== %s Channel Number %d, Channel Type %s",
167 monitorDescription, channelEntry->assignedDMAChannel, channelType[channelEntry->channelType]);
Jeff Johnsone7245742012-09-05 17:12:55 -0700168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700169 "numDesc %d, numFreeDesc %d, numResvDesc %d",
170 channelEntry->numDesc, channelEntry->numFreeDesc, channelEntry->numRsvdDesc);
Jeff Johnsone7245742012-09-05 17:12:55 -0700171 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700172 "headCB 0x%x, next 0x%x, DESC 0x%x",
173 channelEntry->headCtrlBlk, channelEntry->headCtrlBlk->nextCtrlBlk, channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700174 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 "tailCB 0x%x, next 0x%x, DESC 0x%x",
176 channelEntry->tailCtrlBlk, channelEntry->tailCtrlBlk->nextCtrlBlk, channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 "headCB Order %d, tailCB Order %d",
179 channelEntry->headCtrlBlk->ctrlBlkOrder, channelEntry->tailCtrlBlk->ctrlBlkOrder);
Jeff Johnsone7245742012-09-05 17:12:55 -0700180 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700181 "numFragmentCurrentChain %d, numTotalFrame %d ===",
182 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
183
184 return status;
185}
186
Jeff Johnsone7245742012-09-05 17:12:55 -0700187#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700188/*==========================================================================
189 @ Function Name
190 dxeMemoryDump
191
192 @ Description
193
194 @ Parameters
195 WLANDXE_ChannelCBType *channelEntry
196 Channel specific control block
197
198 @ Return
199 wpt_status
200
201===========================================================================*/
202static wpt_status dxeMemoryDump
203(
204 wpt_uint8 *dumpPointer,
205 wpt_uint32 dumpSize,
206 char *dumpTarget
207)
208{
209 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
210 wpt_uint32 numBytes = 0;
211 wpt_uint32 idx;
212
Jeff Johnsone7245742012-09-05 17:12:55 -0700213 if((NULL == dumpPointer) ||
214 (NULL == dumpTarget))
215 {
216 return status;
217 }
218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
220 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
222 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
223
224 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
225 for(idx = 0; idx < dumpSize; idx++)
226 {
227 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
228 "0x%2x ", dumpPointer[idx]);
229 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
230 {
231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
232 }
233 }
234 if(0 != numBytes)
235 {
236 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
237 }
238 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
239 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
240
241 return status;
242}
Jeff Johnsone7245742012-09-05 17:12:55 -0700243#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700244
245/*==========================================================================
246 @ Function Name
247 dxeDescriptorDump
248
249 @ Description
250
251 @ Parameters
252 WLANDXE_ChannelCBType *channelEntry
253 Channel specific control block
254
255 @ Return
256 wpt_status
257
258===========================================================================*/
259wpt_status dxeDescriptorDump
260(
261 WLANDXE_ChannelCBType *channelEntry,
262 WLANDXE_DescType *targetDesc,
263 wpt_uint32 fragmentOrder
264)
265{
266 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
267
268
Jeff Johnsone7245742012-09-05 17:12:55 -0700269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700271 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700272 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700274 fragmentOrder + 1,
275 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700276
Jeff Johnsone7245742012-09-05 17:12:55 -0700277 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 "CTRL WORD 0x%x, TransferSize %d",
279 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
280 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700281 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
283 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
284 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
285 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700286 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
288
289 return status;
290}
291
292/*==========================================================================
293 @ Function Name
294 dxeChannelRegisterDump
295
296 @ Description
297
298 @ Parameters
299 WLANDXE_ChannelCBType *channelEntry
300 Channel specific control block
301
302 @ Return
303 wpt_status
304
305===========================================================================*/
306wpt_status dxeChannelRegisterDump
307(
308 WLANDXE_ChannelCBType *channelEntry,
309 char *dumpTarget
310)
311{
312 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
313 wpt_uint32 regValue = 0;
314
Jeff Johnsone7245742012-09-05 17:12:55 -0700315 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 "%s Channel register dump for %s, base address 0x%x",
317 channelType[channelEntry->channelType],
318 dumpTarget,
319 channelEntry->channelRegister.chDXEBaseAddr);
320 regValue = 0;
321 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700322 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 "Control Register 0x%x", regValue);
324
325 regValue = 0;
326 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700327 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 "Status Register 0x%x", regValue);
329 regValue = 0;
330
331 wpalReadRegister(channelEntry->channelRegister.chDXESadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700332 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 "Source Address Register 0x%x", regValue);
334 regValue = 0;
335
336 wpalReadRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700337 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 "Destination Address Register 0x%x", regValue);
339 regValue = 0;
340
341 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700342 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700343 "Last Descriptor Address Register 0x%x", regValue);
344
345 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &regValue);
346 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
347 "Next Descriptor Address Register 0x%x", regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -0700348
349 return status;
350}
Jeff Johnsone7245742012-09-05 17:12:55 -0700351
352/*==========================================================================
353 @ Function Name
354 dxeChannelAllDescDump
355
356 @ Description
357 Dump all DXE descriptors within assigned channe;
358
359 @ Parameters
360 WLANDXE_ChannelCBType *channelEntry
361
362 @ Return
363 NONE
364
365===========================================================================*/
366void dxeChannelAllDescDump
367(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700368 WLANDXE_ChannelCBType *channelEntry,
369 WDTS_ChannelType channel
Jeff Johnsone7245742012-09-05 17:12:55 -0700370)
371{
372 wpt_uint32 channelLoop;
373 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700374 wpt_uint32 previousCtrlValue = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700375
376 targetCtrlBlk = channelEntry->headCtrlBlk;
377
378 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700379 "%11s, head desc ctrl 0x%x, head order %d",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700380 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700381 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
382 targetCtrlBlk->ctrlBlkOrder);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700383 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
384
385 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
386 (WDTS_CHANNEL_RX_HIGH_PRI == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700387 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700388 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700389 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700390 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
391 {
392 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
393 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
394 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
395 }
396 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
397 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700398 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700399 }
400 else
401 {
402 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
403 {
404 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
405 {
406 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
407 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
408 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
409 }
410 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
411 }
412 }
413 return;
414}
415
416/*==========================================================================
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700417 @ Function Name
418 dxeTxChannelsStatus
419
420 @ Description
421 Dump TX Channels status partailly, not all
422
423 @ Parameters
424 msgPtr Serailize MSG
425
426 @ Return
427 NONE
428
429===========================================================================*/
430void dxeTxChannelsStatus
431(
432 wpt_msg *msgPtr
433)
434{
435 WLANDXE_ChannelCBType *channelEntry;
436 wpt_uint32 ctrlRegValue = 0;
437 wpt_uint32 statRegValue = 0;
438 wpt_uint8 channelLoop;
439
440 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
441
442 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
443 {
444 channelEntry = &tempDxeCtrlBlk->dxeChannel[channelLoop];
445 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &ctrlRegValue);
446 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &statRegValue);
447 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
448 "%11s, ctrl reg 0x%x, stat reg 0x%x, head order %d, tail order %d, numFree %d, numRsv %d",
449 channelType[channelEntry->channelType],
450 ctrlRegValue, statRegValue,
451 channelEntry->headCtrlBlk->ctrlBlkOrder,
452 channelEntry->tailCtrlBlk->ctrlBlkOrder,
453 channelEntry->numFreeDesc,
454 channelEntry->numRsvdDesc);
455 dxeChannelAllDescDump(channelEntry, channelLoop);
456 }
457
458 return;
459}
460
461/*==========================================================================
462 @ Function Name
463 dxeRxChannelsStatus
464
465 @ Description
466 Dump RX Channels status partailly, not all
467
468 @ Parameters
469 msgPtr Serailize MSG
470
471 @ Return
472 NONE
473
474===========================================================================*/
475void dxeRxChannelsStatus
476(
477 wpt_msg *msgPtr
478)
479{
480 WLANDXE_ChannelCBType *channelEntry;
481 wpt_uint32 ctrlRegValue = 0;
482 wpt_uint32 statRegValue = 0;
483 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
484 wpt_uint8 channelLoop;
485
486 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
487
488 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
489 {
490 channelEntry = &tempDxeCtrlBlk->dxeChannel[channelLoop];
491 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &ctrlRegValue);
492 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &statRegValue);
493 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
494 "%11s, ctrl reg 0x%x, stat reg 0x%x",
495 channelType[channelEntry->channelType],
496 ctrlRegValue, statRegValue);
497 dxeChannelAllDescDump(channelEntry, channelLoop);
498 }
499
500 msgPtr->callback = dxeTxChannelsStatus;
501 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
502 msgPtr);
503 if (eWLAN_PAL_STATUS_SUCCESS != status)
504 {
505 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
506 "Tx thread partial state dump req serialize fail status=%d",
507 status, 0, 0);
508 }
509 return;
510}
511
512/*==========================================================================
513 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700514 dxeTxThreadChannelDebugHandler
515
516 @ Description
517 Dump TX channel information
518
519 @ Parameters
520 Wwpt_msg *msgPtr
521
522 @ Return
523 NONE
524
525===========================================================================*/
526void dxeTxThreadChannelDebugHandler
527(
528 wpt_msg *msgPtr
529)
530{
531 wpt_uint8 channelLoop;
532
533 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
534 "%s Enter", __FUNCTION__);
535
536 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
537 * This will not simply wakeup RIVA
538 * Just incase TX not wanted stuck, Trigger TX again */
539 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
540 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
541 {
542 dxeChannelMonitor("******** Get Descriptor Snapshot ",
543 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
544 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700545 tempDxeCtrlBlk->dxeChannel[channelLoop].tailCtrlBlk->linkedDesc,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700546 0);
547 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
548 "Abnormal successive empty interrupt");
549 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700550 }
551
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
553 "%s Exit", __FUNCTION__);
554 return;
555}
556
557/*==========================================================================
558 @ Function Name
559 dxeRxThreadChannelDebugHandler
560
561 @ Description
562 Dump RX channel information
563
564 @ Parameters
565 Wwpt_msg *msgPtr
566
567 @ Return
568 NONE
569
570===========================================================================*/
571void dxeRxThreadChannelDebugHandler
572(
573 wpt_msg *msgPtr
574)
575{
576 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
577 wpt_uint8 channelLoop;
578
579 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
580 "%s Enter", __FUNCTION__);
581
582 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
583 * This will not simply wakeup RIVA
584 * Just incase TX not wanted stuck, Trigger TX again */
585 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
586 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
587 {
588 dxeChannelMonitor("******** Get Descriptor Snapshot ",
589 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
590 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
591 tempDxeCtrlBlk->dxeChannel[channelLoop].headCtrlBlk->linkedDesc,
592 0);
593 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
594 "Abnormal successive empty interrupt");
595 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
596 }
597
598 /* Now serialise the message through Tx thread also to make sure
599 * no register access when RIVA is in powersave */
600 /*Use the same message pointer just change the call back function */
601 msgPtr->callback = dxeTxThreadChannelDebugHandler;
602 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
603 msgPtr);
604 if ( eWLAN_PAL_STATUS_SUCCESS != status )
605 {
606 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700607 "Tx thread state dump req serialize fail status=%d",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700608 status, 0, 0);
609 }
610
611 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
612 "%s Exit", __FUNCTION__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700613 return;
614}
Jeff Johnson295189b2012-06-20 16:38:30 -0700615
616/*==========================================================================
617 @ Function Name
618 dxeCtrlBlkAlloc
619
620 @ Description
621 Allocate DXE Control block
622 DXE control block will used by Host DXE driver only, internal structure
623 Will make ring linked list
624
625 @ Parameters
626 WLANDXE_CtrlBlkType *dxeCtrlBlk,
627 DXE host driver main control block
628 WLANDXE_ChannelCBType *channelEntry
629 Channel specific control block
630
631 @ Return
632 wpt_status
633
634===========================================================================*/
635static wpt_status dxeCtrlBlkAlloc
636(
637 WLANDXE_CtrlBlkType *dxeCtrlBlk,
638 WLANDXE_ChannelCBType *channelEntry
639)
640{
641 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
642 unsigned int idx, fIdx;
643 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
644 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
645 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
646 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
647
648 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
649 "%s Enter", __FUNCTION__);
650
651 /* Sanity check */
652 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
653 {
654 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
655 "dxeCtrlBlkAlloc Channel Entry is not valid");
656 return eWLAN_PAL_STATUS_E_INVAL;
657 }
658
659 /* Allocate pre asigned number of control blocks */
660 for(idx = 0; idx < channelEntry->numDesc; idx++)
661 {
662 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
663 if(NULL == currentCtrlBlk)
664 {
665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
666 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
667 channelEntry->channelType);
668 freeCtrlBlk = channelEntry->headCtrlBlk;
669 for(fIdx = 0; fIdx < idx; fIdx++)
670 {
671 if(NULL == freeCtrlBlk)
672 {
673 break;
674 }
675
676 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
677 wpalMemoryFree((void *)freeCtrlBlk);
678 freeCtrlBlk = nextCtrlBlk;
679 }
680 return eWLAN_PAL_STATUS_E_FAULT;
681 }
682
683 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
684 /* Initialize common elements first */
685 currentCtrlBlk->xfrFrame = NULL;
686 currentCtrlBlk->linkedDesc = NULL;
687 currentCtrlBlk->linkedDescPhyAddr = 0;
688 currentCtrlBlk->ctrlBlkOrder = idx;
689
690 /* This is the first control block allocated
691 * Next Control block is not allocated yet
692 * head and tail must be first control block */
693 if(0 == idx)
694 {
695 currentCtrlBlk->nextCtrlBlk = NULL;
696 channelEntry->headCtrlBlk = currentCtrlBlk;
697 channelEntry->tailCtrlBlk = currentCtrlBlk;
698 }
699 /* This is not first, not last control block
700 * previous control block may has next linked block */
701 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
702 {
703 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
704 }
705 /* This is last control blocl
706 * next control block for the last control block is head, first control block
707 * then whole linked list made RING */
708 else if((channelEntry->numDesc - 1) == idx)
709 {
710 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
711 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
712 }
713 else
714 {
715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
716 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
717 channelEntry->channelType);
718 wpalMemoryFree(currentCtrlBlk);
719 return eWLAN_PAL_STATUS_E_FAULT;
720 }
721
722 prevCtrlBlk = currentCtrlBlk;
723 channelEntry->numFreeDesc++;
724 }
725
726 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __FUNCTION__);
727 return status;
728}
729
730/*==========================================================================
731 @ Function Name
732 dxeDescLinkAlloc
733
734 @ Description
735 Allocate DXE descriptor
736 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
737 Will make RING linked list
738 Will be linked with Descriptor control block one by one
739
740 @ Parameters
741 WLANDXE_CtrlBlkType *dxeCtrlBlk,
742 DXE host driver main control block
743 WLANDXE_ChannelCBType *channelEntry
744 Channel specific control block
745 @ Return
746 wpt_status
747
748===========================================================================*/
749static wpt_status dxeDescAllocAndLink
750(
751 WLANDXE_CtrlBlkType *dxeCtrlBlk,
752 WLANDXE_ChannelCBType *channelEntry
753)
754{
755 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
756 WLANDXE_DescType *currentDesc = NULL;
757 WLANDXE_DescType *prevDesc = NULL;
758 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
759 unsigned int idx;
760 void *physAddress = NULL;
761#ifdef WLANDXE_TEST_CHANNEL_ENABLE
762 WLANDXE_ChannelCBType *testTXChannelCB = &dxeCtrlBlk->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
763 WLANDXE_DescCtrlBlkType *currDescCtrlBlk = testTXChannelCB->headCtrlBlk;
764#endif /* WLANDXE_TEST_CHANNEL_ENABLE*/
765
766 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
767 "%s Enter", __FUNCTION__);
768
769 /* Sanity Check */
770 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
771 {
772 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
773 "dxeDescLinkAlloc Channel Entry is not valid");
774 return eWLAN_PAL_STATUS_E_INVAL;
775 }
776
777 currentCtrlBlk = channelEntry->headCtrlBlk;
778
779#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
780 /* allocate all DXE descriptors for this channel in one chunk */
781 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
782 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
783 &physAddress);
784 if(NULL == channelEntry->descriptorAllocation)
785 {
786 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
787 "dxeDescLinkAlloc Descriptor Alloc Fail");
788 return eWLAN_PAL_STATUS_E_RESOURCES;
789 }
790 currentDesc = channelEntry->descriptorAllocation;
791#endif
792
793 /* Allocate pre asigned number of descriptor */
794 for(idx = 0; idx < channelEntry->numDesc; idx++)
795 {
796#ifndef FEATURE_R33D
797#ifndef WLANDXE_TEST_CHANNEL_ENABLE
798 // descriptors were allocated in a chunk -- use the current one
799 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
800 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
801 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
802#else
803 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
804 {
805 // allocate a descriptor
806 currentDesc = (WLANDXE_DescType *)wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType),
807 &physAddress);
808 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
809 }
810 else
811 {
812 currentDesc = currDescCtrlBlk->linkedDesc;
813 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
814 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
815 }
816#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
817#else
818#ifndef WLANDXE_TEST_CHANNEL_ENABLE
819 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
820 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
821 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
822 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
823#else
824 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
825 {
826 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
827 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
828 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
829 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
830 }
831 else
832 {
833 currentDesc = currDescCtrlBlk->linkedDesc;
834 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
835 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
836 }
837#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
838#endif /* FEATURE_R33D */
839 if(NULL == currentDesc)
840 {
841 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
842 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
843 channelEntry->channelType);
844 return eWLAN_PAL_STATUS_E_FAULT;
845 }
846
847 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
848 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
849 {
850 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
851 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
852 }
853 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
854 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
855 {
856 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
857 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
858 }
859 else
860 {
861 /* Just in case. H2H Test RX channel, do nothing
862 * By Definition this must not happen */
863 }
864
865 currentCtrlBlk->linkedDesc = currentDesc;
866 currentCtrlBlk->linkedDescPhyAddr = (unsigned int)physAddress;
867 /* First descriptor, next none
868 * descriptor bottom location is first descriptor address */
869 if(0 == idx)
870 {
871 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
872 channelEntry->DescBottomLoc = currentDesc;
873 channelEntry->descBottomLocPhyAddr = (unsigned int)physAddress;
874 }
875 /* Not first, not last descriptor
876 * may make link for previous descriptor with current descriptor
877 * ENDIAN SWAP needed ????? */
878 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
879 {
880 prevDesc->dxedesc.dxe_short_desc.phyNextL =
881 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
882 }
883 /* Last descriptor
884 * make a ring by asign next pointer as first descriptor
885 * ENDIAN SWAP NEEDED ??? */
886 else if((channelEntry->numDesc - 1) == idx)
887 {
888 prevDesc->dxedesc.dxe_short_desc.phyNextL =
889 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
890 currentDesc->dxedesc.dxe_short_desc.phyNextL =
891 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)channelEntry->headCtrlBlk->linkedDescPhyAddr);
892 }
893
894 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
895 * Pre allocated and physical address must be assigned into
896 * Corresponding DXE Descriptor */
897#ifdef WLANDXE_TEST_CHANNEL_ENABLE
898 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
899 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
900 (WDTS_CHANNEL_H2H_TEST_RX == channelEntry->channelType))
901#else
902 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
903 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
904#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
905 {
906 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
907 channelEntry,
908 currentCtrlBlk);
909 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
910 {
911 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
912 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
913 channelEntry->channelType);
914 return status;
915 }
916 --channelEntry->numFreeDesc;
917 }
918
919 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
920 prevDesc = currentDesc;
921
922#ifndef FEATURE_R33D
923#ifndef WLANDXE_TEST_CHANNEL_ENABLE
924 // advance to the next pre-allocated descriptor in the chunk
925 currentDesc++;
926 physAddress = ((wpt_int8 *)physAddress) + sizeof(WLANDXE_DescType);
927#endif
928#endif
929 }
930
931 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
932 "%s Exit", __FUNCTION__);
933 return status;
934}
935
936/*==========================================================================
937 @ Function Name
938
939 @ Description
940
941 @ Parameters
942
943 @ Return
944 wpt_status
945
946===========================================================================*/
947static wpt_status dxeSetInterruptPath
948(
949 WLANDXE_CtrlBlkType *dxeCtrlBlk
950)
951{
952 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
953 wpt_uint32 interruptPath = 0;
954 wpt_uint32 idx;
955 WLANDXE_ChannelCBType *channelEntry = NULL;
956
957 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
958 "%s Enter", __FUNCTION__);
959
960 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
961 {
962 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
963#ifdef WLANDXE_TEST_CHANNEL_ENABLE
964 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
965 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) ||
966 (WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType))
967#else
968 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
969 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
970#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
971 {
972 interruptPath |= (1 << channelEntry->assignedDMAChannel);
973 }
974 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
975 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
976 {
977 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
978 }
979 else
980 {
981 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
982 "H2H TEST RX???? %d", channelEntry->channelType);
983 }
984 }
985 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
986 "Interrupt Path Must be 0x%x", interruptPath);
987 dxeCtrlBlk->interruptPath = interruptPath;
988 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
989
990 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
991 "%s Exit", __FUNCTION__);
992 return status;
993}
994
995/*==========================================================================
996 @ Function Name
997 dxeEngineCoreStart
998
999 @ Description
1000 Trigger to start RIVA DXE Hardware
1001
1002 @ Parameters
1003 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1004 DXE host driver main control block
1005
1006 @ Return
1007 wpt_status
1008
1009===========================================================================*/
1010static wpt_status dxeEngineCoreStart
1011(
1012 WLANDXE_CtrlBlkType *dxeCtrlBlk
1013)
1014{
1015 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1016 wpt_uint32 registerData = 0;
1017
1018 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1019 "%s Enter", __FUNCTION__);
1020
1021 /* START This core init is not needed for the integrated system */
1022 /* Reset First */
1023 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1024 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1025 registerData);
1026
1027 registerData = WLANDXE_DMA_CSR_EN_MASK;
1028 registerData |= WLANDXE_DMA_CSR_ECTR_EN_MASK;
1029 registerData |= WLANDXE_DMA_CSR_TSTMP_EN_MASK;
1030 registerData |= WLANDXE_DMA_CSR_H2H_SYNC_EN_MASK;
1031
1032 registerData = 0x00005c89;
1033 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1034 registerData);
1035
1036 /* Is This needed?
1037 * Not sure, revisit with integrated system */
1038 /* END This core init is not needed for the integrated system */
1039
1040 dxeSetInterruptPath(dxeCtrlBlk);
1041 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1042 "%s Exit", __FUNCTION__);
1043 return status;
1044}
1045
1046/*==========================================================================
1047 @ Function Name
1048 dxeChannelInitProgram
1049
1050 @ Description
1051 Program RIVA DXE engine register with initial value
1052 What must be programmed
1053 - Source Address (SADRL, chDXESadrlRegAddr)
1054 - Destination address (DADRL, chDXEDadrlRegAddr)
1055 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1056 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1057
1058 Not need to program now
1059 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1060 TX : Have to program to trigger send out frame
1061 RX : programmed by DXE engine
1062
1063 @ Parameters
1064 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1065 DXE host driver main control block
1066 WLANDXE_ChannelCBType *channelEntry
1067 Channel specific control block
1068 @ Return
1069 wpt_status
1070
1071===========================================================================*/
1072static wpt_status dxeChannelInitProgram
1073(
1074 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1075 WLANDXE_ChannelCBType *channelEntry
1076)
1077{
1078 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1079 wpt_uint32 idx;
1080 WLANDXE_DescType *currentDesc = NULL;
1081 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1082
1083 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1084 "%s Enter", __FUNCTION__);
1085
1086 /* Sanity Check */
1087 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1088 {
1089 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1090 "dxeChannelInitProgram Channel Entry is not valid");
1091 return eWLAN_PAL_STATUS_E_INVAL;
1092 }
1093
1094 /* Program Source address and destination adderss */
1095 if(!channelEntry->channelConfig.useShortDescFmt)
1096 {
1097 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1098 "dxeChannelInitProgram Long Descriptor not support yet");
1099 return eWLAN_PAL_STATUS_E_FAILURE;
1100 }
1101
1102 /* Common register area */
1103 /* Next linked list Descriptor pointer */
1104 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1105 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1106 if(eWLAN_PAL_STATUS_SUCCESS != status)
1107 {
1108 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1109 "dxeChannelInitProgram Write DESC Address register fail");
1110 return status;
1111 }
1112
1113 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1114 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1115 {
1116 /* Program default registers */
1117 /* TX DMA channel, DMA destination address is work Q */
1118 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1119 channelEntry->channelConfig.refWQ);
1120 if(eWLAN_PAL_STATUS_SUCCESS != status)
1121 {
1122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1123 "dxeChannelInitProgram Write TX DAddress register fail");
1124 return status;
1125 }
1126 }
1127 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1128 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1129 {
1130 /* Initialize Descriptor control Word First */
1131 currentCtrlBlk = channelEntry->headCtrlBlk;
1132 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1133 {
1134 currentDesc = currentCtrlBlk->linkedDesc;
1135 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1136 }
1137
1138 /* RX DMA channel, DMA source address is work Q */
1139 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1140 channelEntry->channelConfig.refWQ);
1141 if(eWLAN_PAL_STATUS_SUCCESS != status)
1142 {
1143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1144 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1145 return status;
1146 }
1147
1148 /* RX DMA channel, Program pre allocated destination Address */
1149 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1150 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1151 if(eWLAN_PAL_STATUS_SUCCESS != status)
1152 {
1153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1154 "dxeChannelInitProgram Write RX DAddress register fail");
1155 return status;
1156 }
1157
1158 /* RX Channels, default Control registers MUST BE ENABLED */
1159 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1160 channelEntry->extraConfig.chan_mask);
1161 if(eWLAN_PAL_STATUS_SUCCESS != status)
1162 {
1163 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1164 "dxeChannelInitProgram Write RX Control register fail");
1165 return status;
1166 }
1167 }
1168 else
1169 {
1170 /* H2H test channel, not use work Q */
1171 /* Program pre allocated destination Address */
1172 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1173 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1174 if(eWLAN_PAL_STATUS_SUCCESS != status)
1175 {
1176 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1177 "dxeChannelInitProgram Write RX DAddress register fail");
1178 return status;
1179 }
1180 }
1181
1182 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1183 "%s Exit", __FUNCTION__);
1184 return status;
1185}
1186
1187
1188/*==========================================================================
1189 @ Function Name
1190 dxeChannelStart
1191
1192 @ Description
1193 Start Specific Channel
1194
1195 @ Parameters
1196 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1197 DXE host driver main control block
1198 WLANDXE_ChannelCBType *channelEntry
1199 Channel specific control block
1200
1201 @ Return
1202 wpt_status
1203
1204===========================================================================*/
1205static wpt_status dxeChannelStart
1206(
1207 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1208 WLANDXE_ChannelCBType *channelEntry
1209)
1210{
1211 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1212 wpt_uint32 regValue = 0;
1213 wpt_uint32 intMaskVal = 0;
1214
1215 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1216 "%s Enter", __FUNCTION__);
1217
1218 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1219 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1220
1221 /* Enable individual channel
1222 * not to break current channel setup, first read register */
1223 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1224 &regValue);
1225 if(eWLAN_PAL_STATUS_SUCCESS != status)
1226 {
1227 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1228 "dxeChannelStart Read Channel Enable register fail");
1229 return status;
1230 }
1231
1232 /* Enable Channel specific Interrupt */
1233 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1234 &intMaskVal);
1235 if(eWLAN_PAL_STATUS_SUCCESS != status)
1236 {
1237 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1238 "dxeChannelStart Read INT_MASK register fail");
1239 return status;
1240 }
1241 intMaskVal |= channelEntry->extraConfig.intMask;
1242 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1243 intMaskVal);
1244 if(eWLAN_PAL_STATUS_SUCCESS != status)
1245 {
1246 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1247 "dxeChannelStart Write INT_MASK register fail");
1248 return status;
1249 }
1250
1251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1252 "%s Exit", __FUNCTION__);
1253 return status;
1254}
1255
1256/*==========================================================================
1257 @ Function Name
1258 dxeChannelStop
1259
1260 @ Description
1261 Stop Specific Channel
1262
1263 @ Parameters
1264 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1265 DXE host driver main control block
1266 WLANDXE_ChannelCBType *channelEntry
1267 Channel specific control block
1268
1269 @ Return
1270 wpt_status
1271
1272===========================================================================*/
1273static wpt_status dxeChannelStop
1274(
1275 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1276 WLANDXE_ChannelCBType *channelEntry
1277)
1278{
1279 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1280 wpt_uint32 intMaskVal = 0;
1281
1282 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1283 "%s Enter", __FUNCTION__);
1284
1285 /* Sanity */
1286 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1287 {
1288 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1289 "dxeChannelStop Invalid arg input");
1290 return eWLAN_PAL_STATUS_E_INVAL;
1291 }
1292
1293 /* Maskout interrupt */
1294 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1295 &intMaskVal);
1296 if(eWLAN_PAL_STATUS_SUCCESS != status)
1297 {
1298 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1299 "dxeChannelStop Read INT_MASK register fail");
1300 return status;
1301 }
1302 intMaskVal ^= channelEntry->extraConfig.intMask;
1303 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1304 intMaskVal);
1305 if(eWLAN_PAL_STATUS_SUCCESS != status)
1306 {
1307 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1308 "dxeChannelStop Write INT_MASK register fail");
1309 return status;
1310 }
1311
1312 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1313
1314 /* Stop Channel ??? */
1315 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1316 "%s Exit", __FUNCTION__);
1317 return status;
1318}
1319
1320/*==========================================================================
1321 @ Function Name
1322 dxeChannelClose
1323
1324 @ Description
1325 Close Specific Channel
1326 Free pre allocated RX frame buffer if RX channel
1327 Free DXE descriptor for each channel
1328 Free Descriptor control block for each channel
1329
1330 @ Parameters
1331 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1332 DXE host driver main control block
1333 WLANDXE_ChannelCBType *channelEntry
1334 Channel specific control block
1335
1336 @ Return
1337 wpt_status
1338
1339===========================================================================*/
1340static wpt_status dxeChannelClose
1341(
1342 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1343 WLANDXE_ChannelCBType *channelEntry
1344)
1345{
1346 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1347 wpt_uint32 idx;
1348 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1349 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1350 WLANDXE_DescType *currentDescriptor = NULL;
1351 WLANDXE_DescType *nextDescriptor = NULL;
1352
1353 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1354 "%s Enter", __FUNCTION__);
1355
1356 /* Sanity */
1357 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1358 {
1359 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1360 "dxeChannelStop Invalid arg input");
1361 return eWLAN_PAL_STATUS_E_INVAL;
1362 }
1363
1364 currentCtrlBlk = channelEntry->headCtrlBlk;
1365 if(NULL != currentCtrlBlk)
1366 {
1367 currentDescriptor = currentCtrlBlk->linkedDesc;
1368 for(idx = 0; idx < channelEntry->numDesc; idx++)
1369 {
1370 if (idx + 1 != channelEntry->numDesc)
1371 {
1372 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1373 nextDescriptor = nextCtrlBlk->linkedDesc;
1374 }
1375 else
1376 {
1377 nextCtrlBlk = NULL;
1378 nextDescriptor = NULL;
1379 }
1380 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1381 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1382 {
1383 if (NULL != currentCtrlBlk->xfrFrame)
1384 {
1385 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1386 wpalPacketFree(currentCtrlBlk->xfrFrame);
1387 }
1388 }
1389 /*
1390 * It is the responsibility of DXE to walk through the
1391 * descriptor chain and unlock any pending packets (if
1392 * locked).
1393 */
1394 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1395 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1396 {
1397 if((NULL != currentCtrlBlk->xfrFrame) &&
1398 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1399 {
1400 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1401 wpalPacketFree(currentCtrlBlk->xfrFrame);
1402 }
1403 }
1404#if (defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1405 // descriptors allocated individually so free them individually
1406 wpalDmaMemoryFree(currentDescriptor);
1407#endif
1408 wpalMemoryFree(currentCtrlBlk);
1409
1410 currentCtrlBlk = nextCtrlBlk;
1411 currentDescriptor = nextDescriptor;
1412 }
1413 }
1414
1415#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1416 // descriptors were allocated as a single chunk so free the chunk
1417 if(NULL != channelEntry->descriptorAllocation)
1418 {
1419 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1420 }
1421#endif
1422
1423 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1424 "%s Exit", __FUNCTION__);
1425 return status;
1426}
1427
1428/*==========================================================================
1429 @ Function Name
1430 dxeChannelCleanInt
1431
1432 @ Description
1433 Clean up interrupt from RIVA HW
1434 After Host finish to handle interrupt, interrupt signal must be cleaned up
1435 Otherwise next interrupt will not be generated
1436
1437 @ Parameters
1438 WLANDXE_ChannelCBType *channelEntry
1439 Channel specific control block
1440 wpt_uint32 *chStat
1441 Channel Status register value
1442
1443 @ Return
1444 wpt_status
1445
1446===========================================================================*/
1447static wpt_status dxeChannelCleanInt
1448(
1449 WLANDXE_ChannelCBType *channelEntry,
1450 wpt_uint32 *chStat
1451)
1452{
1453 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1454
1455 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1456 "%s Enter", __FUNCTION__);
1457
1458 /* Read Channel Status Register to know why INT Happen */
1459 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1460 chStat);
1461 if(eWLAN_PAL_STATUS_SUCCESS != status)
1462 {
1463 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1464 "dxeChannelCleanInt Read CH STAT register fail");
1465 return eWLAN_PAL_STATUS_E_FAULT;
1466 }
1467 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1468 "%s Channel INT Clean, Status 0x%x",
1469 channelType[channelEntry->channelType], *chStat);
1470
1471 /* Clean up all the INT within this channel */
1472 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1473 (1 << channelEntry->assignedDMAChannel));
1474 if(eWLAN_PAL_STATUS_SUCCESS != status)
1475 {
1476 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1477 "dxeChannelCleanInt Write CH Clean register fail");
1478 return eWLAN_PAL_STATUS_E_FAULT;
1479 }
1480
Jeff Johnsone7245742012-09-05 17:12:55 -07001481 /* Clean up Error INT Bit */
1482 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1483 {
1484 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1485 (1 << channelEntry->assignedDMAChannel));
1486 if(eWLAN_PAL_STATUS_SUCCESS != status)
1487 {
1488 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1489 "dxeChannelCleanInt Read CH STAT register fail");
1490 return eWLAN_PAL_STATUS_E_FAULT;
1491 }
1492 }
1493
1494 /* Clean up DONE INT Bit */
1495 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1496 {
1497 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1498 (1 << channelEntry->assignedDMAChannel));
1499 if(eWLAN_PAL_STATUS_SUCCESS != status)
1500 {
1501 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1502 "dxeChannelCleanInt Read CH STAT register fail");
1503 return eWLAN_PAL_STATUS_E_FAULT;
1504 }
1505 }
1506
1507 /* Clean up ED INT Bit */
1508 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1509 {
1510 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1511 (1 << channelEntry->assignedDMAChannel));
1512 if(eWLAN_PAL_STATUS_SUCCESS != status)
1513 {
1514 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1515 "dxeChannelCleanInt Read CH STAT register fail");
1516 return eWLAN_PAL_STATUS_E_FAULT;
1517 }
1518 }
1519
Jeff Johnson295189b2012-06-20 16:38:30 -07001520 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1521 "%s Exit", __FUNCTION__);
1522 return status;
1523}
1524
1525/*==========================================================================
1526 @ Function Name
1527 dxeRXPacketAvailableCB
1528
1529 @ Description
1530 If RX frame handler encounts RX buffer pool empty condition,
1531 DXE RX handle loop will be blocked till get available RX buffer pool.
1532 When new RX buffer pool available, Packet available CB function will
1533 be called.
1534
1535 @ Parameters
1536 wpt_packet *freePacket
1537 Newly allocated RX buffer
1538 v_VOID_t *usrData
1539 DXE context
1540
1541 @ Return
1542 NONE
1543
1544===========================================================================*/
1545void dxeRXPacketAvailableCB
1546(
1547 wpt_packet *freePacket,
1548 v_VOID_t *usrData
1549)
1550{
1551 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1552 wpt_status status;
1553
1554 /* Simple Sanity */
1555 if((NULL == freePacket) || (NULL == usrData))
1556 {
1557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1558 "Get Free RX Buffer fail, Critical Error");
1559 HDXE_ASSERT(0);
1560 return;
1561 }
1562
1563 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1564
1565 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1566 {
1567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1568 "DXE Context data corrupted, Critical Error");
1569 HDXE_ASSERT(0);
1570 return;
1571 }
1572
1573 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1574 "DXE RX packet available, post MSG to RX Thread");
1575
1576 dxeCtxt->freeRXPacket = freePacket;
1577
1578 /* Serialize RX Packet Available message upon RX thread */
1579 HDXE_ASSERT(NULL != dxeCtxt->rxPktAvailMsg);
1580
1581 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1582 dxeCtxt->rxPktAvailMsg);
1583 if(eWLAN_PAL_STATUS_SUCCESS != status)
1584 {
1585 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
1586 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1587 "dxeRXPacketAvailableCB serialize fail");
1588 }
1589
1590 return;
1591}
1592
1593/*==========================================================================
1594 @ Function Name
1595 dxeRXFrameSingleBufferAlloc
1596
1597 @ Description
1598 Allocate Platform packet buffer to prepare RX frame
1599 RX frame memory space must be pre allocted and must be asigned to
1600 descriptor
1601 then whenever DMA engine want to tranfer frame from BMU,
1602 buffer must be ready
1603
1604 @ Parameters
1605 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1606 DXE host driver main control block
1607 WLANDXE_ChannelCBType *channelEntry
1608 Channel specific control block
1609 WLANDXE_DescCtrlBlkType currentCtrlBlock
1610 current control block which have to be asigned
1611 frame buffer
1612
1613 @ Return
1614 wpt_status
1615
1616===========================================================================*/
1617static wpt_status dxeRXFrameSingleBufferAlloc
1618(
1619 WLANDXE_CtrlBlkType *dxeCtxt,
1620 WLANDXE_ChannelCBType *channelEntry,
1621 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1622)
1623{
1624 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1625 wpt_packet *currentPalPacketBuffer = NULL;
1626 WLANDXE_DescType *currentDesc = NULL;
1627#ifdef FEATURE_R33D
1628 wpt_uint32 virtualAddressPCIe;
1629 wpt_uint32 physicalAddressPCIe;
1630#else
1631 wpt_iterator iterator;
1632 wpt_uint32 allocatedSize = 0;
1633 void *physAddress = NULL;
1634#endif /* FEATURE_R33D */
1635
Jeff Johnson295189b2012-06-20 16:38:30 -07001636
1637 currentDesc = currentCtrlBlock->linkedDesc;
1638
1639 /* First check if a packet pointer has already been provided by a previously
1640 invoked Rx packet available callback. If so use that packet. */
1641 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1642 {
1643 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1644 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1645 dxeCtxt->freeRXPacket = NULL;
1646 }
1647 else if(!dxeCtxt->rxPalPacketUnavailable)
1648 {
1649 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1650 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
1651 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1652 dxeRXPacketAvailableCB,
1653 (void *)dxeCtxt);
1654
1655 if(NULL == currentPalPacketBuffer)
1656 {
1657 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
1658 }
1659 }
1660
1661 if(NULL == currentPalPacketBuffer)
1662 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 return eWLAN_PAL_STATUS_E_RESOURCES;
1664 }
1665
1666 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1667 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1668 currentPalPacketBuffer->pBD = NULL;
1669 currentPalPacketBuffer->pBDPhys = NULL;
1670 currentPalPacketBuffer->BDLength = 0;
1671#ifdef FEATURE_R33D
1672 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
1673 &physicalAddressPCIe,
1674 &virtualAddressPCIe);
1675 HDXE_ASSERT(0 != physicalAddressPCIe);
1676 HDXE_ASSERT(0 != virtualAddressPCIe);
1677 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
1678 "RX Shadow Memory Va 0x%x, Pa 0x%x",
1679 virtualAddressPCIe, physicalAddressPCIe);
1680 if(eWLAN_PAL_STATUS_SUCCESS != status)
1681 {
1682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1683 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
1684 return status;
1685 }
1686 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
1687 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
1688 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1689#else
1690 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
1691 if(eWLAN_PAL_STATUS_SUCCESS != status)
1692 {
1693 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1694 "dxeRXFrameBufferAlloc unable to lock packet");
1695 return status;
1696 }
1697
1698 /* Init iterator to get physical os buffer address */
1699 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1700 if(eWLAN_PAL_STATUS_SUCCESS != status)
1701 {
1702 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1703 "dxeRXFrameBufferAlloc iterator init fail");
1704 return status;
1705 }
1706 status = wpalIteratorNext(&iterator,
1707 currentPalPacketBuffer,
1708 &physAddress,
1709 &allocatedSize);
1710 if(eWLAN_PAL_STATUS_SUCCESS != status)
1711 {
1712 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1713 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1714 return status;
1715 }
1716 currentPalPacketBuffer->pBDPhys = physAddress;
1717#endif /* FEATURE_R33D */
1718
1719 /* DXE descriptor must have SWAPPED addres in it's structure
1720 * !!! SWAPPED !!! */
1721 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
1722 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)currentPalPacketBuffer->pBDPhys);
1723
Jeff Johnson295189b2012-06-20 16:38:30 -07001724 return status;
1725}
1726
1727/*==========================================================================
1728 @ Function Name
1729 dxeRXFrameRefillRing
1730
1731 @ Description
1732 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1733
1734 @ Parameters
1735 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1736 DXE host driver main control block
1737 WLANDXE_ChannelCBType *channelEntry
1738 Channel specific control block
1739
1740 @ Return
1741 wpt_status
1742
1743===========================================================================*/
1744static wpt_status dxeRXFrameRefillRing
1745(
1746 WLANDXE_CtrlBlkType *dxeCtxt,
1747 WLANDXE_ChannelCBType *channelEntry
1748)
1749{
1750 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1751 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
1752 WLANDXE_DescType *currentDesc = NULL;
1753
1754 while(channelEntry->numFreeDesc > 0)
1755 {
1756 /* Current Control block is free
1757 * and associated frame buffer is not linked with control block anymore
1758 * allocate new frame buffer for current control block */
1759 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
1760 channelEntry,
1761 currentCtrlBlk);
1762
1763 if(eWLAN_PAL_STATUS_SUCCESS != status)
1764 {
1765 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1766 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
1767 break;
1768 }
1769
1770 currentDesc = currentCtrlBlk->linkedDesc;
1771 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1772
1773 /* Issue a dummy read from the DXE descriptor DDR location to ensure
1774 that any posted writes are reflected in memory before DXE looks at
1775 the descriptor. */
1776 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
1777 {
1778 //HDXE_ASSERT(0);
1779 }
1780
1781 /* Kick off the DXE ring, if not in any power save mode */
1782 if((WLANDXE_POWER_STATE_IMPS != dxeCtxt->hostPowerState) &&
1783 (WLANDXE_POWER_STATE_DOWN != dxeCtxt->hostPowerState))
1784 {
1785 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
1786 1 << channelEntry->assignedDMAChannel);
1787 }
1788 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1789 --channelEntry->numFreeDesc;
1790 }
1791
1792 channelEntry->tailCtrlBlk = currentCtrlBlk;
1793
1794 return status;
1795}
1796
1797/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07001798 @ Function Name
1799 dxeRXFrameRouteUpperLayer
1800
1801 @ Description
1802 Test DXE descriptors and if any RX frame pending within RING,
1803 Route to upper layer
1804
1805 @ Parameters
1806 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1807 DXE host driver main control block
1808 WLANDXE_ChannelCBType *channelEntry
1809 Channel specific control block
1810 @ Return
1811 -1 Any error happen
1812 0 No frame pulled from RX RING
1813 int number of RX frames pulled from RX ring
1814
1815===========================================================================*/
1816static wpt_int32 dxeRXFrameRouteUpperLayer
1817(
1818 WLANDXE_CtrlBlkType *dxeCtxt,
1819 WLANDXE_ChannelCBType *channelEntry
1820)
1821{
1822 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1823 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1824 WLANDXE_DescType *currentDesc = NULL;
1825 wpt_uint32 descCtrl, frameCount = 0, i;
1826
1827 currentCtrlBlk = channelEntry->headCtrlBlk;
1828 currentDesc = currentCtrlBlk->linkedDesc;
1829
1830 /* Descriptoe should be SWAPPED ???? */
1831 descCtrl = currentDesc->descCtrl.ctrl;
1832
1833 /* Get frames while VALID bit is not set (DMA complete) and a data
1834 * associated with it */
1835 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
1836 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
1837 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
1838 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
1839 {
1840 channelEntry->numTotalFrame++;
1841 channelEntry->numFreeDesc++;
1842#ifdef FEATURE_R33D
1843 /* Transfer Size should be */
1844 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1845 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
1846 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
1847 currentCtrlBlk->shadowBufferVa,
1848 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1849 if(eWLAN_PAL_STATUS_SUCCESS != status)
1850 {
1851 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1852 "dxeRXFrameReady Prepare RX Frame fail");
1853 return -1;
1854 }
1855 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
1856 if(eWLAN_PAL_STATUS_SUCCESS != status)
1857 {
1858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1859 "dxeRXFrameReady Free Shadow RX Frame fail");
1860 return -1;
1861 }
1862
1863#else /* FEATURE_R33D */
1864 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1865 if (eWLAN_PAL_STATUS_SUCCESS != status)
1866 {
1867 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1868 "dxeRXFrameReady unable to unlock packet");
1869 return -1;
1870 }
1871#endif /* FEATURE_R33D */
1872 /* This Descriptor is valid, so linked Control block is also valid
1873 * Linked Control block has pre allocated packet buffer
1874 * So, just let upper layer knows preallocated frame pointer will be OK */
1875 /* Reap Rx frames */
1876 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
1877 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07001878 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07001879
1880 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
1881 dxeRXFrameRefillRing(dxeCtxt,channelEntry);
1882
1883 /* Test next contorl block
1884 * if valid, this control block also has new RX frame must be handled */
1885 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
1886 currentDesc = currentCtrlBlk->linkedDesc;
1887 descCtrl = currentDesc->descCtrl.ctrl;
1888 }
1889
1890 /* Update head control block
1891 * current control block's valid bit was 0
1892 * next trial first control block must be current control block */
1893 channelEntry->headCtrlBlk = currentCtrlBlk;
1894
1895 /* Deliver all the reaped RX frames to upper layers */
1896 i = 0;
1897 while(i < frameCount) {
1898 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
1899 i++;
1900 }
1901
1902 return frameCount;
1903}
1904
1905/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 @ Function Name
1907 dxeRXFrameReady
1908
1909 @ Description
1910 Pop frame from descriptor and route frame to upper transport layer
1911 Assign new platform packet buffer into used descriptor
1912 Actual frame pop and resource realloc
1913
1914 @ Parameters
1915 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1916 DXE host driver main control block
1917 WLANDXE_ChannelCBType *channelEntry
1918 Channel specific control block
1919
1920 @ Return
1921 wpt_status
1922
1923===========================================================================*/
1924static wpt_status dxeRXFrameReady
1925(
1926 WLANDXE_CtrlBlkType *dxeCtxt,
1927 WLANDXE_ChannelCBType *channelEntry
1928)
1929{
1930 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1931 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1932 WLANDXE_DescType *currentDesc = NULL;
1933 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07001934 wpt_int32 frameCount = 0;
1935
1936 wpt_uint32 descLoop;
1937 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001938
1939 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1940 "%s Enter", __FUNCTION__);
1941
1942 /* Sanity Check */
1943 if((NULL == dxeCtxt) || (NULL == channelEntry))
1944 {
1945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1946 "dxeRXFrameReady Channel Entry is not valid");
1947 return eWLAN_PAL_STATUS_E_INVAL;
1948 }
1949
Jeff Johnsone7245742012-09-05 17:12:55 -07001950 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07001951
Jeff Johnsone7245742012-09-05 17:12:55 -07001952 if(0 > frameCount)
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 {
1954 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07001955 "dxeRXFrameReady RX frame route fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 return eWLAN_PAL_STATUS_E_INVAL;
1957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001958
Jeff Johnsone7245742012-09-05 17:12:55 -07001959 if((0 == frameCount) &&
1960 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
1961 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
1962 {
1963 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 currentDesc = currentCtrlBlk->linkedDesc;
1965 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07001966
1967 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
1968 {
1969 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1970 "RX ISR called but no frame handled PWS %d, channel %s",
1971 (int)dxeCtxt->hostPowerState,
1972 channelType[channelEntry->channelType]);
1973 }
1974
1975 /* Current interupt empty and previous interrupt also empty
1976 * detected successive empty interrupt
1977 * or first interrupt empty, this should not happen */
1978 if(0 == channelEntry->numFragmentCurrentChain)
1979 {
1980 dxeChannelMonitor("RX Ready", channelEntry);
1981 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
1982 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt");
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07001983 dxeChannelAllDescDump(channelEntry, channelEntry->channelType);
Jeff Johnsone7245742012-09-05 17:12:55 -07001984
1985 /* Abnormal interrupt detected, try to find not validated descriptor */
1986 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
1987 {
1988 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
1989 {
1990 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1991 "Found Invalidated Descriptor %d", (int)descLoop);
1992 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
1993 {
1994 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1995 "Packet locked, Resync Host and HW");
1996 channelEntry->headCtrlBlk = currentCtrlBlk;
1997 invalidatedFound = 1;
1998 break;
1999 }
2000 else
2001 {
2002 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2003 "Packet Not Locked, cannot transfer frame");
2004 }
2005 }
2006 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2007 currentDesc = currentCtrlBlk->linkedDesc;
2008 descCtrl = currentDesc->descCtrl.ctrl;
2009 }
2010
Jeff Johnson32d95a32012-09-10 13:15:23 -07002011 /* Invalidated descriptor found, and that is not head descriptor
2012 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2013 * Try re-sync here */
2014 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002015 {
2016 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2017 "Found New Sync location with HW, handle frames from there");
2018 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2019 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2020 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002021 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002022 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002023 /* Successive Empty interrupt
2024 * But this case, first descriptor also invalidated, then it means head descriptor
2025 * is linked with already handled RX frame, then could not unlock RX frame
2026 * This is just Out of RX buffer pool, not need to anything here */
2027 else if((invalidatedFound) && (0 == descLoop))
2028 {
2029 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2030 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2031 }
2032 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002033 else
2034 {
2035 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2036 "Could not found invalidated descriptor");
2037 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2038 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2039 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2040 wpalWlanReload();
2041 }
2042 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002043 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002044 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2046 "%s Exit", __FUNCTION__);
2047 return status;
2048}
2049
2050/*==========================================================================
2051 @ Function Name
2052 dxeNotifySmsm
2053
2054 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2055 buffer
2056
2057 @ Parameters
2058
2059 @ Return
2060 wpt_status
2061
2062===========================================================================*/
2063static wpt_status dxeNotifySmsm
2064(
2065 wpt_boolean kickDxe,
2066 wpt_boolean ringEmpty
2067)
2068{
2069 wpt_uint32 clrSt = 0;
2070 wpt_uint32 setSt = 0;
2071
2072 if(kickDxe)
2073 {
2074 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2075
2076 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2077 {
2078 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2079 tempDxeCtrlBlk->lastKickOffDxe = 1;
2080 }
2081 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2082 {
2083 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2084 tempDxeCtrlBlk->lastKickOffDxe = 0;
2085 }
2086 else
2087 {
2088 HDXE_ASSERT(0);
2089 }
2090 }
2091 else
2092 {
2093 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2094 }
2095
2096 if(ringEmpty)
2097 {
2098 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2099 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2100 }
2101 else
2102 {
2103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2104 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2105 }
2106
2107 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2108
2109 wpalNotifySmsm(clrSt, setSt);
2110
2111 return eWLAN_PAL_STATUS_SUCCESS;
2112}
2113
2114/*==========================================================================
2115 @ Function Name
2116 dxePsComplete
2117
2118 @ Description: Utility function to check the resv desc to deside if we can
2119 get into Power Save mode now
2120
2121 @ Parameters
2122
2123 @ Return
2124 None
2125
2126===========================================================================*/
2127static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2128{
2129 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2130 {
2131 return;
2132 }
2133
2134 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2135 //must have been consumed by RIVA, OK to get into BMPS
2136 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2137 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2138 {
2139 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2140 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2141 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2142 {
2143 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2144 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2145 }
2146 }
2147 else //still more pkts to be served by RIVA
2148 {
2149 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2150
2151 switch(dxeCtxt->rivaPowerState)
2152 {
2153 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2154 //NOP
2155 break;
2156 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2157 if(intr_based)
2158 {
2159 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2160 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2161 }
2162 break;
2163 default:
2164 //assert
2165 break;
2166 }
2167 }
2168}
2169
2170/*==========================================================================
2171 @ Function Name
2172 dxeRXEventHandler
2173
2174 @ Description
2175 Handle serailized RX frame ready event
2176 First disable interrupt then pick up frame from pre allocated buffer
2177 Since frame handle is doen, clear interrupt bit to ready next interrupt
2178 Finally re enable interrupt
2179
2180 @ Parameters
2181 wpt_msg *rxReadyMsg
2182 RX frame ready MSG pointer
2183 include DXE control context
2184
2185 @ Return
2186 NONE
2187
2188===========================================================================*/
2189void dxeRXEventHandler
2190(
2191 wpt_msg *rxReadyMsg
2192)
2193{
2194 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2195 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2196 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2197 wpt_uint32 intSrc = 0;
2198 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002199 wpt_uint32 chHighStat = 0;
2200 wpt_uint32 chLowStat = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002201
Jeff Johnsone7245742012-09-05 17:12:55 -07002202 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002203
Jeff Johnsone7245742012-09-05 17:12:55 -07002204 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 {
2206 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002207 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002208 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 }
2210
Jeff Johnsone7245742012-09-05 17:12:55 -07002211 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2212 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2213 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
2214
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2216
2217 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
2218 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
2219 {
2220 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2221 "DXE already stopped in RX event handler. Just return");
2222 return;
2223 }
2224
2225 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2226 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2227 {
2228 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2229 "%s Riva is in %d, Just Pull frames without any register touch ",
2230 __FUNCTION__, dxeCtxt->hostPowerState);
2231
2232 /* Not to touch any register, just pull frame directly from chain ring
2233 * First high priority */
2234 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2235 status = dxeRXFrameReady(dxeCtxt,
2236 channelCb);
2237 if(eWLAN_PAL_STATUS_SUCCESS != status)
2238 {
2239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2240 "dxeRXEventHandler Pull from RX high channel fail");
2241 }
2242
2243 /* Second low priority */
2244 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2245 status = dxeRXFrameReady(dxeCtxt,
2246 channelCb);
2247 if(eWLAN_PAL_STATUS_SUCCESS != status)
2248 {
2249 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2250 "dxeRXEventHandler Pull from RX low channel fail");
2251 }
2252
2253 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2254 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2255
2256 return;
2257 }
2258
2259 /* Disable device interrupt */
2260 /* Read whole interrupt mask register and exclusive only this channel int */
2261 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2262 &intSrc);
2263 if(eWLAN_PAL_STATUS_SUCCESS != status)
2264 {
2265 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2266 "dxeRXEventHandler Read INT_SRC register fail");
2267 return;
2268 }
2269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2270 "RX Event Handler INT Source 0x%x", intSrc);
2271
2272#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2273 /* Test High Priority Channel interrupt is enabled or not */
2274 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2275 if(intSrc & (1 << channelCb->assignedDMAChannel))
2276 {
2277 status = dxeChannelCleanInt(channelCb, &chHighStat);
2278 if(eWLAN_PAL_STATUS_SUCCESS != status)
2279 {
2280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2281 "dxeRXEventHandler INT Clean up fail");
2282 return;
2283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2285 {
2286 /* Error Happen during transaction, Handle it */
2287 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002288 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2289 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002290 {
2291 /* Handle RX Ready for high priority channel */
2292 status = dxeRXFrameReady(dxeCtxt,
2293 channelCb);
2294 }
2295 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2296 {
2297 status = dxeRXFrameReady(dxeCtxt,
2298 channelCb);
2299 }
2300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2301 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002302 /* Update the Rx DONE histogram */
2303 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2304 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2305 {
2306 channelCb->rxDoneHistogram |= 1;
2307 }
2308 else
2309 {
2310 channelCb->rxDoneHistogram &= ~1;
2311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002312 }
2313#else
2314 /* Test H2H Test interrupt is enabled or not */
2315 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2316 if(intSrc & (1 << channelCb->assignedDMAChannel))
2317 {
2318 status = dxeChannelCleanInt(channelCb, &chStat);
2319 if(eWLAN_PAL_STATUS_SUCCESS != status)
2320 {
2321 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2322 "dxeRXEventHandler INT Clean up fail");
2323 return;
2324 }
2325
2326 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2327 {
2328 /* Error Happen during transaction, Handle it */
2329 }
2330 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2331 {
2332 /* Handle RX Ready for high priority channel */
2333 status = dxeRXFrameReady(dxeCtxt,
2334 channelCb);
2335 }
2336 /* Update the Rx DONE histogram */
2337 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2338 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2339 {
2340 channelCb->rxDoneHistogram |= 1;
2341 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2342 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2343 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2344 }
2345 else
2346 {
2347 channelCb->rxDoneHistogram &= ~1;
2348 }
2349 }
2350#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2351
2352 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002353 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 if(intSrc & (1 << channelCb->assignedDMAChannel))
2355 {
2356 status = dxeChannelCleanInt(channelCb, &chLowStat);
2357 if(eWLAN_PAL_STATUS_SUCCESS != status)
2358 {
2359 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2360 "dxeRXEventHandler INT Clean up fail");
2361 return;
2362 }
2363
2364 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2365 {
2366 /* Error Happen during transaction, Handle it */
2367 }
2368 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2369 {
2370 /* Handle RX Ready for low priority channel */
2371 status = dxeRXFrameReady(dxeCtxt,
2372 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07002373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002374
2375 /* Update the Rx DONE histogram */
2376 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2377 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2378 {
2379 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002380 }
2381 else
2382 {
2383 channelCb->rxDoneHistogram &= ~1;
2384 }
2385 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2386 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2387 }
2388 if(eWLAN_PAL_STATUS_SUCCESS != status)
2389 {
2390 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2391 "dxeRXEventHandler Handle Frame Ready Fail");
2392 return;
2393 }
2394
2395 /* Enable system level ISR */
2396 /* Enable RX ready Interrupt at here */
2397 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2398 if(eWLAN_PAL_STATUS_SUCCESS != status)
2399 {
2400 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2401 "dxeRXEventHandler Enable RX Ready interrupt fail");
2402 return;
2403 }
2404
2405 /* Prepare Control Register EN Channel */
2406 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2407 {
2408 HDXE_ASSERT(0);
2409 }
2410 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
2411 {
2412 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2413 "dxeRXEventHandler RX High, Not yet ED, re-enable CH");
2414 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
2415 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
2416 }
2417 else
2418 {
2419 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2420 "dxeRXEventHandler RX High, CH STAT = ED_MASK, will RIVA PC");
2421 }
2422
2423 /* Prepare Control Register EN Channel */
2424 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2425 {
2426 HDXE_ASSERT(0);
2427 }
2428 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat))
2429 {
2430 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2431 "dxeRXEventHandler RX Low, Not yet ED, re-enable CH");
2432 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
2433 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
2434 }
2435 else
2436 {
2437 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2438 "dxeRXEventHandler RX Low, CH STAT = ED_MASK, will RIVA PC");
2439 }
2440
2441 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2442 "%s Exit", __FUNCTION__);
2443 return;
2444}
2445
2446/*==========================================================================
2447 @ Function Name
2448 dxeRXPacketAvailableEventHandler
2449
2450 @ Description
2451 Handle serialized RX Packet Available event when the corresponding callback
2452 is invoked by WPAL.
2453 Try to fill up any completed DXE descriptors with available Rx packet buffer
2454 pointers.
2455
2456 @ Parameters
2457 wpt_msg *rxPktAvailMsg
2458 RX frame ready MSG pointer
2459 include DXE control context
2460
2461 @ Return
2462 NONE
2463
2464===========================================================================*/
2465void dxeRXPacketAvailableEventHandler
2466(
2467 wpt_msg *rxPktAvailMsg
2468)
2469{
2470 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2471 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2472 WLANDXE_ChannelCBType *channelCb = NULL;
2473
2474 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2475 "%s Enter", __FUNCTION__);
2476
2477 /* Sanity Check */
2478 if(NULL == rxPktAvailMsg)
2479 {
2480 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2481 "dxeRXPacketAvailableEventHandler Context is not valid");
2482 return;
2483 }
2484
2485 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
2486
2487 do
2488 {
2489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2490 "dxeRXPacketAvailableEventHandler, start refilling ring");
2491
2492 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2493 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2494
2495 // Wait for another callback to indicate when Rx resources are available
2496 // again.
2497 if(eWLAN_PAL_STATUS_SUCCESS != status)
2498 {
2499 break;
2500 }
2501
2502 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2503 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2504 if(eWLAN_PAL_STATUS_SUCCESS != status)
2505 {
2506 break;
2507 }
2508 } while(0);
2509
2510 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2511 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2512 {
2513 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2514 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2515 }
2516}
2517
2518/*==========================================================================
2519 @ Function Name
2520 dxeRXISR
2521
2522 @ Description
2523 RX frame ready interrupt service routine
2524 interrupt entry function, this function called based on ISR context
2525 Must be serialized
2526
2527 @ Parameters
2528 void *hostCtxt
2529 DXE host driver control context,
2530 pre registerd during interrupt registration
2531
2532 @ Return
2533 NONE
2534
2535===========================================================================*/
2536static void dxeRXISR
2537(
2538 void *hostCtxt
2539)
2540{
2541 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2542 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2543#ifdef FEATURE_R33D
2544 wpt_uint32 regValue;
2545#endif /* FEATURE_R33D */
2546
Jeff Johnson295189b2012-06-20 16:38:30 -07002547
2548#ifdef FEATURE_R33D
2549 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2550 &regValue);
2551 if(eWLAN_PAL_STATUS_SUCCESS != status)
2552 {
2553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2554 "dxeTXCompISR Read INT_SRC_RAW fail");
2555 return;
2556 }
2557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2558 "INT_SRC_RAW 0x%x", regValue);
2559 if(0 == regValue)
2560 {
2561 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2562 "This is not DXE Interrupt, Reject it 0x%x", regValue);
2563 return;
2564 }
2565#endif /* FEATURE_R33D */
2566
2567 /* Disable interrupt at here
2568 * Disable RX Ready system level Interrupt at here
2569 * Otherwise infinite loop might happen */
2570 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2571 if(eWLAN_PAL_STATUS_SUCCESS != status)
2572 {
2573 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2574 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2575 return;
2576 }
2577
2578 /* Serialize RX Ready interrupt upon RX thread */
2579 HDXE_ASSERT(NULL != dxeCtxt->rxIsrMsg);
2580 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2581 dxeCtxt->rxIsrMsg);
2582 if(eWLAN_PAL_STATUS_SUCCESS != status)
2583 {
2584 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
2585 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2586 "dxeRXFrameReadyISR interrupt serialize fail");
2587 }
2588
Jeff Johnson295189b2012-06-20 16:38:30 -07002589 return;
2590}
2591
2592/*==========================================================================
2593 @ Function Name
2594 dxeTXPushFrame
2595
2596 @ Description
2597 Push TX frame into DXE descriptor and DXE register
2598 Send notification to DXE register that TX frame is ready to transfer
2599
2600 @ Parameters
2601 WLANDXE_ChannelCBType *channelEntry
2602 Channel specific control block
2603 wpt_packet *palPacket
2604 Packet pointer ready to transfer
2605
2606 @ Return
2607 PAL_STATUS_T
2608===========================================================================*/
2609static wpt_status dxeTXPushFrame
2610(
2611 WLANDXE_ChannelCBType *channelEntry,
2612 wpt_packet *palPacket
2613)
2614{
2615 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2616 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2617 WLANDXE_DescType *currentDesc = NULL;
2618 WLANDXE_DescType *firstDesc = NULL;
2619 WLANDXE_DescType *LastDesc = NULL;
2620 void *sourcePhysicalAddress = NULL;
2621 wpt_uint32 xferSize = 0;
2622#ifdef FEATURE_R33D
2623 tx_frm_pcie_vector_t frameVector;
2624 wpt_uint32 Va;
2625 wpt_uint32 fragCount = 0;
2626#else
2627 wpt_iterator iterator;
2628#endif /* FEATURE_R33D */
Jeff Johnsone7245742012-09-05 17:12:55 -07002629
2630 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002631
2632 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2633 "%s Enter", __FUNCTION__);
2634
Jeff Johnsone7245742012-09-05 17:12:55 -07002635 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2636 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002638 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002639 }
2640
2641 channelEntry->numFragmentCurrentChain = 0;
2642 currentCtrlBlk = channelEntry->headCtrlBlk;
2643
2644 /* Initialize interator, TX is fragmented */
2645#ifdef FEATURE_R33D
2646 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2647 status = wpalPrepareTxFrame(palPacket,
2648 &frameVector,
2649 &Va);
2650#else
2651 status = wpalLockPacketForTransfer(palPacket);
2652 if(eWLAN_PAL_STATUS_SUCCESS != status)
2653 {
2654 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2655 "dxeTXPushFrame unable to lock packet");
2656 return status;
2657 }
2658
2659 status = wpalIteratorInit(&iterator, palPacket);
2660#endif /* FEATURE_R33D */
2661 if(eWLAN_PAL_STATUS_SUCCESS != status)
2662 {
2663 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2664 "dxeTXPushFrame iterator init fail");
2665 return status;
2666 }
2667
2668 /* !!!! Revisit break condition !!!!!!! */
2669 while(1)
2670 {
2671 /* Get current descriptor pointer from current control block */
2672 currentDesc = currentCtrlBlk->linkedDesc;
2673 if(NULL == firstDesc)
2674 {
2675 firstDesc = currentCtrlBlk->linkedDesc;
2676 }
2677 /* All control block will have same palPacket Pointer
2678 * to make logic simpler */
2679 currentCtrlBlk->xfrFrame = palPacket;
2680
2681 /* Get next fragment physical address and fragment size
2682 * if this is the first trial, will get first physical address
2683 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2684#ifdef FEATURE_R33D
2685 if(fragCount == frameVector.num_frg)
2686 {
2687 break;
2688 }
2689 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2690 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2691 xferSize = frameVector.frg[fragCount].size;
2692 fragCount++;
2693 HDXE_ASSERT(0 != xferSize);
2694 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2695#else
2696 status = wpalIteratorNext(&iterator,
2697 palPacket,
2698 &sourcePhysicalAddress,
2699 &xferSize);
2700 if((NULL == sourcePhysicalAddress) ||
2701 (0 == xferSize))
2702 {
2703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2704 "dxeTXPushFrame end of current frame");
2705 break;
2706 }
2707 if(eWLAN_PAL_STATUS_SUCCESS != status)
2708 {
2709 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2710 "dxeTXPushFrame Get next frame fail");
2711 return status;
2712 }
2713#endif /* FEATURE_R33D */
2714
2715 /* This is the LAST descriptor valid for this transaction */
2716 LastDesc = currentCtrlBlk->linkedDesc;
2717
2718 /* Program DXE descriptor */
2719 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2720 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2721
2722 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2723 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2724 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2725 {
2726 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
2727 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
2728 }
2729 else
2730 {
2731 /* Test specific H2H transfer, destination address already set
2732 * Do Nothing */
2733 }
2734 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
2735
2736 /* Program channel control register */
2737 /* First frame not set VAL bit, why ??? */
2738 if(0 == channelEntry->numFragmentCurrentChain)
2739 {
2740 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
2741 }
2742 else
2743 {
2744 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2745 }
2746
2747 /* Update statistics */
2748 channelEntry->numFragmentCurrentChain++;
2749 channelEntry->numFreeDesc--;
2750 channelEntry->numRsvdDesc++;
2751
2752 /* Get next control block */
2753 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2754 }
2755 channelEntry->numTotalFrame++;
2756 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2757 "NUM TX FRAG %d, Total Frame %d",
2758 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
2759
2760 /* Program Channel control register
2761 * Set as end of packet
2762 * Enable interrupt also for first code lock down
2763 * performace optimization, this will be revisited */
2764 if(NULL == LastDesc)
2765 {
2766 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2767 "dxeTXPushFrame NULL Last Descriptor, broken chain");
2768 return eWLAN_PAL_STATUS_E_FAULT;
2769 }
2770 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
2771 /* Now First one also Valid ????
2772 * this procedure will prevent over handle descriptor from previous
2773 * TX trigger */
2774 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2775
2776 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
2777 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
2778 {
2779 /* Update channel head as next avaliable linked slot */
2780 channelEntry->headCtrlBlk = currentCtrlBlk;
Jeff Johnsone7245742012-09-05 17:12:55 -07002781
2782 if( isEmpty )
2783 {
2784 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2785 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,
2786 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
2787 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002789 return status;
2790 }
2791
2792 /* If DXE use external descriptor, registers are not needed to be programmed
2793 * Just after finish to program descriptor, tirigger to send */
2794 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
2795 {
2796 /* Issue a dummy read from the DXE descriptor DDR location to
2797 ensure that any previously posted write to the descriptor
2798 completes. */
2799 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
2800 {
2801 //HDXE_ASSERT(0);
2802 }
2803
2804 /* Everything is ready
2805 * Trigger to start DMA */
2806 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
2807 channelEntry->extraConfig.chan_mask);
2808 if(eWLAN_PAL_STATUS_SUCCESS != status)
2809 {
2810 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2811 "dxeTXPushFrame Write Channel Ctrl Register fail");
2812 return status;
2813 }
2814
2815 /* Update channel head as next avaliable linked slot */
2816 channelEntry->headCtrlBlk = currentCtrlBlk;
2817
2818 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2819 "%s Exit", __FUNCTION__);
2820 return status;
2821 }
2822
2823 /* If DXE not use external descriptor, program each registers */
2824 /* Circular buffer handle not need to program DESC register???
2825 * GEN5 code not programed RING buffer case
2826 * REVISIT THIS !!!!!! */
2827 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2828 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2829 {
2830 /* Destination address, assigned Work Q */
2831 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
2832 channelEntry->channelConfig.refWQ);
2833 if(eWLAN_PAL_STATUS_SUCCESS != status)
2834 {
2835 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2836 "dxeTXPushFrame Program dest address register fail");
2837 return status;
2838 }
2839 /* If descriptor format is SHORT */
2840 if(channelEntry->channelConfig.useShortDescFmt)
2841 {
2842 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
2843 0);
2844 if(eWLAN_PAL_STATUS_SUCCESS != status)
2845 {
2846 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2847 "dxeTXPushFrame Program dest address register fail");
2848 return status;
2849 }
2850 }
2851 else
2852 {
2853 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2854 "dxeTXPushFrame LONG Descriptor Format!!!");
2855 }
2856 }
2857#ifdef WLANDXE_TEST_CHANNEL_ENABLE
2858 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
2859 {
2860 /* Destination address, Physical memory address */
2861 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
2862 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
2863 if(eWLAN_PAL_STATUS_SUCCESS != status)
2864 {
2865 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2866 "dxeTXPushFrame Program dest address register fail");
2867 return status;
2868 }
2869 /* If descriptor format is SHORT */
2870 if(channelEntry->channelConfig.useShortDescFmt)
2871 {
2872 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
2873 0);
2874 if(eWLAN_PAL_STATUS_SUCCESS != status)
2875 {
2876 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2877 "dxeTXPushFrame Program dest address register fail");
2878 return status;
2879 }
2880 }
2881 else
2882 {
2883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2884 "dxeTXPushFrame LONG Descriptor Format!!!");
2885 }
2886 }
2887#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2888
2889 /* Program Source address register
2890 * This address is already programmed into DXE Descriptor
2891 * But register also upadte */
2892 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
2893 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
2894 if(eWLAN_PAL_STATUS_SUCCESS != status)
2895 {
2896 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2897 "dxeTXPushFrame Program src address register fail");
2898 return status;
2899 }
2900 /* If descriptor format is SHORT */
2901 if(channelEntry->channelConfig.useShortDescFmt)
2902 {
2903 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
2904 0);
2905 if(eWLAN_PAL_STATUS_SUCCESS != status)
2906 {
2907 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2908 "dxeTXPushFrame Program dest address register fail");
2909 return status;
2910 }
2911 }
2912 else
2913 {
2914 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2915 "dxeTXPushFrame LONG Descriptor Format!!!");
2916 }
2917
2918 /* Linked list Descriptor pointer */
2919 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
2920 channelEntry->headCtrlBlk->linkedDescPhyAddr);
2921 if(eWLAN_PAL_STATUS_SUCCESS != status)
2922 {
2923 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2924 "dxeTXPushFrame Write DESC Address register fail");
2925 return status;
2926 }
2927 /* If descriptor format is SHORT */
2928 if(channelEntry->channelConfig.useShortDescFmt)
2929 {
2930 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
2931 0);
2932 if(eWLAN_PAL_STATUS_SUCCESS != status)
2933 {
2934 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2935 "dxeTXPushFrame Program dest address register fail");
2936 return status;
2937 }
2938 }
2939 else
2940 {
2941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2942 "dxeTXPushFrame LONG Descriptor Format!!!");
2943 }
2944
2945 /* Transfer Size */
2946 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
2947 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
2948 xferSize);
2949 if(eWLAN_PAL_STATUS_SUCCESS != status)
2950 {
2951 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2952 "dxeTXPushFrame Write DESC Address register fail");
2953 return status;
2954 }
2955
2956 /* Everything is ready
2957 * Trigger to start DMA */
2958 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
2959 channelEntry->extraConfig.chan_mask);
2960 if(eWLAN_PAL_STATUS_SUCCESS != status)
2961 {
2962 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2963 "dxeTXPushFrame Write Channel Ctrl Register fail");
2964 return status;
2965 }
2966
2967 /* Update channel head as next avaliable linked slot */
2968 channelEntry->headCtrlBlk = currentCtrlBlk;
2969
2970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2971 "%s Exit", __FUNCTION__);
2972 return status;
2973}
2974
2975/*==========================================================================
2976 @ Function Name
2977 dxeTXCompFrame
2978
2979 @ Description
2980 TX Frame transfer complete event handler
2981
2982 @ Parameters
2983 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2984 DXE host driver main control block
2985 WLANDXE_ChannelCBType *channelEntry
2986 Channel specific control block
2987
2988 @ Return
2989 PAL_STATUS_T
2990===========================================================================*/
2991static wpt_status dxeTXCompFrame
2992(
2993 WLANDXE_CtrlBlkType *hostCtxt,
2994 WLANDXE_ChannelCBType *channelEntry
2995)
2996{
2997 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2998 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2999 WLANDXE_DescType *currentDesc = NULL;
3000 wpt_uint32 descCtrlValue = 0;
3001 unsigned int *lowThreshold = NULL;
3002
3003 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3004 "%s Enter", __FUNCTION__);
3005
3006 /* Sanity */
3007 if((NULL == hostCtxt) || (NULL == channelEntry))
3008 {
3009 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3010 "dxeTXCompFrame Invalid ARG");
3011 return eWLAN_PAL_STATUS_E_INVAL;
3012 }
3013
3014 if(NULL == hostCtxt->txCompCB)
3015 {
3016 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3017 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003018 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003019 }
3020
3021 wpalMutexAcquire(&channelEntry->dxeChannelLock);
3022
3023 currentCtrlBlk = channelEntry->tailCtrlBlk;
3024 currentDesc = currentCtrlBlk->linkedDesc;
3025
3026 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3027 {
3028 wpalMutexRelease(&channelEntry->dxeChannelLock);
Jeff Johnsone7245742012-09-05 17:12:55 -07003029 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003030 }
3031
3032 /* */
3033 while(1)
3034 {
3035// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3036 descCtrlValue = currentDesc->descCtrl.ctrl;
3037 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3038 {
3039 /* caught up with head, bail out */
3040 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3041 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3042 break;
3043 }
3044
3045 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
3046 channelEntry->numFreeDesc++;
3047 channelEntry->numRsvdDesc--;
3048
3049 /* Send Frame TX Complete notification with frame start fragment location */
3050 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3051 {
3052 hostCtxt->txCompletedFrames--;
3053#ifdef FEATURE_R33D
3054 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3055#else
3056 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3057 if (eWLAN_PAL_STATUS_SUCCESS != status)
3058 {
3059 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3060 "dxeRXFrameReady unable to unlock packet");
3061 wpalMutexRelease(&channelEntry->dxeChannelLock);
3062 return status;
3063 }
3064#endif /* FEATURE_R33D */
3065 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3066 currentCtrlBlk->xfrFrame,
3067 eWLAN_PAL_STATUS_SUCCESS);
3068 channelEntry->numFragmentCurrentChain = 0;
3069 }
3070 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3071 currentDesc = currentCtrlBlk->linkedDesc;
3072
3073 /* Break condition
3074 * Head control block is the control block must be programed for the next TX
3075 * so, head control block is not programmed control block yet
3076 * if loop encounte head control block, stop to complete
3077 * in theory, COMP CB must be called already ??? */
3078 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3079 {
3080 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3081 "dxeTXCompFrame caught up with head ptr");
3082 break;
3083 }
3084 /* VALID Bit check ???? */
3085 }
3086
3087 /* Tail and Head Control block must be same */
3088 channelEntry->tailCtrlBlk = currentCtrlBlk;
3089
3090 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3091 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3092 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3093
3094 /* If specific channel hit low resource condition send notification to upper layer */
3095 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3096 (channelEntry->numFreeDesc > *lowThreshold))
3097 {
3098 /* Change it back if we raised it for fetching a remaining packet from TL */
3099 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3100 {
3101 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3102 }
3103
3104 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3105 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3106 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3107 channelEntry->channelType,
3108 eWLAN_PAL_TRUE);
3109 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3110 }
3111
3112 wpalMutexRelease(&channelEntry->dxeChannelLock);
3113
3114 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3115 "%s Exit", __FUNCTION__);
3116 return status;
3117}
3118
3119/*==========================================================================
3120 @ Function Name
3121 dxeTXEventHandler
3122
3123 @ Description
3124 If DXE HW sends TX related interrupt, this event handler will be called
3125 Handle higher priority channel first
3126 Figureout why interrupt happen and call appropriate final even handler
3127 TX complete or error happen
3128
3129 @ Parameters
3130 void *msgPtr
3131 Even MSG
3132
3133 @ Return
3134 PAL_STATUS_T
3135===========================================================================*/
3136void dxeTXEventHandler
3137(
3138 wpt_msg *msgPtr
3139)
3140{
3141 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3142 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3143 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3144 wpt_uint32 intSrc = 0;
3145 wpt_uint32 chStat = 0;
3146 WLANDXE_ChannelCBType *channelCb = NULL;
3147
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003148 wpt_uint8 bEnableISR = 0;
3149 static wpt_uint8 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003150
3151 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3152 "%s Enter", __FUNCTION__);
3153
3154 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003155 dxeCtxt->ucTxMsgCnt = 0;
3156
3157 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3158 {
3159 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3160 "wlan: TX COMP WLAN Driver re-loading in progress");
3161 return;
3162 }
3163
Jeff Johnson295189b2012-06-20 16:38:30 -07003164 /* Return from here if the RIVA is in IMPS, to avoid register access */
3165 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3166 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003167 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003169 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003170 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3171 if(eWLAN_PAL_STATUS_SUCCESS != status)
3172 {
3173 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003174 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003175 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003176
3177 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3178 if(eWLAN_PAL_STATUS_SUCCESS != status)
3179 {
3180 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3181 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3182 }
3183
3184 if(((dxeCtxt->txCompletedFrames) &&
3185 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3186 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003187 {
3188 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3189 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3190 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3191 "TX COMP INT Enabled, remain TX frame count on ring %d",
3192 dxeCtxt->txCompletedFrames);
3193 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3194 the posibility of a race*/
3195 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3196 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003197 else
3198 {
3199 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3200 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3201 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3202 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3203 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003204 return;
3205 }
3206
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003207 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003208 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3209 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3210 {
3211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3212 "DXE already stopped in TX event handler. Just return");
3213 return;
3214 }
3215
Jeff Johnson295189b2012-06-20 16:38:30 -07003216 /* Disable device interrupt */
3217 /* Read whole interrupt mask register and exclusive only this channel int */
3218 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3219 &intSrc);
3220 if(eWLAN_PAL_STATUS_SUCCESS != status)
3221 {
3222 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3223 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3224 return;
3225 }
3226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3227 "TX Event Handler INT Source 0x%x", intSrc);
3228
3229 /* Test High Priority Channel is the INT source or not */
3230 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3231 if(intSrc & (1 << channelCb->assignedDMAChannel))
3232 {
3233 status = dxeChannelCleanInt(channelCb, &chStat);
3234 if(eWLAN_PAL_STATUS_SUCCESS != status)
3235 {
3236 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3237 "dxeTXEventHandler INT Clean up fail");
3238 return;
3239 }
3240
3241 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3242 {
3243 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3244 "dxeTXEventHandler TX HI status=%x", chStat);
3245 HDXE_ASSERT(0);
3246 }
3247 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3248 {
3249 /* Handle TX complete for high priority channel */
3250 status = dxeTXCompFrame(dxeCtxt,
3251 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003252 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003253 }
3254 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3255 {
3256 /* Handle TX complete for high priority channel */
3257 status = dxeTXCompFrame(dxeCtxt,
3258 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003259 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003260 }
3261 else
3262 {
3263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3264 "dxeTXEventHandler TX HI status=%x", chStat);
3265 }
3266
3267 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3268 {
3269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3270 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3271 }
3272
3273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3274 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3275 }
3276
3277 /* Test Low Priority Channel interrupt is enabled or not */
3278 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3279 if(intSrc & (1 << channelCb->assignedDMAChannel))
3280 {
3281 status = dxeChannelCleanInt(channelCb, &chStat);
3282 if(eWLAN_PAL_STATUS_SUCCESS != status)
3283 {
3284 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3285 "dxeTXEventHandler INT Clean up fail");
3286 return;
3287 }
3288
3289 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3290 {
3291 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3292 "dxeTXEventHandler TX LO status=%x", chStat);
3293 HDXE_ASSERT(0);
3294 }
3295 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3296 {
3297 /* Handle TX complete for low priority channel */
3298 status = dxeTXCompFrame(dxeCtxt,
3299 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003300 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 }
3302 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3303 {
3304 /* Handle TX complete for low priority channel */
3305 status = dxeTXCompFrame(dxeCtxt,
3306 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003307 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003308 }
3309 else
3310 {
3311 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3312 "dxeTXEventHandler TX LO status=%x", chStat);
3313 }
3314
3315 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3316 {
3317 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3318 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3319 }
3320 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3321 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3322 }
3323
3324
3325#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3326 /* Test H2H TX Channel interrupt is enabled or not */
3327 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3328 if(intSrc & (1 << channelCb->assignedDMAChannel))
3329 {
3330 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3331 &chStat);
3332 if(eWLAN_PAL_STATUS_SUCCESS != status)
3333 {
3334 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3335 "dxeChannelCleanInt Read CH STAT register fail");
3336 return;
3337 }
3338
3339 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3340 {
3341 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3342 "WLANDXE_CH_STAT_INT_ERR_MASK occurred");
3343 HDXE_ASSERT(0);
3344 }
3345 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3346 {
3347 /* Handle TX complete for high priority channel */
3348 status = dxeTXCompFrame(dxeCtxt,
3349 channelCb);
3350 if(eWLAN_PAL_STATUS_SUCCESS != status)
3351 {
3352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3353 "dxeTXEventHandler INT Clean up fail");
3354 return;
3355 }
3356 }
3357 else
3358 {
3359 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3360 "unexpected channel state %d", chStat);
3361 }
3362 }
3363#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3364
3365 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3366 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3367 {
3368 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3369 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3371 "TX COMP INT Enabled, remain TX frame count on ring %d",
3372 dxeCtxt->txCompletedFrames);
3373 }
3374
3375 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3376 the posibility of a race*/
3377 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3378
3379 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3380 "%s Exit", __FUNCTION__);
3381 return;
3382}
3383
3384
3385/*==========================================================================
3386 @ Function Name
3387 dxeTXCompleteProcessing
3388
3389 @ Description
3390 If DXE HW sends TX related interrupt, this event handler will be called
3391 Handle higher priority channel first
3392 Figureout why interrupt happen and call appropriate final even handler
3393 TX complete or error happen
3394
3395 @ Parameters
3396 dxeCtxt DXE context
3397
3398 @ Return
3399 PAL_STATUS_T
3400===========================================================================*/
3401void dxeTXCompleteProcessing
3402(
3403 WLANDXE_CtrlBlkType *dxeCtxt
3404)
3405{
3406 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3407 WLANDXE_ChannelCBType *channelCb = NULL;
3408
3409 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3410 "%s Enter", __FUNCTION__);
3411
3412 /* Test High Priority Channel is the INT source or not */
3413 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3414
3415 /* Handle TX complete for high priority channel */
3416 status = dxeTXCompFrame(dxeCtxt, channelCb);
3417
3418 /* Test Low Priority Channel interrupt is enabled or not */
3419 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3420
3421 /* Handle TX complete for low priority channel */
3422 status = dxeTXCompFrame(dxeCtxt, channelCb);
3423
3424 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3425 ((dxeCtxt->txCompletedFrames > 0) ||
3426 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3427 {
3428 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3429 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3430 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3431 "%s %s : %d, %s : %d", __FUNCTION__,
3432 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3433 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3434 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3435 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
3436 }
3437
3438 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3439 the posibility of a race*/
3440 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3441
3442 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3443 "%s Exit", __FUNCTION__);
3444 return;
3445}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003446
3447/*==========================================================================
3448 @ Function Name
3449 dxeTXReSyncDesc
3450
3451 @ Description
3452 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3453 And HW programmed descriptor.
3454 If any async happen between HW/SW TX stall will happen
3455
3456 @ Parameters
3457 void *msgPtr
3458 Message pointer to sync with TX thread
3459
3460 @ Return
3461 NONE
3462===========================================================================*/
3463void dxeTXReSyncDesc
3464(
3465 wpt_msg *msgPtr
3466)
3467{
3468 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3469 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3470 wpt_uint32 nextDescReg;
3471 WLANDXE_ChannelCBType *channelEntry;
3472 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3473 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003474 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003475
3476 if(NULL == msgContent)
3477 {
3478 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3479 "dxeTXReSyncDesc Invalid Control Block");
3480 return;
3481 }
3482
3483 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3484 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3485 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3486
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003487 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003488 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003489 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3491 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3492 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3493 &nextDescReg);
3494 /* Async detect without TX pending frame */
3495 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003496 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003497 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003498 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3500 "TX Async no Pending frame");
3501 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry);
3502 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!");
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003503 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003504 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003505 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003506 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003507 /* Async detect with some TX pending frames
3508 * next descriptor register should sync with first valid descriptor */
3509 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003510 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003511 validCtrlBlk = channelEntry->tailCtrlBlk;
3512 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003513 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003514 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3515 {
3516 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3517 {
3518 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3519 "TX Async");
3520 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3521 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3522 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3523 validCtrlBlk->linkedDescPhyAddr);
3524 }
3525 break;
3526 }
3527 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3528 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3529 {
3530 /* Finished to test till head control blcok, but could not find valid descriptor
3531 * from head to tail all descriptors are invalidated
3532 * host point of view head descriptor is next TX candidate
3533 * So, next descriptor control have to be programmed with head descriptor
3534 * check */
3535 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3536 {
3537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3538 "TX Async with not completed transfered frames, next descriptior must be head");
3539 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3540 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3541 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3542 validCtrlBlk->linkedDescPhyAddr);
3543 }
3544 break;
3545 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003546 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003547 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003548 }
3549
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003550 /* HW/SW descriptor resync is done.
3551 * Next if there are any valid descriptor in chain, Push to HW again */
3552 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3553 {
3554 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3555 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3556 {
3557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3558 "%11s : No TX Pending frame",
3559 channelType[channelEntry->channelType]);
3560 /* No Pending frame, Do nothing */
3561 }
3562 else
3563 {
3564 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3565 "%11s : TX Pending frame, process it",
3566 channelType[channelEntry->channelType]);
3567 validCtrlBlk = channelEntry->tailCtrlBlk;
3568 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3569 {
3570 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3571 {
3572 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3573 "%11s : when exit IMPS found valid descriptor",
3574 channelType[channelEntry->channelType]);
3575
3576 /* Found valid descriptor, kick DXE */
3577 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3578 channelEntry->extraConfig.chan_mask);
3579 break;
3580 }
3581 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3582 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3583 {
3584 /* Finished to test till head control blcok, but could not find valid descriptor
3585 * from head to tail all descriptors are invalidated */
3586 break;
3587 }
3588 }
3589 }
3590 }
3591
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003592 wpalMemoryFree(msgPtr);
3593 return;
3594}
3595
Jeff Johnson295189b2012-06-20 16:38:30 -07003596/*==========================================================================
3597 @ Function Name
3598 dxeTXISR
3599
3600 @ Description
3601 TX interrupt ISR
3602 Platform will call this function if INT is happen
3603 This function must be registered into platform interrupt module
3604
3605 @ Parameters
3606 void *hostCtxt
3607 DXE host driver control context,
3608 pre registerd during interrupt registration
3609
3610 @ Return
3611 PAL_STATUS_T
3612===========================================================================*/
3613static void dxeTXISR
3614(
3615 void *hostCtxt
3616)
3617{
3618 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3619 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3620#ifdef FEATURE_R33D
3621 wpt_uint32 regValue;
3622#endif /* FEATURE_R33D */
3623
3624 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3625 "%s Enter", __FUNCTION__);
3626
3627 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003628 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003629 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003630 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003631 /* Disable interrupt at here,
3632 IMPS or IMPS Pending state should not access RIVA register */
3633 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3634 if(eWLAN_PAL_STATUS_SUCCESS != status)
3635 {
3636 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3637 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3638 return;
3639 }
3640 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3641 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3642 "%s Riva is in %d, return from here ", __FUNCTION__, dxeCtxt->hostPowerState);
3643 return;
3644 }
3645
3646#ifdef FEATURE_R33D
3647 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3648 &regValue);
3649 if(eWLAN_PAL_STATUS_SUCCESS != status)
3650 {
3651 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3652 "dxeTXCompISR Read INT_SRC_RAW fail");
3653 return;
3654 }
3655 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3656 "INT_SRC_RAW 0x%x", regValue);
3657 if(0 == regValue)
3658 {
3659 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3660 "This is not DXE Interrupt, Reject it");
3661 return;
3662 }
3663#endif /* FEATURE_R33D */
3664
3665 /* Disable TX Complete Interrupt at here */
3666 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3667 if(eWLAN_PAL_STATUS_SUCCESS != status)
3668 {
3669 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3670 "dxeTXCompISR Disable TX complete interrupt fail");
3671 return;
3672 }
3673 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3674
3675
3676 if( dxeCtxt->ucTxMsgCnt )
3677 {
3678 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3679 "Avoiding serializing TX Complete event");
3680 return;
3681 }
3682
3683 dxeCtxt->ucTxMsgCnt = 1;
3684
3685 /* Serialize TX complete interrupt upon TX thread */
3686 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3687 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3688 dxeCtxt->txIsrMsg);
3689 if(eWLAN_PAL_STATUS_SUCCESS != status)
3690 {
3691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3692 "dxeTXCompISR interrupt serialize fail status=%d", status);
3693 }
3694
3695 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3696 "%s Exit", __FUNCTION__);
3697 return;
3698}
3699
3700/*-------------------------------------------------------------------------
3701 * Global Function
3702 *-------------------------------------------------------------------------*/
3703/*==========================================================================
3704 @ Function Name
3705 WLANDXE_Open
3706
3707 @ Description
3708 Open host DXE driver, allocate DXE resources
3709 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
3710
3711 @ Parameters
3712 pVoid pAdaptor : Driver global control block pointer
3713
3714 @ Return
3715 pVoid DXE local module control block pointer
3716===========================================================================*/
3717void *WLANDXE_Open
3718(
3719 void
3720)
3721{
3722 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3723 unsigned int idx;
3724 WLANDXE_ChannelCBType *currentChannel = NULL;
3725 int smsmInitState;
3726#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3727 wpt_uint32 sIdx;
3728 WLANDXE_ChannelCBType *channel = NULL;
3729 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
3730 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
3731#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3732
3733 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3734 "%s Enter", __FUNCTION__);
3735
3736 /* This is temporary allocation */
3737 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
3738 if(NULL == tempDxeCtrlBlk)
3739 {
3740 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3741 "WLANDXE_Open Control Block Alloc Fail");
3742 return NULL;
3743 }
3744 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
3745
3746 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
3747 if(eWLAN_PAL_STATUS_SUCCESS != status)
3748 {
3749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3750 "WLANDXE_Open Common Configuration Fail");
3751 WLANDXE_Close(tempDxeCtrlBlk);
3752 return NULL;
3753 }
3754
3755 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3756 {
3757 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3758 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
3759 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
3760 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
3761 {
3762 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
3763 }
3764 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
3765 {
3766 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
3767 }
3768 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
3769 {
3770 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
3771 }
3772 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
3773 {
3774 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
3775 }
3776#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3777 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
3778 {
3779 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
3780 }
3781 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
3782 {
3783 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
3784 }
3785#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3786
3787 /* Config individual channels from channel default setup table */
3788 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
3789 currentChannel);
3790 if(eWLAN_PAL_STATUS_SUCCESS != status)
3791 {
3792 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3793 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
3794 WLANDXE_Close(tempDxeCtrlBlk);
3795 return NULL;
3796 }
3797
3798 /* Allocate DXE Control Block will be used by host DXE driver */
3799 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
3800 if(eWLAN_PAL_STATUS_SUCCESS != status)
3801 {
3802 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3803 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
3804
3805 WLANDXE_Close(tempDxeCtrlBlk);
3806 return NULL;
3807 }
3808 status = wpalMutexInit(&currentChannel->dxeChannelLock);
3809 if(eWLAN_PAL_STATUS_SUCCESS != status)
3810 {
3811 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3812 "WLANDXE_Open Lock Init Fail for channel %d", idx);
3813 WLANDXE_Close(tempDxeCtrlBlk);
3814 return NULL;
3815 }
3816
3817 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3818 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
3819 }
3820
3821 /* Allocate and Init RX READY ISR Serialize Buffer */
3822 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3823 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
3824 {
3825 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3826 "WLANDXE_Open Alloc RX ISR Fail");
3827 WLANDXE_Close(tempDxeCtrlBlk);
3828 return NULL;
3829 }
3830 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
3831 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
3832 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
3833
3834 /* Allocate and Init TX COMP ISR Serialize Buffer */
3835 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3836 if(NULL == tempDxeCtrlBlk->txIsrMsg)
3837 {
3838 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3839 "WLANDXE_Open Alloc TX ISR Fail");
3840 WLANDXE_Close(tempDxeCtrlBlk);
3841 return NULL;
3842 }
3843 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
3844 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
3845 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
3846
3847 /* Allocate and Init RX Packet Available Serialize Message Buffer */
3848 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3849 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
3850 {
3851 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3852 "WLANDXE_Open Alloc RX Packet Available Message Fail");
3853 WLANDXE_Close(tempDxeCtrlBlk);
3854 return NULL;
3855 }
3856 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07003857
3858 /* Allocate and Init CH Debug MSG Serialize Buffer */
3859 tempDxeCtrlBlk->chDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3860 if(NULL == tempDxeCtrlBlk->chDebugMsg)
3861 {
3862 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3863 "WLANDXE_Open Alloc TX ISR Fail");
3864 WLANDXE_Close(tempDxeCtrlBlk);
3865 return NULL;
3866 }
3867 wpalMemoryZero(tempDxeCtrlBlk->chDebugMsg, sizeof(wpt_msg));
3868 tempDxeCtrlBlk->chDebugMsg->callback = dxeRxThreadChannelDebugHandler;
3869 tempDxeCtrlBlk->chDebugMsg->pContext = (void *)tempDxeCtrlBlk;
3870
Jeff Johnson295189b2012-06-20 16:38:30 -07003871 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
3872 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
3873
3874 tempDxeCtrlBlk->freeRXPacket = NULL;
3875 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
3876 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
3877 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003878 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003879
3880 /* Initialize SMSM state
3881 * Init State is
3882 * Clear TX Enable
3883 * RING EMPTY STATE */
3884 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
3885 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
3886 if(0 != smsmInitState)
3887 {
3888 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3889 "SMSM Channel init fail %d", smsmInitState);
3890 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3891 {
3892 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
3893 }
3894 wpalMemoryFree((void *)&tempDxeCtrlBlk->rxIsrMsg);
3895 wpalMemoryFree((void *)&tempDxeCtrlBlk->txIsrMsg);
3896 wpalMemoryFree(tempDxeCtrlBlk);
3897 return NULL;
3898 }
3899
3900 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3901 "WLANDXE_Open Success");
3902 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3903 "%s Exit", __FUNCTION__);
3904 return (void *)tempDxeCtrlBlk;
3905}
3906
3907/*==========================================================================
3908 @ Function Name
3909 WLANDXE_ClientRegistration
3910
3911 @ Description
3912 Make callback functions registration into DXE driver from DXE driver client
3913
3914 @ Parameters
3915 pVoid pDXEContext : DXE module control block
3916 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
3917 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
3918 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
3919 void *userContext : DXE Cliennt control block
3920
3921 @ Return
3922 wpt_status
3923===========================================================================*/
3924wpt_status WLANDXE_ClientRegistration
3925(
3926 void *pDXEContext,
3927 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
3928 WLANDXE_TxCompleteCbType txCompleteCB,
3929 WLANDXE_LowResourceCbType lowResourceCB,
3930 void *userContext
3931)
3932{
3933 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3934 WLANDXE_CtrlBlkType *dxeCtxt;
3935
3936 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3937 "%s Enter", __FUNCTION__);
3938
3939 /* Sanity */
3940 if(NULL == pDXEContext)
3941 {
3942 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3943 "WLANDXE_ClientRegistration Invalid DXE CB");
3944 return eWLAN_PAL_STATUS_E_INVAL;
3945 }
3946
3947 if(NULL == rxFrameReadyCB)
3948 {
3949 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3950 "WLANDXE_ClientRegistration Invalid RX READY CB");
3951 return eWLAN_PAL_STATUS_E_INVAL;
3952 }
3953
3954 if(NULL == txCompleteCB)
3955 {
3956 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3957 "WLANDXE_ClientRegistration Invalid txCompleteCB");
3958 return eWLAN_PAL_STATUS_E_INVAL;
3959 }
3960
3961 if(NULL == lowResourceCB)
3962 {
3963 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3964 "WLANDXE_ClientRegistration Invalid lowResourceCB");
3965 return eWLAN_PAL_STATUS_E_INVAL;
3966 }
3967
3968 if(NULL == userContext)
3969 {
3970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3971 "WLANDXE_ClientRegistration Invalid userContext");
3972 return eWLAN_PAL_STATUS_E_INVAL;
3973 }
3974
3975 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3976
3977 /* Assign */
3978 dxeCtxt->rxReadyCB = rxFrameReadyCB;
3979 dxeCtxt->txCompCB = txCompleteCB;
3980 dxeCtxt->lowResourceCB = lowResourceCB;
3981 dxeCtxt->clientCtxt = userContext;
3982
3983 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3984 "%s Exit", __FUNCTION__);
3985 return status;
3986}
3987
3988/*==========================================================================
3989 @ Function Name
3990 WLANDXE_Start
3991
3992 @ Description
3993 Start Host DXE driver
3994 Initialize DXE channels and start channel
3995
3996 @ Parameters
3997 pVoid pDXEContext : DXE module control block
3998
3999 @ Return
4000 wpt_status
4001===========================================================================*/
4002wpt_status WLANDXE_Start
4003(
4004 void *pDXEContext
4005)
4006{
4007 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4008 wpt_uint32 idx;
4009 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4010
4011 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4012 "%s Enter", __FUNCTION__);
4013
4014 /* Sanity */
4015 if(NULL == pDXEContext)
4016 {
4017 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4018 "WLANDXE_Start Invalid DXE CB");
4019 return eWLAN_PAL_STATUS_E_INVAL;
4020 }
4021 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4022
4023 /* WLANDXE_Start called means DXE engine already initiates
4024 * And DXE HW is reset and init finished
4025 * But here to make sure HW is initialized, reset again */
4026 status = dxeEngineCoreStart(dxeCtxt);
4027 if(eWLAN_PAL_STATUS_SUCCESS != status)
4028 {
4029 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4030 "WLANDXE_Start DXE HW init Fail");
4031 return status;
4032 }
4033
4034 /* Individual Channel Start */
4035 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4036 {
4037 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4038 "WLANDXE_Start Channel %s Start", channelType[idx]);
4039
4040 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4041 /* Make connection between DXE descriptor and DXE control block */
4042 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4043 if(eWLAN_PAL_STATUS_SUCCESS != status)
4044 {
4045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4046 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4047 return status;
4048 }
4049
4050 /* Program each channel register with configuration arguments */
4051 status = dxeChannelInitProgram(dxeCtxt,
4052 &dxeCtxt->dxeChannel[idx]);
4053 if(eWLAN_PAL_STATUS_SUCCESS != status)
4054 {
4055 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4056 "WLANDXE_Start %d Program DMA channel Fail", idx);
4057 return status;
4058 }
4059
4060 /* ??? Trigger to start DMA channel
4061 * This must be seperated from ??? */
4062 status = dxeChannelStart(dxeCtxt,
4063 &dxeCtxt->dxeChannel[idx]);
4064 if(eWLAN_PAL_STATUS_SUCCESS != status)
4065 {
4066 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4067 "WLANDXE_Start %d Channel Start Fail", idx);
4068 return status;
4069 }
4070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4071 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4072 }
4073
4074 /* Register ISR to OS */
4075 /* Register TX complete interrupt into platform */
4076 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4077 dxeTXISR,
4078 dxeCtxt);
4079 if(eWLAN_PAL_STATUS_SUCCESS != status)
4080 {
4081 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4082 "WLANDXE_Start TX comp interrupt registration Fail");
4083 return status;
4084 }
4085
4086 /* Register RX ready interrupt into platform */
4087 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4088 dxeRXISR,
4089 dxeCtxt);
4090 if(eWLAN_PAL_STATUS_SUCCESS != status)
4091 {
4092 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4093 "WLANDXE_Start RX Ready interrupt registration Fail");
4094 return status;
4095 }
4096
4097 /* Enable system level ISR */
4098 /* Enable RX ready Interrupt at here */
4099 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4100 if(eWLAN_PAL_STATUS_SUCCESS != status)
4101 {
4102 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4103 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4104 return status;
4105 }
4106
4107 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4108 "%s Exit", __FUNCTION__);
4109 return status;
4110}
4111
4112/*==========================================================================
4113 @ Function Name
4114 WLANDXE_TXFrame
4115
4116 @ Description
4117 Trigger frame transmit from host to RIVA
4118
4119 @ Parameters
4120 pVoid pDXEContext : DXE Control Block
4121 wpt_packet pPacket : transmit packet structure
4122 WDTS_ChannelType channel : TX channel
4123
4124 @ Return
4125 wpt_status
4126===========================================================================*/
4127wpt_status WLANDXE_TxFrame
4128(
4129 void *pDXEContext,
4130 wpt_packet *pPacket,
4131 WDTS_ChannelType channel
4132)
4133{
4134 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4135 WLANDXE_ChannelCBType *currentChannel = NULL;
4136 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4137 unsigned int *lowThreshold = NULL;
4138
4139 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4140 "%s Enter", __FUNCTION__);
4141
4142 /* Sanity */
4143 if(NULL == pDXEContext)
4144 {
4145 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4146 "WLANDXE_Start Invalid DXE CB");
4147 return eWLAN_PAL_STATUS_E_INVAL;
4148 }
4149
4150 if(NULL == pPacket)
4151 {
4152 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4153 "WLANDXE_Start Invalid pPacket");
4154 return eWLAN_PAL_STATUS_E_INVAL;
4155 }
4156
4157 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4158 {
4159 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4160 "WLANDXE_Start Invalid channel");
4161 return eWLAN_PAL_STATUS_E_INVAL;
4162 }
4163
4164 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4165
4166 currentChannel = &dxeCtxt->dxeChannel[channel];
4167
4168
4169 wpalMutexAcquire(&currentChannel->dxeChannelLock);
4170
4171 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4172 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4173 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4174
4175 /* Decide have to activate TX complete event or not */
4176 switch(dxeCtxt->txCompInt.txIntEnable)
4177 {
4178 /* TX complete interrupt will be activated when low DXE resource */
4179 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4180 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4181 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4182 {
4183 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4184 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4185 channel,
4186 eWLAN_PAL_FALSE);
4187 }
4188 break;
4189
4190 /* TX complete interrupt will be activated n number of frames transfered */
4191 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4192 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4193 {
4194 currentChannel->numFrameBeforeInt++;
4195 }
4196 break;
4197
4198 /* TX complete interrupt will be activated periodically */
4199 case WLANDXE_TX_COMP_INT_TIMER:
4200 break;
4201 }
4202
4203 dxeCtxt->txCompletedFrames++;
4204
4205 /* Update DXE descriptor, this is frame based
4206 * if a frame consist of N fragments, N Descriptor will be programed */
4207 status = dxeTXPushFrame(currentChannel, pPacket);
4208 if(eWLAN_PAL_STATUS_SUCCESS != status)
4209 {
4210 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4211 "WLANDXE_TxFrame TX Push Frame fail");
4212 wpalMutexRelease(&currentChannel->dxeChannelLock);
4213 return status;
4214 }
4215
4216 /* If specific channel hit low resource condition, send notification to upper layer */
4217 if(currentChannel->numFreeDesc <= *lowThreshold)
4218 {
4219 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4220 channel,
4221 eWLAN_PAL_FALSE);
4222 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
4223 }
4224 wpalMutexRelease(&currentChannel->dxeChannelLock);
4225
4226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4227 "%s Exit", __FUNCTION__);
4228 return status;
4229}
4230
4231/*==========================================================================
4232 @ Function Name
4233 WLANDXE_CompleteTX
4234
4235 @ Description
4236 Informs DXE that the current series of Tx packets is complete
4237
4238 @ Parameters
4239 pContext pDXEContext : DXE Control Block
4240 ucTxResReq TX resource number required by TL/WDI
4241
4242 @ Return
4243 wpt_status
4244===========================================================================*/
4245wpt_status
4246WLANDXE_CompleteTX
4247(
4248 void* pContext,
4249 wpt_uint32 ucTxResReq
4250)
4251{
4252 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4253 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4254 WLANDXE_ChannelCBType *channelCb = NULL;
4255 wpt_boolean inLowRes;
4256
4257 /* Sanity Check */
4258 if( NULL == pContext )
4259 {
4260 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4261 "WLANDXE_CompleteTX invalid param");
4262 return eWLAN_PAL_STATUS_E_INVAL;
4263 }
4264
4265 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4266 inLowRes = channelCb->hitLowResource;
4267
4268 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4269 {
4270 /* Raise threshold temporarily if necessary */
4271 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4272
4273 if(eWLAN_PAL_FALSE == inLowRes)
4274 {
4275 /* Put the channel to low resource condition */
4276 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4277 WDTS_CHANNEL_TX_LOW_PRI,
4278 eWLAN_PAL_FALSE);
4279 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
4280 }
4281 }
4282
4283 /*Try to reclaim resources*/
4284 dxeTXCompleteProcessing(dxeCtxt);
4285
4286 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4287 because its fragment size is larger than DXE free resource. */
4288 if(0 < ucTxResReq)
4289 {
4290 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4291 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4292 {
4293 /* DXE has not been in low resource condition. DXE forces to kick off
4294 TX tranmit */
4295 if((eWLAN_PAL_FALSE == inLowRes) &&
4296 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4297 {
4298 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4299 WDTS_CHANNEL_TX_LOW_PRI,
4300 eWLAN_PAL_FALSE);
4301 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4302 WDTS_CHANNEL_TX_LOW_PRI,
4303 eWLAN_PAL_TRUE);
4304 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4305 }
4306 }
4307 else
4308 {
4309 /* DXE doesn't have enough free DXE resources. Put the channel
4310 to low resource condition. */
4311 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4312 {
4313 /* Put the channel to low resource condition */
4314 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4315 WDTS_CHANNEL_TX_LOW_PRI,
4316 eWLAN_PAL_FALSE);
4317 channelCb->hitLowResource = eWLAN_PAL_TRUE;
4318 }
4319 }
4320 }
4321
4322 return status;
4323}
4324
4325/*==========================================================================
4326 @ Function Name
4327 WLANDXE_Stop
4328
4329 @ Description
4330 Stop DXE channels and DXE engine operations
4331 Disable all channel interrupt
4332 Stop all channel operation
4333
4334 @ Parameters
4335 pVoid pDXEContext : DXE Control Block
4336
4337 @ Return
4338 wpt_status
4339===========================================================================*/
4340wpt_status WLANDXE_Stop
4341(
4342 void *pDXEContext
4343)
4344{
4345 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4346 wpt_uint32 idx;
4347 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4348
4349 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4350 "%s Enter", __FUNCTION__);
4351
4352 /* Sanity */
4353 if(NULL == pDXEContext)
4354 {
4355 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4356 "WLANDXE_Stop Invalid DXE CB");
4357 return eWLAN_PAL_STATUS_E_INVAL;
4358 }
4359
4360 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4361 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4362 {
4363 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4364 if(eWLAN_PAL_STATUS_SUCCESS != status)
4365 {
4366 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4367 "WLANDXE_Stop Channel %d Stop Fail", idx);
4368 return status;
4369 }
4370 }
4371
4372 /* During Stop unregister interrupt */
4373 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4374 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4375
4376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4377 "%s Exit", __FUNCTION__);
4378 return status;
4379}
4380
4381/*==========================================================================
4382 @ Function Name
4383 WLANDXE_Close
4384
4385 @ Description
4386 Close DXE channels
4387 Free DXE related resources
4388 DXE descriptor free
4389 Descriptor control block free
4390 Pre allocated RX buffer free
4391
4392 @ Parameters
4393 pVoid pDXEContext : DXE Control Block
4394
4395 @ Return
4396 wpt_status
4397===========================================================================*/
4398wpt_status WLANDXE_Close
4399(
4400 void *pDXEContext
4401)
4402{
4403 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4404 wpt_uint32 idx;
4405 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4406#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4407 wpt_uint32 sIdx;
4408 WLANDXE_ChannelCBType *channel = NULL;
4409 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4410 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4411#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4412
4413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4414 "%s Enter", __FUNCTION__);
4415
4416 /* Sanity */
4417 if(NULL == pDXEContext)
4418 {
4419 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4420 "WLANDXE_Stop Invalid DXE CB");
4421 return eWLAN_PAL_STATUS_E_INVAL;
4422 }
4423
4424 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4425 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4426 {
4427 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
4428 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4429#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4430 channel = &dxeCtxt->dxeChannel[idx];
4431 crntDescCB = channel->headCtrlBlk;
4432 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4433 {
4434 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4435 wpalMemoryFree((void *)crntDescCB);
4436 crntDescCB = nextDescCB;
4437 if(NULL == crntDescCB)
4438 {
4439 break;
4440 }
4441 }
4442#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4443 }
4444
4445 if(NULL != dxeCtxt->rxIsrMsg)
4446 {
4447 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4448 }
4449 if(NULL != dxeCtxt->txIsrMsg)
4450 {
4451 wpalMemoryFree(dxeCtxt->txIsrMsg);
4452 }
4453 if(NULL != dxeCtxt->rxPktAvailMsg)
4454 {
4455 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4456 }
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004457 if(NULL != dxeCtxt->chDebugMsg)
4458 {
4459 wpalMemoryFree(dxeCtxt->chDebugMsg);
4460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004461
4462 wpalMemoryFree(pDXEContext);
4463
4464 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4465 "%s Exit", __FUNCTION__);
4466 return status;
4467}
4468
4469/*==========================================================================
4470 @ Function Name
4471 WLANDXE_TriggerTX
4472
4473 @ Description
4474 TBD
4475
4476 @ Parameters
4477 pVoid pDXEContext : DXE Control Block
4478
4479 @ Return
4480 wpt_status
4481===========================================================================*/
4482wpt_status WLANDXE_TriggerTX
4483(
4484 void *pDXEContext
4485)
4486{
4487 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4488
4489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4490 "%s Enter", __FUNCTION__);
4491
4492 /* TBD */
4493
4494 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4495 "%s Exit", __FUNCTION__);
4496 return status;
4497}
4498
4499/*==========================================================================
4500 @ Function Name
4501 dxeTxThreadSetPowerStateEventHandler
4502
4503 @ Description
4504 If WDI sends set power state req, this event handler will be called in Tx
4505 thread context
4506
4507 @ Parameters
4508 void *msgPtr
4509 Event MSG
4510
4511 @ Return
4512 None
4513===========================================================================*/
4514void dxeTxThreadSetPowerStateEventHandler
4515(
4516 wpt_msg *msgPtr
4517)
4518{
4519 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4520 WLANDXE_CtrlBlkType *dxeCtxt;
4521 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4522 WLANDXE_PowerStateType reqPowerState;
4523
4524 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4525 "%s Enter", __FUNCTION__);
4526
Jeff Johnson295189b2012-06-20 16:38:30 -07004527 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4528 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4529 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4530
4531 switch(reqPowerState)
4532 {
4533 case WLANDXE_POWER_STATE_BMPS:
4534 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4535 {
4536 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4537 //based on amount of TX and RX activity - during this time any received
4538 // management frames will remain un-processed consuming RX buffers
4539 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4540 dxeCtxt->hostPowerState = reqPowerState;
4541 }
4542 else
4543 {
4544 status = eWLAN_PAL_STATUS_E_INVAL;
4545 }
4546 break;
4547 case WLANDXE_POWER_STATE_IMPS:
4548 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4549 {
4550 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4551 }
4552 else
4553 {
4554 status = eWLAN_PAL_STATUS_E_INVAL;
4555 }
4556 break;
4557 case WLANDXE_POWER_STATE_FULL:
4558 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4559 {
4560 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4561 }
4562 dxeCtxt->hostPowerState = reqPowerState;
4563 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4564 break;
4565 case WLANDXE_POWER_STATE_DOWN:
4566 WLANDXE_Stop((void *)dxeCtxt);
4567 break;
4568 default:
4569 //assert
4570 break;
4571 }
4572
4573 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4574 {
4575 dxeCtxt->setPowerStateCb(status,
4576 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4577 }
4578 /* Free MSG buffer */
4579 wpalMemoryFree(msgPtr);
4580 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4581 "%s Exit", __FUNCTION__);
4582 return;
4583}
4584
4585
4586/*==========================================================================
4587 @ Function Name
4588 dxeRxThreadSetPowerStateEventHandler
4589
4590 @ Description
4591 If WDI sends set power state req, this event handler will be called in Rx
4592 thread context
4593
4594 @ Parameters
4595 void *msgPtr
4596 Event MSG
4597
4598 @ Return
4599 None
4600===========================================================================*/
4601void dxeRxThreadSetPowerStateEventHandler
4602(
4603 wpt_msg *msgPtr
4604)
4605{
4606 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4607
4608 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4609 "%s Enter", __FUNCTION__);
4610
4611 /* Now serialise the message through Tx thread also to make sure
4612 * no register access when RIVA is in powersave */
4613 /*Use the same message pointer just change the call back function */
4614 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4615 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4616 msgPtr);
4617 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4618 {
4619 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4620 "Tx thread Set power state req serialize fail status=%d",
4621 status, 0, 0);
4622 }
4623
4624 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4625 "%s Exit", __FUNCTION__);
4626}
4627
4628/*==========================================================================
4629 @ Function Name
4630 WLANDXE_SetPowerState
4631
4632 @ Description
4633 From Client let DXE knows what is the WLAN HW(RIVA) power state
4634
4635 @ Parameters
4636 pVoid pDXEContext : DXE Control Block
4637 WLANDXE_PowerStateType powerState
4638
4639 @ Return
4640 wpt_status
4641===========================================================================*/
4642wpt_status WLANDXE_SetPowerState
4643(
4644 void *pDXEContext,
4645 WDTS_PowerStateType powerState,
4646 WDTS_SetPSCbType cBack
4647)
4648{
4649 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4650 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4651 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004652 wpt_msg *rxCompMsg;
4653 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07004654
4655 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4656 "%s Enter", __FUNCTION__);
4657 if(NULL == pDXEContext)
4658 {
4659 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4660 "NULL pDXEContext passed by caller", 0, 0, 0);
4661 return eWLAN_PAL_STATUS_E_FAILURE;
4662 }
4663 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
4664
Jeff Johnson295189b2012-06-20 16:38:30 -07004665 switch(powerState)
4666 {
4667 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004668 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
4669 {
4670 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4671 if(NULL == txDescReSyncMsg)
4672 {
4673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4674 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
4675 }
4676 else
4677 {
4678 txDescReSyncMsg->callback = dxeTXReSyncDesc;
4679 txDescReSyncMsg->pContext = pDxeCtrlBlk;
4680 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4681 txDescReSyncMsg);
4682 if(eWLAN_PAL_STATUS_SUCCESS != status)
4683 {
4684 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4685 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
4686 }
4687 }
4688 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004689 hostPowerState = WLANDXE_POWER_STATE_FULL;
4690 break;
4691 case WDTS_POWER_STATE_BMPS:
4692 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
4693 hostPowerState = WLANDXE_POWER_STATE_BMPS;
4694 break;
4695 case WDTS_POWER_STATE_IMPS:
4696 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
4697 hostPowerState = WLANDXE_POWER_STATE_IMPS;
4698 break;
4699 case WDTS_POWER_STATE_DOWN:
4700 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
4701 hostPowerState = WLANDXE_POWER_STATE_DOWN;
4702 break;
4703 default:
4704 hostPowerState = WLANDXE_POWER_STATE_MAX;
4705 }
4706
4707 // A callback i.e. ACK back is needed only when we want to enable BMPS
4708 // and the data/management path is active because we want to ensure
4709 // DXE registers are not accessed when RIVA may be power-collapsed. So
4710 // we need a callback in enter_bmps_req (the request to RIVA is sent
4711 // only after ACK back from TX thread). A callback is not needed in
4712 // finish_scan_req during BMPS since data-path is resumed only in
4713 // finish_scan_rsp and no management frames are sent in between. No
4714 // callback is needed when going from BMPS enabled to BMPS suspended/
4715 // disabled when it is known that RIVA is awake and cannot enter power
4716 // collapse autonomously so no callback is needed in exit_bmps_rsp or
4717 // init_scan_rsp
4718 if ( cBack )
4719 {
4720 //serialize through Rx thread
4721 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4722 if(NULL == rxCompMsg)
4723 {
4724 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4725 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
4726 return eWLAN_PAL_STATUS_E_RESOURCES;
4727 }
4728
4729 /* Event type, where it must be defined???? */
4730 /* THIS MUST BE CLEARED ASAP
4731 txCompMsg->type = TX_COMPLETE; */
4732 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
4733 rxCompMsg->pContext = pDxeCtrlBlk;
4734 rxCompMsg->val = hostPowerState;
4735 rxCompMsg->ptr = cBack;
4736 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
4737 rxCompMsg);
4738 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4739 {
4740 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4741 "Rx thread Set power state req serialize fail status=%d",
4742 status, 0, 0);
4743 }
4744 }
4745 else
4746 {
4747 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
4748 {
4749 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
4750 {
4751 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4752 }
4753 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
4754 {
4755 /* Requested Full power from exit IMPS, reenable the interrupts*/
4756 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
4757 {
4758 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4759 /* Enable RX interrupt at here, if new PS is not IMPS */
4760 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4761 if(eWLAN_PAL_STATUS_SUCCESS != status)
4762 {
4763 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4764 "%s Enable RX ready interrupt fail", __FUNCTION__);
4765 return status;
4766 }
4767 }
4768 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
4769 {
4770 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004771 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004772 /* Enable RX interrupt at here, if new PS is not IMPS */
4773 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4774 if(eWLAN_PAL_STATUS_SUCCESS != status)
4775 {
4776 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4777 "%s Enable TX comp interrupt fail", __FUNCTION__);
4778 return status;
4779 }
4780 }
4781 }
4782 pDxeCtrlBlk->hostPowerState = hostPowerState;
4783 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4784 }
4785 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
4786 {
4787 pDxeCtrlBlk->hostPowerState = hostPowerState;
4788 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4789 }
4790 else
4791 {
4792 HDXE_ASSERT(0);
4793 }
4794 }
4795
4796 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4797 "%s Exit", __FUNCTION__);
4798
4799 return status;
4800}
4801
4802/*==========================================================================
4803 @ Function Name
4804 WLANDXE_GetFreeTxDataResNumber
4805
4806 @ Description
4807 Returns free descriptor numbers for TX data channel (TX high priority)
4808
4809 @ Parameters
4810 pVoid pDXEContext : DXE Control Block
4811
4812 @ Return
4813 wpt_uint32 Free descriptor number of TX high pri ch
4814===========================================================================*/
4815wpt_uint32 WLANDXE_GetFreeTxDataResNumber
4816(
4817 void *pDXEContext
4818)
4819{
4820 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4821 "%s Enter", __FUNCTION__);
4822
4823 if(NULL == pDXEContext)
4824 {
4825 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4826 "NULL parameter passed by caller", 0, 0, 0);
4827 return (0);
4828 }
4829
4830 return
4831 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
4832}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004833
4834/*==========================================================================
4835 @ Function Name
4836 WLANDXE_ChannelDebug
4837
4838 @ Description
4839 Display DXE Channel debugging information
4840 User may request to display DXE channel snapshot
4841 Or if host driver detects any abnormal stcuk may display
4842
4843 @ Parameters
4844 displaySnapshot : Dispaly DXE snapshot option
4845 enableStallDetect : Enable stall detect feature
4846 This feature will take effect to data performance
4847 Not integrate till fully verification
4848
4849 @ Return
4850 NONE
4851
4852===========================================================================*/
4853void WLANDXE_ChannelDebug
4854(
4855 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004856 wpt_boolean enableStallDetect,
4857 wpt_boolean fullChannelsDump
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004858)
4859{
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004860 wpt_uint32 regValue;
4861 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4862
4863 /* Debug Type 1, Display current snapshot */
4864 if(displaySnapshot)
4865 {
4866 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
4867 * This will not simply wakeup RIVA
4868 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004869 if(fullChannelsDump)
4870 {
4871 /* Full DXE Channel dump, kick DXE TX */
4872 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4873 }
4874 else
4875 {
4876 /* Partial DXE Channel dump,
4877 do not kick DXE TX, must be handled by TX Thread */
4878 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
4879 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004880 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4881 "Host power state %d, RIVA power state %d",
4882 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
4883 /* Get free BD count */
4884 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
4885 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4886 "TX Pending frames count %d, Current available BD %d",
4887 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004888 if(fullChannelsDump)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004889 {
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004890 tempDxeCtrlBlk->chDebugMsg->callback = dxeRxThreadChannelDebugHandler;
4891 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), tempDxeCtrlBlk->chDebugMsg);
4892 if (eWLAN_PAL_STATUS_SUCCESS != status)
4893 {
4894 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4895 "Rx thread state dump req serialize fail status=%d",
4896 status, 0, 0);
4897 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004898 }
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004899 else
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004900 {
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004901 tempDxeCtrlBlk->chDebugMsg->callback = dxeRxChannelsStatus;
4902 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), tempDxeCtrlBlk->chDebugMsg);
4903 if (eWLAN_PAL_STATUS_SUCCESS != status)
4904 {
4905 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4906 "Rx thread partial state dump req serialize fail status=%d",
4907 status, 0, 0);
4908 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004909 }
4910 }
4911
4912 /* Debug Type 2, toggling stall detect enable/disable */
4913 if(enableStallDetect)
4914 {
4915 /* Do nothing till not
4916 * This feature will take effect to data path, needed intensive test */
4917 }
4918 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004919}