blob: 6d30e73c25bcbdf333b2f7b7ac541f1714e5a113 [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
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -070080#define T_WLANDXE_PERIODIC_HEALTH_M_TIME 1500
81#define T_WLANDXE_MAX_HW_ACCESS_WAIT 2000
Jeff Johnsone7245742012-09-05 17:12:55 -070082#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -070083
84/* This is temporary fot the compile
85 * WDI will release official version
86 * This must be removed */
87#define WDI_GET_PAL_CTX() NULL
88
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070089
Jeff Johnson295189b2012-06-20 16:38:30 -070090/*-------------------------------------------------------------------------
91 * Local Varables
92 *-------------------------------------------------------------------------*/
93/* This is temp, someone have to allocate for me, and must be part of global context */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070094static WLANDXE_CtrlBlkType *tempDxeCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -070095static char *channelType[WDTS_CHANNEL_MAX] =
96 {
97 "TX_LOW_PRI",
98 "TX_HIGH_PRI",
99 "RX_LOW_PRI",
100#ifndef WLANDXE_TEST_CHANNEL_ENABLE
101 "RX_HIGH_PRI",
102#else
103 "H2H_TEST_TX",
104 "H2H_TEST_RX"
105#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
106 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700107static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700108
109/*-------------------------------------------------------------------------
110 * External Function Proto Type
111 *-------------------------------------------------------------------------*/
112
113/*-------------------------------------------------------------------------
114 * Local Function Proto Type
115 *-------------------------------------------------------------------------*/
116static wpt_status dxeRXFrameSingleBufferAlloc
117(
118 WLANDXE_CtrlBlkType *dxeCtxt,
119 WLANDXE_ChannelCBType *channelEntry,
120 WLANDXE_DescCtrlBlkType *currentCtrlBlock
121);
122
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700123static wpt_status dxeNotifySmsm
124(
125 wpt_boolean kickDxe,
126 wpt_boolean ringEmpty
127);
128
Jeff Johnson295189b2012-06-20 16:38:30 -0700129/*-------------------------------------------------------------------------
130 * Local Function
131 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700132/*==========================================================================
133 @ Function Name
134 dxeChannelMonitor
135
136 @ Description
137
138 @ Parameters
139 WLANDXE_ChannelCBType *channelEntry
140 Channel specific control block
141
142 @ Return
143 wpt_status
144
145===========================================================================*/
146static wpt_status dxeChannelMonitor
147(
148 char *monitorDescription,
149 WLANDXE_ChannelCBType *channelEntry
150)
151{
152 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
153
Jeff Johnsone7245742012-09-05 17:12:55 -0700154 if((NULL == monitorDescription) || (NULL == channelEntry))
155 {
156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
157 "INVALID Input ARG");
158 return eWLAN_PAL_STATUS_E_INVAL;
159 }
160
161 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
162 {
163 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
164 "INVALID Channel type");
165 return eWLAN_PAL_STATUS_E_INVAL;
166 }
167
168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700169 "=== %s Channel Number %d, Channel Type %s",
170 monitorDescription, channelEntry->assignedDMAChannel, channelType[channelEntry->channelType]);
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 "numDesc %d, numFreeDesc %d, numResvDesc %d",
173 channelEntry->numDesc, channelEntry->numFreeDesc, channelEntry->numRsvdDesc);
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 "headCB 0x%x, next 0x%x, DESC 0x%x",
176 channelEntry->headCtrlBlk, channelEntry->headCtrlBlk->nextCtrlBlk, channelEntry->headCtrlBlk->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 "tailCB 0x%x, next 0x%x, DESC 0x%x",
179 channelEntry->tailCtrlBlk, channelEntry->tailCtrlBlk->nextCtrlBlk, channelEntry->tailCtrlBlk->linkedDescPhyAddr);
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 "headCB Order %d, tailCB Order %d",
182 channelEntry->headCtrlBlk->ctrlBlkOrder, channelEntry->tailCtrlBlk->ctrlBlkOrder);
Jeff Johnsone7245742012-09-05 17:12:55 -0700183 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 "numFragmentCurrentChain %d, numTotalFrame %d ===",
185 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
186
187 return status;
188}
189
Jeff Johnsone7245742012-09-05 17:12:55 -0700190#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700191/*==========================================================================
192 @ Function Name
193 dxeMemoryDump
194
195 @ Description
196
197 @ Parameters
198 WLANDXE_ChannelCBType *channelEntry
199 Channel specific control block
200
201 @ Return
202 wpt_status
203
204===========================================================================*/
205static wpt_status dxeMemoryDump
206(
207 wpt_uint8 *dumpPointer,
208 wpt_uint32 dumpSize,
209 char *dumpTarget
210)
211{
212 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
213 wpt_uint32 numBytes = 0;
214 wpt_uint32 idx;
215
Jeff Johnsone7245742012-09-05 17:12:55 -0700216 if((NULL == dumpPointer) ||
217 (NULL == dumpTarget))
218 {
219 return status;
220 }
221
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
223 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
224 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
225 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
226
227 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
228 for(idx = 0; idx < dumpSize; idx++)
229 {
230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
231 "0x%2x ", dumpPointer[idx]);
232 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
233 {
234 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
235 }
236 }
237 if(0 != numBytes)
238 {
239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
240 }
241 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
242 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
243
244 return status;
245}
Jeff Johnsone7245742012-09-05 17:12:55 -0700246#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700247
248/*==========================================================================
249 @ Function Name
250 dxeDescriptorDump
251
252 @ Description
253
254 @ Parameters
255 WLANDXE_ChannelCBType *channelEntry
256 Channel specific control block
257
258 @ Return
259 wpt_status
260
261===========================================================================*/
262wpt_status dxeDescriptorDump
263(
264 WLANDXE_ChannelCBType *channelEntry,
265 WLANDXE_DescType *targetDesc,
266 wpt_uint32 fragmentOrder
267)
268{
269 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
270
271
Jeff Johnsone7245742012-09-05 17:12:55 -0700272 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700274 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700275 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700277 fragmentOrder + 1,
278 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
Jeff Johnsone7245742012-09-05 17:12:55 -0700280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 "CTRL WORD 0x%x, TransferSize %d",
282 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
283 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700284 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700285 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
286 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
287 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
288 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700289 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
291
292 return status;
293}
294
295/*==========================================================================
296 @ Function Name
297 dxeChannelRegisterDump
298
299 @ Description
300
301 @ Parameters
302 WLANDXE_ChannelCBType *channelEntry
303 Channel specific control block
304
305 @ Return
306 wpt_status
307
308===========================================================================*/
309wpt_status dxeChannelRegisterDump
310(
311 WLANDXE_ChannelCBType *channelEntry,
312 char *dumpTarget
313)
314{
315 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
316 wpt_uint32 regValue = 0;
317
Jeff Johnsone7245742012-09-05 17:12:55 -0700318 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 "%s Channel register dump for %s, base address 0x%x",
320 channelType[channelEntry->channelType],
321 dumpTarget,
322 channelEntry->channelRegister.chDXEBaseAddr);
323 regValue = 0;
324 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 "Control Register 0x%x", regValue);
327
328 regValue = 0;
329 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700330 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 "Status Register 0x%x", regValue);
332 regValue = 0;
333
334 wpalReadRegister(channelEntry->channelRegister.chDXESadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700335 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 "Source Address Register 0x%x", regValue);
337 regValue = 0;
338
339 wpalReadRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700340 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 "Destination Address Register 0x%x", regValue);
342 regValue = 0;
343
344 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700345 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700346 "Last Descriptor Address Register 0x%x", regValue);
347
348 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &regValue);
349 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
350 "Next Descriptor Address Register 0x%x", regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -0700351
352 return status;
353}
Jeff Johnsone7245742012-09-05 17:12:55 -0700354
355/*==========================================================================
356 @ Function Name
357 dxeChannelAllDescDump
358
359 @ Description
360 Dump all DXE descriptors within assigned channe;
361
362 @ Parameters
363 WLANDXE_ChannelCBType *channelEntry
364
365 @ Return
366 NONE
367
368===========================================================================*/
369void dxeChannelAllDescDump
370(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700371 WLANDXE_ChannelCBType *channelEntry,
372 WDTS_ChannelType channel
Jeff Johnsone7245742012-09-05 17:12:55 -0700373)
374{
375 wpt_uint32 channelLoop;
376 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700377 wpt_uint32 previousCtrlValue = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700378
379 targetCtrlBlk = channelEntry->headCtrlBlk;
380
381 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700382 "%s %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700383 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700384 channelEntry->numDesc,
385 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700386 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
387
388 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
389 (WDTS_CHANNEL_RX_HIGH_PRI == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700390 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700391 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700392 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700393 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
394 {
395 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
396 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
397 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
398 }
399 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
400 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700401 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700402 }
403 else
404 {
405 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
406 {
407 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
408 {
409 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
410 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
411 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
412 }
413 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
414 }
415 }
416 return;
417}
418
419/*==========================================================================
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700420 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700421 dxeTxThreadChannelDebugHandler
422
423 @ Description
424 Dump TX channel information
425
426 @ Parameters
427 Wwpt_msg *msgPtr
428
429 @ Return
430 NONE
431
432===========================================================================*/
433void dxeTxThreadChannelDebugHandler
434(
435 wpt_msg *msgPtr
436)
437{
438 wpt_uint8 channelLoop;
439
440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700441 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700442
443 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
444 * This will not simply wakeup RIVA
445 * Just incase TX not wanted stuck, Trigger TX again */
446 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
447 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
448 {
449 dxeChannelMonitor("******** Get Descriptor Snapshot ",
450 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
451 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700452 tempDxeCtrlBlk->dxeChannel[channelLoop].tailCtrlBlk->linkedDesc,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700453 0);
454 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
455 "Abnormal successive empty interrupt");
456 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700457 }
458
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700459 wpalMemoryFree(msgPtr);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700460 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700461 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700462 return;
463}
464
465/*==========================================================================
466 @ Function Name
467 dxeRxThreadChannelDebugHandler
468
469 @ Description
470 Dump RX channel information
471
472 @ Parameters
473 Wwpt_msg *msgPtr
474
475 @ Return
476 NONE
477
478===========================================================================*/
479void dxeRxThreadChannelDebugHandler
480(
481 wpt_msg *msgPtr
482)
483{
484 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
485 wpt_uint8 channelLoop;
486
487 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700488 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700489
490 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
491 * This will not simply wakeup RIVA
492 * Just incase TX not wanted stuck, Trigger TX again */
493 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
494 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
495 {
496 dxeChannelMonitor("******** Get Descriptor Snapshot ",
497 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
498 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
499 tempDxeCtrlBlk->dxeChannel[channelLoop].headCtrlBlk->linkedDesc,
500 0);
501 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
502 "Abnormal successive empty interrupt");
503 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
504 }
505
506 /* Now serialise the message through Tx thread also to make sure
507 * no register access when RIVA is in powersave */
508 /*Use the same message pointer just change the call back function */
509 msgPtr->callback = dxeTxThreadChannelDebugHandler;
510 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
511 msgPtr);
512 if ( eWLAN_PAL_STATUS_SUCCESS != status )
513 {
514 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700515 "Tx thread state dump req serialize fail status=%d",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700516 status, 0, 0);
517 }
518
519 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700520 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700521 return;
522}
Jeff Johnson295189b2012-06-20 16:38:30 -0700523
524/*==========================================================================
525 @ Function Name
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700526 dxeRXHealthMonitor
527
528 @ Description
529 Monitoring RX channel healthy stataus
530 If detect any problem, try to recover
531
532 @ Parameters
533 healthMonitorMsg MSG pointer.
534 will have low resource TX channel context
535
536 @ Return
537 NONE
538
539===========================================================================*/
540void dxeRXHealthMonitor
541(
542 wpt_msg *healthMonitorMsg
543)
544{
545 WLANDXE_ChannelCBType *channelCtrlBlk;
546 WLANDXE_ChannelCBType *testCHCtrlBlk;
547 wpt_uint32 regValue;
548 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
549 wpt_uint32 hwWakeLoop, chLoop;
550
551 if(NULL == healthMonitorMsg)
552 {
553 return;
554 }
555
556 /* Make wake up HW */
557 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
558 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
559
560 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
561 {
562 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
563 if(0 != regValue)
564 {
565 break;
566 }
567 }
568
569 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
570 "Scheduled RX, num free BD/PDU %d, loop Count %d",
571 regValue, hwWakeLoop, 0);
572
573 for(chLoop = WDTS_CHANNEL_RX_LOW_PRI; chLoop < WDTS_CHANNEL_MAX; chLoop++)
574 {
575 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
576 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
577 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
578 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
579 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
580
581 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
582 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
583 channelType[chLoop],
584 chControlReg, chStatusReg, chDescReg, chLDescReg,
585 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
586 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
587 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
588 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
589
590 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
591 (chLDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
592 {
593 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
594 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
595 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
596 channelType[chLoop],
597 chControlReg, chStatusReg, chDescReg, chLDescReg,
598 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
599 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
600 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
601 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
603 "%11s : RX CH EN Descriptor Async, resync it", channelType[chLoop], 0, 0);
604 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
605 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
606 }
607 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
608 (chDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
609 {
610 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
611 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
612 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
613 channelType[chLoop],
614 chControlReg, chStatusReg, chDescReg, chLDescReg,
615 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
616 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
617 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
618 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
619 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
620 "%11s : RX CH DIS Descriptor Async, resync it", channelType[chLoop], 0, 0);
621 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
622 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
623 }
624 }
625
626 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
627 if(channelCtrlBlk->hitLowResource)
628 {
629 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
630 "%11s : Still Low Resource, kick DXE TX and restart timer",
631 channelType[channelCtrlBlk->channelType], 0, 0);
632 /* Still Low Resource, Kick DXE again and start timer again */
633 wpalTimerStart(&channelCtrlBlk->healthMonitorTimer,
634 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
635 }
636 else
637 {
638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
639 "%11s : Out from Low resource condition, do nothing",
640 channelType[channelCtrlBlk->channelType], 0, 0);
641 /* Recovered from low resource condition
642 * Not need to do anything */
643 }
644
645 return;
646}
647
648/*==========================================================================
649 @ Function Name
650 dxeTXHealthMonitor
651
652 @ Description
653 Monitoring TX channel healthy stataus
654 If detect any problem, try to recover
655
656 @ Parameters
657 healthMonitorMsg MSG pointer.
658 will have low resource TX channel context
659
660 @ Return
661 NONE
662
663===========================================================================*/
664void dxeTXHealthMonitor
665(
666 wpt_msg *healthMonitorMsg
667)
668{
669 WLANDXE_ChannelCBType *channelCtrlBlk;
670 WLANDXE_ChannelCBType *testCHCtrlBlk;
671 wpt_uint32 regValue;
672 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
673 wpt_uint32 hwWakeLoop, chLoop;
674 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
675
676 if(NULL == healthMonitorMsg)
677 {
678 return;
679 }
680
681 /* First of all kick TX channel
682 * This will fix if there is any problem with SMSM state */
683 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
684 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
685
686 /* Wait till RIVA up */
687 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
688 {
689 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
690 if(0 != regValue)
691 {
692 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
693 "num free BD/PDU %d, loop Count %d",
694 regValue, hwWakeLoop, 0);
695 break;
696 }
697 }
698
699 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
700 "Scheduled TX, num free BD/PDU %d, loop Count %d",
701 regValue, hwWakeLoop, 0);
702
703 for(chLoop = 0; chLoop < WDTS_CHANNEL_RX_LOW_PRI; chLoop++)
704 {
705 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
706 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
707 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
708 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
709 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
710
711 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
712 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
713 channelType[chLoop],
714 chControlReg, chStatusReg, chDescReg, chLDescReg,
715 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
716 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
717 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
718 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
719
720 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
721 (chLDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
722 {
723 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
724 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
725 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
726 channelType[chLoop],
727 chControlReg, chStatusReg, chDescReg, chLDescReg,
728 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
729 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
730 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
731 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
732 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
733 "%11s : TX CH EN Descriptor Async, resync it", channelType[chLoop], 0, 0);
734 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
735 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
736 }
737 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
738 (chDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
739 {
740 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
741 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
742 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
743 channelType[chLoop],
744 chControlReg, chStatusReg, chDescReg, chLDescReg,
745 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
746 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
747 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
748 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
750 "%11s : TX CH DIS Descriptor Async, resync it", channelType[chLoop], 0, 0);
751 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
752 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
753 }
754 }
755
756 /* TX channel test done, test RX channels */
757 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
758 channelCtrlBlk->healthMonitorMsg->callback = dxeRXHealthMonitor;
759 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
760 channelCtrlBlk->healthMonitorMsg);
761 if (eWLAN_PAL_STATUS_SUCCESS != status)
762 {
763 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
764 "TX Low resource Kick DXE MSG Serialize fail",
765 status, 0, 0);
766 }
767
768 return;
769}
770
771/*==========================================================================
772 @ Function Name
773 dxeHealthMonitorTimeout
774
775 @ Description
776 Health Monitor timer started when TX channel low resource condition
777 And if reciovered from low resource condition, timer would not fired
778 Timer fired means during certain time, TX CH could not be recovered
779
780 @ Parameters
781 channelCtxt Low resource condition happen Channel context
782
783 @ Return
784 NONE
785
786===========================================================================*/
787void dxeHealthMonitorTimeout
788(
789 void *channelCtxt
790)
791{
792 WLANDXE_ChannelCBType *channelCtrlBlk;
793 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
794
795 if(NULL == channelCtxt)
796 {
797 return;
798 }
799
800 /* Timeout Fired, DXE TX should kick on TX thread
801 * Serailize to TX Thread */
802 channelCtrlBlk = (WLANDXE_ChannelCBType *)channelCtxt;
803 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
804 "%11s : Health Monitor timer expired",
805 channelType[channelCtrlBlk->channelType], 0, 0);
806
807 channelCtrlBlk->healthMonitorMsg->callback = dxeTXHealthMonitor;
808 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
809 channelCtrlBlk->healthMonitorMsg);
810 if (eWLAN_PAL_STATUS_SUCCESS != status)
811 {
812 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
813 "TX Low resource Kick DXE MSG Serialize fail",
814 status, 0, 0);
815 }
816
817 return;
818}
819
820/*==========================================================================
821 @ Function Name
Jeff Johnson295189b2012-06-20 16:38:30 -0700822 dxeCtrlBlkAlloc
823
824 @ Description
825 Allocate DXE Control block
826 DXE control block will used by Host DXE driver only, internal structure
827 Will make ring linked list
828
829 @ Parameters
830 WLANDXE_CtrlBlkType *dxeCtrlBlk,
831 DXE host driver main control block
832 WLANDXE_ChannelCBType *channelEntry
833 Channel specific control block
834
835 @ Return
836 wpt_status
837
838===========================================================================*/
839static wpt_status dxeCtrlBlkAlloc
840(
841 WLANDXE_CtrlBlkType *dxeCtrlBlk,
842 WLANDXE_ChannelCBType *channelEntry
843)
844{
845 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
846 unsigned int idx, fIdx;
847 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
848 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
849 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
850 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
851
852 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700853 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700854
855 /* Sanity check */
856 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
857 {
858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
859 "dxeCtrlBlkAlloc Channel Entry is not valid");
860 return eWLAN_PAL_STATUS_E_INVAL;
861 }
862
863 /* Allocate pre asigned number of control blocks */
864 for(idx = 0; idx < channelEntry->numDesc; idx++)
865 {
866 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
867 if(NULL == currentCtrlBlk)
868 {
869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
870 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
871 channelEntry->channelType);
872 freeCtrlBlk = channelEntry->headCtrlBlk;
873 for(fIdx = 0; fIdx < idx; fIdx++)
874 {
875 if(NULL == freeCtrlBlk)
876 {
877 break;
878 }
879
880 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
881 wpalMemoryFree((void *)freeCtrlBlk);
882 freeCtrlBlk = nextCtrlBlk;
883 }
884 return eWLAN_PAL_STATUS_E_FAULT;
885 }
886
887 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
888 /* Initialize common elements first */
889 currentCtrlBlk->xfrFrame = NULL;
890 currentCtrlBlk->linkedDesc = NULL;
891 currentCtrlBlk->linkedDescPhyAddr = 0;
892 currentCtrlBlk->ctrlBlkOrder = idx;
893
894 /* This is the first control block allocated
895 * Next Control block is not allocated yet
896 * head and tail must be first control block */
897 if(0 == idx)
898 {
899 currentCtrlBlk->nextCtrlBlk = NULL;
900 channelEntry->headCtrlBlk = currentCtrlBlk;
901 channelEntry->tailCtrlBlk = currentCtrlBlk;
902 }
903 /* This is not first, not last control block
904 * previous control block may has next linked block */
905 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
906 {
907 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
908 }
909 /* This is last control blocl
910 * next control block for the last control block is head, first control block
911 * then whole linked list made RING */
912 else if((channelEntry->numDesc - 1) == idx)
913 {
914 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
915 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
916 }
917 else
918 {
919 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
920 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
921 channelEntry->channelType);
922 wpalMemoryFree(currentCtrlBlk);
923 return eWLAN_PAL_STATUS_E_FAULT;
924 }
925
926 prevCtrlBlk = currentCtrlBlk;
927 channelEntry->numFreeDesc++;
928 }
929
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700930 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700931 return status;
932}
933
934/*==========================================================================
935 @ Function Name
936 dxeDescLinkAlloc
937
938 @ Description
939 Allocate DXE descriptor
940 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
941 Will make RING linked list
942 Will be linked with Descriptor control block one by one
943
944 @ Parameters
945 WLANDXE_CtrlBlkType *dxeCtrlBlk,
946 DXE host driver main control block
947 WLANDXE_ChannelCBType *channelEntry
948 Channel specific control block
949 @ Return
950 wpt_status
951
952===========================================================================*/
953static wpt_status dxeDescAllocAndLink
954(
955 WLANDXE_CtrlBlkType *dxeCtrlBlk,
956 WLANDXE_ChannelCBType *channelEntry
957)
958{
959 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
960 WLANDXE_DescType *currentDesc = NULL;
961 WLANDXE_DescType *prevDesc = NULL;
962 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
963 unsigned int idx;
964 void *physAddress = NULL;
965#ifdef WLANDXE_TEST_CHANNEL_ENABLE
966 WLANDXE_ChannelCBType *testTXChannelCB = &dxeCtrlBlk->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
967 WLANDXE_DescCtrlBlkType *currDescCtrlBlk = testTXChannelCB->headCtrlBlk;
968#endif /* WLANDXE_TEST_CHANNEL_ENABLE*/
969
970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700971 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700972
973 /* Sanity Check */
974 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
975 {
976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
977 "dxeDescLinkAlloc Channel Entry is not valid");
978 return eWLAN_PAL_STATUS_E_INVAL;
979 }
980
981 currentCtrlBlk = channelEntry->headCtrlBlk;
982
983#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
984 /* allocate all DXE descriptors for this channel in one chunk */
985 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
986 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
987 &physAddress);
988 if(NULL == channelEntry->descriptorAllocation)
989 {
990 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
991 "dxeDescLinkAlloc Descriptor Alloc Fail");
992 return eWLAN_PAL_STATUS_E_RESOURCES;
993 }
994 currentDesc = channelEntry->descriptorAllocation;
995#endif
996
997 /* Allocate pre asigned number of descriptor */
998 for(idx = 0; idx < channelEntry->numDesc; idx++)
999 {
1000#ifndef FEATURE_R33D
1001#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1002 // descriptors were allocated in a chunk -- use the current one
1003 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1004 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1005 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1006#else
1007 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1008 {
1009 // allocate a descriptor
1010 currentDesc = (WLANDXE_DescType *)wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType),
1011 &physAddress);
1012 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1013 }
1014 else
1015 {
1016 currentDesc = currDescCtrlBlk->linkedDesc;
1017 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
1018 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1019 }
1020#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1021#else
1022#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1023 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
1024 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1025 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1026 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1027#else
1028 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1029 {
1030 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
1031 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1032 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1033 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1034 }
1035 else
1036 {
1037 currentDesc = currDescCtrlBlk->linkedDesc;
1038 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
1039 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1040 }
1041#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1042#endif /* FEATURE_R33D */
1043 if(NULL == currentDesc)
1044 {
1045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1046 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
1047 channelEntry->channelType);
1048 return eWLAN_PAL_STATUS_E_FAULT;
1049 }
1050
1051 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1052 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1053 {
1054 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1055 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1056 }
1057 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1058 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1059 {
1060 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1061 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1062 }
1063 else
1064 {
1065 /* Just in case. H2H Test RX channel, do nothing
1066 * By Definition this must not happen */
1067 }
1068
1069 currentCtrlBlk->linkedDesc = currentDesc;
1070 currentCtrlBlk->linkedDescPhyAddr = (unsigned int)physAddress;
1071 /* First descriptor, next none
1072 * descriptor bottom location is first descriptor address */
1073 if(0 == idx)
1074 {
1075 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
1076 channelEntry->DescBottomLoc = currentDesc;
1077 channelEntry->descBottomLocPhyAddr = (unsigned int)physAddress;
1078 }
1079 /* Not first, not last descriptor
1080 * may make link for previous descriptor with current descriptor
1081 * ENDIAN SWAP needed ????? */
1082 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
1083 {
1084 prevDesc->dxedesc.dxe_short_desc.phyNextL =
1085 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
1086 }
1087 /* Last descriptor
1088 * make a ring by asign next pointer as first descriptor
1089 * ENDIAN SWAP NEEDED ??? */
1090 else if((channelEntry->numDesc - 1) == idx)
1091 {
1092 prevDesc->dxedesc.dxe_short_desc.phyNextL =
1093 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
1094 currentDesc->dxedesc.dxe_short_desc.phyNextL =
1095 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)channelEntry->headCtrlBlk->linkedDescPhyAddr);
1096 }
1097
1098 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
1099 * Pre allocated and physical address must be assigned into
1100 * Corresponding DXE Descriptor */
1101#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1102 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1103 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1104 (WDTS_CHANNEL_H2H_TEST_RX == channelEntry->channelType))
1105#else
1106 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1107 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1108#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1109 {
1110 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
1111 channelEntry,
1112 currentCtrlBlk);
1113 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1114 {
1115 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1116 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1117 channelEntry->channelType);
1118 return status;
1119 }
1120 --channelEntry->numFreeDesc;
1121 }
1122
1123 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1124 prevDesc = currentDesc;
1125
1126#ifndef FEATURE_R33D
1127#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1128 // advance to the next pre-allocated descriptor in the chunk
1129 currentDesc++;
1130 physAddress = ((wpt_int8 *)physAddress) + sizeof(WLANDXE_DescType);
1131#endif
1132#endif
1133 }
1134
1135 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001136 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001137 return status;
1138}
1139
1140/*==========================================================================
1141 @ Function Name
1142
1143 @ Description
1144
1145 @ Parameters
1146
1147 @ Return
1148 wpt_status
1149
1150===========================================================================*/
1151static wpt_status dxeSetInterruptPath
1152(
1153 WLANDXE_CtrlBlkType *dxeCtrlBlk
1154)
1155{
1156 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1157 wpt_uint32 interruptPath = 0;
1158 wpt_uint32 idx;
1159 WLANDXE_ChannelCBType *channelEntry = NULL;
1160
1161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001162 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001163
1164 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
1165 {
1166 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
1167#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1168 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1169 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) ||
1170 (WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType))
1171#else
1172 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1173 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1174#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1175 {
1176 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1177 }
1178 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1179 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1180 {
1181 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1182 }
1183 else
1184 {
1185 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1186 "H2H TEST RX???? %d", channelEntry->channelType);
1187 }
1188 }
1189 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1190 "Interrupt Path Must be 0x%x", interruptPath);
1191 dxeCtrlBlk->interruptPath = interruptPath;
1192 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1193
1194 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001195 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 return status;
1197}
1198
1199/*==========================================================================
1200 @ Function Name
1201 dxeEngineCoreStart
1202
1203 @ Description
1204 Trigger to start RIVA DXE Hardware
1205
1206 @ Parameters
1207 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1208 DXE host driver main control block
1209
1210 @ Return
1211 wpt_status
1212
1213===========================================================================*/
1214static wpt_status dxeEngineCoreStart
1215(
1216 WLANDXE_CtrlBlkType *dxeCtrlBlk
1217)
1218{
1219 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1220 wpt_uint32 registerData = 0;
1221
1222 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001223 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001224
1225 /* START This core init is not needed for the integrated system */
1226 /* Reset First */
1227 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1228 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1229 registerData);
1230
1231 registerData = WLANDXE_DMA_CSR_EN_MASK;
1232 registerData |= WLANDXE_DMA_CSR_ECTR_EN_MASK;
1233 registerData |= WLANDXE_DMA_CSR_TSTMP_EN_MASK;
1234 registerData |= WLANDXE_DMA_CSR_H2H_SYNC_EN_MASK;
1235
1236 registerData = 0x00005c89;
1237 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1238 registerData);
1239
1240 /* Is This needed?
1241 * Not sure, revisit with integrated system */
1242 /* END This core init is not needed for the integrated system */
1243
1244 dxeSetInterruptPath(dxeCtrlBlk);
1245 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001246 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001247 return status;
1248}
1249
1250/*==========================================================================
1251 @ Function Name
1252 dxeChannelInitProgram
1253
1254 @ Description
1255 Program RIVA DXE engine register with initial value
1256 What must be programmed
1257 - Source Address (SADRL, chDXESadrlRegAddr)
1258 - Destination address (DADRL, chDXEDadrlRegAddr)
1259 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1260 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1261
1262 Not need to program now
1263 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1264 TX : Have to program to trigger send out frame
1265 RX : programmed by DXE engine
1266
1267 @ Parameters
1268 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1269 DXE host driver main control block
1270 WLANDXE_ChannelCBType *channelEntry
1271 Channel specific control block
1272 @ Return
1273 wpt_status
1274
1275===========================================================================*/
1276static wpt_status dxeChannelInitProgram
1277(
1278 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1279 WLANDXE_ChannelCBType *channelEntry
1280)
1281{
1282 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1283 wpt_uint32 idx;
1284 WLANDXE_DescType *currentDesc = NULL;
1285 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1286
1287 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001288 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001289
1290 /* Sanity Check */
1291 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1292 {
1293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1294 "dxeChannelInitProgram Channel Entry is not valid");
1295 return eWLAN_PAL_STATUS_E_INVAL;
1296 }
1297
1298 /* Program Source address and destination adderss */
1299 if(!channelEntry->channelConfig.useShortDescFmt)
1300 {
1301 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1302 "dxeChannelInitProgram Long Descriptor not support yet");
1303 return eWLAN_PAL_STATUS_E_FAILURE;
1304 }
1305
1306 /* Common register area */
1307 /* Next linked list Descriptor pointer */
1308 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1309 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1310 if(eWLAN_PAL_STATUS_SUCCESS != status)
1311 {
1312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1313 "dxeChannelInitProgram Write DESC Address register fail");
1314 return status;
1315 }
1316
1317 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1318 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1319 {
1320 /* Program default registers */
1321 /* TX DMA channel, DMA destination address is work Q */
1322 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1323 channelEntry->channelConfig.refWQ);
1324 if(eWLAN_PAL_STATUS_SUCCESS != status)
1325 {
1326 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1327 "dxeChannelInitProgram Write TX DAddress register fail");
1328 return status;
1329 }
1330 }
1331 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1332 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1333 {
1334 /* Initialize Descriptor control Word First */
1335 currentCtrlBlk = channelEntry->headCtrlBlk;
1336 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1337 {
1338 currentDesc = currentCtrlBlk->linkedDesc;
1339 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1340 }
1341
1342 /* RX DMA channel, DMA source address is work Q */
1343 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1344 channelEntry->channelConfig.refWQ);
1345 if(eWLAN_PAL_STATUS_SUCCESS != status)
1346 {
1347 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1348 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1349 return status;
1350 }
1351
1352 /* RX DMA channel, Program pre allocated destination Address */
1353 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1354 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1355 if(eWLAN_PAL_STATUS_SUCCESS != status)
1356 {
1357 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1358 "dxeChannelInitProgram Write RX DAddress register fail");
1359 return status;
1360 }
1361
1362 /* RX Channels, default Control registers MUST BE ENABLED */
1363 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1364 channelEntry->extraConfig.chan_mask);
1365 if(eWLAN_PAL_STATUS_SUCCESS != status)
1366 {
1367 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1368 "dxeChannelInitProgram Write RX Control register fail");
1369 return status;
1370 }
1371 }
1372 else
1373 {
1374 /* H2H test channel, not use work Q */
1375 /* Program pre allocated destination Address */
1376 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1377 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1378 if(eWLAN_PAL_STATUS_SUCCESS != status)
1379 {
1380 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1381 "dxeChannelInitProgram Write RX DAddress register fail");
1382 return status;
1383 }
1384 }
1385
1386 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001387 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001388 return status;
1389}
1390
1391
1392/*==========================================================================
1393 @ Function Name
1394 dxeChannelStart
1395
1396 @ Description
1397 Start Specific Channel
1398
1399 @ Parameters
1400 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1401 DXE host driver main control block
1402 WLANDXE_ChannelCBType *channelEntry
1403 Channel specific control block
1404
1405 @ Return
1406 wpt_status
1407
1408===========================================================================*/
1409static wpt_status dxeChannelStart
1410(
1411 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1412 WLANDXE_ChannelCBType *channelEntry
1413)
1414{
1415 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1416 wpt_uint32 regValue = 0;
1417 wpt_uint32 intMaskVal = 0;
1418
1419 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001420 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001421
1422 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1423 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1424
1425 /* Enable individual channel
1426 * not to break current channel setup, first read register */
1427 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1428 &regValue);
1429 if(eWLAN_PAL_STATUS_SUCCESS != status)
1430 {
1431 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1432 "dxeChannelStart Read Channel Enable register fail");
1433 return status;
1434 }
1435
1436 /* Enable Channel specific Interrupt */
1437 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1438 &intMaskVal);
1439 if(eWLAN_PAL_STATUS_SUCCESS != status)
1440 {
1441 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1442 "dxeChannelStart Read INT_MASK register fail");
1443 return status;
1444 }
1445 intMaskVal |= channelEntry->extraConfig.intMask;
1446 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1447 intMaskVal);
1448 if(eWLAN_PAL_STATUS_SUCCESS != status)
1449 {
1450 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1451 "dxeChannelStart Write INT_MASK register fail");
1452 return status;
1453 }
1454
1455 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001456 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001457 return status;
1458}
1459
1460/*==========================================================================
1461 @ Function Name
1462 dxeChannelStop
1463
1464 @ Description
1465 Stop Specific Channel
1466
1467 @ Parameters
1468 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1469 DXE host driver main control block
1470 WLANDXE_ChannelCBType *channelEntry
1471 Channel specific control block
1472
1473 @ Return
1474 wpt_status
1475
1476===========================================================================*/
1477static wpt_status dxeChannelStop
1478(
1479 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1480 WLANDXE_ChannelCBType *channelEntry
1481)
1482{
1483 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1484 wpt_uint32 intMaskVal = 0;
1485
1486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001487 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001488
1489 /* Sanity */
1490 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1491 {
1492 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1493 "dxeChannelStop Invalid arg input");
1494 return eWLAN_PAL_STATUS_E_INVAL;
1495 }
1496
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001497 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1498 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1499 {
1500 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1501 "dxeChannelStop channels are not enabled ");
1502 return status;
1503 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001504 /* Maskout interrupt */
1505 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1506 &intMaskVal);
1507 if(eWLAN_PAL_STATUS_SUCCESS != status)
1508 {
1509 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1510 "dxeChannelStop Read INT_MASK register fail");
1511 return status;
1512 }
1513 intMaskVal ^= channelEntry->extraConfig.intMask;
1514 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1515 intMaskVal);
1516 if(eWLAN_PAL_STATUS_SUCCESS != status)
1517 {
1518 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1519 "dxeChannelStop Write INT_MASK register fail");
1520 return status;
1521 }
1522
1523 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1524
1525 /* Stop Channel ??? */
1526 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001527 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 return status;
1529}
1530
1531/*==========================================================================
1532 @ Function Name
1533 dxeChannelClose
1534
1535 @ Description
1536 Close Specific Channel
1537 Free pre allocated RX frame buffer if RX channel
1538 Free DXE descriptor for each channel
1539 Free Descriptor control block for each channel
1540
1541 @ Parameters
1542 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1543 DXE host driver main control block
1544 WLANDXE_ChannelCBType *channelEntry
1545 Channel specific control block
1546
1547 @ Return
1548 wpt_status
1549
1550===========================================================================*/
1551static wpt_status dxeChannelClose
1552(
1553 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1554 WLANDXE_ChannelCBType *channelEntry
1555)
1556{
1557 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1558 wpt_uint32 idx;
1559 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1560 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1561 WLANDXE_DescType *currentDescriptor = NULL;
1562 WLANDXE_DescType *nextDescriptor = NULL;
1563
1564 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001565 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001566
1567 /* Sanity */
1568 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1569 {
1570 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1571 "dxeChannelStop Invalid arg input");
1572 return eWLAN_PAL_STATUS_E_INVAL;
1573 }
1574
1575 currentCtrlBlk = channelEntry->headCtrlBlk;
1576 if(NULL != currentCtrlBlk)
1577 {
1578 currentDescriptor = currentCtrlBlk->linkedDesc;
1579 for(idx = 0; idx < channelEntry->numDesc; idx++)
1580 {
1581 if (idx + 1 != channelEntry->numDesc)
1582 {
1583 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1584 nextDescriptor = nextCtrlBlk->linkedDesc;
1585 }
1586 else
1587 {
1588 nextCtrlBlk = NULL;
1589 nextDescriptor = NULL;
1590 }
1591 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1592 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1593 {
1594 if (NULL != currentCtrlBlk->xfrFrame)
1595 {
1596 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1597 wpalPacketFree(currentCtrlBlk->xfrFrame);
1598 }
1599 }
1600 /*
1601 * It is the responsibility of DXE to walk through the
1602 * descriptor chain and unlock any pending packets (if
1603 * locked).
1604 */
1605 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1606 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1607 {
1608 if((NULL != currentCtrlBlk->xfrFrame) &&
1609 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1610 {
1611 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1612 wpalPacketFree(currentCtrlBlk->xfrFrame);
1613 }
1614 }
1615#if (defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1616 // descriptors allocated individually so free them individually
1617 wpalDmaMemoryFree(currentDescriptor);
1618#endif
1619 wpalMemoryFree(currentCtrlBlk);
1620
1621 currentCtrlBlk = nextCtrlBlk;
1622 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001623 if(NULL == currentCtrlBlk)
1624 {
1625 /* Already reach last of the control block
1626 * Not need to process anymore, break */
1627 break;
1628 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001629 }
1630 }
1631
1632#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1633 // descriptors were allocated as a single chunk so free the chunk
1634 if(NULL != channelEntry->descriptorAllocation)
1635 {
1636 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1637 }
1638#endif
1639
1640 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001641 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 return status;
1643}
1644
1645/*==========================================================================
1646 @ Function Name
1647 dxeChannelCleanInt
1648
1649 @ Description
1650 Clean up interrupt from RIVA HW
1651 After Host finish to handle interrupt, interrupt signal must be cleaned up
1652 Otherwise next interrupt will not be generated
1653
1654 @ Parameters
1655 WLANDXE_ChannelCBType *channelEntry
1656 Channel specific control block
1657 wpt_uint32 *chStat
1658 Channel Status register value
1659
1660 @ Return
1661 wpt_status
1662
1663===========================================================================*/
1664static wpt_status dxeChannelCleanInt
1665(
1666 WLANDXE_ChannelCBType *channelEntry,
1667 wpt_uint32 *chStat
1668)
1669{
1670 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1671
1672 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001673 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001674
1675 /* Read Channel Status Register to know why INT Happen */
1676 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1677 chStat);
1678 if(eWLAN_PAL_STATUS_SUCCESS != status)
1679 {
1680 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1681 "dxeChannelCleanInt Read CH STAT register fail");
1682 return eWLAN_PAL_STATUS_E_FAULT;
1683 }
1684 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1685 "%s Channel INT Clean, Status 0x%x",
1686 channelType[channelEntry->channelType], *chStat);
1687
1688 /* Clean up all the INT within this channel */
1689 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1690 (1 << channelEntry->assignedDMAChannel));
1691 if(eWLAN_PAL_STATUS_SUCCESS != status)
1692 {
1693 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1694 "dxeChannelCleanInt Write CH Clean register fail");
1695 return eWLAN_PAL_STATUS_E_FAULT;
1696 }
1697
Jeff Johnsone7245742012-09-05 17:12:55 -07001698 /* Clean up Error INT Bit */
1699 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1700 {
1701 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1702 (1 << channelEntry->assignedDMAChannel));
1703 if(eWLAN_PAL_STATUS_SUCCESS != status)
1704 {
1705 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1706 "dxeChannelCleanInt Read CH STAT register fail");
1707 return eWLAN_PAL_STATUS_E_FAULT;
1708 }
1709 }
1710
1711 /* Clean up DONE INT Bit */
1712 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1713 {
1714 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1715 (1 << channelEntry->assignedDMAChannel));
1716 if(eWLAN_PAL_STATUS_SUCCESS != status)
1717 {
1718 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1719 "dxeChannelCleanInt Read CH STAT register fail");
1720 return eWLAN_PAL_STATUS_E_FAULT;
1721 }
1722 }
1723
1724 /* Clean up ED INT Bit */
1725 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1726 {
1727 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1728 (1 << channelEntry->assignedDMAChannel));
1729 if(eWLAN_PAL_STATUS_SUCCESS != status)
1730 {
1731 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1732 "dxeChannelCleanInt Read CH STAT register fail");
1733 return eWLAN_PAL_STATUS_E_FAULT;
1734 }
1735 }
1736
Jeff Johnson295189b2012-06-20 16:38:30 -07001737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001738 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 return status;
1740}
1741
1742/*==========================================================================
1743 @ Function Name
1744 dxeRXPacketAvailableCB
1745
1746 @ Description
1747 If RX frame handler encounts RX buffer pool empty condition,
1748 DXE RX handle loop will be blocked till get available RX buffer pool.
1749 When new RX buffer pool available, Packet available CB function will
1750 be called.
1751
1752 @ Parameters
1753 wpt_packet *freePacket
1754 Newly allocated RX buffer
1755 v_VOID_t *usrData
1756 DXE context
1757
1758 @ Return
1759 NONE
1760
1761===========================================================================*/
1762void dxeRXPacketAvailableCB
1763(
1764 wpt_packet *freePacket,
1765 v_VOID_t *usrData
1766)
1767{
1768 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1769 wpt_status status;
1770
1771 /* Simple Sanity */
1772 if((NULL == freePacket) || (NULL == usrData))
1773 {
1774 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1775 "Get Free RX Buffer fail, Critical Error");
1776 HDXE_ASSERT(0);
1777 return;
1778 }
1779
1780 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1781
1782 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1783 {
1784 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1785 "DXE Context data corrupted, Critical Error");
1786 HDXE_ASSERT(0);
1787 return;
1788 }
1789
1790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1791 "DXE RX packet available, post MSG to RX Thread");
1792
1793 dxeCtxt->freeRXPacket = freePacket;
1794
1795 /* Serialize RX Packet Available message upon RX thread */
1796 HDXE_ASSERT(NULL != dxeCtxt->rxPktAvailMsg);
1797
1798 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1799 dxeCtxt->rxPktAvailMsg);
1800 if(eWLAN_PAL_STATUS_SUCCESS != status)
1801 {
1802 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
1803 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1804 "dxeRXPacketAvailableCB serialize fail");
1805 }
1806
1807 return;
1808}
1809
1810/*==========================================================================
1811 @ Function Name
1812 dxeRXFrameSingleBufferAlloc
1813
1814 @ Description
1815 Allocate Platform packet buffer to prepare RX frame
1816 RX frame memory space must be pre allocted and must be asigned to
1817 descriptor
1818 then whenever DMA engine want to tranfer frame from BMU,
1819 buffer must be ready
1820
1821 @ Parameters
1822 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1823 DXE host driver main control block
1824 WLANDXE_ChannelCBType *channelEntry
1825 Channel specific control block
1826 WLANDXE_DescCtrlBlkType currentCtrlBlock
1827 current control block which have to be asigned
1828 frame buffer
1829
1830 @ Return
1831 wpt_status
1832
1833===========================================================================*/
1834static wpt_status dxeRXFrameSingleBufferAlloc
1835(
1836 WLANDXE_CtrlBlkType *dxeCtxt,
1837 WLANDXE_ChannelCBType *channelEntry,
1838 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1839)
1840{
1841 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1842 wpt_packet *currentPalPacketBuffer = NULL;
1843 WLANDXE_DescType *currentDesc = NULL;
1844#ifdef FEATURE_R33D
1845 wpt_uint32 virtualAddressPCIe;
1846 wpt_uint32 physicalAddressPCIe;
1847#else
1848 wpt_iterator iterator;
1849 wpt_uint32 allocatedSize = 0;
1850 void *physAddress = NULL;
1851#endif /* FEATURE_R33D */
1852
Jeff Johnson295189b2012-06-20 16:38:30 -07001853
1854 currentDesc = currentCtrlBlock->linkedDesc;
1855
1856 /* First check if a packet pointer has already been provided by a previously
1857 invoked Rx packet available callback. If so use that packet. */
1858 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1859 {
1860 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1861 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1862 dxeCtxt->freeRXPacket = NULL;
1863 }
1864 else if(!dxeCtxt->rxPalPacketUnavailable)
1865 {
1866 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1867 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
1868 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1869 dxeRXPacketAvailableCB,
1870 (void *)dxeCtxt);
1871
1872 if(NULL == currentPalPacketBuffer)
1873 {
1874 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
1875 }
1876 }
1877
1878 if(NULL == currentPalPacketBuffer)
1879 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001880 return eWLAN_PAL_STATUS_E_RESOURCES;
1881 }
1882
1883 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1884 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1885 currentPalPacketBuffer->pBD = NULL;
1886 currentPalPacketBuffer->pBDPhys = NULL;
1887 currentPalPacketBuffer->BDLength = 0;
1888#ifdef FEATURE_R33D
1889 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
1890 &physicalAddressPCIe,
1891 &virtualAddressPCIe);
1892 HDXE_ASSERT(0 != physicalAddressPCIe);
1893 HDXE_ASSERT(0 != virtualAddressPCIe);
1894 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
1895 "RX Shadow Memory Va 0x%x, Pa 0x%x",
1896 virtualAddressPCIe, physicalAddressPCIe);
1897 if(eWLAN_PAL_STATUS_SUCCESS != status)
1898 {
1899 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1900 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
1901 return status;
1902 }
1903 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
1904 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
1905 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1906#else
1907 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
1908 if(eWLAN_PAL_STATUS_SUCCESS != status)
1909 {
1910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1911 "dxeRXFrameBufferAlloc unable to lock packet");
1912 return status;
1913 }
1914
1915 /* Init iterator to get physical os buffer address */
1916 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1917 if(eWLAN_PAL_STATUS_SUCCESS != status)
1918 {
1919 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1920 "dxeRXFrameBufferAlloc iterator init fail");
1921 return status;
1922 }
1923 status = wpalIteratorNext(&iterator,
1924 currentPalPacketBuffer,
1925 &physAddress,
1926 &allocatedSize);
1927 if(eWLAN_PAL_STATUS_SUCCESS != status)
1928 {
1929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1930 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1931 return status;
1932 }
1933 currentPalPacketBuffer->pBDPhys = physAddress;
1934#endif /* FEATURE_R33D */
1935
1936 /* DXE descriptor must have SWAPPED addres in it's structure
1937 * !!! SWAPPED !!! */
1938 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
1939 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)currentPalPacketBuffer->pBDPhys);
1940
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 return status;
1942}
1943
1944/*==========================================================================
1945 @ Function Name
1946 dxeRXFrameRefillRing
1947
1948 @ Description
1949 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1950
1951 @ Parameters
1952 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1953 DXE host driver main control block
1954 WLANDXE_ChannelCBType *channelEntry
1955 Channel specific control block
1956
1957 @ Return
1958 wpt_status
1959
1960===========================================================================*/
1961static wpt_status dxeRXFrameRefillRing
1962(
1963 WLANDXE_CtrlBlkType *dxeCtxt,
1964 WLANDXE_ChannelCBType *channelEntry
1965)
1966{
1967 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1968 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
1969 WLANDXE_DescType *currentDesc = NULL;
1970
1971 while(channelEntry->numFreeDesc > 0)
1972 {
1973 /* Current Control block is free
1974 * and associated frame buffer is not linked with control block anymore
1975 * allocate new frame buffer for current control block */
1976 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
1977 channelEntry,
1978 currentCtrlBlk);
1979
1980 if(eWLAN_PAL_STATUS_SUCCESS != status)
1981 {
1982 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1983 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
1984 break;
1985 }
1986
1987 currentDesc = currentCtrlBlk->linkedDesc;
1988 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1989
1990 /* Issue a dummy read from the DXE descriptor DDR location to ensure
1991 that any posted writes are reflected in memory before DXE looks at
1992 the descriptor. */
1993 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
1994 {
1995 //HDXE_ASSERT(0);
1996 }
1997
1998 /* Kick off the DXE ring, if not in any power save mode */
1999 if((WLANDXE_POWER_STATE_IMPS != dxeCtxt->hostPowerState) &&
2000 (WLANDXE_POWER_STATE_DOWN != dxeCtxt->hostPowerState))
2001 {
2002 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2003 1 << channelEntry->assignedDMAChannel);
2004 }
2005 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2006 --channelEntry->numFreeDesc;
2007 }
2008
2009 channelEntry->tailCtrlBlk = currentCtrlBlk;
2010
2011 return status;
2012}
2013
2014/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002015 @ Function Name
2016 dxeRXFrameRouteUpperLayer
2017
2018 @ Description
2019 Test DXE descriptors and if any RX frame pending within RING,
2020 Route to upper layer
2021
2022 @ Parameters
2023 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2024 DXE host driver main control block
2025 WLANDXE_ChannelCBType *channelEntry
2026 Channel specific control block
2027 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002028 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002029 0 No frame pulled from RX RING
2030 int number of RX frames pulled from RX ring
2031
2032===========================================================================*/
2033static wpt_int32 dxeRXFrameRouteUpperLayer
2034(
2035 WLANDXE_CtrlBlkType *dxeCtxt,
2036 WLANDXE_ChannelCBType *channelEntry
2037)
2038{
2039 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2040 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2041 WLANDXE_DescType *currentDesc = NULL;
2042 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002043 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002044
2045 currentCtrlBlk = channelEntry->headCtrlBlk;
2046 currentDesc = currentCtrlBlk->linkedDesc;
2047
2048 /* Descriptoe should be SWAPPED ???? */
2049 descCtrl = currentDesc->descCtrl.ctrl;
2050
2051 /* Get frames while VALID bit is not set (DMA complete) and a data
2052 * associated with it */
2053 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2054 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2055 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2056 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2057 {
2058 channelEntry->numTotalFrame++;
2059 channelEntry->numFreeDesc++;
2060#ifdef FEATURE_R33D
2061 /* Transfer Size should be */
2062 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2063 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
2064 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
2065 currentCtrlBlk->shadowBufferVa,
2066 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2067 if(eWLAN_PAL_STATUS_SUCCESS != status)
2068 {
2069 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2070 "dxeRXFrameReady Prepare RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002071 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002072 }
2073 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
2074 if(eWLAN_PAL_STATUS_SUCCESS != status)
2075 {
2076 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2077 "dxeRXFrameReady Free Shadow RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002078 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002079 }
2080
2081#else /* FEATURE_R33D */
2082 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
2083 if (eWLAN_PAL_STATUS_SUCCESS != status)
2084 {
2085 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2086 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002087 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002088 }
2089#endif /* FEATURE_R33D */
2090 /* This Descriptor is valid, so linked Control block is also valid
2091 * Linked Control block has pre allocated packet buffer
2092 * So, just let upper layer knows preallocated frame pointer will be OK */
2093 /* Reap Rx frames */
2094 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2095 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002096 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002097
2098 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2099 dxeRXFrameRefillRing(dxeCtxt,channelEntry);
2100
2101 /* Test next contorl block
2102 * if valid, this control block also has new RX frame must be handled */
2103 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2104 currentDesc = currentCtrlBlk->linkedDesc;
2105 descCtrl = currentDesc->descCtrl.ctrl;
2106 }
2107
2108 /* Update head control block
2109 * current control block's valid bit was 0
2110 * next trial first control block must be current control block */
2111 channelEntry->headCtrlBlk = currentCtrlBlk;
2112
2113 /* Deliver all the reaped RX frames to upper layers */
2114 i = 0;
2115 while(i < frameCount) {
2116 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2117 i++;
2118 }
2119
2120 return frameCount;
2121}
2122
2123/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 @ Function Name
2125 dxeRXFrameReady
2126
2127 @ Description
2128 Pop frame from descriptor and route frame to upper transport layer
2129 Assign new platform packet buffer into used descriptor
2130 Actual frame pop and resource realloc
2131
2132 @ Parameters
2133 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2134 DXE host driver main control block
2135 WLANDXE_ChannelCBType *channelEntry
2136 Channel specific control block
2137
2138 @ Return
2139 wpt_status
2140
2141===========================================================================*/
2142static wpt_status dxeRXFrameReady
2143(
2144 WLANDXE_CtrlBlkType *dxeCtxt,
2145 WLANDXE_ChannelCBType *channelEntry
2146)
2147{
2148 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2149 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2150 WLANDXE_DescType *currentDesc = NULL;
2151 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002152 wpt_int32 frameCount = 0;
2153
2154 wpt_uint32 descLoop;
2155 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002156
2157 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002158 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002159
2160 /* Sanity Check */
2161 if((NULL == dxeCtxt) || (NULL == channelEntry))
2162 {
2163 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2164 "dxeRXFrameReady Channel Entry is not valid");
2165 return eWLAN_PAL_STATUS_E_INVAL;
2166 }
2167
Jeff Johnsone7245742012-09-05 17:12:55 -07002168 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002169
Jeff Johnsone7245742012-09-05 17:12:55 -07002170 if(0 > frameCount)
Jeff Johnson295189b2012-06-20 16:38:30 -07002171 {
2172 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002173 "dxeRXFrameReady RX frame route fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002174 return eWLAN_PAL_STATUS_E_INVAL;
2175 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002176
Jeff Johnsone7245742012-09-05 17:12:55 -07002177 if((0 == frameCount) &&
2178 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2179 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2180 {
2181 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002182 currentDesc = currentCtrlBlk->linkedDesc;
2183 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002184
2185 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2186 {
2187 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2188 "RX ISR called but no frame handled PWS %d, channel %s",
2189 (int)dxeCtxt->hostPowerState,
2190 channelType[channelEntry->channelType]);
2191 }
2192
2193 /* Current interupt empty and previous interrupt also empty
2194 * detected successive empty interrupt
2195 * or first interrupt empty, this should not happen */
2196 if(0 == channelEntry->numFragmentCurrentChain)
2197 {
2198 dxeChannelMonitor("RX Ready", channelEntry);
2199 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2200 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt");
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07002201 dxeChannelAllDescDump(channelEntry, channelEntry->channelType);
Jeff Johnsone7245742012-09-05 17:12:55 -07002202
2203 /* Abnormal interrupt detected, try to find not validated descriptor */
2204 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2205 {
2206 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2207 {
2208 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2209 "Found Invalidated Descriptor %d", (int)descLoop);
2210 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2211 {
2212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2213 "Packet locked, Resync Host and HW");
2214 channelEntry->headCtrlBlk = currentCtrlBlk;
2215 invalidatedFound = 1;
2216 break;
2217 }
2218 else
2219 {
2220 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2221 "Packet Not Locked, cannot transfer frame");
2222 }
2223 }
2224 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2225 currentDesc = currentCtrlBlk->linkedDesc;
2226 descCtrl = currentDesc->descCtrl.ctrl;
2227 }
2228
Jeff Johnson32d95a32012-09-10 13:15:23 -07002229 /* Invalidated descriptor found, and that is not head descriptor
2230 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2231 * Try re-sync here */
2232 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002233 {
2234 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2235 "Found New Sync location with HW, handle frames from there");
2236 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2237 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2238 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002239 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002240 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002241 /* Successive Empty interrupt
2242 * But this case, first descriptor also invalidated, then it means head descriptor
2243 * is linked with already handled RX frame, then could not unlock RX frame
2244 * This is just Out of RX buffer pool, not need to anything here */
2245 else if((invalidatedFound) && (0 == descLoop))
2246 {
2247 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2248 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2249 }
2250 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002251 else
2252 {
2253 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2254 "Could not found invalidated descriptor");
2255 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2256 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2257 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2258 wpalWlanReload();
2259 }
2260 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002262 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002264 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002265 return status;
2266}
2267
2268/*==========================================================================
2269 @ Function Name
2270 dxeNotifySmsm
2271
2272 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2273 buffer
2274
2275 @ Parameters
2276
2277 @ Return
2278 wpt_status
2279
2280===========================================================================*/
2281static wpt_status dxeNotifySmsm
2282(
2283 wpt_boolean kickDxe,
2284 wpt_boolean ringEmpty
2285)
2286{
2287 wpt_uint32 clrSt = 0;
2288 wpt_uint32 setSt = 0;
2289
2290 if(kickDxe)
2291 {
2292 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2293
2294 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2295 {
2296 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2297 tempDxeCtrlBlk->lastKickOffDxe = 1;
2298 }
2299 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2300 {
2301 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2302 tempDxeCtrlBlk->lastKickOffDxe = 0;
2303 }
2304 else
2305 {
2306 HDXE_ASSERT(0);
2307 }
2308 }
2309 else
2310 {
2311 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2312 }
2313
2314 if(ringEmpty)
2315 {
2316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2317 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2318 }
2319 else
2320 {
2321 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2322 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2323 }
2324
2325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2326
2327 wpalNotifySmsm(clrSt, setSt);
2328
2329 return eWLAN_PAL_STATUS_SUCCESS;
2330}
2331
2332/*==========================================================================
2333 @ Function Name
2334 dxePsComplete
2335
2336 @ Description: Utility function to check the resv desc to deside if we can
2337 get into Power Save mode now
2338
2339 @ Parameters
2340
2341 @ Return
2342 None
2343
2344===========================================================================*/
2345static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2346{
2347 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2348 {
2349 return;
2350 }
2351
2352 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2353 //must have been consumed by RIVA, OK to get into BMPS
2354 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2355 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2356 {
2357 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2358 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2359 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2360 {
2361 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2362 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2363 }
2364 }
2365 else //still more pkts to be served by RIVA
2366 {
2367 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2368
2369 switch(dxeCtxt->rivaPowerState)
2370 {
2371 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2372 //NOP
2373 break;
2374 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2375 if(intr_based)
2376 {
2377 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2378 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2379 }
2380 break;
2381 default:
2382 //assert
2383 break;
2384 }
2385 }
2386}
2387
2388/*==========================================================================
2389 @ Function Name
2390 dxeRXEventHandler
2391
2392 @ Description
2393 Handle serailized RX frame ready event
2394 First disable interrupt then pick up frame from pre allocated buffer
2395 Since frame handle is doen, clear interrupt bit to ready next interrupt
2396 Finally re enable interrupt
2397
2398 @ Parameters
2399 wpt_msg *rxReadyMsg
2400 RX frame ready MSG pointer
2401 include DXE control context
2402
2403 @ Return
2404 NONE
2405
2406===========================================================================*/
2407void dxeRXEventHandler
2408(
2409 wpt_msg *rxReadyMsg
2410)
2411{
2412 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2413 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2414 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2415 wpt_uint32 intSrc = 0;
2416 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002417 wpt_uint32 chHighStat = 0;
2418 wpt_uint32 chLowStat = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002419
Jeff Johnsone7245742012-09-05 17:12:55 -07002420 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421
Jeff Johnsone7245742012-09-05 17:12:55 -07002422 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 {
2424 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002425 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002426 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 }
2428
Jeff Johnsone7245742012-09-05 17:12:55 -07002429 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2430 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2431 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
2432
Jeff Johnson295189b2012-06-20 16:38:30 -07002433 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2434
2435 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
2436 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
2437 {
2438 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2439 "DXE already stopped in RX event handler. Just return");
2440 return;
2441 }
2442
2443 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2444 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2445 {
2446 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2447 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002448 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002449
2450 /* Not to touch any register, just pull frame directly from chain ring
2451 * First high priority */
2452 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2453 status = dxeRXFrameReady(dxeCtxt,
2454 channelCb);
2455 if(eWLAN_PAL_STATUS_SUCCESS != status)
2456 {
2457 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2458 "dxeRXEventHandler Pull from RX high channel fail");
2459 }
2460
2461 /* Second low priority */
2462 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2463 status = dxeRXFrameReady(dxeCtxt,
2464 channelCb);
2465 if(eWLAN_PAL_STATUS_SUCCESS != status)
2466 {
2467 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2468 "dxeRXEventHandler Pull from RX low channel fail");
2469 }
2470
2471 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2472 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2473
2474 return;
2475 }
2476
2477 /* Disable device interrupt */
2478 /* Read whole interrupt mask register and exclusive only this channel int */
2479 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2480 &intSrc);
2481 if(eWLAN_PAL_STATUS_SUCCESS != status)
2482 {
2483 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2484 "dxeRXEventHandler Read INT_SRC register fail");
2485 return;
2486 }
2487 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2488 "RX Event Handler INT Source 0x%x", intSrc);
2489
2490#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2491 /* Test High Priority Channel interrupt is enabled or not */
2492 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2493 if(intSrc & (1 << channelCb->assignedDMAChannel))
2494 {
2495 status = dxeChannelCleanInt(channelCb, &chHighStat);
2496 if(eWLAN_PAL_STATUS_SUCCESS != status)
2497 {
2498 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2499 "dxeRXEventHandler INT Clean up fail");
2500 return;
2501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002502 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2503 {
2504 /* Error Happen during transaction, Handle it */
2505 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002506 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2507 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002508 {
2509 /* Handle RX Ready for high priority channel */
2510 status = dxeRXFrameReady(dxeCtxt,
2511 channelCb);
2512 }
2513 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2514 {
2515 status = dxeRXFrameReady(dxeCtxt,
2516 channelCb);
2517 }
2518 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2519 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002520 /* Update the Rx DONE histogram */
2521 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2522 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2523 {
2524 channelCb->rxDoneHistogram |= 1;
2525 }
2526 else
2527 {
2528 channelCb->rxDoneHistogram &= ~1;
2529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 }
2531#else
2532 /* Test H2H Test interrupt is enabled or not */
2533 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2534 if(intSrc & (1 << channelCb->assignedDMAChannel))
2535 {
2536 status = dxeChannelCleanInt(channelCb, &chStat);
2537 if(eWLAN_PAL_STATUS_SUCCESS != status)
2538 {
2539 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2540 "dxeRXEventHandler INT Clean up fail");
2541 return;
2542 }
2543
2544 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2545 {
2546 /* Error Happen during transaction, Handle it */
2547 }
2548 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2549 {
2550 /* Handle RX Ready for high priority channel */
2551 status = dxeRXFrameReady(dxeCtxt,
2552 channelCb);
2553 }
2554 /* Update the Rx DONE histogram */
2555 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2556 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2557 {
2558 channelCb->rxDoneHistogram |= 1;
2559 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2560 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2561 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2562 }
2563 else
2564 {
2565 channelCb->rxDoneHistogram &= ~1;
2566 }
2567 }
2568#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2569
2570 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002571 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002572 if(intSrc & (1 << channelCb->assignedDMAChannel))
2573 {
2574 status = dxeChannelCleanInt(channelCb, &chLowStat);
2575 if(eWLAN_PAL_STATUS_SUCCESS != status)
2576 {
2577 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2578 "dxeRXEventHandler INT Clean up fail");
2579 return;
2580 }
2581
2582 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2583 {
2584 /* Error Happen during transaction, Handle it */
2585 }
2586 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2587 {
2588 /* Handle RX Ready for low priority channel */
2589 status = dxeRXFrameReady(dxeCtxt,
2590 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07002591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002592
2593 /* Update the Rx DONE histogram */
2594 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2595 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2596 {
2597 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 }
2599 else
2600 {
2601 channelCb->rxDoneHistogram &= ~1;
2602 }
2603 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2604 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2605 }
2606 if(eWLAN_PAL_STATUS_SUCCESS != status)
2607 {
2608 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2609 "dxeRXEventHandler Handle Frame Ready Fail");
2610 return;
2611 }
2612
2613 /* Enable system level ISR */
2614 /* Enable RX ready Interrupt at here */
2615 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2616 if(eWLAN_PAL_STATUS_SUCCESS != status)
2617 {
2618 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2619 "dxeRXEventHandler Enable RX Ready interrupt fail");
2620 return;
2621 }
2622
2623 /* Prepare Control Register EN Channel */
2624 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2625 {
2626 HDXE_ASSERT(0);
2627 }
2628 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
2629 {
2630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2631 "dxeRXEventHandler RX High, Not yet ED, re-enable CH");
2632 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
2633 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
2634 }
2635 else
2636 {
2637 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2638 "dxeRXEventHandler RX High, CH STAT = ED_MASK, will RIVA PC");
2639 }
2640
2641 /* Prepare Control Register EN Channel */
2642 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2643 {
2644 HDXE_ASSERT(0);
2645 }
2646 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat))
2647 {
2648 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2649 "dxeRXEventHandler RX Low, Not yet ED, re-enable CH");
2650 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
2651 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
2652 }
2653 else
2654 {
2655 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2656 "dxeRXEventHandler RX Low, CH STAT = ED_MASK, will RIVA PC");
2657 }
2658
2659 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002660 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002661 return;
2662}
2663
2664/*==========================================================================
2665 @ Function Name
2666 dxeRXPacketAvailableEventHandler
2667
2668 @ Description
2669 Handle serialized RX Packet Available event when the corresponding callback
2670 is invoked by WPAL.
2671 Try to fill up any completed DXE descriptors with available Rx packet buffer
2672 pointers.
2673
2674 @ Parameters
2675 wpt_msg *rxPktAvailMsg
2676 RX frame ready MSG pointer
2677 include DXE control context
2678
2679 @ Return
2680 NONE
2681
2682===========================================================================*/
2683void dxeRXPacketAvailableEventHandler
2684(
2685 wpt_msg *rxPktAvailMsg
2686)
2687{
2688 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2689 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2690 WLANDXE_ChannelCBType *channelCb = NULL;
2691
2692 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002693 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002694
2695 /* Sanity Check */
2696 if(NULL == rxPktAvailMsg)
2697 {
2698 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2699 "dxeRXPacketAvailableEventHandler Context is not valid");
2700 return;
2701 }
2702
2703 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
2704
2705 do
2706 {
2707 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2708 "dxeRXPacketAvailableEventHandler, start refilling ring");
2709
2710 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2711 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2712
2713 // Wait for another callback to indicate when Rx resources are available
2714 // again.
2715 if(eWLAN_PAL_STATUS_SUCCESS != status)
2716 {
2717 break;
2718 }
2719
2720 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2721 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2722 if(eWLAN_PAL_STATUS_SUCCESS != status)
2723 {
2724 break;
2725 }
2726 } while(0);
2727
2728 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2729 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2730 {
2731 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2732 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2733 }
2734}
2735
2736/*==========================================================================
2737 @ Function Name
2738 dxeRXISR
2739
2740 @ Description
2741 RX frame ready interrupt service routine
2742 interrupt entry function, this function called based on ISR context
2743 Must be serialized
2744
2745 @ Parameters
2746 void *hostCtxt
2747 DXE host driver control context,
2748 pre registerd during interrupt registration
2749
2750 @ Return
2751 NONE
2752
2753===========================================================================*/
2754static void dxeRXISR
2755(
2756 void *hostCtxt
2757)
2758{
2759 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2760 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2761#ifdef FEATURE_R33D
2762 wpt_uint32 regValue;
2763#endif /* FEATURE_R33D */
2764
Jeff Johnson295189b2012-06-20 16:38:30 -07002765
2766#ifdef FEATURE_R33D
2767 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2768 &regValue);
2769 if(eWLAN_PAL_STATUS_SUCCESS != status)
2770 {
2771 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2772 "dxeTXCompISR Read INT_SRC_RAW fail");
2773 return;
2774 }
2775 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2776 "INT_SRC_RAW 0x%x", regValue);
2777 if(0 == regValue)
2778 {
2779 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2780 "This is not DXE Interrupt, Reject it 0x%x", regValue);
2781 return;
2782 }
2783#endif /* FEATURE_R33D */
2784
2785 /* Disable interrupt at here
2786 * Disable RX Ready system level Interrupt at here
2787 * Otherwise infinite loop might happen */
2788 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2789 if(eWLAN_PAL_STATUS_SUCCESS != status)
2790 {
2791 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2792 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2793 return;
2794 }
2795
2796 /* Serialize RX Ready interrupt upon RX thread */
2797 HDXE_ASSERT(NULL != dxeCtxt->rxIsrMsg);
2798 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2799 dxeCtxt->rxIsrMsg);
2800 if(eWLAN_PAL_STATUS_SUCCESS != status)
2801 {
2802 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
2803 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2804 "dxeRXFrameReadyISR interrupt serialize fail");
2805 }
2806
Jeff Johnson295189b2012-06-20 16:38:30 -07002807 return;
2808}
2809
2810/*==========================================================================
2811 @ Function Name
2812 dxeTXPushFrame
2813
2814 @ Description
2815 Push TX frame into DXE descriptor and DXE register
2816 Send notification to DXE register that TX frame is ready to transfer
2817
2818 @ Parameters
2819 WLANDXE_ChannelCBType *channelEntry
2820 Channel specific control block
2821 wpt_packet *palPacket
2822 Packet pointer ready to transfer
2823
2824 @ Return
2825 PAL_STATUS_T
2826===========================================================================*/
2827static wpt_status dxeTXPushFrame
2828(
2829 WLANDXE_ChannelCBType *channelEntry,
2830 wpt_packet *palPacket
2831)
2832{
2833 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2834 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2835 WLANDXE_DescType *currentDesc = NULL;
2836 WLANDXE_DescType *firstDesc = NULL;
2837 WLANDXE_DescType *LastDesc = NULL;
2838 void *sourcePhysicalAddress = NULL;
2839 wpt_uint32 xferSize = 0;
2840#ifdef FEATURE_R33D
2841 tx_frm_pcie_vector_t frameVector;
2842 wpt_uint32 Va;
2843 wpt_uint32 fragCount = 0;
2844#else
2845 wpt_iterator iterator;
2846#endif /* FEATURE_R33D */
2847
2848 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002849 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002850
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002851 if(WLANDXE_POWER_STATE_BMPS == tempDxeCtrlBlk->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002852 {
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002853 tempDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2854 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002855 }
2856
2857 channelEntry->numFragmentCurrentChain = 0;
2858 currentCtrlBlk = channelEntry->headCtrlBlk;
2859
2860 /* Initialize interator, TX is fragmented */
2861#ifdef FEATURE_R33D
2862 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2863 status = wpalPrepareTxFrame(palPacket,
2864 &frameVector,
2865 &Va);
2866#else
2867 status = wpalLockPacketForTransfer(palPacket);
2868 if(eWLAN_PAL_STATUS_SUCCESS != status)
2869 {
2870 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2871 "dxeTXPushFrame unable to lock packet");
2872 return status;
2873 }
2874
2875 status = wpalIteratorInit(&iterator, palPacket);
2876#endif /* FEATURE_R33D */
2877 if(eWLAN_PAL_STATUS_SUCCESS != status)
2878 {
2879 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2880 "dxeTXPushFrame iterator init fail");
2881 return status;
2882 }
2883
2884 /* !!!! Revisit break condition !!!!!!! */
2885 while(1)
2886 {
2887 /* Get current descriptor pointer from current control block */
2888 currentDesc = currentCtrlBlk->linkedDesc;
2889 if(NULL == firstDesc)
2890 {
2891 firstDesc = currentCtrlBlk->linkedDesc;
2892 }
2893 /* All control block will have same palPacket Pointer
2894 * to make logic simpler */
2895 currentCtrlBlk->xfrFrame = palPacket;
2896
2897 /* Get next fragment physical address and fragment size
2898 * if this is the first trial, will get first physical address
2899 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2900#ifdef FEATURE_R33D
2901 if(fragCount == frameVector.num_frg)
2902 {
2903 break;
2904 }
2905 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2906 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2907 xferSize = frameVector.frg[fragCount].size;
2908 fragCount++;
2909 HDXE_ASSERT(0 != xferSize);
2910 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2911#else
2912 status = wpalIteratorNext(&iterator,
2913 palPacket,
2914 &sourcePhysicalAddress,
2915 &xferSize);
2916 if((NULL == sourcePhysicalAddress) ||
2917 (0 == xferSize))
2918 {
2919 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2920 "dxeTXPushFrame end of current frame");
2921 break;
2922 }
2923 if(eWLAN_PAL_STATUS_SUCCESS != status)
2924 {
2925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2926 "dxeTXPushFrame Get next frame fail");
2927 return status;
2928 }
2929#endif /* FEATURE_R33D */
2930
2931 /* This is the LAST descriptor valid for this transaction */
2932 LastDesc = currentCtrlBlk->linkedDesc;
2933
2934 /* Program DXE descriptor */
2935 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2936 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2937
2938 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2939 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2940 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2941 {
2942 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
2943 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
2944 }
2945 else
2946 {
2947 /* Test specific H2H transfer, destination address already set
2948 * Do Nothing */
2949 }
2950 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
2951
2952 /* Program channel control register */
2953 /* First frame not set VAL bit, why ??? */
2954 if(0 == channelEntry->numFragmentCurrentChain)
2955 {
2956 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
2957 }
2958 else
2959 {
2960 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2961 }
2962
2963 /* Update statistics */
2964 channelEntry->numFragmentCurrentChain++;
2965 channelEntry->numFreeDesc--;
2966 channelEntry->numRsvdDesc++;
2967
2968 /* Get next control block */
2969 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2970 }
2971 channelEntry->numTotalFrame++;
2972 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2973 "NUM TX FRAG %d, Total Frame %d",
2974 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
2975
2976 /* Program Channel control register
2977 * Set as end of packet
2978 * Enable interrupt also for first code lock down
2979 * performace optimization, this will be revisited */
2980 if(NULL == LastDesc)
2981 {
2982 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2983 "dxeTXPushFrame NULL Last Descriptor, broken chain");
2984 return eWLAN_PAL_STATUS_E_FAULT;
2985 }
2986 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
2987 /* Now First one also Valid ????
2988 * this procedure will prevent over handle descriptor from previous
2989 * TX trigger */
2990 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2991
2992 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
2993 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
2994 {
2995 /* Update channel head as next avaliable linked slot */
2996 channelEntry->headCtrlBlk = currentCtrlBlk;
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002997 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2998 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,
2999 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3000 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3001 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003002 }
3003
3004 /* If DXE use external descriptor, registers are not needed to be programmed
3005 * Just after finish to program descriptor, tirigger to send */
3006 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3007 {
3008 /* Issue a dummy read from the DXE descriptor DDR location to
3009 ensure that any previously posted write to the descriptor
3010 completes. */
3011 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3012 {
3013 //HDXE_ASSERT(0);
3014 }
3015
3016 /* Everything is ready
3017 * Trigger to start DMA */
3018 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3019 channelEntry->extraConfig.chan_mask);
3020 if(eWLAN_PAL_STATUS_SUCCESS != status)
3021 {
3022 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3023 "dxeTXPushFrame Write Channel Ctrl Register fail");
3024 return status;
3025 }
3026
3027 /* Update channel head as next avaliable linked slot */
3028 channelEntry->headCtrlBlk = currentCtrlBlk;
3029
3030 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003031 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003032 return status;
3033 }
3034
3035 /* If DXE not use external descriptor, program each registers */
3036 /* Circular buffer handle not need to program DESC register???
3037 * GEN5 code not programed RING buffer case
3038 * REVISIT THIS !!!!!! */
3039 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3040 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3041 {
3042 /* Destination address, assigned Work Q */
3043 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3044 channelEntry->channelConfig.refWQ);
3045 if(eWLAN_PAL_STATUS_SUCCESS != status)
3046 {
3047 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3048 "dxeTXPushFrame Program dest address register fail");
3049 return status;
3050 }
3051 /* If descriptor format is SHORT */
3052 if(channelEntry->channelConfig.useShortDescFmt)
3053 {
3054 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3055 0);
3056 if(eWLAN_PAL_STATUS_SUCCESS != status)
3057 {
3058 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3059 "dxeTXPushFrame Program dest address register fail");
3060 return status;
3061 }
3062 }
3063 else
3064 {
3065 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3066 "dxeTXPushFrame LONG Descriptor Format!!!");
3067 }
3068 }
3069#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3070 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3071 {
3072 /* Destination address, Physical memory address */
3073 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3074 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3075 if(eWLAN_PAL_STATUS_SUCCESS != status)
3076 {
3077 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3078 "dxeTXPushFrame Program dest address register fail");
3079 return status;
3080 }
3081 /* If descriptor format is SHORT */
3082 if(channelEntry->channelConfig.useShortDescFmt)
3083 {
3084 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3085 0);
3086 if(eWLAN_PAL_STATUS_SUCCESS != status)
3087 {
3088 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3089 "dxeTXPushFrame Program dest address register fail");
3090 return status;
3091 }
3092 }
3093 else
3094 {
3095 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3096 "dxeTXPushFrame LONG Descriptor Format!!!");
3097 }
3098 }
3099#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3100
3101 /* Program Source address register
3102 * This address is already programmed into DXE Descriptor
3103 * But register also upadte */
3104 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3105 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3106 if(eWLAN_PAL_STATUS_SUCCESS != status)
3107 {
3108 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3109 "dxeTXPushFrame Program src address register fail");
3110 return status;
3111 }
3112 /* If descriptor format is SHORT */
3113 if(channelEntry->channelConfig.useShortDescFmt)
3114 {
3115 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3116 0);
3117 if(eWLAN_PAL_STATUS_SUCCESS != status)
3118 {
3119 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3120 "dxeTXPushFrame Program dest address register fail");
3121 return status;
3122 }
3123 }
3124 else
3125 {
3126 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3127 "dxeTXPushFrame LONG Descriptor Format!!!");
3128 }
3129
3130 /* Linked list Descriptor pointer */
3131 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3132 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3133 if(eWLAN_PAL_STATUS_SUCCESS != status)
3134 {
3135 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3136 "dxeTXPushFrame Write DESC Address register fail");
3137 return status;
3138 }
3139 /* If descriptor format is SHORT */
3140 if(channelEntry->channelConfig.useShortDescFmt)
3141 {
3142 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3143 0);
3144 if(eWLAN_PAL_STATUS_SUCCESS != status)
3145 {
3146 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3147 "dxeTXPushFrame Program dest address register fail");
3148 return status;
3149 }
3150 }
3151 else
3152 {
3153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3154 "dxeTXPushFrame LONG Descriptor Format!!!");
3155 }
3156
3157 /* Transfer Size */
3158 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3159 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3160 xferSize);
3161 if(eWLAN_PAL_STATUS_SUCCESS != status)
3162 {
3163 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3164 "dxeTXPushFrame Write DESC Address register fail");
3165 return status;
3166 }
3167
3168 /* Everything is ready
3169 * Trigger to start DMA */
3170 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3171 channelEntry->extraConfig.chan_mask);
3172 if(eWLAN_PAL_STATUS_SUCCESS != status)
3173 {
3174 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3175 "dxeTXPushFrame Write Channel Ctrl Register fail");
3176 return status;
3177 }
3178
3179 /* Update channel head as next avaliable linked slot */
3180 channelEntry->headCtrlBlk = currentCtrlBlk;
3181
3182 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003183 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003184 return status;
3185}
3186
3187/*==========================================================================
3188 @ Function Name
3189 dxeTXCompFrame
3190
3191 @ Description
3192 TX Frame transfer complete event handler
3193
3194 @ Parameters
3195 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3196 DXE host driver main control block
3197 WLANDXE_ChannelCBType *channelEntry
3198 Channel specific control block
3199
3200 @ Return
3201 PAL_STATUS_T
3202===========================================================================*/
3203static wpt_status dxeTXCompFrame
3204(
3205 WLANDXE_CtrlBlkType *hostCtxt,
3206 WLANDXE_ChannelCBType *channelEntry
3207)
3208{
3209 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3210 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3211 WLANDXE_DescType *currentDesc = NULL;
3212 wpt_uint32 descCtrlValue = 0;
3213 unsigned int *lowThreshold = NULL;
3214
3215 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003216 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003217
3218 /* Sanity */
3219 if((NULL == hostCtxt) || (NULL == channelEntry))
3220 {
3221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3222 "dxeTXCompFrame Invalid ARG");
3223 return eWLAN_PAL_STATUS_E_INVAL;
3224 }
3225
3226 if(NULL == hostCtxt->txCompCB)
3227 {
3228 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3229 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003230 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003231 }
3232
3233 wpalMutexAcquire(&channelEntry->dxeChannelLock);
3234
3235 currentCtrlBlk = channelEntry->tailCtrlBlk;
3236 currentDesc = currentCtrlBlk->linkedDesc;
3237
3238 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3239 {
3240 wpalMutexRelease(&channelEntry->dxeChannelLock);
Jeff Johnsone7245742012-09-05 17:12:55 -07003241 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003242 }
3243
3244 /* */
3245 while(1)
3246 {
3247// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3248 descCtrlValue = currentDesc->descCtrl.ctrl;
3249 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3250 {
3251 /* caught up with head, bail out */
3252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3253 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3254 break;
3255 }
3256
3257 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
3258 channelEntry->numFreeDesc++;
3259 channelEntry->numRsvdDesc--;
3260
3261 /* Send Frame TX Complete notification with frame start fragment location */
3262 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3263 {
3264 hostCtxt->txCompletedFrames--;
3265#ifdef FEATURE_R33D
3266 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3267#else
3268 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3269 if (eWLAN_PAL_STATUS_SUCCESS != status)
3270 {
3271 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3272 "dxeRXFrameReady unable to unlock packet");
3273 wpalMutexRelease(&channelEntry->dxeChannelLock);
3274 return status;
3275 }
3276#endif /* FEATURE_R33D */
3277 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3278 currentCtrlBlk->xfrFrame,
3279 eWLAN_PAL_STATUS_SUCCESS);
3280 channelEntry->numFragmentCurrentChain = 0;
3281 }
3282 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3283 currentDesc = currentCtrlBlk->linkedDesc;
3284
3285 /* Break condition
3286 * Head control block is the control block must be programed for the next TX
3287 * so, head control block is not programmed control block yet
3288 * if loop encounte head control block, stop to complete
3289 * in theory, COMP CB must be called already ??? */
3290 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3291 {
3292 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3293 "dxeTXCompFrame caught up with head ptr");
3294 break;
3295 }
3296 /* VALID Bit check ???? */
3297 }
3298
3299 /* Tail and Head Control block must be same */
3300 channelEntry->tailCtrlBlk = currentCtrlBlk;
3301
3302 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3303 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3304 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3305
3306 /* If specific channel hit low resource condition send notification to upper layer */
3307 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3308 (channelEntry->numFreeDesc > *lowThreshold))
3309 {
3310 /* Change it back if we raised it for fetching a remaining packet from TL */
3311 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3312 {
3313 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3314 }
3315
3316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3317 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3318 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3319 channelEntry->channelType,
3320 eWLAN_PAL_TRUE);
3321 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003322 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003323 }
3324
3325 wpalMutexRelease(&channelEntry->dxeChannelLock);
3326
3327 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003328 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003329 return status;
3330}
3331
3332/*==========================================================================
3333 @ Function Name
3334 dxeTXEventHandler
3335
3336 @ Description
3337 If DXE HW sends TX related interrupt, this event handler will be called
3338 Handle higher priority channel first
3339 Figureout why interrupt happen and call appropriate final even handler
3340 TX complete or error happen
3341
3342 @ Parameters
3343 void *msgPtr
3344 Even MSG
3345
3346 @ Return
3347 PAL_STATUS_T
3348===========================================================================*/
3349void dxeTXEventHandler
3350(
3351 wpt_msg *msgPtr
3352)
3353{
3354 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3355 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3356 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3357 wpt_uint32 intSrc = 0;
3358 wpt_uint32 chStat = 0;
3359 WLANDXE_ChannelCBType *channelCb = NULL;
3360
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003361 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003362 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003363
3364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003365 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003366
3367 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003368 dxeCtxt->ucTxMsgCnt = 0;
3369
3370 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3371 {
3372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3373 "wlan: TX COMP WLAN Driver re-loading in progress");
3374 return;
3375 }
3376
Jeff Johnson295189b2012-06-20 16:38:30 -07003377 /* Return from here if the RIVA is in IMPS, to avoid register access */
3378 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3379 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003380 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003381 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003382 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003383 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3384 if(eWLAN_PAL_STATUS_SUCCESS != status)
3385 {
3386 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003387 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003388 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003389
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003390 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3391 if(eWLAN_PAL_STATUS_SUCCESS != status)
3392 {
3393 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3394 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3395 }
3396
3397 if(((dxeCtxt->txCompletedFrames) &&
3398 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3399 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003400 {
3401 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3402 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3403 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3404 "TX COMP INT Enabled, remain TX frame count on ring %d",
3405 dxeCtxt->txCompletedFrames);
3406 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3407 the posibility of a race*/
3408 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3409 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003410 else
3411 {
3412 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3414 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3415 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3416 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 return;
3418 }
3419
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003420 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003421 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3422 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3423 {
3424 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3425 "DXE already stopped in TX event handler. Just return");
3426 return;
3427 }
3428
Jeff Johnson295189b2012-06-20 16:38:30 -07003429 /* Disable device interrupt */
3430 /* Read whole interrupt mask register and exclusive only this channel int */
3431 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3432 &intSrc);
3433 if(eWLAN_PAL_STATUS_SUCCESS != status)
3434 {
3435 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3436 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3437 return;
3438 }
3439 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3440 "TX Event Handler INT Source 0x%x", intSrc);
3441
3442 /* Test High Priority Channel is the INT source or not */
3443 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3444 if(intSrc & (1 << channelCb->assignedDMAChannel))
3445 {
3446 status = dxeChannelCleanInt(channelCb, &chStat);
3447 if(eWLAN_PAL_STATUS_SUCCESS != status)
3448 {
3449 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3450 "dxeTXEventHandler INT Clean up fail");
3451 return;
3452 }
3453
3454 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3455 {
3456 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3457 "dxeTXEventHandler TX HI status=%x", chStat);
3458 HDXE_ASSERT(0);
3459 }
3460 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3461 {
3462 /* Handle TX complete for high priority channel */
3463 status = dxeTXCompFrame(dxeCtxt,
3464 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003465 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003466 }
3467 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3468 {
3469 /* Handle TX complete for high priority channel */
3470 status = dxeTXCompFrame(dxeCtxt,
3471 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003472 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003473 }
3474 else
3475 {
3476 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3477 "dxeTXEventHandler TX HI status=%x", chStat);
3478 }
3479
3480 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3481 {
3482 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3483 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3484 }
3485
3486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3487 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3488 }
3489
3490 /* Test Low Priority Channel interrupt is enabled or not */
3491 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3492 if(intSrc & (1 << channelCb->assignedDMAChannel))
3493 {
3494 status = dxeChannelCleanInt(channelCb, &chStat);
3495 if(eWLAN_PAL_STATUS_SUCCESS != status)
3496 {
3497 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3498 "dxeTXEventHandler INT Clean up fail");
3499 return;
3500 }
3501
3502 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3503 {
3504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3505 "dxeTXEventHandler TX LO status=%x", chStat);
3506 HDXE_ASSERT(0);
3507 }
3508 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3509 {
3510 /* Handle TX complete for low priority channel */
3511 status = dxeTXCompFrame(dxeCtxt,
3512 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003513 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003514 }
3515 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3516 {
3517 /* Handle TX complete for low priority channel */
3518 status = dxeTXCompFrame(dxeCtxt,
3519 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003520 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003521 }
3522 else
3523 {
3524 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3525 "dxeTXEventHandler TX LO status=%x", chStat);
3526 }
3527
3528 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3529 {
3530 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3531 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3532 }
3533 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3534 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3535 }
3536
3537
3538#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3539 /* Test H2H TX Channel interrupt is enabled or not */
3540 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3541 if(intSrc & (1 << channelCb->assignedDMAChannel))
3542 {
3543 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3544 &chStat);
3545 if(eWLAN_PAL_STATUS_SUCCESS != status)
3546 {
3547 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3548 "dxeChannelCleanInt Read CH STAT register fail");
3549 return;
3550 }
3551
3552 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3553 {
3554 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3555 "WLANDXE_CH_STAT_INT_ERR_MASK occurred");
3556 HDXE_ASSERT(0);
3557 }
3558 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3559 {
3560 /* Handle TX complete for high priority channel */
3561 status = dxeTXCompFrame(dxeCtxt,
3562 channelCb);
3563 if(eWLAN_PAL_STATUS_SUCCESS != status)
3564 {
3565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3566 "dxeTXEventHandler INT Clean up fail");
3567 return;
3568 }
3569 }
3570 else
3571 {
3572 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3573 "unexpected channel state %d", chStat);
3574 }
3575 }
3576#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3577
3578 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3579 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3580 {
3581 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3582 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3583 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3584 "TX COMP INT Enabled, remain TX frame count on ring %d",
3585 dxeCtxt->txCompletedFrames);
3586 }
3587
3588 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3589 the posibility of a race*/
3590 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3591
3592 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003593 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003594 return;
3595}
3596
3597
3598/*==========================================================================
3599 @ Function Name
3600 dxeTXCompleteProcessing
3601
3602 @ Description
3603 If DXE HW sends TX related interrupt, this event handler will be called
3604 Handle higher priority channel first
3605 Figureout why interrupt happen and call appropriate final even handler
3606 TX complete or error happen
3607
3608 @ Parameters
3609 dxeCtxt DXE context
3610
3611 @ Return
3612 PAL_STATUS_T
3613===========================================================================*/
3614void dxeTXCompleteProcessing
3615(
3616 WLANDXE_CtrlBlkType *dxeCtxt
3617)
3618{
3619 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3620 WLANDXE_ChannelCBType *channelCb = NULL;
3621
3622 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003623 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003624
3625 /* Test High Priority Channel is the INT source or not */
3626 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3627
3628 /* Handle TX complete for high priority channel */
3629 status = dxeTXCompFrame(dxeCtxt, channelCb);
3630
3631 /* Test Low Priority Channel interrupt is enabled or not */
3632 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3633
3634 /* Handle TX complete for low priority channel */
3635 status = dxeTXCompFrame(dxeCtxt, channelCb);
3636
3637 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3638 ((dxeCtxt->txCompletedFrames > 0) ||
3639 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3640 {
3641 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3642 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3643 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003644 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003645 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3646 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3647 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3648 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
3649 }
3650
3651 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3652 the posibility of a race*/
3653 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3654
3655 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003656 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 return;
3658}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003659
3660/*==========================================================================
3661 @ Function Name
3662 dxeTXReSyncDesc
3663
3664 @ Description
3665 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3666 And HW programmed descriptor.
3667 If any async happen between HW/SW TX stall will happen
3668
3669 @ Parameters
3670 void *msgPtr
3671 Message pointer to sync with TX thread
3672
3673 @ Return
3674 NONE
3675===========================================================================*/
3676void dxeTXReSyncDesc
3677(
3678 wpt_msg *msgPtr
3679)
3680{
3681 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3682 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3683 wpt_uint32 nextDescReg;
3684 WLANDXE_ChannelCBType *channelEntry;
3685 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3686 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003687 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003688
3689 if(NULL == msgContent)
3690 {
3691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3692 "dxeTXReSyncDesc Invalid Control Block");
3693 return;
3694 }
3695
3696 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3697 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3698 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3699
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003700 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003701 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003702 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3704 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3705 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3706 &nextDescReg);
3707 /* Async detect without TX pending frame */
3708 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003709 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003710 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003711 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003712 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3713 "TX Async no Pending frame");
3714 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry);
3715 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!");
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003716 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003717 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003718 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003719 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003720 /* Async detect with some TX pending frames
3721 * next descriptor register should sync with first valid descriptor */
3722 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003723 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003724 validCtrlBlk = channelEntry->tailCtrlBlk;
3725 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003726 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003727 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3728 {
3729 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3730 {
3731 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3732 "TX Async");
3733 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3734 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3735 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3736 validCtrlBlk->linkedDescPhyAddr);
3737 }
3738 break;
3739 }
3740 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3741 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3742 {
3743 /* Finished to test till head control blcok, but could not find valid descriptor
3744 * from head to tail all descriptors are invalidated
3745 * host point of view head descriptor is next TX candidate
3746 * So, next descriptor control have to be programmed with head descriptor
3747 * check */
3748 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3749 {
3750 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3751 "TX Async with not completed transfered frames, next descriptior must be head");
3752 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3753 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3754 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3755 validCtrlBlk->linkedDescPhyAddr);
3756 }
3757 break;
3758 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003759 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003760 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003761 }
3762
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003763 /* HW/SW descriptor resync is done.
3764 * Next if there are any valid descriptor in chain, Push to HW again */
3765 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3766 {
3767 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3768 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3769 {
3770 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3771 "%11s : No TX Pending frame",
3772 channelType[channelEntry->channelType]);
3773 /* No Pending frame, Do nothing */
3774 }
3775 else
3776 {
3777 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3778 "%11s : TX Pending frame, process it",
3779 channelType[channelEntry->channelType]);
3780 validCtrlBlk = channelEntry->tailCtrlBlk;
3781 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3782 {
3783 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3784 {
3785 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3786 "%11s : when exit IMPS found valid descriptor",
3787 channelType[channelEntry->channelType]);
3788
3789 /* Found valid descriptor, kick DXE */
3790 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3791 channelEntry->extraConfig.chan_mask);
3792 break;
3793 }
3794 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3795 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3796 {
3797 /* Finished to test till head control blcok, but could not find valid descriptor
3798 * from head to tail all descriptors are invalidated */
3799 break;
3800 }
3801 }
3802 }
3803 }
3804
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003805 wpalMemoryFree(msgPtr);
3806 return;
3807}
3808
Jeff Johnson295189b2012-06-20 16:38:30 -07003809/*==========================================================================
3810 @ Function Name
3811 dxeTXISR
3812
3813 @ Description
3814 TX interrupt ISR
3815 Platform will call this function if INT is happen
3816 This function must be registered into platform interrupt module
3817
3818 @ Parameters
3819 void *hostCtxt
3820 DXE host driver control context,
3821 pre registerd during interrupt registration
3822
3823 @ Return
3824 PAL_STATUS_T
3825===========================================================================*/
3826static void dxeTXISR
3827(
3828 void *hostCtxt
3829)
3830{
3831 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3832 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3833#ifdef FEATURE_R33D
3834 wpt_uint32 regValue;
3835#endif /* FEATURE_R33D */
3836
3837 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003838 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003839
3840 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003841 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003842 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003843 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003844 /* Disable interrupt at here,
3845 IMPS or IMPS Pending state should not access RIVA register */
3846 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3847 if(eWLAN_PAL_STATUS_SUCCESS != status)
3848 {
3849 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3850 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3851 return;
3852 }
3853 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3854 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003855 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003856 return;
3857 }
3858
3859#ifdef FEATURE_R33D
3860 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3861 &regValue);
3862 if(eWLAN_PAL_STATUS_SUCCESS != status)
3863 {
3864 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3865 "dxeTXCompISR Read INT_SRC_RAW fail");
3866 return;
3867 }
3868 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3869 "INT_SRC_RAW 0x%x", regValue);
3870 if(0 == regValue)
3871 {
3872 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3873 "This is not DXE Interrupt, Reject it");
3874 return;
3875 }
3876#endif /* FEATURE_R33D */
3877
3878 /* Disable TX Complete Interrupt at here */
3879 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3880 if(eWLAN_PAL_STATUS_SUCCESS != status)
3881 {
3882 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3883 "dxeTXCompISR Disable TX complete interrupt fail");
3884 return;
3885 }
3886 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3887
3888
3889 if( dxeCtxt->ucTxMsgCnt )
3890 {
3891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3892 "Avoiding serializing TX Complete event");
3893 return;
3894 }
3895
3896 dxeCtxt->ucTxMsgCnt = 1;
3897
3898 /* Serialize TX complete interrupt upon TX thread */
3899 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3900 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3901 dxeCtxt->txIsrMsg);
3902 if(eWLAN_PAL_STATUS_SUCCESS != status)
3903 {
3904 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3905 "dxeTXCompISR interrupt serialize fail status=%d", status);
3906 }
3907
3908 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003909 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003910 return;
3911}
3912
3913/*-------------------------------------------------------------------------
3914 * Global Function
3915 *-------------------------------------------------------------------------*/
3916/*==========================================================================
3917 @ Function Name
3918 WLANDXE_Open
3919
3920 @ Description
3921 Open host DXE driver, allocate DXE resources
3922 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
3923
3924 @ Parameters
3925 pVoid pAdaptor : Driver global control block pointer
3926
3927 @ Return
3928 pVoid DXE local module control block pointer
3929===========================================================================*/
3930void *WLANDXE_Open
3931(
3932 void
3933)
3934{
3935 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3936 unsigned int idx;
3937 WLANDXE_ChannelCBType *currentChannel = NULL;
3938 int smsmInitState;
3939#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3940 wpt_uint32 sIdx;
3941 WLANDXE_ChannelCBType *channel = NULL;
3942 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
3943 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
3944#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3945
3946 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003947 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003948
3949 /* This is temporary allocation */
3950 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
3951 if(NULL == tempDxeCtrlBlk)
3952 {
3953 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3954 "WLANDXE_Open Control Block Alloc Fail");
3955 return NULL;
3956 }
3957 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
3958
3959 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
3960 if(eWLAN_PAL_STATUS_SUCCESS != status)
3961 {
3962 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3963 "WLANDXE_Open Common Configuration Fail");
3964 WLANDXE_Close(tempDxeCtrlBlk);
3965 return NULL;
3966 }
3967
3968 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3969 {
3970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3971 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
3972 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
3973 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
3974 {
3975 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
3976 }
3977 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
3978 {
3979 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
3980 }
3981 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
3982 {
3983 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
3984 }
3985 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
3986 {
3987 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
3988 }
3989#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3990 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
3991 {
3992 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
3993 }
3994 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
3995 {
3996 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
3997 }
3998#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3999
4000 /* Config individual channels from channel default setup table */
4001 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4002 currentChannel);
4003 if(eWLAN_PAL_STATUS_SUCCESS != status)
4004 {
4005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4006 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4007 WLANDXE_Close(tempDxeCtrlBlk);
4008 return NULL;
4009 }
4010
4011 /* Allocate DXE Control Block will be used by host DXE driver */
4012 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4013 if(eWLAN_PAL_STATUS_SUCCESS != status)
4014 {
4015 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4016 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4017
4018 WLANDXE_Close(tempDxeCtrlBlk);
4019 return NULL;
4020 }
4021 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4022 if(eWLAN_PAL_STATUS_SUCCESS != status)
4023 {
4024 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4025 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4026 WLANDXE_Close(tempDxeCtrlBlk);
4027 return NULL;
4028 }
4029
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004030 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4031 dxeHealthMonitorTimeout,
4032 (void *)currentChannel);
4033 if(eWLAN_PAL_STATUS_SUCCESS != status)
4034 {
4035 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4036 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4037 WLANDXE_Close(tempDxeCtrlBlk);
4038 return NULL;
4039 }
4040
4041 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4042 if(NULL == currentChannel->healthMonitorMsg)
4043 {
4044 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4045 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4046 WLANDXE_Close(tempDxeCtrlBlk);
4047 return NULL;
4048 }
4049 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4050 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4051 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4052
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4054 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4055 }
4056
4057 /* Allocate and Init RX READY ISR Serialize Buffer */
4058 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4059 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4060 {
4061 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4062 "WLANDXE_Open Alloc RX ISR Fail");
4063 WLANDXE_Close(tempDxeCtrlBlk);
4064 return NULL;
4065 }
4066 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4067 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4068 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4069
4070 /* Allocate and Init TX COMP ISR Serialize Buffer */
4071 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4072 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4073 {
4074 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4075 "WLANDXE_Open Alloc TX ISR Fail");
4076 WLANDXE_Close(tempDxeCtrlBlk);
4077 return NULL;
4078 }
4079 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4080 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4081 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4082
4083 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4084 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4085 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4086 {
4087 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4088 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4089 WLANDXE_Close(tempDxeCtrlBlk);
4090 return NULL;
4091 }
4092 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4093 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4094 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4095
4096 tempDxeCtrlBlk->freeRXPacket = NULL;
4097 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4098 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4099 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004100 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004101
4102 /* Initialize SMSM state
4103 * Init State is
4104 * Clear TX Enable
4105 * RING EMPTY STATE */
4106 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4107 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4108 if(0 != smsmInitState)
4109 {
4110 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4111 "SMSM Channel init fail %d", smsmInitState);
4112 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4113 {
4114 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4115 }
4116 wpalMemoryFree((void *)&tempDxeCtrlBlk->rxIsrMsg);
4117 wpalMemoryFree((void *)&tempDxeCtrlBlk->txIsrMsg);
4118 wpalMemoryFree(tempDxeCtrlBlk);
4119 return NULL;
4120 }
4121
4122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4123 "WLANDXE_Open Success");
4124 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004125 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004126 return (void *)tempDxeCtrlBlk;
4127}
4128
4129/*==========================================================================
4130 @ Function Name
4131 WLANDXE_ClientRegistration
4132
4133 @ Description
4134 Make callback functions registration into DXE driver from DXE driver client
4135
4136 @ Parameters
4137 pVoid pDXEContext : DXE module control block
4138 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4139 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4140 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4141 void *userContext : DXE Cliennt control block
4142
4143 @ Return
4144 wpt_status
4145===========================================================================*/
4146wpt_status WLANDXE_ClientRegistration
4147(
4148 void *pDXEContext,
4149 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4150 WLANDXE_TxCompleteCbType txCompleteCB,
4151 WLANDXE_LowResourceCbType lowResourceCB,
4152 void *userContext
4153)
4154{
4155 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4156 WLANDXE_CtrlBlkType *dxeCtxt;
4157
4158 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004159 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004160
4161 /* Sanity */
4162 if(NULL == pDXEContext)
4163 {
4164 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4165 "WLANDXE_ClientRegistration Invalid DXE CB");
4166 return eWLAN_PAL_STATUS_E_INVAL;
4167 }
4168
4169 if(NULL == rxFrameReadyCB)
4170 {
4171 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4172 "WLANDXE_ClientRegistration Invalid RX READY CB");
4173 return eWLAN_PAL_STATUS_E_INVAL;
4174 }
4175
4176 if(NULL == txCompleteCB)
4177 {
4178 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4179 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4180 return eWLAN_PAL_STATUS_E_INVAL;
4181 }
4182
4183 if(NULL == lowResourceCB)
4184 {
4185 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4186 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4187 return eWLAN_PAL_STATUS_E_INVAL;
4188 }
4189
4190 if(NULL == userContext)
4191 {
4192 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4193 "WLANDXE_ClientRegistration Invalid userContext");
4194 return eWLAN_PAL_STATUS_E_INVAL;
4195 }
4196
4197 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4198
4199 /* Assign */
4200 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4201 dxeCtxt->txCompCB = txCompleteCB;
4202 dxeCtxt->lowResourceCB = lowResourceCB;
4203 dxeCtxt->clientCtxt = userContext;
4204
4205 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004206 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 return status;
4208}
4209
4210/*==========================================================================
4211 @ Function Name
4212 WLANDXE_Start
4213
4214 @ Description
4215 Start Host DXE driver
4216 Initialize DXE channels and start channel
4217
4218 @ Parameters
4219 pVoid pDXEContext : DXE module control block
4220
4221 @ Return
4222 wpt_status
4223===========================================================================*/
4224wpt_status WLANDXE_Start
4225(
4226 void *pDXEContext
4227)
4228{
4229 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4230 wpt_uint32 idx;
4231 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4232
4233 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004234 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004235
4236 /* Sanity */
4237 if(NULL == pDXEContext)
4238 {
4239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4240 "WLANDXE_Start Invalid DXE CB");
4241 return eWLAN_PAL_STATUS_E_INVAL;
4242 }
4243 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4244
4245 /* WLANDXE_Start called means DXE engine already initiates
4246 * And DXE HW is reset and init finished
4247 * But here to make sure HW is initialized, reset again */
4248 status = dxeEngineCoreStart(dxeCtxt);
4249 if(eWLAN_PAL_STATUS_SUCCESS != status)
4250 {
4251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4252 "WLANDXE_Start DXE HW init Fail");
4253 return status;
4254 }
4255
4256 /* Individual Channel Start */
4257 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4258 {
4259 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4260 "WLANDXE_Start Channel %s Start", channelType[idx]);
4261
4262 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4263 /* Make connection between DXE descriptor and DXE control block */
4264 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4265 if(eWLAN_PAL_STATUS_SUCCESS != status)
4266 {
4267 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4268 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4269 return status;
4270 }
4271
4272 /* Program each channel register with configuration arguments */
4273 status = dxeChannelInitProgram(dxeCtxt,
4274 &dxeCtxt->dxeChannel[idx]);
4275 if(eWLAN_PAL_STATUS_SUCCESS != status)
4276 {
4277 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4278 "WLANDXE_Start %d Program DMA channel Fail", idx);
4279 return status;
4280 }
4281
4282 /* ??? Trigger to start DMA channel
4283 * This must be seperated from ??? */
4284 status = dxeChannelStart(dxeCtxt,
4285 &dxeCtxt->dxeChannel[idx]);
4286 if(eWLAN_PAL_STATUS_SUCCESS != status)
4287 {
4288 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4289 "WLANDXE_Start %d Channel Start Fail", idx);
4290 return status;
4291 }
4292 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4293 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4294 }
4295
4296 /* Register ISR to OS */
4297 /* Register TX complete interrupt into platform */
4298 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4299 dxeTXISR,
4300 dxeCtxt);
4301 if(eWLAN_PAL_STATUS_SUCCESS != status)
4302 {
4303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4304 "WLANDXE_Start TX comp interrupt registration Fail");
4305 return status;
4306 }
4307
4308 /* Register RX ready interrupt into platform */
4309 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4310 dxeRXISR,
4311 dxeCtxt);
4312 if(eWLAN_PAL_STATUS_SUCCESS != status)
4313 {
4314 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4315 "WLANDXE_Start RX Ready interrupt registration Fail");
4316 return status;
4317 }
4318
4319 /* Enable system level ISR */
4320 /* Enable RX ready Interrupt at here */
4321 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4322 if(eWLAN_PAL_STATUS_SUCCESS != status)
4323 {
4324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4325 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4326 return status;
4327 }
4328
4329 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004330 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004331 return status;
4332}
4333
4334/*==========================================================================
4335 @ Function Name
4336 WLANDXE_TXFrame
4337
4338 @ Description
4339 Trigger frame transmit from host to RIVA
4340
4341 @ Parameters
4342 pVoid pDXEContext : DXE Control Block
4343 wpt_packet pPacket : transmit packet structure
4344 WDTS_ChannelType channel : TX channel
4345
4346 @ Return
4347 wpt_status
4348===========================================================================*/
4349wpt_status WLANDXE_TxFrame
4350(
4351 void *pDXEContext,
4352 wpt_packet *pPacket,
4353 WDTS_ChannelType channel
4354)
4355{
4356 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4357 WLANDXE_ChannelCBType *currentChannel = NULL;
4358 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4359 unsigned int *lowThreshold = NULL;
4360
4361 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004362 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004363
4364 /* Sanity */
4365 if(NULL == pDXEContext)
4366 {
4367 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4368 "WLANDXE_Start Invalid DXE CB");
4369 return eWLAN_PAL_STATUS_E_INVAL;
4370 }
4371
4372 if(NULL == pPacket)
4373 {
4374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4375 "WLANDXE_Start Invalid pPacket");
4376 return eWLAN_PAL_STATUS_E_INVAL;
4377 }
4378
4379 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4380 {
4381 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4382 "WLANDXE_Start Invalid channel");
4383 return eWLAN_PAL_STATUS_E_INVAL;
4384 }
4385
4386 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4387
4388 currentChannel = &dxeCtxt->dxeChannel[channel];
4389
4390
4391 wpalMutexAcquire(&currentChannel->dxeChannelLock);
4392
4393 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4394 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4395 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4396
4397 /* Decide have to activate TX complete event or not */
4398 switch(dxeCtxt->txCompInt.txIntEnable)
4399 {
4400 /* TX complete interrupt will be activated when low DXE resource */
4401 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4402 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4403 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4404 {
4405 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4406 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4407 channel,
4408 eWLAN_PAL_FALSE);
4409 }
4410 break;
4411
4412 /* TX complete interrupt will be activated n number of frames transfered */
4413 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4414 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4415 {
4416 currentChannel->numFrameBeforeInt++;
4417 }
4418 break;
4419
4420 /* TX complete interrupt will be activated periodically */
4421 case WLANDXE_TX_COMP_INT_TIMER:
4422 break;
4423 }
4424
4425 dxeCtxt->txCompletedFrames++;
4426
4427 /* Update DXE descriptor, this is frame based
4428 * if a frame consist of N fragments, N Descriptor will be programed */
4429 status = dxeTXPushFrame(currentChannel, pPacket);
4430 if(eWLAN_PAL_STATUS_SUCCESS != status)
4431 {
4432 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4433 "WLANDXE_TxFrame TX Push Frame fail");
4434 wpalMutexRelease(&currentChannel->dxeChannelLock);
4435 return status;
4436 }
4437
4438 /* If specific channel hit low resource condition, send notification to upper layer */
4439 if(currentChannel->numFreeDesc <= *lowThreshold)
4440 {
4441 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4442 channel,
4443 eWLAN_PAL_FALSE);
4444 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004445
4446 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4447 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4448 channelType[currentChannel->channelType],
4449 currentChannel->numRsvdDesc);
4450 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4451 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4452 wpalTimerStart(&currentChannel->healthMonitorTimer,
4453 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004454 }
4455 wpalMutexRelease(&currentChannel->dxeChannelLock);
4456
4457 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004458 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004459 return status;
4460}
4461
4462/*==========================================================================
4463 @ Function Name
4464 WLANDXE_CompleteTX
4465
4466 @ Description
4467 Informs DXE that the current series of Tx packets is complete
4468
4469 @ Parameters
4470 pContext pDXEContext : DXE Control Block
4471 ucTxResReq TX resource number required by TL/WDI
4472
4473 @ Return
4474 wpt_status
4475===========================================================================*/
4476wpt_status
4477WLANDXE_CompleteTX
4478(
4479 void* pContext,
4480 wpt_uint32 ucTxResReq
4481)
4482{
4483 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4484 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4485 WLANDXE_ChannelCBType *channelCb = NULL;
4486 wpt_boolean inLowRes;
4487
4488 /* Sanity Check */
4489 if( NULL == pContext )
4490 {
4491 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4492 "WLANDXE_CompleteTX invalid param");
4493 return eWLAN_PAL_STATUS_E_INVAL;
4494 }
4495
4496 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4497 inLowRes = channelCb->hitLowResource;
4498
4499 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4500 {
4501 /* Raise threshold temporarily if necessary */
4502 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4503
4504 if(eWLAN_PAL_FALSE == inLowRes)
4505 {
4506 /* Put the channel to low resource condition */
4507 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4508 WDTS_CHANNEL_TX_LOW_PRI,
4509 eWLAN_PAL_FALSE);
4510 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004511 wpalTimerStart(&channelCb->healthMonitorTimer,
4512 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004513 }
4514 }
4515
4516 /*Try to reclaim resources*/
4517 dxeTXCompleteProcessing(dxeCtxt);
4518
4519 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4520 because its fragment size is larger than DXE free resource. */
4521 if(0 < ucTxResReq)
4522 {
4523 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4524 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4525 {
4526 /* DXE has not been in low resource condition. DXE forces to kick off
4527 TX tranmit */
4528 if((eWLAN_PAL_FALSE == inLowRes) &&
4529 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4530 {
4531 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4532 WDTS_CHANNEL_TX_LOW_PRI,
4533 eWLAN_PAL_FALSE);
4534 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4535 WDTS_CHANNEL_TX_LOW_PRI,
4536 eWLAN_PAL_TRUE);
4537 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4538 }
4539 }
4540 else
4541 {
4542 /* DXE doesn't have enough free DXE resources. Put the channel
4543 to low resource condition. */
4544 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4545 {
4546 /* Put the channel to low resource condition */
4547 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4548 WDTS_CHANNEL_TX_LOW_PRI,
4549 eWLAN_PAL_FALSE);
4550 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004551 wpalTimerStart(&channelCb->healthMonitorTimer,
4552 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 }
4554 }
4555 }
4556
4557 return status;
4558}
4559
4560/*==========================================================================
4561 @ Function Name
4562 WLANDXE_Stop
4563
4564 @ Description
4565 Stop DXE channels and DXE engine operations
4566 Disable all channel interrupt
4567 Stop all channel operation
4568
4569 @ Parameters
4570 pVoid pDXEContext : DXE Control Block
4571
4572 @ Return
4573 wpt_status
4574===========================================================================*/
4575wpt_status WLANDXE_Stop
4576(
4577 void *pDXEContext
4578)
4579{
4580 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4581 wpt_uint32 idx;
4582 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4583
4584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004585 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004586
4587 /* Sanity */
4588 if(NULL == pDXEContext)
4589 {
4590 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4591 "WLANDXE_Stop Invalid DXE CB");
4592 return eWLAN_PAL_STATUS_E_INVAL;
4593 }
4594
4595 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4596 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4597 {
4598 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4599 if(eWLAN_PAL_STATUS_SUCCESS != status)
4600 {
4601 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4602 "WLANDXE_Stop Channel %d Stop Fail", idx);
4603 return status;
4604 }
4605 }
4606
4607 /* During Stop unregister interrupt */
4608 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4609 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4610
4611 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004612 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 return status;
4614}
4615
4616/*==========================================================================
4617 @ Function Name
4618 WLANDXE_Close
4619
4620 @ Description
4621 Close DXE channels
4622 Free DXE related resources
4623 DXE descriptor free
4624 Descriptor control block free
4625 Pre allocated RX buffer free
4626
4627 @ Parameters
4628 pVoid pDXEContext : DXE Control Block
4629
4630 @ Return
4631 wpt_status
4632===========================================================================*/
4633wpt_status WLANDXE_Close
4634(
4635 void *pDXEContext
4636)
4637{
4638 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4639 wpt_uint32 idx;
4640 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4641#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4642 wpt_uint32 sIdx;
4643 WLANDXE_ChannelCBType *channel = NULL;
4644 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4645 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4646#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4647
4648 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004649 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004650
4651 /* Sanity */
4652 if(NULL == pDXEContext)
4653 {
4654 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4655 "WLANDXE_Stop Invalid DXE CB");
4656 return eWLAN_PAL_STATUS_E_INVAL;
4657 }
4658
4659 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4660 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4661 {
4662 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004663 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4664 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
4665 {
4666 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
4667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004668 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4669#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4670 channel = &dxeCtxt->dxeChannel[idx];
4671 crntDescCB = channel->headCtrlBlk;
4672 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4673 {
4674 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4675 wpalMemoryFree((void *)crntDescCB);
4676 crntDescCB = nextDescCB;
4677 if(NULL == crntDescCB)
4678 {
4679 break;
4680 }
4681 }
4682#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4683 }
4684
4685 if(NULL != dxeCtxt->rxIsrMsg)
4686 {
4687 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4688 }
4689 if(NULL != dxeCtxt->txIsrMsg)
4690 {
4691 wpalMemoryFree(dxeCtxt->txIsrMsg);
4692 }
4693 if(NULL != dxeCtxt->rxPktAvailMsg)
4694 {
4695 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4696 }
4697
4698 wpalMemoryFree(pDXEContext);
4699
4700 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004701 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004702 return status;
4703}
4704
4705/*==========================================================================
4706 @ Function Name
4707 WLANDXE_TriggerTX
4708
4709 @ Description
4710 TBD
4711
4712 @ Parameters
4713 pVoid pDXEContext : DXE Control Block
4714
4715 @ Return
4716 wpt_status
4717===========================================================================*/
4718wpt_status WLANDXE_TriggerTX
4719(
4720 void *pDXEContext
4721)
4722{
4723 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4724
4725 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004726 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004727
4728 /* TBD */
4729
4730 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004731 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004732 return status;
4733}
4734
4735/*==========================================================================
4736 @ Function Name
4737 dxeTxThreadSetPowerStateEventHandler
4738
4739 @ Description
4740 If WDI sends set power state req, this event handler will be called in Tx
4741 thread context
4742
4743 @ Parameters
4744 void *msgPtr
4745 Event MSG
4746
4747 @ Return
4748 None
4749===========================================================================*/
4750void dxeTxThreadSetPowerStateEventHandler
4751(
4752 wpt_msg *msgPtr
4753)
4754{
4755 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4756 WLANDXE_CtrlBlkType *dxeCtxt;
4757 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4758 WLANDXE_PowerStateType reqPowerState;
4759
4760 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004761 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004762
Jeff Johnson295189b2012-06-20 16:38:30 -07004763 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4764 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4765 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4766
4767 switch(reqPowerState)
4768 {
4769 case WLANDXE_POWER_STATE_BMPS:
4770 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4771 {
4772 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4773 //based on amount of TX and RX activity - during this time any received
4774 // management frames will remain un-processed consuming RX buffers
4775 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4776 dxeCtxt->hostPowerState = reqPowerState;
4777 }
4778 else
4779 {
4780 status = eWLAN_PAL_STATUS_E_INVAL;
4781 }
4782 break;
4783 case WLANDXE_POWER_STATE_IMPS:
4784 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4785 {
4786 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4787 }
4788 else
4789 {
4790 status = eWLAN_PAL_STATUS_E_INVAL;
4791 }
4792 break;
4793 case WLANDXE_POWER_STATE_FULL:
4794 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4795 {
4796 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4797 }
4798 dxeCtxt->hostPowerState = reqPowerState;
4799 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4800 break;
4801 case WLANDXE_POWER_STATE_DOWN:
4802 WLANDXE_Stop((void *)dxeCtxt);
4803 break;
4804 default:
4805 //assert
4806 break;
4807 }
4808
4809 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4810 {
4811 dxeCtxt->setPowerStateCb(status,
4812 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4813 }
4814 /* Free MSG buffer */
4815 wpalMemoryFree(msgPtr);
4816 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004817 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004818 return;
4819}
4820
4821
4822/*==========================================================================
4823 @ Function Name
4824 dxeRxThreadSetPowerStateEventHandler
4825
4826 @ Description
4827 If WDI sends set power state req, this event handler will be called in Rx
4828 thread context
4829
4830 @ Parameters
4831 void *msgPtr
4832 Event MSG
4833
4834 @ Return
4835 None
4836===========================================================================*/
4837void dxeRxThreadSetPowerStateEventHandler
4838(
4839 wpt_msg *msgPtr
4840)
4841{
4842 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4843
4844 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004845 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004846
4847 /* Now serialise the message through Tx thread also to make sure
4848 * no register access when RIVA is in powersave */
4849 /*Use the same message pointer just change the call back function */
4850 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4851 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4852 msgPtr);
4853 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4854 {
4855 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4856 "Tx thread Set power state req serialize fail status=%d",
4857 status, 0, 0);
4858 }
4859
4860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004861 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004862}
4863
4864/*==========================================================================
4865 @ Function Name
4866 WLANDXE_SetPowerState
4867
4868 @ Description
4869 From Client let DXE knows what is the WLAN HW(RIVA) power state
4870
4871 @ Parameters
4872 pVoid pDXEContext : DXE Control Block
4873 WLANDXE_PowerStateType powerState
4874
4875 @ Return
4876 wpt_status
4877===========================================================================*/
4878wpt_status WLANDXE_SetPowerState
4879(
4880 void *pDXEContext,
4881 WDTS_PowerStateType powerState,
4882 WDTS_SetPSCbType cBack
4883)
4884{
4885 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4886 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4887 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004888 wpt_msg *rxCompMsg;
4889 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07004890
4891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004892 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 if(NULL == pDXEContext)
4894 {
4895 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4896 "NULL pDXEContext passed by caller", 0, 0, 0);
4897 return eWLAN_PAL_STATUS_E_FAILURE;
4898 }
4899 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
4900
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 switch(powerState)
4902 {
4903 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004904 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
4905 {
4906 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4907 if(NULL == txDescReSyncMsg)
4908 {
4909 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4910 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
4911 }
4912 else
4913 {
4914 txDescReSyncMsg->callback = dxeTXReSyncDesc;
4915 txDescReSyncMsg->pContext = pDxeCtrlBlk;
4916 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4917 txDescReSyncMsg);
4918 if(eWLAN_PAL_STATUS_SUCCESS != status)
4919 {
4920 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4921 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
4922 }
4923 }
4924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 hostPowerState = WLANDXE_POWER_STATE_FULL;
4926 break;
4927 case WDTS_POWER_STATE_BMPS:
4928 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
4929 hostPowerState = WLANDXE_POWER_STATE_BMPS;
4930 break;
4931 case WDTS_POWER_STATE_IMPS:
4932 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
4933 hostPowerState = WLANDXE_POWER_STATE_IMPS;
4934 break;
4935 case WDTS_POWER_STATE_DOWN:
4936 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
4937 hostPowerState = WLANDXE_POWER_STATE_DOWN;
4938 break;
4939 default:
4940 hostPowerState = WLANDXE_POWER_STATE_MAX;
4941 }
4942
4943 // A callback i.e. ACK back is needed only when we want to enable BMPS
4944 // and the data/management path is active because we want to ensure
4945 // DXE registers are not accessed when RIVA may be power-collapsed. So
4946 // we need a callback in enter_bmps_req (the request to RIVA is sent
4947 // only after ACK back from TX thread). A callback is not needed in
4948 // finish_scan_req during BMPS since data-path is resumed only in
4949 // finish_scan_rsp and no management frames are sent in between. No
4950 // callback is needed when going from BMPS enabled to BMPS suspended/
4951 // disabled when it is known that RIVA is awake and cannot enter power
4952 // collapse autonomously so no callback is needed in exit_bmps_rsp or
4953 // init_scan_rsp
4954 if ( cBack )
4955 {
4956 //serialize through Rx thread
4957 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4958 if(NULL == rxCompMsg)
4959 {
4960 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4961 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
4962 return eWLAN_PAL_STATUS_E_RESOURCES;
4963 }
4964
4965 /* Event type, where it must be defined???? */
4966 /* THIS MUST BE CLEARED ASAP
4967 txCompMsg->type = TX_COMPLETE; */
4968 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
4969 rxCompMsg->pContext = pDxeCtrlBlk;
4970 rxCompMsg->val = hostPowerState;
4971 rxCompMsg->ptr = cBack;
4972 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
4973 rxCompMsg);
4974 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4975 {
4976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4977 "Rx thread Set power state req serialize fail status=%d",
4978 status, 0, 0);
4979 }
4980 }
4981 else
4982 {
4983 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
4984 {
4985 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
4986 {
4987 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4988 }
4989 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
4990 {
4991 /* Requested Full power from exit IMPS, reenable the interrupts*/
4992 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
4993 {
4994 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4995 /* Enable RX interrupt at here, if new PS is not IMPS */
4996 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4997 if(eWLAN_PAL_STATUS_SUCCESS != status)
4998 {
4999 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005000 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005001 return status;
5002 }
5003 }
5004 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5005 {
5006 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005007 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005008 /* Enable RX interrupt at here, if new PS is not IMPS */
5009 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5010 if(eWLAN_PAL_STATUS_SUCCESS != status)
5011 {
5012 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005013 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 return status;
5015 }
5016 }
5017 }
5018 pDxeCtrlBlk->hostPowerState = hostPowerState;
5019 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5020 }
5021 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5022 {
5023 pDxeCtrlBlk->hostPowerState = hostPowerState;
5024 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5025 }
5026 else
5027 {
5028 HDXE_ASSERT(0);
5029 }
5030 }
5031
5032 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005033 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005034
5035 return status;
5036}
5037
5038/*==========================================================================
5039 @ Function Name
5040 WLANDXE_GetFreeTxDataResNumber
5041
5042 @ Description
5043 Returns free descriptor numbers for TX data channel (TX high priority)
5044
5045 @ Parameters
5046 pVoid pDXEContext : DXE Control Block
5047
5048 @ Return
5049 wpt_uint32 Free descriptor number of TX high pri ch
5050===========================================================================*/
5051wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5052(
5053 void *pDXEContext
5054)
5055{
5056 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005057 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005058
5059 if(NULL == pDXEContext)
5060 {
5061 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5062 "NULL parameter passed by caller", 0, 0, 0);
5063 return (0);
5064 }
5065
5066 return
5067 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5068}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005069
5070/*==========================================================================
5071 @ Function Name
5072 WLANDXE_ChannelDebug
5073
5074 @ Description
5075 Display DXE Channel debugging information
5076 User may request to display DXE channel snapshot
5077 Or if host driver detects any abnormal stcuk may display
5078
5079 @ Parameters
5080 displaySnapshot : Dispaly DXE snapshot option
5081 enableStallDetect : Enable stall detect feature
5082 This feature will take effect to data performance
5083 Not integrate till fully verification
5084
5085 @ Return
5086 NONE
5087
5088===========================================================================*/
5089void WLANDXE_ChannelDebug
5090(
5091 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005092 wpt_boolean enableStallDetect
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005093)
5094{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005095 wpt_msg *channelDebugMsg;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005096 wpt_uint32 regValue;
5097 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5098
5099 /* Debug Type 1, Display current snapshot */
5100 if(displaySnapshot)
5101 {
5102 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5103 * This will not simply wakeup RIVA
5104 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005105 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005106 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5107 "Host power state %d, RIVA power state %d",
5108 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
5109 /* Get free BD count */
5110 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
5111 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5112 "TX Pending frames count %d, Current available BD %d",
5113 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005114
5115 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5116 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005117 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005118 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5119 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5120 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005121 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005122
5123 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5124 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5125 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005126 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005127 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5128 "Tx thread Set power state req serialize fail status=%d",
5129 status, 0, 0);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005130 }
5131 }
5132
5133 /* Debug Type 2, toggling stall detect enable/disable */
5134 if(enableStallDetect)
5135 {
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005136 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5137 "DXE TX Stall detect",
5138 0, 0, 0);
5139 /* Start Stall detect timer and detect stall */
5140 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5141 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005142 }
5143 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005144}