blob: d1aeea0479442e6fc1e46e93f56bfda6a14a7931 [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
3550 wpalMemoryFree(msgPtr);
3551 return;
3552}
3553
Jeff Johnson295189b2012-06-20 16:38:30 -07003554/*==========================================================================
3555 @ Function Name
3556 dxeTXISR
3557
3558 @ Description
3559 TX interrupt ISR
3560 Platform will call this function if INT is happen
3561 This function must be registered into platform interrupt module
3562
3563 @ Parameters
3564 void *hostCtxt
3565 DXE host driver control context,
3566 pre registerd during interrupt registration
3567
3568 @ Return
3569 PAL_STATUS_T
3570===========================================================================*/
3571static void dxeTXISR
3572(
3573 void *hostCtxt
3574)
3575{
3576 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3577 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3578#ifdef FEATURE_R33D
3579 wpt_uint32 regValue;
3580#endif /* FEATURE_R33D */
3581
3582 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3583 "%s Enter", __FUNCTION__);
3584
3585 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003586 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003587 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003588 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 /* Disable interrupt at here,
3590 IMPS or IMPS Pending state should not access RIVA register */
3591 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3592 if(eWLAN_PAL_STATUS_SUCCESS != status)
3593 {
3594 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3595 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3596 return;
3597 }
3598 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3599 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3600 "%s Riva is in %d, return from here ", __FUNCTION__, dxeCtxt->hostPowerState);
3601 return;
3602 }
3603
3604#ifdef FEATURE_R33D
3605 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3606 &regValue);
3607 if(eWLAN_PAL_STATUS_SUCCESS != status)
3608 {
3609 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3610 "dxeTXCompISR Read INT_SRC_RAW fail");
3611 return;
3612 }
3613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3614 "INT_SRC_RAW 0x%x", regValue);
3615 if(0 == regValue)
3616 {
3617 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3618 "This is not DXE Interrupt, Reject it");
3619 return;
3620 }
3621#endif /* FEATURE_R33D */
3622
3623 /* Disable TX Complete Interrupt at here */
3624 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3625 if(eWLAN_PAL_STATUS_SUCCESS != status)
3626 {
3627 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3628 "dxeTXCompISR Disable TX complete interrupt fail");
3629 return;
3630 }
3631 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3632
3633
3634 if( dxeCtxt->ucTxMsgCnt )
3635 {
3636 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3637 "Avoiding serializing TX Complete event");
3638 return;
3639 }
3640
3641 dxeCtxt->ucTxMsgCnt = 1;
3642
3643 /* Serialize TX complete interrupt upon TX thread */
3644 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3645 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3646 dxeCtxt->txIsrMsg);
3647 if(eWLAN_PAL_STATUS_SUCCESS != status)
3648 {
3649 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3650 "dxeTXCompISR interrupt serialize fail status=%d", status);
3651 }
3652
3653 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3654 "%s Exit", __FUNCTION__);
3655 return;
3656}
3657
3658/*-------------------------------------------------------------------------
3659 * Global Function
3660 *-------------------------------------------------------------------------*/
3661/*==========================================================================
3662 @ Function Name
3663 WLANDXE_Open
3664
3665 @ Description
3666 Open host DXE driver, allocate DXE resources
3667 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
3668
3669 @ Parameters
3670 pVoid pAdaptor : Driver global control block pointer
3671
3672 @ Return
3673 pVoid DXE local module control block pointer
3674===========================================================================*/
3675void *WLANDXE_Open
3676(
3677 void
3678)
3679{
3680 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3681 unsigned int idx;
3682 WLANDXE_ChannelCBType *currentChannel = NULL;
3683 int smsmInitState;
3684#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3685 wpt_uint32 sIdx;
3686 WLANDXE_ChannelCBType *channel = NULL;
3687 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
3688 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
3689#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3690
3691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3692 "%s Enter", __FUNCTION__);
3693
3694 /* This is temporary allocation */
3695 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
3696 if(NULL == tempDxeCtrlBlk)
3697 {
3698 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3699 "WLANDXE_Open Control Block Alloc Fail");
3700 return NULL;
3701 }
3702 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
3703
3704 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
3705 if(eWLAN_PAL_STATUS_SUCCESS != status)
3706 {
3707 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3708 "WLANDXE_Open Common Configuration Fail");
3709 WLANDXE_Close(tempDxeCtrlBlk);
3710 return NULL;
3711 }
3712
3713 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3714 {
3715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3716 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
3717 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
3718 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
3719 {
3720 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
3721 }
3722 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
3723 {
3724 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
3725 }
3726 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
3727 {
3728 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
3729 }
3730 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
3731 {
3732 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
3733 }
3734#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3735 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
3736 {
3737 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
3738 }
3739 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
3740 {
3741 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
3742 }
3743#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3744
3745 /* Config individual channels from channel default setup table */
3746 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
3747 currentChannel);
3748 if(eWLAN_PAL_STATUS_SUCCESS != status)
3749 {
3750 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3751 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
3752 WLANDXE_Close(tempDxeCtrlBlk);
3753 return NULL;
3754 }
3755
3756 /* Allocate DXE Control Block will be used by host DXE driver */
3757 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
3758 if(eWLAN_PAL_STATUS_SUCCESS != status)
3759 {
3760 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3761 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
3762
3763 WLANDXE_Close(tempDxeCtrlBlk);
3764 return NULL;
3765 }
3766 status = wpalMutexInit(&currentChannel->dxeChannelLock);
3767 if(eWLAN_PAL_STATUS_SUCCESS != status)
3768 {
3769 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3770 "WLANDXE_Open Lock Init Fail for channel %d", idx);
3771 WLANDXE_Close(tempDxeCtrlBlk);
3772 return NULL;
3773 }
3774
3775 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3776 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
3777 }
3778
3779 /* Allocate and Init RX READY ISR Serialize Buffer */
3780 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3781 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
3782 {
3783 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3784 "WLANDXE_Open Alloc RX ISR Fail");
3785 WLANDXE_Close(tempDxeCtrlBlk);
3786 return NULL;
3787 }
3788 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
3789 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
3790 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
3791
3792 /* Allocate and Init TX COMP ISR Serialize Buffer */
3793 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3794 if(NULL == tempDxeCtrlBlk->txIsrMsg)
3795 {
3796 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3797 "WLANDXE_Open Alloc TX ISR Fail");
3798 WLANDXE_Close(tempDxeCtrlBlk);
3799 return NULL;
3800 }
3801 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
3802 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
3803 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
3804
3805 /* Allocate and Init RX Packet Available Serialize Message Buffer */
3806 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3807 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
3808 {
3809 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3810 "WLANDXE_Open Alloc RX Packet Available Message Fail");
3811 WLANDXE_Close(tempDxeCtrlBlk);
3812 return NULL;
3813 }
3814 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07003815
3816 /* Allocate and Init CH Debug MSG Serialize Buffer */
3817 tempDxeCtrlBlk->chDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3818 if(NULL == tempDxeCtrlBlk->chDebugMsg)
3819 {
3820 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3821 "WLANDXE_Open Alloc TX ISR Fail");
3822 WLANDXE_Close(tempDxeCtrlBlk);
3823 return NULL;
3824 }
3825 wpalMemoryZero(tempDxeCtrlBlk->chDebugMsg, sizeof(wpt_msg));
3826 tempDxeCtrlBlk->chDebugMsg->callback = dxeRxThreadChannelDebugHandler;
3827 tempDxeCtrlBlk->chDebugMsg->pContext = (void *)tempDxeCtrlBlk;
3828
Jeff Johnson295189b2012-06-20 16:38:30 -07003829 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
3830 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
3831
3832 tempDxeCtrlBlk->freeRXPacket = NULL;
3833 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
3834 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
3835 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003836 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003837
3838 /* Initialize SMSM state
3839 * Init State is
3840 * Clear TX Enable
3841 * RING EMPTY STATE */
3842 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
3843 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
3844 if(0 != smsmInitState)
3845 {
3846 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3847 "SMSM Channel init fail %d", smsmInitState);
3848 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3849 {
3850 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
3851 }
3852 wpalMemoryFree((void *)&tempDxeCtrlBlk->rxIsrMsg);
3853 wpalMemoryFree((void *)&tempDxeCtrlBlk->txIsrMsg);
3854 wpalMemoryFree(tempDxeCtrlBlk);
3855 return NULL;
3856 }
3857
3858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3859 "WLANDXE_Open Success");
3860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3861 "%s Exit", __FUNCTION__);
3862 return (void *)tempDxeCtrlBlk;
3863}
3864
3865/*==========================================================================
3866 @ Function Name
3867 WLANDXE_ClientRegistration
3868
3869 @ Description
3870 Make callback functions registration into DXE driver from DXE driver client
3871
3872 @ Parameters
3873 pVoid pDXEContext : DXE module control block
3874 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
3875 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
3876 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
3877 void *userContext : DXE Cliennt control block
3878
3879 @ Return
3880 wpt_status
3881===========================================================================*/
3882wpt_status WLANDXE_ClientRegistration
3883(
3884 void *pDXEContext,
3885 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
3886 WLANDXE_TxCompleteCbType txCompleteCB,
3887 WLANDXE_LowResourceCbType lowResourceCB,
3888 void *userContext
3889)
3890{
3891 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3892 WLANDXE_CtrlBlkType *dxeCtxt;
3893
3894 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3895 "%s Enter", __FUNCTION__);
3896
3897 /* Sanity */
3898 if(NULL == pDXEContext)
3899 {
3900 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3901 "WLANDXE_ClientRegistration Invalid DXE CB");
3902 return eWLAN_PAL_STATUS_E_INVAL;
3903 }
3904
3905 if(NULL == rxFrameReadyCB)
3906 {
3907 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3908 "WLANDXE_ClientRegistration Invalid RX READY CB");
3909 return eWLAN_PAL_STATUS_E_INVAL;
3910 }
3911
3912 if(NULL == txCompleteCB)
3913 {
3914 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3915 "WLANDXE_ClientRegistration Invalid txCompleteCB");
3916 return eWLAN_PAL_STATUS_E_INVAL;
3917 }
3918
3919 if(NULL == lowResourceCB)
3920 {
3921 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3922 "WLANDXE_ClientRegistration Invalid lowResourceCB");
3923 return eWLAN_PAL_STATUS_E_INVAL;
3924 }
3925
3926 if(NULL == userContext)
3927 {
3928 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3929 "WLANDXE_ClientRegistration Invalid userContext");
3930 return eWLAN_PAL_STATUS_E_INVAL;
3931 }
3932
3933 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3934
3935 /* Assign */
3936 dxeCtxt->rxReadyCB = rxFrameReadyCB;
3937 dxeCtxt->txCompCB = txCompleteCB;
3938 dxeCtxt->lowResourceCB = lowResourceCB;
3939 dxeCtxt->clientCtxt = userContext;
3940
3941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3942 "%s Exit", __FUNCTION__);
3943 return status;
3944}
3945
3946/*==========================================================================
3947 @ Function Name
3948 WLANDXE_Start
3949
3950 @ Description
3951 Start Host DXE driver
3952 Initialize DXE channels and start channel
3953
3954 @ Parameters
3955 pVoid pDXEContext : DXE module control block
3956
3957 @ Return
3958 wpt_status
3959===========================================================================*/
3960wpt_status WLANDXE_Start
3961(
3962 void *pDXEContext
3963)
3964{
3965 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3966 wpt_uint32 idx;
3967 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3968
3969 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3970 "%s Enter", __FUNCTION__);
3971
3972 /* Sanity */
3973 if(NULL == pDXEContext)
3974 {
3975 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3976 "WLANDXE_Start Invalid DXE CB");
3977 return eWLAN_PAL_STATUS_E_INVAL;
3978 }
3979 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3980
3981 /* WLANDXE_Start called means DXE engine already initiates
3982 * And DXE HW is reset and init finished
3983 * But here to make sure HW is initialized, reset again */
3984 status = dxeEngineCoreStart(dxeCtxt);
3985 if(eWLAN_PAL_STATUS_SUCCESS != status)
3986 {
3987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3988 "WLANDXE_Start DXE HW init Fail");
3989 return status;
3990 }
3991
3992 /* Individual Channel Start */
3993 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3994 {
3995 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3996 "WLANDXE_Start Channel %s Start", channelType[idx]);
3997
3998 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
3999 /* Make connection between DXE descriptor and DXE control block */
4000 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4001 if(eWLAN_PAL_STATUS_SUCCESS != status)
4002 {
4003 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4004 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4005 return status;
4006 }
4007
4008 /* Program each channel register with configuration arguments */
4009 status = dxeChannelInitProgram(dxeCtxt,
4010 &dxeCtxt->dxeChannel[idx]);
4011 if(eWLAN_PAL_STATUS_SUCCESS != status)
4012 {
4013 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4014 "WLANDXE_Start %d Program DMA channel Fail", idx);
4015 return status;
4016 }
4017
4018 /* ??? Trigger to start DMA channel
4019 * This must be seperated from ??? */
4020 status = dxeChannelStart(dxeCtxt,
4021 &dxeCtxt->dxeChannel[idx]);
4022 if(eWLAN_PAL_STATUS_SUCCESS != status)
4023 {
4024 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4025 "WLANDXE_Start %d Channel Start Fail", idx);
4026 return status;
4027 }
4028 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4029 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4030 }
4031
4032 /* Register ISR to OS */
4033 /* Register TX complete interrupt into platform */
4034 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4035 dxeTXISR,
4036 dxeCtxt);
4037 if(eWLAN_PAL_STATUS_SUCCESS != status)
4038 {
4039 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4040 "WLANDXE_Start TX comp interrupt registration Fail");
4041 return status;
4042 }
4043
4044 /* Register RX ready interrupt into platform */
4045 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4046 dxeRXISR,
4047 dxeCtxt);
4048 if(eWLAN_PAL_STATUS_SUCCESS != status)
4049 {
4050 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4051 "WLANDXE_Start RX Ready interrupt registration Fail");
4052 return status;
4053 }
4054
4055 /* Enable system level ISR */
4056 /* Enable RX ready Interrupt at here */
4057 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4058 if(eWLAN_PAL_STATUS_SUCCESS != status)
4059 {
4060 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4061 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4062 return status;
4063 }
4064
4065 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4066 "%s Exit", __FUNCTION__);
4067 return status;
4068}
4069
4070/*==========================================================================
4071 @ Function Name
4072 WLANDXE_TXFrame
4073
4074 @ Description
4075 Trigger frame transmit from host to RIVA
4076
4077 @ Parameters
4078 pVoid pDXEContext : DXE Control Block
4079 wpt_packet pPacket : transmit packet structure
4080 WDTS_ChannelType channel : TX channel
4081
4082 @ Return
4083 wpt_status
4084===========================================================================*/
4085wpt_status WLANDXE_TxFrame
4086(
4087 void *pDXEContext,
4088 wpt_packet *pPacket,
4089 WDTS_ChannelType channel
4090)
4091{
4092 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4093 WLANDXE_ChannelCBType *currentChannel = NULL;
4094 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4095 unsigned int *lowThreshold = NULL;
4096
4097 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4098 "%s Enter", __FUNCTION__);
4099
4100 /* Sanity */
4101 if(NULL == pDXEContext)
4102 {
4103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4104 "WLANDXE_Start Invalid DXE CB");
4105 return eWLAN_PAL_STATUS_E_INVAL;
4106 }
4107
4108 if(NULL == pPacket)
4109 {
4110 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4111 "WLANDXE_Start Invalid pPacket");
4112 return eWLAN_PAL_STATUS_E_INVAL;
4113 }
4114
4115 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4116 {
4117 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4118 "WLANDXE_Start Invalid channel");
4119 return eWLAN_PAL_STATUS_E_INVAL;
4120 }
4121
4122 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4123
4124 currentChannel = &dxeCtxt->dxeChannel[channel];
4125
4126
4127 wpalMutexAcquire(&currentChannel->dxeChannelLock);
4128
4129 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4130 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4131 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4132
4133 /* Decide have to activate TX complete event or not */
4134 switch(dxeCtxt->txCompInt.txIntEnable)
4135 {
4136 /* TX complete interrupt will be activated when low DXE resource */
4137 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4138 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4139 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4140 {
4141 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4142 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4143 channel,
4144 eWLAN_PAL_FALSE);
4145 }
4146 break;
4147
4148 /* TX complete interrupt will be activated n number of frames transfered */
4149 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4150 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4151 {
4152 currentChannel->numFrameBeforeInt++;
4153 }
4154 break;
4155
4156 /* TX complete interrupt will be activated periodically */
4157 case WLANDXE_TX_COMP_INT_TIMER:
4158 break;
4159 }
4160
4161 dxeCtxt->txCompletedFrames++;
4162
4163 /* Update DXE descriptor, this is frame based
4164 * if a frame consist of N fragments, N Descriptor will be programed */
4165 status = dxeTXPushFrame(currentChannel, pPacket);
4166 if(eWLAN_PAL_STATUS_SUCCESS != status)
4167 {
4168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4169 "WLANDXE_TxFrame TX Push Frame fail");
4170 wpalMutexRelease(&currentChannel->dxeChannelLock);
4171 return status;
4172 }
4173
4174 /* If specific channel hit low resource condition, send notification to upper layer */
4175 if(currentChannel->numFreeDesc <= *lowThreshold)
4176 {
4177 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4178 channel,
4179 eWLAN_PAL_FALSE);
4180 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
4181 }
4182 wpalMutexRelease(&currentChannel->dxeChannelLock);
4183
4184 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4185 "%s Exit", __FUNCTION__);
4186 return status;
4187}
4188
4189/*==========================================================================
4190 @ Function Name
4191 WLANDXE_CompleteTX
4192
4193 @ Description
4194 Informs DXE that the current series of Tx packets is complete
4195
4196 @ Parameters
4197 pContext pDXEContext : DXE Control Block
4198 ucTxResReq TX resource number required by TL/WDI
4199
4200 @ Return
4201 wpt_status
4202===========================================================================*/
4203wpt_status
4204WLANDXE_CompleteTX
4205(
4206 void* pContext,
4207 wpt_uint32 ucTxResReq
4208)
4209{
4210 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4211 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4212 WLANDXE_ChannelCBType *channelCb = NULL;
4213 wpt_boolean inLowRes;
4214
4215 /* Sanity Check */
4216 if( NULL == pContext )
4217 {
4218 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4219 "WLANDXE_CompleteTX invalid param");
4220 return eWLAN_PAL_STATUS_E_INVAL;
4221 }
4222
4223 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4224 inLowRes = channelCb->hitLowResource;
4225
4226 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4227 {
4228 /* Raise threshold temporarily if necessary */
4229 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4230
4231 if(eWLAN_PAL_FALSE == inLowRes)
4232 {
4233 /* Put the channel to low resource condition */
4234 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4235 WDTS_CHANNEL_TX_LOW_PRI,
4236 eWLAN_PAL_FALSE);
4237 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
4238 }
4239 }
4240
4241 /*Try to reclaim resources*/
4242 dxeTXCompleteProcessing(dxeCtxt);
4243
4244 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4245 because its fragment size is larger than DXE free resource. */
4246 if(0 < ucTxResReq)
4247 {
4248 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4249 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4250 {
4251 /* DXE has not been in low resource condition. DXE forces to kick off
4252 TX tranmit */
4253 if((eWLAN_PAL_FALSE == inLowRes) &&
4254 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4255 {
4256 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4257 WDTS_CHANNEL_TX_LOW_PRI,
4258 eWLAN_PAL_FALSE);
4259 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4260 WDTS_CHANNEL_TX_LOW_PRI,
4261 eWLAN_PAL_TRUE);
4262 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4263 }
4264 }
4265 else
4266 {
4267 /* DXE doesn't have enough free DXE resources. Put the channel
4268 to low resource condition. */
4269 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4270 {
4271 /* Put the channel to low resource condition */
4272 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4273 WDTS_CHANNEL_TX_LOW_PRI,
4274 eWLAN_PAL_FALSE);
4275 channelCb->hitLowResource = eWLAN_PAL_TRUE;
4276 }
4277 }
4278 }
4279
4280 return status;
4281}
4282
4283/*==========================================================================
4284 @ Function Name
4285 WLANDXE_Stop
4286
4287 @ Description
4288 Stop DXE channels and DXE engine operations
4289 Disable all channel interrupt
4290 Stop all channel operation
4291
4292 @ Parameters
4293 pVoid pDXEContext : DXE Control Block
4294
4295 @ Return
4296 wpt_status
4297===========================================================================*/
4298wpt_status WLANDXE_Stop
4299(
4300 void *pDXEContext
4301)
4302{
4303 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4304 wpt_uint32 idx;
4305 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4306
4307 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4308 "%s Enter", __FUNCTION__);
4309
4310 /* Sanity */
4311 if(NULL == pDXEContext)
4312 {
4313 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4314 "WLANDXE_Stop Invalid DXE CB");
4315 return eWLAN_PAL_STATUS_E_INVAL;
4316 }
4317
4318 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4319 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4320 {
4321 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4322 if(eWLAN_PAL_STATUS_SUCCESS != status)
4323 {
4324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4325 "WLANDXE_Stop Channel %d Stop Fail", idx);
4326 return status;
4327 }
4328 }
4329
4330 /* During Stop unregister interrupt */
4331 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4332 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4333
4334 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4335 "%s Exit", __FUNCTION__);
4336 return status;
4337}
4338
4339/*==========================================================================
4340 @ Function Name
4341 WLANDXE_Close
4342
4343 @ Description
4344 Close DXE channels
4345 Free DXE related resources
4346 DXE descriptor free
4347 Descriptor control block free
4348 Pre allocated RX buffer free
4349
4350 @ Parameters
4351 pVoid pDXEContext : DXE Control Block
4352
4353 @ Return
4354 wpt_status
4355===========================================================================*/
4356wpt_status WLANDXE_Close
4357(
4358 void *pDXEContext
4359)
4360{
4361 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4362 wpt_uint32 idx;
4363 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4364#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4365 wpt_uint32 sIdx;
4366 WLANDXE_ChannelCBType *channel = NULL;
4367 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4368 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4369#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4370
4371 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4372 "%s Enter", __FUNCTION__);
4373
4374 /* Sanity */
4375 if(NULL == pDXEContext)
4376 {
4377 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4378 "WLANDXE_Stop Invalid DXE CB");
4379 return eWLAN_PAL_STATUS_E_INVAL;
4380 }
4381
4382 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4383 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4384 {
4385 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
4386 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4387#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4388 channel = &dxeCtxt->dxeChannel[idx];
4389 crntDescCB = channel->headCtrlBlk;
4390 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4391 {
4392 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4393 wpalMemoryFree((void *)crntDescCB);
4394 crntDescCB = nextDescCB;
4395 if(NULL == crntDescCB)
4396 {
4397 break;
4398 }
4399 }
4400#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4401 }
4402
4403 if(NULL != dxeCtxt->rxIsrMsg)
4404 {
4405 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4406 }
4407 if(NULL != dxeCtxt->txIsrMsg)
4408 {
4409 wpalMemoryFree(dxeCtxt->txIsrMsg);
4410 }
4411 if(NULL != dxeCtxt->rxPktAvailMsg)
4412 {
4413 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4414 }
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004415 if(NULL != dxeCtxt->chDebugMsg)
4416 {
4417 wpalMemoryFree(dxeCtxt->chDebugMsg);
4418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004419
4420 wpalMemoryFree(pDXEContext);
4421
4422 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4423 "%s Exit", __FUNCTION__);
4424 return status;
4425}
4426
4427/*==========================================================================
4428 @ Function Name
4429 WLANDXE_TriggerTX
4430
4431 @ Description
4432 TBD
4433
4434 @ Parameters
4435 pVoid pDXEContext : DXE Control Block
4436
4437 @ Return
4438 wpt_status
4439===========================================================================*/
4440wpt_status WLANDXE_TriggerTX
4441(
4442 void *pDXEContext
4443)
4444{
4445 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4446
4447 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4448 "%s Enter", __FUNCTION__);
4449
4450 /* TBD */
4451
4452 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4453 "%s Exit", __FUNCTION__);
4454 return status;
4455}
4456
4457/*==========================================================================
4458 @ Function Name
4459 dxeTxThreadSetPowerStateEventHandler
4460
4461 @ Description
4462 If WDI sends set power state req, this event handler will be called in Tx
4463 thread context
4464
4465 @ Parameters
4466 void *msgPtr
4467 Event MSG
4468
4469 @ Return
4470 None
4471===========================================================================*/
4472void dxeTxThreadSetPowerStateEventHandler
4473(
4474 wpt_msg *msgPtr
4475)
4476{
4477 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4478 WLANDXE_CtrlBlkType *dxeCtxt;
4479 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4480 WLANDXE_PowerStateType reqPowerState;
4481
4482 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4483 "%s Enter", __FUNCTION__);
4484
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4486 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4487 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4488
4489 switch(reqPowerState)
4490 {
4491 case WLANDXE_POWER_STATE_BMPS:
4492 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4493 {
4494 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4495 //based on amount of TX and RX activity - during this time any received
4496 // management frames will remain un-processed consuming RX buffers
4497 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4498 dxeCtxt->hostPowerState = reqPowerState;
4499 }
4500 else
4501 {
4502 status = eWLAN_PAL_STATUS_E_INVAL;
4503 }
4504 break;
4505 case WLANDXE_POWER_STATE_IMPS:
4506 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4507 {
4508 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4509 }
4510 else
4511 {
4512 status = eWLAN_PAL_STATUS_E_INVAL;
4513 }
4514 break;
4515 case WLANDXE_POWER_STATE_FULL:
4516 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4517 {
4518 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4519 }
4520 dxeCtxt->hostPowerState = reqPowerState;
4521 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4522 break;
4523 case WLANDXE_POWER_STATE_DOWN:
4524 WLANDXE_Stop((void *)dxeCtxt);
4525 break;
4526 default:
4527 //assert
4528 break;
4529 }
4530
4531 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4532 {
4533 dxeCtxt->setPowerStateCb(status,
4534 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4535 }
4536 /* Free MSG buffer */
4537 wpalMemoryFree(msgPtr);
4538 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4539 "%s Exit", __FUNCTION__);
4540 return;
4541}
4542
4543
4544/*==========================================================================
4545 @ Function Name
4546 dxeRxThreadSetPowerStateEventHandler
4547
4548 @ Description
4549 If WDI sends set power state req, this event handler will be called in Rx
4550 thread context
4551
4552 @ Parameters
4553 void *msgPtr
4554 Event MSG
4555
4556 @ Return
4557 None
4558===========================================================================*/
4559void dxeRxThreadSetPowerStateEventHandler
4560(
4561 wpt_msg *msgPtr
4562)
4563{
4564 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4565
4566 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4567 "%s Enter", __FUNCTION__);
4568
4569 /* Now serialise the message through Tx thread also to make sure
4570 * no register access when RIVA is in powersave */
4571 /*Use the same message pointer just change the call back function */
4572 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4573 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4574 msgPtr);
4575 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4576 {
4577 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4578 "Tx thread Set power state req serialize fail status=%d",
4579 status, 0, 0);
4580 }
4581
4582 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4583 "%s Exit", __FUNCTION__);
4584}
4585
4586/*==========================================================================
4587 @ Function Name
4588 WLANDXE_SetPowerState
4589
4590 @ Description
4591 From Client let DXE knows what is the WLAN HW(RIVA) power state
4592
4593 @ Parameters
4594 pVoid pDXEContext : DXE Control Block
4595 WLANDXE_PowerStateType powerState
4596
4597 @ Return
4598 wpt_status
4599===========================================================================*/
4600wpt_status WLANDXE_SetPowerState
4601(
4602 void *pDXEContext,
4603 WDTS_PowerStateType powerState,
4604 WDTS_SetPSCbType cBack
4605)
4606{
4607 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4608 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4609 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004610 wpt_msg *rxCompMsg;
4611 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07004612
4613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4614 "%s Enter", __FUNCTION__);
4615 if(NULL == pDXEContext)
4616 {
4617 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4618 "NULL pDXEContext passed by caller", 0, 0, 0);
4619 return eWLAN_PAL_STATUS_E_FAILURE;
4620 }
4621 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
4622
Jeff Johnson295189b2012-06-20 16:38:30 -07004623 switch(powerState)
4624 {
4625 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004626 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
4627 {
4628 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4629 if(NULL == txDescReSyncMsg)
4630 {
4631 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4632 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
4633 }
4634 else
4635 {
4636 txDescReSyncMsg->callback = dxeTXReSyncDesc;
4637 txDescReSyncMsg->pContext = pDxeCtrlBlk;
4638 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4639 txDescReSyncMsg);
4640 if(eWLAN_PAL_STATUS_SUCCESS != status)
4641 {
4642 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4643 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
4644 }
4645 }
4646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 hostPowerState = WLANDXE_POWER_STATE_FULL;
4648 break;
4649 case WDTS_POWER_STATE_BMPS:
4650 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
4651 hostPowerState = WLANDXE_POWER_STATE_BMPS;
4652 break;
4653 case WDTS_POWER_STATE_IMPS:
4654 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
4655 hostPowerState = WLANDXE_POWER_STATE_IMPS;
4656 break;
4657 case WDTS_POWER_STATE_DOWN:
4658 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
4659 hostPowerState = WLANDXE_POWER_STATE_DOWN;
4660 break;
4661 default:
4662 hostPowerState = WLANDXE_POWER_STATE_MAX;
4663 }
4664
4665 // A callback i.e. ACK back is needed only when we want to enable BMPS
4666 // and the data/management path is active because we want to ensure
4667 // DXE registers are not accessed when RIVA may be power-collapsed. So
4668 // we need a callback in enter_bmps_req (the request to RIVA is sent
4669 // only after ACK back from TX thread). A callback is not needed in
4670 // finish_scan_req during BMPS since data-path is resumed only in
4671 // finish_scan_rsp and no management frames are sent in between. No
4672 // callback is needed when going from BMPS enabled to BMPS suspended/
4673 // disabled when it is known that RIVA is awake and cannot enter power
4674 // collapse autonomously so no callback is needed in exit_bmps_rsp or
4675 // init_scan_rsp
4676 if ( cBack )
4677 {
4678 //serialize through Rx thread
4679 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4680 if(NULL == rxCompMsg)
4681 {
4682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4683 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
4684 return eWLAN_PAL_STATUS_E_RESOURCES;
4685 }
4686
4687 /* Event type, where it must be defined???? */
4688 /* THIS MUST BE CLEARED ASAP
4689 txCompMsg->type = TX_COMPLETE; */
4690 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
4691 rxCompMsg->pContext = pDxeCtrlBlk;
4692 rxCompMsg->val = hostPowerState;
4693 rxCompMsg->ptr = cBack;
4694 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
4695 rxCompMsg);
4696 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4697 {
4698 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4699 "Rx thread Set power state req serialize fail status=%d",
4700 status, 0, 0);
4701 }
4702 }
4703 else
4704 {
4705 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
4706 {
4707 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
4708 {
4709 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4710 }
4711 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
4712 {
4713 /* Requested Full power from exit IMPS, reenable the interrupts*/
4714 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
4715 {
4716 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4717 /* Enable RX interrupt at here, if new PS is not IMPS */
4718 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4719 if(eWLAN_PAL_STATUS_SUCCESS != status)
4720 {
4721 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4722 "%s Enable RX ready interrupt fail", __FUNCTION__);
4723 return status;
4724 }
4725 }
4726 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
4727 {
4728 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004729 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004730 /* Enable RX interrupt at here, if new PS is not IMPS */
4731 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4732 if(eWLAN_PAL_STATUS_SUCCESS != status)
4733 {
4734 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4735 "%s Enable TX comp interrupt fail", __FUNCTION__);
4736 return status;
4737 }
4738 }
4739 }
4740 pDxeCtrlBlk->hostPowerState = hostPowerState;
4741 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4742 }
4743 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
4744 {
4745 pDxeCtrlBlk->hostPowerState = hostPowerState;
4746 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4747 }
4748 else
4749 {
4750 HDXE_ASSERT(0);
4751 }
4752 }
4753
4754 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4755 "%s Exit", __FUNCTION__);
4756
4757 return status;
4758}
4759
4760/*==========================================================================
4761 @ Function Name
4762 WLANDXE_GetFreeTxDataResNumber
4763
4764 @ Description
4765 Returns free descriptor numbers for TX data channel (TX high priority)
4766
4767 @ Parameters
4768 pVoid pDXEContext : DXE Control Block
4769
4770 @ Return
4771 wpt_uint32 Free descriptor number of TX high pri ch
4772===========================================================================*/
4773wpt_uint32 WLANDXE_GetFreeTxDataResNumber
4774(
4775 void *pDXEContext
4776)
4777{
4778 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4779 "%s Enter", __FUNCTION__);
4780
4781 if(NULL == pDXEContext)
4782 {
4783 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4784 "NULL parameter passed by caller", 0, 0, 0);
4785 return (0);
4786 }
4787
4788 return
4789 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
4790}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004791
4792/*==========================================================================
4793 @ Function Name
4794 WLANDXE_ChannelDebug
4795
4796 @ Description
4797 Display DXE Channel debugging information
4798 User may request to display DXE channel snapshot
4799 Or if host driver detects any abnormal stcuk may display
4800
4801 @ Parameters
4802 displaySnapshot : Dispaly DXE snapshot option
4803 enableStallDetect : Enable stall detect feature
4804 This feature will take effect to data performance
4805 Not integrate till fully verification
4806
4807 @ Return
4808 NONE
4809
4810===========================================================================*/
4811void WLANDXE_ChannelDebug
4812(
4813 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004814 wpt_boolean enableStallDetect,
4815 wpt_boolean fullChannelsDump
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004816)
4817{
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004818 wpt_uint32 regValue;
4819 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4820
4821 /* Debug Type 1, Display current snapshot */
4822 if(displaySnapshot)
4823 {
4824 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
4825 * This will not simply wakeup RIVA
4826 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004827 if(fullChannelsDump)
4828 {
4829 /* Full DXE Channel dump, kick DXE TX */
4830 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4831 }
4832 else
4833 {
4834 /* Partial DXE Channel dump,
4835 do not kick DXE TX, must be handled by TX Thread */
4836 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
4837 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004838 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4839 "Host power state %d, RIVA power state %d",
4840 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
4841 /* Get free BD count */
4842 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
4843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4844 "TX Pending frames count %d, Current available BD %d",
4845 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004846 if(fullChannelsDump)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004847 {
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004848 tempDxeCtrlBlk->chDebugMsg->callback = dxeRxThreadChannelDebugHandler;
4849 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), tempDxeCtrlBlk->chDebugMsg);
4850 if (eWLAN_PAL_STATUS_SUCCESS != status)
4851 {
4852 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4853 "Rx thread state dump req serialize fail status=%d",
4854 status, 0, 0);
4855 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004856 }
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004857 else
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004858 {
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004859 tempDxeCtrlBlk->chDebugMsg->callback = dxeRxChannelsStatus;
4860 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), tempDxeCtrlBlk->chDebugMsg);
4861 if (eWLAN_PAL_STATUS_SUCCESS != status)
4862 {
4863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4864 "Rx thread partial state dump req serialize fail status=%d",
4865 status, 0, 0);
4866 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004867 }
4868 }
4869
4870 /* Debug Type 2, toggling stall detect enable/disable */
4871 if(enableStallDetect)
4872 {
4873 /* Do nothing till not
4874 * This feature will take effect to data path, needed intensive test */
4875 }
4876 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07004877}