blob: 0612f7fc2dc99b421563dd7518b154e120c1e409 [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 ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001502 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001503 }
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 */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002505 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2506 "%11s : 0x%x Error Reported, Reload Driver",
2507 channelType[channelCb->channelType], chHighStat);
2508 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2509 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002510 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002511 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2512 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 {
2514 /* Handle RX Ready for high priority channel */
2515 status = dxeRXFrameReady(dxeCtxt,
2516 channelCb);
2517 }
2518 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2519 {
2520 status = dxeRXFrameReady(dxeCtxt,
2521 channelCb);
2522 }
2523 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2524 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002525 /* Update the Rx DONE histogram */
2526 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2527 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2528 {
2529 channelCb->rxDoneHistogram |= 1;
2530 }
2531 else
2532 {
2533 channelCb->rxDoneHistogram &= ~1;
2534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002535 }
2536#else
2537 /* Test H2H Test interrupt is enabled or not */
2538 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2539 if(intSrc & (1 << channelCb->assignedDMAChannel))
2540 {
2541 status = dxeChannelCleanInt(channelCb, &chStat);
2542 if(eWLAN_PAL_STATUS_SUCCESS != status)
2543 {
2544 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2545 "dxeRXEventHandler INT Clean up fail");
2546 return;
2547 }
2548
2549 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2550 {
2551 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2553 "%11s : 0x%x Error Reported, Reload Driver",
2554 channelType[channelCb->channelType], chStat);
2555 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2556 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002557 }
2558 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2559 {
2560 /* Handle RX Ready for high priority channel */
2561 status = dxeRXFrameReady(dxeCtxt,
2562 channelCb);
2563 }
2564 /* Update the Rx DONE histogram */
2565 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2566 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2567 {
2568 channelCb->rxDoneHistogram |= 1;
2569 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2570 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2571 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2572 }
2573 else
2574 {
2575 channelCb->rxDoneHistogram &= ~1;
2576 }
2577 }
2578#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2579
2580 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002581 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002582 if(intSrc & (1 << channelCb->assignedDMAChannel))
2583 {
2584 status = dxeChannelCleanInt(channelCb, &chLowStat);
2585 if(eWLAN_PAL_STATUS_SUCCESS != status)
2586 {
2587 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2588 "dxeRXEventHandler INT Clean up fail");
2589 return;
2590 }
2591
2592 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2593 {
2594 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002595 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2596 "%11s : 0x%x Error Reported, Reload Driver",
2597 channelType[channelCb->channelType], chLowStat);
2598 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2599 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002600 }
2601 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2602 {
2603 /* Handle RX Ready for low priority channel */
2604 status = dxeRXFrameReady(dxeCtxt,
2605 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07002606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002607
2608 /* Update the Rx DONE histogram */
2609 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2610 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2611 {
2612 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002613 }
2614 else
2615 {
2616 channelCb->rxDoneHistogram &= ~1;
2617 }
2618 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2619 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2620 }
2621 if(eWLAN_PAL_STATUS_SUCCESS != status)
2622 {
2623 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2624 "dxeRXEventHandler Handle Frame Ready Fail");
2625 return;
2626 }
2627
2628 /* Enable system level ISR */
2629 /* Enable RX ready Interrupt at here */
2630 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2631 if(eWLAN_PAL_STATUS_SUCCESS != status)
2632 {
2633 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2634 "dxeRXEventHandler Enable RX Ready interrupt fail");
2635 return;
2636 }
2637
2638 /* Prepare Control Register EN Channel */
2639 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2640 {
2641 HDXE_ASSERT(0);
2642 }
2643 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
2644 {
2645 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2646 "dxeRXEventHandler RX High, Not yet ED, re-enable CH");
2647 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
2648 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
2649 }
2650 else
2651 {
2652 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2653 "dxeRXEventHandler RX High, CH STAT = ED_MASK, will RIVA PC");
2654 }
2655
2656 /* Prepare Control Register EN Channel */
2657 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2658 {
2659 HDXE_ASSERT(0);
2660 }
2661 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat))
2662 {
2663 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2664 "dxeRXEventHandler RX Low, Not yet ED, re-enable CH");
2665 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
2666 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
2667 }
2668 else
2669 {
2670 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2671 "dxeRXEventHandler RX Low, CH STAT = ED_MASK, will RIVA PC");
2672 }
2673
2674 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002675 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002676 return;
2677}
2678
2679/*==========================================================================
2680 @ Function Name
2681 dxeRXPacketAvailableEventHandler
2682
2683 @ Description
2684 Handle serialized RX Packet Available event when the corresponding callback
2685 is invoked by WPAL.
2686 Try to fill up any completed DXE descriptors with available Rx packet buffer
2687 pointers.
2688
2689 @ Parameters
2690 wpt_msg *rxPktAvailMsg
2691 RX frame ready MSG pointer
2692 include DXE control context
2693
2694 @ Return
2695 NONE
2696
2697===========================================================================*/
2698void dxeRXPacketAvailableEventHandler
2699(
2700 wpt_msg *rxPktAvailMsg
2701)
2702{
2703 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2704 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2705 WLANDXE_ChannelCBType *channelCb = NULL;
2706
2707 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002708 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002709
2710 /* Sanity Check */
2711 if(NULL == rxPktAvailMsg)
2712 {
2713 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2714 "dxeRXPacketAvailableEventHandler Context is not valid");
2715 return;
2716 }
2717
2718 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
2719
2720 do
2721 {
2722 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2723 "dxeRXPacketAvailableEventHandler, start refilling ring");
2724
2725 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2726 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2727
2728 // Wait for another callback to indicate when Rx resources are available
2729 // again.
2730 if(eWLAN_PAL_STATUS_SUCCESS != status)
2731 {
2732 break;
2733 }
2734
2735 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2736 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2737 if(eWLAN_PAL_STATUS_SUCCESS != status)
2738 {
2739 break;
2740 }
2741 } while(0);
2742
2743 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2744 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2745 {
2746 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2747 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2748 }
2749}
2750
2751/*==========================================================================
2752 @ Function Name
2753 dxeRXISR
2754
2755 @ Description
2756 RX frame ready interrupt service routine
2757 interrupt entry function, this function called based on ISR context
2758 Must be serialized
2759
2760 @ Parameters
2761 void *hostCtxt
2762 DXE host driver control context,
2763 pre registerd during interrupt registration
2764
2765 @ Return
2766 NONE
2767
2768===========================================================================*/
2769static void dxeRXISR
2770(
2771 void *hostCtxt
2772)
2773{
2774 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2775 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2776#ifdef FEATURE_R33D
2777 wpt_uint32 regValue;
2778#endif /* FEATURE_R33D */
2779
Jeff Johnson295189b2012-06-20 16:38:30 -07002780
2781#ifdef FEATURE_R33D
2782 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2783 &regValue);
2784 if(eWLAN_PAL_STATUS_SUCCESS != status)
2785 {
2786 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2787 "dxeTXCompISR Read INT_SRC_RAW fail");
2788 return;
2789 }
2790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2791 "INT_SRC_RAW 0x%x", regValue);
2792 if(0 == regValue)
2793 {
2794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2795 "This is not DXE Interrupt, Reject it 0x%x", regValue);
2796 return;
2797 }
2798#endif /* FEATURE_R33D */
2799
2800 /* Disable interrupt at here
2801 * Disable RX Ready system level Interrupt at here
2802 * Otherwise infinite loop might happen */
2803 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2804 if(eWLAN_PAL_STATUS_SUCCESS != status)
2805 {
2806 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2807 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2808 return;
2809 }
2810
2811 /* Serialize RX Ready interrupt upon RX thread */
2812 HDXE_ASSERT(NULL != dxeCtxt->rxIsrMsg);
2813 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2814 dxeCtxt->rxIsrMsg);
2815 if(eWLAN_PAL_STATUS_SUCCESS != status)
2816 {
2817 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
2818 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2819 "dxeRXFrameReadyISR interrupt serialize fail");
2820 }
2821
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 return;
2823}
2824
2825/*==========================================================================
2826 @ Function Name
2827 dxeTXPushFrame
2828
2829 @ Description
2830 Push TX frame into DXE descriptor and DXE register
2831 Send notification to DXE register that TX frame is ready to transfer
2832
2833 @ Parameters
2834 WLANDXE_ChannelCBType *channelEntry
2835 Channel specific control block
2836 wpt_packet *palPacket
2837 Packet pointer ready to transfer
2838
2839 @ Return
2840 PAL_STATUS_T
2841===========================================================================*/
2842static wpt_status dxeTXPushFrame
2843(
2844 WLANDXE_ChannelCBType *channelEntry,
2845 wpt_packet *palPacket
2846)
2847{
2848 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2849 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2850 WLANDXE_DescType *currentDesc = NULL;
2851 WLANDXE_DescType *firstDesc = NULL;
2852 WLANDXE_DescType *LastDesc = NULL;
2853 void *sourcePhysicalAddress = NULL;
2854 wpt_uint32 xferSize = 0;
2855#ifdef FEATURE_R33D
2856 tx_frm_pcie_vector_t frameVector;
2857 wpt_uint32 Va;
2858 wpt_uint32 fragCount = 0;
2859#else
2860 wpt_iterator iterator;
2861#endif /* FEATURE_R33D */
2862
2863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002864 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002865
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002866 if(WLANDXE_POWER_STATE_BMPS == tempDxeCtrlBlk->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002867 {
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002868 tempDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2869 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002870 }
2871
2872 channelEntry->numFragmentCurrentChain = 0;
2873 currentCtrlBlk = channelEntry->headCtrlBlk;
2874
2875 /* Initialize interator, TX is fragmented */
2876#ifdef FEATURE_R33D
2877 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2878 status = wpalPrepareTxFrame(palPacket,
2879 &frameVector,
2880 &Va);
2881#else
2882 status = wpalLockPacketForTransfer(palPacket);
2883 if(eWLAN_PAL_STATUS_SUCCESS != status)
2884 {
2885 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2886 "dxeTXPushFrame unable to lock packet");
2887 return status;
2888 }
2889
2890 status = wpalIteratorInit(&iterator, palPacket);
2891#endif /* FEATURE_R33D */
2892 if(eWLAN_PAL_STATUS_SUCCESS != status)
2893 {
2894 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2895 "dxeTXPushFrame iterator init fail");
2896 return status;
2897 }
2898
2899 /* !!!! Revisit break condition !!!!!!! */
2900 while(1)
2901 {
2902 /* Get current descriptor pointer from current control block */
2903 currentDesc = currentCtrlBlk->linkedDesc;
2904 if(NULL == firstDesc)
2905 {
2906 firstDesc = currentCtrlBlk->linkedDesc;
2907 }
2908 /* All control block will have same palPacket Pointer
2909 * to make logic simpler */
2910 currentCtrlBlk->xfrFrame = palPacket;
2911
2912 /* Get next fragment physical address and fragment size
2913 * if this is the first trial, will get first physical address
2914 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2915#ifdef FEATURE_R33D
2916 if(fragCount == frameVector.num_frg)
2917 {
2918 break;
2919 }
2920 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2921 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2922 xferSize = frameVector.frg[fragCount].size;
2923 fragCount++;
2924 HDXE_ASSERT(0 != xferSize);
2925 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2926#else
2927 status = wpalIteratorNext(&iterator,
2928 palPacket,
2929 &sourcePhysicalAddress,
2930 &xferSize);
2931 if((NULL == sourcePhysicalAddress) ||
2932 (0 == xferSize))
2933 {
2934 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2935 "dxeTXPushFrame end of current frame");
2936 break;
2937 }
2938 if(eWLAN_PAL_STATUS_SUCCESS != status)
2939 {
2940 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2941 "dxeTXPushFrame Get next frame fail");
2942 return status;
2943 }
2944#endif /* FEATURE_R33D */
2945
2946 /* This is the LAST descriptor valid for this transaction */
2947 LastDesc = currentCtrlBlk->linkedDesc;
2948
2949 /* Program DXE descriptor */
2950 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2951 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2952
2953 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2954 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2955 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2956 {
2957 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
2958 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
2959 }
2960 else
2961 {
2962 /* Test specific H2H transfer, destination address already set
2963 * Do Nothing */
2964 }
2965 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
2966
2967 /* Program channel control register */
2968 /* First frame not set VAL bit, why ??? */
2969 if(0 == channelEntry->numFragmentCurrentChain)
2970 {
2971 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
2972 }
2973 else
2974 {
2975 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2976 }
2977
2978 /* Update statistics */
2979 channelEntry->numFragmentCurrentChain++;
2980 channelEntry->numFreeDesc--;
2981 channelEntry->numRsvdDesc++;
2982
2983 /* Get next control block */
2984 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2985 }
2986 channelEntry->numTotalFrame++;
2987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2988 "NUM TX FRAG %d, Total Frame %d",
2989 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
2990
2991 /* Program Channel control register
2992 * Set as end of packet
2993 * Enable interrupt also for first code lock down
2994 * performace optimization, this will be revisited */
2995 if(NULL == LastDesc)
2996 {
2997 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2998 "dxeTXPushFrame NULL Last Descriptor, broken chain");
2999 return eWLAN_PAL_STATUS_E_FAULT;
3000 }
3001 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3002 /* Now First one also Valid ????
3003 * this procedure will prevent over handle descriptor from previous
3004 * TX trigger */
3005 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3006
3007 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3008 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3009 {
3010 /* Update channel head as next avaliable linked slot */
3011 channelEntry->headCtrlBlk = currentCtrlBlk;
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003012 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3013 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,
3014 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3015 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3016 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003017 }
3018
3019 /* If DXE use external descriptor, registers are not needed to be programmed
3020 * Just after finish to program descriptor, tirigger to send */
3021 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3022 {
3023 /* Issue a dummy read from the DXE descriptor DDR location to
3024 ensure that any previously posted write to the descriptor
3025 completes. */
3026 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3027 {
3028 //HDXE_ASSERT(0);
3029 }
3030
3031 /* Everything is ready
3032 * Trigger to start DMA */
3033 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3034 channelEntry->extraConfig.chan_mask);
3035 if(eWLAN_PAL_STATUS_SUCCESS != status)
3036 {
3037 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3038 "dxeTXPushFrame Write Channel Ctrl Register fail");
3039 return status;
3040 }
3041
3042 /* Update channel head as next avaliable linked slot */
3043 channelEntry->headCtrlBlk = currentCtrlBlk;
3044
3045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003046 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003047 return status;
3048 }
3049
3050 /* If DXE not use external descriptor, program each registers */
3051 /* Circular buffer handle not need to program DESC register???
3052 * GEN5 code not programed RING buffer case
3053 * REVISIT THIS !!!!!! */
3054 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3055 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3056 {
3057 /* Destination address, assigned Work Q */
3058 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3059 channelEntry->channelConfig.refWQ);
3060 if(eWLAN_PAL_STATUS_SUCCESS != status)
3061 {
3062 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3063 "dxeTXPushFrame Program dest address register fail");
3064 return status;
3065 }
3066 /* If descriptor format is SHORT */
3067 if(channelEntry->channelConfig.useShortDescFmt)
3068 {
3069 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3070 0);
3071 if(eWLAN_PAL_STATUS_SUCCESS != status)
3072 {
3073 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3074 "dxeTXPushFrame Program dest address register fail");
3075 return status;
3076 }
3077 }
3078 else
3079 {
3080 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3081 "dxeTXPushFrame LONG Descriptor Format!!!");
3082 }
3083 }
3084#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3085 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3086 {
3087 /* Destination address, Physical memory address */
3088 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3089 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3090 if(eWLAN_PAL_STATUS_SUCCESS != status)
3091 {
3092 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3093 "dxeTXPushFrame Program dest address register fail");
3094 return status;
3095 }
3096 /* If descriptor format is SHORT */
3097 if(channelEntry->channelConfig.useShortDescFmt)
3098 {
3099 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3100 0);
3101 if(eWLAN_PAL_STATUS_SUCCESS != status)
3102 {
3103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3104 "dxeTXPushFrame Program dest address register fail");
3105 return status;
3106 }
3107 }
3108 else
3109 {
3110 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3111 "dxeTXPushFrame LONG Descriptor Format!!!");
3112 }
3113 }
3114#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3115
3116 /* Program Source address register
3117 * This address is already programmed into DXE Descriptor
3118 * But register also upadte */
3119 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3120 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3121 if(eWLAN_PAL_STATUS_SUCCESS != status)
3122 {
3123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3124 "dxeTXPushFrame Program src address register fail");
3125 return status;
3126 }
3127 /* If descriptor format is SHORT */
3128 if(channelEntry->channelConfig.useShortDescFmt)
3129 {
3130 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3131 0);
3132 if(eWLAN_PAL_STATUS_SUCCESS != status)
3133 {
3134 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3135 "dxeTXPushFrame Program dest address register fail");
3136 return status;
3137 }
3138 }
3139 else
3140 {
3141 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3142 "dxeTXPushFrame LONG Descriptor Format!!!");
3143 }
3144
3145 /* Linked list Descriptor pointer */
3146 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3147 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3148 if(eWLAN_PAL_STATUS_SUCCESS != status)
3149 {
3150 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3151 "dxeTXPushFrame Write DESC Address register fail");
3152 return status;
3153 }
3154 /* If descriptor format is SHORT */
3155 if(channelEntry->channelConfig.useShortDescFmt)
3156 {
3157 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3158 0);
3159 if(eWLAN_PAL_STATUS_SUCCESS != status)
3160 {
3161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3162 "dxeTXPushFrame Program dest address register fail");
3163 return status;
3164 }
3165 }
3166 else
3167 {
3168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3169 "dxeTXPushFrame LONG Descriptor Format!!!");
3170 }
3171
3172 /* Transfer Size */
3173 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3174 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3175 xferSize);
3176 if(eWLAN_PAL_STATUS_SUCCESS != status)
3177 {
3178 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3179 "dxeTXPushFrame Write DESC Address register fail");
3180 return status;
3181 }
3182
3183 /* Everything is ready
3184 * Trigger to start DMA */
3185 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3186 channelEntry->extraConfig.chan_mask);
3187 if(eWLAN_PAL_STATUS_SUCCESS != status)
3188 {
3189 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3190 "dxeTXPushFrame Write Channel Ctrl Register fail");
3191 return status;
3192 }
3193
3194 /* Update channel head as next avaliable linked slot */
3195 channelEntry->headCtrlBlk = currentCtrlBlk;
3196
3197 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003198 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 return status;
3200}
3201
3202/*==========================================================================
3203 @ Function Name
3204 dxeTXCompFrame
3205
3206 @ Description
3207 TX Frame transfer complete event handler
3208
3209 @ Parameters
3210 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3211 DXE host driver main control block
3212 WLANDXE_ChannelCBType *channelEntry
3213 Channel specific control block
3214
3215 @ Return
3216 PAL_STATUS_T
3217===========================================================================*/
3218static wpt_status dxeTXCompFrame
3219(
3220 WLANDXE_CtrlBlkType *hostCtxt,
3221 WLANDXE_ChannelCBType *channelEntry
3222)
3223{
3224 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3225 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3226 WLANDXE_DescType *currentDesc = NULL;
3227 wpt_uint32 descCtrlValue = 0;
3228 unsigned int *lowThreshold = NULL;
3229
3230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003231 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003232
3233 /* Sanity */
3234 if((NULL == hostCtxt) || (NULL == channelEntry))
3235 {
3236 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3237 "dxeTXCompFrame Invalid ARG");
3238 return eWLAN_PAL_STATUS_E_INVAL;
3239 }
3240
3241 if(NULL == hostCtxt->txCompCB)
3242 {
3243 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3244 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003245 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 }
3247
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003248 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3249 if(eWLAN_PAL_STATUS_SUCCESS != status)
3250 {
3251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3252 "dxeTXCompFrame Mutex Acquire fail");
3253 return status;
3254 }
3255
Jeff Johnson295189b2012-06-20 16:38:30 -07003256 currentCtrlBlk = channelEntry->tailCtrlBlk;
3257 currentDesc = currentCtrlBlk->linkedDesc;
3258
3259 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3260 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003261 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3262 if(eWLAN_PAL_STATUS_SUCCESS != status)
3263 {
3264 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3265 "dxeTXCompFrame Mutex Release fail");
3266 return status;
3267 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003268 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003269 }
3270
3271 /* */
3272 while(1)
3273 {
3274// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3275 descCtrlValue = currentDesc->descCtrl.ctrl;
3276 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3277 {
3278 /* caught up with head, bail out */
3279 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3280 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3281 break;
3282 }
3283
3284 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
3285 channelEntry->numFreeDesc++;
3286 channelEntry->numRsvdDesc--;
3287
3288 /* Send Frame TX Complete notification with frame start fragment location */
3289 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3290 {
3291 hostCtxt->txCompletedFrames--;
3292#ifdef FEATURE_R33D
3293 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3294#else
3295 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3296 if (eWLAN_PAL_STATUS_SUCCESS != status)
3297 {
3298 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3299 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003300 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3301 if(eWLAN_PAL_STATUS_SUCCESS != status)
3302 {
3303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3304 "dxeTXCompFrame Mutex Release fail");
3305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 return status;
3307 }
3308#endif /* FEATURE_R33D */
3309 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3310 currentCtrlBlk->xfrFrame,
3311 eWLAN_PAL_STATUS_SUCCESS);
3312 channelEntry->numFragmentCurrentChain = 0;
3313 }
3314 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3315 currentDesc = currentCtrlBlk->linkedDesc;
3316
3317 /* Break condition
3318 * Head control block is the control block must be programed for the next TX
3319 * so, head control block is not programmed control block yet
3320 * if loop encounte head control block, stop to complete
3321 * in theory, COMP CB must be called already ??? */
3322 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3323 {
3324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3325 "dxeTXCompFrame caught up with head ptr");
3326 break;
3327 }
3328 /* VALID Bit check ???? */
3329 }
3330
3331 /* Tail and Head Control block must be same */
3332 channelEntry->tailCtrlBlk = currentCtrlBlk;
3333
3334 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3335 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3336 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3337
3338 /* If specific channel hit low resource condition send notification to upper layer */
3339 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3340 (channelEntry->numFreeDesc > *lowThreshold))
3341 {
3342 /* Change it back if we raised it for fetching a remaining packet from TL */
3343 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3344 {
3345 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3346 }
3347
3348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3349 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3350 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3351 channelEntry->channelType,
3352 eWLAN_PAL_TRUE);
3353 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003354 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003355 }
3356
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003357 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3358 if(eWLAN_PAL_STATUS_SUCCESS != status)
3359 {
3360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3361 "dxeTXCompFrame Mutex Release fail");
3362 }
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 Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003366 return status;
3367}
3368
3369/*==========================================================================
3370 @ Function Name
3371 dxeTXEventHandler
3372
3373 @ Description
3374 If DXE HW sends TX related interrupt, this event handler will be called
3375 Handle higher priority channel first
3376 Figureout why interrupt happen and call appropriate final even handler
3377 TX complete or error happen
3378
3379 @ Parameters
3380 void *msgPtr
3381 Even MSG
3382
3383 @ Return
3384 PAL_STATUS_T
3385===========================================================================*/
3386void dxeTXEventHandler
3387(
3388 wpt_msg *msgPtr
3389)
3390{
3391 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3392 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3393 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3394 wpt_uint32 intSrc = 0;
3395 wpt_uint32 chStat = 0;
3396 WLANDXE_ChannelCBType *channelCb = NULL;
3397
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003398 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003399 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003400
3401 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003402 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003403
3404 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003405 dxeCtxt->ucTxMsgCnt = 0;
3406
3407 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3408 {
3409 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3410 "wlan: TX COMP WLAN Driver re-loading in progress");
3411 return;
3412 }
3413
Jeff Johnson295189b2012-06-20 16:38:30 -07003414 /* Return from here if the RIVA is in IMPS, to avoid register access */
3415 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3416 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003417 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003418 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003419 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003420 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3421 if(eWLAN_PAL_STATUS_SUCCESS != status)
3422 {
3423 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003424 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003425 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003426
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003427 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3428 if(eWLAN_PAL_STATUS_SUCCESS != status)
3429 {
3430 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3431 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3432 }
3433
3434 if(((dxeCtxt->txCompletedFrames) &&
3435 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3436 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003437 {
3438 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3439 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003441 "TX COMP INT Enabled, remain TX frame count on ring %d",
3442 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003443 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3444 the posibility of a race*/
3445 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3446 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003447 else
3448 {
3449 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3450 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3451 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3452 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3453 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003454 return;
3455 }
3456
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003457 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003458 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3459 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3460 {
3461 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3462 "DXE already stopped in TX event handler. Just return");
3463 return;
3464 }
3465
Jeff Johnson295189b2012-06-20 16:38:30 -07003466 /* Disable device interrupt */
3467 /* Read whole interrupt mask register and exclusive only this channel int */
3468 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3469 &intSrc);
3470 if(eWLAN_PAL_STATUS_SUCCESS != status)
3471 {
3472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3473 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3474 return;
3475 }
3476 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3477 "TX Event Handler INT Source 0x%x", intSrc);
3478
3479 /* Test High Priority Channel is the INT source or not */
3480 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3481 if(intSrc & (1 << channelCb->assignedDMAChannel))
3482 {
3483 status = dxeChannelCleanInt(channelCb, &chStat);
3484 if(eWLAN_PAL_STATUS_SUCCESS != status)
3485 {
3486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3487 "dxeTXEventHandler INT Clean up fail");
3488 return;
3489 }
3490
3491 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3492 {
3493 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003494 "%11s : 0x%x Error Reported, Reload Driver",
3495 channelType[channelCb->channelType], chStat);
3496 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3497 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003498 }
3499 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3500 {
3501 /* Handle TX complete for high priority channel */
3502 status = dxeTXCompFrame(dxeCtxt,
3503 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003504 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003505 }
3506 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3507 {
3508 /* Handle TX complete for high priority channel */
3509 status = dxeTXCompFrame(dxeCtxt,
3510 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003511 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003512 }
3513 else
3514 {
3515 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3516 "dxeTXEventHandler TX HI status=%x", chStat);
3517 }
3518
3519 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3520 {
3521 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3522 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3523 }
3524
3525 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3526 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3527 }
3528
3529 /* Test Low Priority Channel interrupt is enabled or not */
3530 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3531 if(intSrc & (1 << channelCb->assignedDMAChannel))
3532 {
3533 status = dxeChannelCleanInt(channelCb, &chStat);
3534 if(eWLAN_PAL_STATUS_SUCCESS != status)
3535 {
3536 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3537 "dxeTXEventHandler INT Clean up fail");
3538 return;
3539 }
3540
3541 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3542 {
3543 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003544 "%11s : 0x%x Error Reported, Reload Driver",
3545 channelType[channelCb->channelType], chStat);
3546 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3547 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003548 }
3549 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3550 {
3551 /* Handle TX complete for low priority channel */
3552 status = dxeTXCompFrame(dxeCtxt,
3553 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003554 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003555 }
3556 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3557 {
3558 /* Handle TX complete for low priority channel */
3559 status = dxeTXCompFrame(dxeCtxt,
3560 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003561 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003562 }
3563 else
3564 {
3565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3566 "dxeTXEventHandler TX LO status=%x", chStat);
3567 }
3568
3569 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3570 {
3571 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3572 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3573 }
3574 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3575 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3576 }
3577
3578
3579#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3580 /* Test H2H TX Channel interrupt is enabled or not */
3581 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3582 if(intSrc & (1 << channelCb->assignedDMAChannel))
3583 {
3584 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3585 &chStat);
3586 if(eWLAN_PAL_STATUS_SUCCESS != status)
3587 {
3588 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3589 "dxeChannelCleanInt Read CH STAT register fail");
3590 return;
3591 }
3592
3593 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3594 {
3595 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003596 "%11s : 0x%x Error Reported, Reload Driver",
3597 channelType[channelCb->channelType], chStat);
3598 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3599 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003600 }
3601 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3602 {
3603 /* Handle TX complete for high priority channel */
3604 status = dxeTXCompFrame(dxeCtxt,
3605 channelCb);
3606 if(eWLAN_PAL_STATUS_SUCCESS != status)
3607 {
3608 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3609 "dxeTXEventHandler INT Clean up fail");
3610 return;
3611 }
3612 }
3613 else
3614 {
3615 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3616 "unexpected channel state %d", chStat);
3617 }
3618 }
3619#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3620
3621 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3622 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3623 {
3624 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3625 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003626 if(0 != dxeCtxt->txCompletedFrames)
3627 {
3628 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3629 "TX COMP INT Enabled, remain TX frame count on ring %d",
3630 dxeCtxt->txCompletedFrames);
3631 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003632 }
3633
3634 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3635 the posibility of a race*/
3636 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3637
3638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003639 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003640 return;
3641}
3642
3643
3644/*==========================================================================
3645 @ Function Name
3646 dxeTXCompleteProcessing
3647
3648 @ Description
3649 If DXE HW sends TX related interrupt, this event handler will be called
3650 Handle higher priority channel first
3651 Figureout why interrupt happen and call appropriate final even handler
3652 TX complete or error happen
3653
3654 @ Parameters
3655 dxeCtxt DXE context
3656
3657 @ Return
3658 PAL_STATUS_T
3659===========================================================================*/
3660void dxeTXCompleteProcessing
3661(
3662 WLANDXE_CtrlBlkType *dxeCtxt
3663)
3664{
3665 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3666 WLANDXE_ChannelCBType *channelCb = NULL;
3667
3668 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003669 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003670
3671 /* Test High Priority Channel is the INT source or not */
3672 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3673
3674 /* Handle TX complete for high priority channel */
3675 status = dxeTXCompFrame(dxeCtxt, channelCb);
3676
3677 /* Test Low Priority Channel interrupt is enabled or not */
3678 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3679
3680 /* Handle TX complete for low priority channel */
3681 status = dxeTXCompFrame(dxeCtxt, channelCb);
3682
3683 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3684 ((dxeCtxt->txCompletedFrames > 0) ||
3685 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3686 {
3687 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3688 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3689 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003690 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003691 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3692 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3693 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3694 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
3695 }
3696
3697 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3698 the posibility of a race*/
3699 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3700
3701 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003702 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003703 return;
3704}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003705
3706/*==========================================================================
3707 @ Function Name
3708 dxeTXReSyncDesc
3709
3710 @ Description
3711 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3712 And HW programmed descriptor.
3713 If any async happen between HW/SW TX stall will happen
3714
3715 @ Parameters
3716 void *msgPtr
3717 Message pointer to sync with TX thread
3718
3719 @ Return
3720 NONE
3721===========================================================================*/
3722void dxeTXReSyncDesc
3723(
3724 wpt_msg *msgPtr
3725)
3726{
3727 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3728 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3729 wpt_uint32 nextDescReg;
3730 WLANDXE_ChannelCBType *channelEntry;
3731 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3732 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003733 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003734
3735 if(NULL == msgContent)
3736 {
3737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3738 "dxeTXReSyncDesc Invalid Control Block");
3739 return;
3740 }
3741
3742 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3743 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3744 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3745
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003746 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003747 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003748 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3750 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3751 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3752 &nextDescReg);
3753 /* Async detect without TX pending frame */
3754 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003755 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003756 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003757 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3759 "TX Async no Pending frame");
3760 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry);
3761 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!");
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003762 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003763 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003764 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003765 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003766 /* Async detect with some TX pending frames
3767 * next descriptor register should sync with first valid descriptor */
3768 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003769 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003770 validCtrlBlk = channelEntry->tailCtrlBlk;
3771 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003772 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003773 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3774 {
3775 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3776 {
3777 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3778 "TX Async");
3779 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3780 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3781 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3782 validCtrlBlk->linkedDescPhyAddr);
3783 }
3784 break;
3785 }
3786 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3787 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3788 {
3789 /* Finished to test till head control blcok, but could not find valid descriptor
3790 * from head to tail all descriptors are invalidated
3791 * host point of view head descriptor is next TX candidate
3792 * So, next descriptor control have to be programmed with head descriptor
3793 * check */
3794 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3795 {
3796 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08003797 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003798 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3799 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3800 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3801 validCtrlBlk->linkedDescPhyAddr);
3802 }
3803 break;
3804 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003805 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003806 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003807 }
3808
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003809 /* HW/SW descriptor resync is done.
3810 * Next if there are any valid descriptor in chain, Push to HW again */
3811 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3812 {
3813 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3814 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3815 {
3816 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3817 "%11s : No TX Pending frame",
3818 channelType[channelEntry->channelType]);
3819 /* No Pending frame, Do nothing */
3820 }
3821 else
3822 {
3823 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3824 "%11s : TX Pending frame, process it",
3825 channelType[channelEntry->channelType]);
3826 validCtrlBlk = channelEntry->tailCtrlBlk;
3827 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3828 {
3829 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3830 {
3831 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3832 "%11s : when exit IMPS found valid descriptor",
3833 channelType[channelEntry->channelType]);
3834
3835 /* Found valid descriptor, kick DXE */
3836 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3837 channelEntry->extraConfig.chan_mask);
3838 break;
3839 }
3840 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3841 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3842 {
3843 /* Finished to test till head control blcok, but could not find valid descriptor
3844 * from head to tail all descriptors are invalidated */
3845 break;
3846 }
3847 }
3848 }
3849 }
3850
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003851 wpalMemoryFree(msgPtr);
3852 return;
3853}
3854
Jeff Johnson295189b2012-06-20 16:38:30 -07003855/*==========================================================================
3856 @ Function Name
3857 dxeTXISR
3858
3859 @ Description
3860 TX interrupt ISR
3861 Platform will call this function if INT is happen
3862 This function must be registered into platform interrupt module
3863
3864 @ Parameters
3865 void *hostCtxt
3866 DXE host driver control context,
3867 pre registerd during interrupt registration
3868
3869 @ Return
3870 PAL_STATUS_T
3871===========================================================================*/
3872static void dxeTXISR
3873(
3874 void *hostCtxt
3875)
3876{
3877 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3878 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3879#ifdef FEATURE_R33D
3880 wpt_uint32 regValue;
3881#endif /* FEATURE_R33D */
3882
3883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003884 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003885
3886 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003887 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003889 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003890 /* Disable interrupt at here,
3891 IMPS or IMPS Pending state should not access RIVA register */
3892 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3893 if(eWLAN_PAL_STATUS_SUCCESS != status)
3894 {
3895 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3896 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3897 return;
3898 }
3899 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3900 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003901 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003902 return;
3903 }
3904
3905#ifdef FEATURE_R33D
3906 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3907 &regValue);
3908 if(eWLAN_PAL_STATUS_SUCCESS != status)
3909 {
3910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3911 "dxeTXCompISR Read INT_SRC_RAW fail");
3912 return;
3913 }
3914 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3915 "INT_SRC_RAW 0x%x", regValue);
3916 if(0 == regValue)
3917 {
3918 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3919 "This is not DXE Interrupt, Reject it");
3920 return;
3921 }
3922#endif /* FEATURE_R33D */
3923
3924 /* Disable TX Complete Interrupt at here */
3925 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3926 if(eWLAN_PAL_STATUS_SUCCESS != status)
3927 {
3928 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3929 "dxeTXCompISR Disable TX complete interrupt fail");
3930 return;
3931 }
3932 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3933
3934
3935 if( dxeCtxt->ucTxMsgCnt )
3936 {
3937 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3938 "Avoiding serializing TX Complete event");
3939 return;
3940 }
3941
3942 dxeCtxt->ucTxMsgCnt = 1;
3943
3944 /* Serialize TX complete interrupt upon TX thread */
3945 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3946 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3947 dxeCtxt->txIsrMsg);
3948 if(eWLAN_PAL_STATUS_SUCCESS != status)
3949 {
3950 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3951 "dxeTXCompISR interrupt serialize fail status=%d", status);
3952 }
3953
3954 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003955 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003956 return;
3957}
3958
3959/*-------------------------------------------------------------------------
3960 * Global Function
3961 *-------------------------------------------------------------------------*/
3962/*==========================================================================
3963 @ Function Name
3964 WLANDXE_Open
3965
3966 @ Description
3967 Open host DXE driver, allocate DXE resources
3968 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
3969
3970 @ Parameters
3971 pVoid pAdaptor : Driver global control block pointer
3972
3973 @ Return
3974 pVoid DXE local module control block pointer
3975===========================================================================*/
3976void *WLANDXE_Open
3977(
3978 void
3979)
3980{
3981 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3982 unsigned int idx;
3983 WLANDXE_ChannelCBType *currentChannel = NULL;
3984 int smsmInitState;
3985#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3986 wpt_uint32 sIdx;
3987 WLANDXE_ChannelCBType *channel = NULL;
3988 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
3989 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
3990#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3991
3992 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003993 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003994
3995 /* This is temporary allocation */
3996 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
3997 if(NULL == tempDxeCtrlBlk)
3998 {
3999 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4000 "WLANDXE_Open Control Block Alloc Fail");
4001 return NULL;
4002 }
4003 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4004
4005 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4006 if(eWLAN_PAL_STATUS_SUCCESS != status)
4007 {
4008 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4009 "WLANDXE_Open Common Configuration Fail");
4010 WLANDXE_Close(tempDxeCtrlBlk);
4011 return NULL;
4012 }
4013
4014 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4015 {
4016 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4017 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4018 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
4019 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
4020 {
4021 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
4022 }
4023 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
4024 {
4025 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
4026 }
4027 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
4028 {
4029 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
4030 }
4031 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
4032 {
4033 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
4034 }
4035#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4036 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
4037 {
4038 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
4039 }
4040 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
4041 {
4042 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
4043 }
4044#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4045
4046 /* Config individual channels from channel default setup table */
4047 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4048 currentChannel);
4049 if(eWLAN_PAL_STATUS_SUCCESS != status)
4050 {
4051 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4052 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4053 WLANDXE_Close(tempDxeCtrlBlk);
4054 return NULL;
4055 }
4056
4057 /* Allocate DXE Control Block will be used by host DXE driver */
4058 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4059 if(eWLAN_PAL_STATUS_SUCCESS != status)
4060 {
4061 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4062 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4063
4064 WLANDXE_Close(tempDxeCtrlBlk);
4065 return NULL;
4066 }
4067 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4068 if(eWLAN_PAL_STATUS_SUCCESS != status)
4069 {
4070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4071 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4072 WLANDXE_Close(tempDxeCtrlBlk);
4073 return NULL;
4074 }
4075
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004076 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4077 dxeHealthMonitorTimeout,
4078 (void *)currentChannel);
4079 if(eWLAN_PAL_STATUS_SUCCESS != status)
4080 {
4081 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4082 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4083 WLANDXE_Close(tempDxeCtrlBlk);
4084 return NULL;
4085 }
4086
4087 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4088 if(NULL == currentChannel->healthMonitorMsg)
4089 {
4090 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4091 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4092 WLANDXE_Close(tempDxeCtrlBlk);
4093 return NULL;
4094 }
4095 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4096 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4097 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4098
Jeff Johnson295189b2012-06-20 16:38:30 -07004099 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4100 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4101 }
4102
4103 /* Allocate and Init RX READY ISR Serialize Buffer */
4104 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4105 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4106 {
4107 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4108 "WLANDXE_Open Alloc RX ISR Fail");
4109 WLANDXE_Close(tempDxeCtrlBlk);
4110 return NULL;
4111 }
4112 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4113 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4114 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4115
4116 /* Allocate and Init TX COMP ISR Serialize Buffer */
4117 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4118 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4119 {
4120 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4121 "WLANDXE_Open Alloc TX ISR Fail");
4122 WLANDXE_Close(tempDxeCtrlBlk);
4123 return NULL;
4124 }
4125 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4126 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4127 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4128
4129 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4130 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4131 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4132 {
4133 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4134 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4135 WLANDXE_Close(tempDxeCtrlBlk);
4136 return NULL;
4137 }
4138 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4139 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4140 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4141
4142 tempDxeCtrlBlk->freeRXPacket = NULL;
4143 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4144 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4145 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004146 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004147
4148 /* Initialize SMSM state
4149 * Init State is
4150 * Clear TX Enable
4151 * RING EMPTY STATE */
4152 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4153 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4154 if(0 != smsmInitState)
4155 {
4156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4157 "SMSM Channel init fail %d", smsmInitState);
4158 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4159 {
4160 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4161 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004162 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4163 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004164 wpalMemoryFree(tempDxeCtrlBlk);
4165 return NULL;
4166 }
4167
4168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4169 "WLANDXE_Open Success");
4170 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004171 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 return (void *)tempDxeCtrlBlk;
4173}
4174
4175/*==========================================================================
4176 @ Function Name
4177 WLANDXE_ClientRegistration
4178
4179 @ Description
4180 Make callback functions registration into DXE driver from DXE driver client
4181
4182 @ Parameters
4183 pVoid pDXEContext : DXE module control block
4184 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4185 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4186 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4187 void *userContext : DXE Cliennt control block
4188
4189 @ Return
4190 wpt_status
4191===========================================================================*/
4192wpt_status WLANDXE_ClientRegistration
4193(
4194 void *pDXEContext,
4195 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4196 WLANDXE_TxCompleteCbType txCompleteCB,
4197 WLANDXE_LowResourceCbType lowResourceCB,
4198 void *userContext
4199)
4200{
4201 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4202 WLANDXE_CtrlBlkType *dxeCtxt;
4203
4204 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004205 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004206
4207 /* Sanity */
4208 if(NULL == pDXEContext)
4209 {
4210 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4211 "WLANDXE_ClientRegistration Invalid DXE CB");
4212 return eWLAN_PAL_STATUS_E_INVAL;
4213 }
4214
4215 if(NULL == rxFrameReadyCB)
4216 {
4217 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4218 "WLANDXE_ClientRegistration Invalid RX READY CB");
4219 return eWLAN_PAL_STATUS_E_INVAL;
4220 }
4221
4222 if(NULL == txCompleteCB)
4223 {
4224 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4225 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4226 return eWLAN_PAL_STATUS_E_INVAL;
4227 }
4228
4229 if(NULL == lowResourceCB)
4230 {
4231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4232 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4233 return eWLAN_PAL_STATUS_E_INVAL;
4234 }
4235
4236 if(NULL == userContext)
4237 {
4238 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4239 "WLANDXE_ClientRegistration Invalid userContext");
4240 return eWLAN_PAL_STATUS_E_INVAL;
4241 }
4242
4243 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4244
4245 /* Assign */
4246 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4247 dxeCtxt->txCompCB = txCompleteCB;
4248 dxeCtxt->lowResourceCB = lowResourceCB;
4249 dxeCtxt->clientCtxt = userContext;
4250
4251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004252 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004253 return status;
4254}
4255
4256/*==========================================================================
4257 @ Function Name
4258 WLANDXE_Start
4259
4260 @ Description
4261 Start Host DXE driver
4262 Initialize DXE channels and start channel
4263
4264 @ Parameters
4265 pVoid pDXEContext : DXE module control block
4266
4267 @ Return
4268 wpt_status
4269===========================================================================*/
4270wpt_status WLANDXE_Start
4271(
4272 void *pDXEContext
4273)
4274{
4275 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4276 wpt_uint32 idx;
4277 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4278
4279 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004280 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004281
4282 /* Sanity */
4283 if(NULL == pDXEContext)
4284 {
4285 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4286 "WLANDXE_Start Invalid DXE CB");
4287 return eWLAN_PAL_STATUS_E_INVAL;
4288 }
4289 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4290
4291 /* WLANDXE_Start called means DXE engine already initiates
4292 * And DXE HW is reset and init finished
4293 * But here to make sure HW is initialized, reset again */
4294 status = dxeEngineCoreStart(dxeCtxt);
4295 if(eWLAN_PAL_STATUS_SUCCESS != status)
4296 {
4297 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4298 "WLANDXE_Start DXE HW init Fail");
4299 return status;
4300 }
4301
4302 /* Individual Channel Start */
4303 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4304 {
4305 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4306 "WLANDXE_Start Channel %s Start", channelType[idx]);
4307
4308 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4309 /* Make connection between DXE descriptor and DXE control block */
4310 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4311 if(eWLAN_PAL_STATUS_SUCCESS != status)
4312 {
4313 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4314 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4315 return status;
4316 }
4317
4318 /* Program each channel register with configuration arguments */
4319 status = dxeChannelInitProgram(dxeCtxt,
4320 &dxeCtxt->dxeChannel[idx]);
4321 if(eWLAN_PAL_STATUS_SUCCESS != status)
4322 {
4323 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4324 "WLANDXE_Start %d Program DMA channel Fail", idx);
4325 return status;
4326 }
4327
4328 /* ??? Trigger to start DMA channel
4329 * This must be seperated from ??? */
4330 status = dxeChannelStart(dxeCtxt,
4331 &dxeCtxt->dxeChannel[idx]);
4332 if(eWLAN_PAL_STATUS_SUCCESS != status)
4333 {
4334 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4335 "WLANDXE_Start %d Channel Start Fail", idx);
4336 return status;
4337 }
4338 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4339 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4340 }
4341
4342 /* Register ISR to OS */
4343 /* Register TX complete interrupt into platform */
4344 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4345 dxeTXISR,
4346 dxeCtxt);
4347 if(eWLAN_PAL_STATUS_SUCCESS != status)
4348 {
4349 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4350 "WLANDXE_Start TX comp interrupt registration Fail");
4351 return status;
4352 }
4353
4354 /* Register RX ready interrupt into platform */
4355 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4356 dxeRXISR,
4357 dxeCtxt);
4358 if(eWLAN_PAL_STATUS_SUCCESS != status)
4359 {
4360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4361 "WLANDXE_Start RX Ready interrupt registration Fail");
4362 return status;
4363 }
4364
4365 /* Enable system level ISR */
4366 /* Enable RX ready Interrupt at here */
4367 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4368 if(eWLAN_PAL_STATUS_SUCCESS != status)
4369 {
4370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4371 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4372 return status;
4373 }
4374
4375 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004376 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004377 return status;
4378}
4379
4380/*==========================================================================
4381 @ Function Name
4382 WLANDXE_TXFrame
4383
4384 @ Description
4385 Trigger frame transmit from host to RIVA
4386
4387 @ Parameters
4388 pVoid pDXEContext : DXE Control Block
4389 wpt_packet pPacket : transmit packet structure
4390 WDTS_ChannelType channel : TX channel
4391
4392 @ Return
4393 wpt_status
4394===========================================================================*/
4395wpt_status WLANDXE_TxFrame
4396(
4397 void *pDXEContext,
4398 wpt_packet *pPacket,
4399 WDTS_ChannelType channel
4400)
4401{
4402 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4403 WLANDXE_ChannelCBType *currentChannel = NULL;
4404 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4405 unsigned int *lowThreshold = NULL;
4406
4407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004408 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004409
4410 /* Sanity */
4411 if(NULL == pDXEContext)
4412 {
4413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4414 "WLANDXE_Start Invalid DXE CB");
4415 return eWLAN_PAL_STATUS_E_INVAL;
4416 }
4417
4418 if(NULL == pPacket)
4419 {
4420 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4421 "WLANDXE_Start Invalid pPacket");
4422 return eWLAN_PAL_STATUS_E_INVAL;
4423 }
4424
4425 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4426 {
4427 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4428 "WLANDXE_Start Invalid channel");
4429 return eWLAN_PAL_STATUS_E_INVAL;
4430 }
4431
4432 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4433
4434 currentChannel = &dxeCtxt->dxeChannel[channel];
4435
4436
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004437 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4438 if(eWLAN_PAL_STATUS_SUCCESS != status)
4439 {
4440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4441 "WLANDXE_TxFrame Mutex Acquire fail");
4442 return status;
4443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004444
4445 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4446 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4447 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4448
4449 /* Decide have to activate TX complete event or not */
4450 switch(dxeCtxt->txCompInt.txIntEnable)
4451 {
4452 /* TX complete interrupt will be activated when low DXE resource */
4453 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4454 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4455 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4456 {
4457 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4458 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4459 channel,
4460 eWLAN_PAL_FALSE);
4461 }
4462 break;
4463
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004464 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4466 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4467 {
4468 currentChannel->numFrameBeforeInt++;
4469 }
4470 break;
4471
4472 /* TX complete interrupt will be activated periodically */
4473 case WLANDXE_TX_COMP_INT_TIMER:
4474 break;
4475 }
4476
4477 dxeCtxt->txCompletedFrames++;
4478
4479 /* Update DXE descriptor, this is frame based
4480 * if a frame consist of N fragments, N Descriptor will be programed */
4481 status = dxeTXPushFrame(currentChannel, pPacket);
4482 if(eWLAN_PAL_STATUS_SUCCESS != status)
4483 {
4484 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4485 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004486 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4487 if(eWLAN_PAL_STATUS_SUCCESS != status)
4488 {
4489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4490 "WLANDXE_TxFrame Mutex Release fail");
4491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004492 return status;
4493 }
4494
4495 /* If specific channel hit low resource condition, send notification to upper layer */
4496 if(currentChannel->numFreeDesc <= *lowThreshold)
4497 {
4498 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4499 channel,
4500 eWLAN_PAL_FALSE);
4501 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004502
4503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4504 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4505 channelType[currentChannel->channelType],
4506 currentChannel->numRsvdDesc);
4507 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4508 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4509 wpalTimerStart(&currentChannel->healthMonitorTimer,
4510 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004512 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4513 if(eWLAN_PAL_STATUS_SUCCESS != status)
4514 {
4515 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4516 "WLANDXE_TxFrame Mutex Release fail");
4517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004518
4519 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004520 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004521 return status;
4522}
4523
4524/*==========================================================================
4525 @ Function Name
4526 WLANDXE_CompleteTX
4527
4528 @ Description
4529 Informs DXE that the current series of Tx packets is complete
4530
4531 @ Parameters
4532 pContext pDXEContext : DXE Control Block
4533 ucTxResReq TX resource number required by TL/WDI
4534
4535 @ Return
4536 wpt_status
4537===========================================================================*/
4538wpt_status
4539WLANDXE_CompleteTX
4540(
4541 void* pContext,
4542 wpt_uint32 ucTxResReq
4543)
4544{
4545 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4546 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4547 WLANDXE_ChannelCBType *channelCb = NULL;
4548 wpt_boolean inLowRes;
4549
4550 /* Sanity Check */
4551 if( NULL == pContext )
4552 {
4553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4554 "WLANDXE_CompleteTX invalid param");
4555 return eWLAN_PAL_STATUS_E_INVAL;
4556 }
4557
4558 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4559 inLowRes = channelCb->hitLowResource;
4560
4561 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4562 {
4563 /* Raise threshold temporarily if necessary */
4564 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4565
4566 if(eWLAN_PAL_FALSE == inLowRes)
4567 {
4568 /* Put the channel to low resource condition */
4569 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4570 WDTS_CHANNEL_TX_LOW_PRI,
4571 eWLAN_PAL_FALSE);
4572 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004573 wpalTimerStart(&channelCb->healthMonitorTimer,
4574 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004575 }
4576 }
4577
4578 /*Try to reclaim resources*/
4579 dxeTXCompleteProcessing(dxeCtxt);
4580
4581 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4582 because its fragment size is larger than DXE free resource. */
4583 if(0 < ucTxResReq)
4584 {
4585 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4586 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4587 {
4588 /* DXE has not been in low resource condition. DXE forces to kick off
4589 TX tranmit */
4590 if((eWLAN_PAL_FALSE == inLowRes) &&
4591 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4592 {
4593 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4594 WDTS_CHANNEL_TX_LOW_PRI,
4595 eWLAN_PAL_FALSE);
4596 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4597 WDTS_CHANNEL_TX_LOW_PRI,
4598 eWLAN_PAL_TRUE);
4599 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4600 }
4601 }
4602 else
4603 {
4604 /* DXE doesn't have enough free DXE resources. Put the channel
4605 to low resource condition. */
4606 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4607 {
4608 /* Put the channel to low resource condition */
4609 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4610 WDTS_CHANNEL_TX_LOW_PRI,
4611 eWLAN_PAL_FALSE);
4612 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004613 wpalTimerStart(&channelCb->healthMonitorTimer,
4614 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004615 }
4616 }
4617 }
4618
4619 return status;
4620}
4621
4622/*==========================================================================
4623 @ Function Name
4624 WLANDXE_Stop
4625
4626 @ Description
4627 Stop DXE channels and DXE engine operations
4628 Disable all channel interrupt
4629 Stop all channel operation
4630
4631 @ Parameters
4632 pVoid pDXEContext : DXE Control Block
4633
4634 @ Return
4635 wpt_status
4636===========================================================================*/
4637wpt_status WLANDXE_Stop
4638(
4639 void *pDXEContext
4640)
4641{
4642 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4643 wpt_uint32 idx;
4644 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4645
4646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004647 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004648
4649 /* Sanity */
4650 if(NULL == pDXEContext)
4651 {
4652 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4653 "WLANDXE_Stop Invalid DXE CB");
4654 return eWLAN_PAL_STATUS_E_INVAL;
4655 }
4656
4657 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4658 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4659 {
4660 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4661 if(eWLAN_PAL_STATUS_SUCCESS != status)
4662 {
4663 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4664 "WLANDXE_Stop Channel %d Stop Fail", idx);
4665 return status;
4666 }
4667 }
4668
4669 /* During Stop unregister interrupt */
4670 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4671 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4672
4673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004674 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 return status;
4676}
4677
4678/*==========================================================================
4679 @ Function Name
4680 WLANDXE_Close
4681
4682 @ Description
4683 Close DXE channels
4684 Free DXE related resources
4685 DXE descriptor free
4686 Descriptor control block free
4687 Pre allocated RX buffer free
4688
4689 @ Parameters
4690 pVoid pDXEContext : DXE Control Block
4691
4692 @ Return
4693 wpt_status
4694===========================================================================*/
4695wpt_status WLANDXE_Close
4696(
4697 void *pDXEContext
4698)
4699{
4700 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4701 wpt_uint32 idx;
4702 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4703#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4704 wpt_uint32 sIdx;
4705 WLANDXE_ChannelCBType *channel = NULL;
4706 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4707 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4708#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4709
4710 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004711 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004712
4713 /* Sanity */
4714 if(NULL == pDXEContext)
4715 {
4716 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4717 "WLANDXE_Stop Invalid DXE CB");
4718 return eWLAN_PAL_STATUS_E_INVAL;
4719 }
4720
4721 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4722 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4723 {
4724 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004725 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4726 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
4727 {
4728 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
4729 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004730 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4731#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4732 channel = &dxeCtxt->dxeChannel[idx];
4733 crntDescCB = channel->headCtrlBlk;
4734 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4735 {
4736 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4737 wpalMemoryFree((void *)crntDescCB);
4738 crntDescCB = nextDescCB;
4739 if(NULL == crntDescCB)
4740 {
4741 break;
4742 }
4743 }
4744#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4745 }
4746
4747 if(NULL != dxeCtxt->rxIsrMsg)
4748 {
4749 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4750 }
4751 if(NULL != dxeCtxt->txIsrMsg)
4752 {
4753 wpalMemoryFree(dxeCtxt->txIsrMsg);
4754 }
4755 if(NULL != dxeCtxt->rxPktAvailMsg)
4756 {
4757 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4758 }
4759
4760 wpalMemoryFree(pDXEContext);
4761
4762 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004763 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004764 return status;
4765}
4766
4767/*==========================================================================
4768 @ Function Name
4769 WLANDXE_TriggerTX
4770
4771 @ Description
4772 TBD
4773
4774 @ Parameters
4775 pVoid pDXEContext : DXE Control Block
4776
4777 @ Return
4778 wpt_status
4779===========================================================================*/
4780wpt_status WLANDXE_TriggerTX
4781(
4782 void *pDXEContext
4783)
4784{
4785 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4786
4787 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004788 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004789
4790 /* TBD */
4791
4792 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004793 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004794 return status;
4795}
4796
4797/*==========================================================================
4798 @ Function Name
4799 dxeTxThreadSetPowerStateEventHandler
4800
4801 @ Description
4802 If WDI sends set power state req, this event handler will be called in Tx
4803 thread context
4804
4805 @ Parameters
4806 void *msgPtr
4807 Event MSG
4808
4809 @ Return
4810 None
4811===========================================================================*/
4812void dxeTxThreadSetPowerStateEventHandler
4813(
4814 wpt_msg *msgPtr
4815)
4816{
4817 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4818 WLANDXE_CtrlBlkType *dxeCtxt;
4819 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4820 WLANDXE_PowerStateType reqPowerState;
4821
4822 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004823 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004824
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4826 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4827 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4828
4829 switch(reqPowerState)
4830 {
4831 case WLANDXE_POWER_STATE_BMPS:
4832 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4833 {
4834 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4835 //based on amount of TX and RX activity - during this time any received
4836 // management frames will remain un-processed consuming RX buffers
4837 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4838 dxeCtxt->hostPowerState = reqPowerState;
4839 }
4840 else
4841 {
4842 status = eWLAN_PAL_STATUS_E_INVAL;
4843 }
4844 break;
4845 case WLANDXE_POWER_STATE_IMPS:
4846 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4847 {
4848 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4849 }
4850 else
4851 {
4852 status = eWLAN_PAL_STATUS_E_INVAL;
4853 }
4854 break;
4855 case WLANDXE_POWER_STATE_FULL:
4856 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4857 {
4858 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4859 }
4860 dxeCtxt->hostPowerState = reqPowerState;
4861 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4862 break;
4863 case WLANDXE_POWER_STATE_DOWN:
4864 WLANDXE_Stop((void *)dxeCtxt);
4865 break;
4866 default:
4867 //assert
4868 break;
4869 }
4870
4871 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4872 {
4873 dxeCtxt->setPowerStateCb(status,
4874 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4875 }
Ravali85acf6b2012-12-12 14:01:38 -08004876 else
4877 {
4878 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4879 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
4880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 /* Free MSG buffer */
4882 wpalMemoryFree(msgPtr);
4883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004884 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 return;
4886}
4887
4888
4889/*==========================================================================
4890 @ Function Name
4891 dxeRxThreadSetPowerStateEventHandler
4892
4893 @ Description
4894 If WDI sends set power state req, this event handler will be called in Rx
4895 thread context
4896
4897 @ Parameters
4898 void *msgPtr
4899 Event MSG
4900
4901 @ Return
4902 None
4903===========================================================================*/
4904void dxeRxThreadSetPowerStateEventHandler
4905(
4906 wpt_msg *msgPtr
4907)
4908{
4909 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4910
4911 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004912 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004913
4914 /* Now serialise the message through Tx thread also to make sure
4915 * no register access when RIVA is in powersave */
4916 /*Use the same message pointer just change the call back function */
4917 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4918 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4919 msgPtr);
4920 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4921 {
4922 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4923 "Tx thread Set power state req serialize fail status=%d",
4924 status, 0, 0);
4925 }
4926
4927 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004928 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004929}
4930
4931/*==========================================================================
4932 @ Function Name
4933 WLANDXE_SetPowerState
4934
4935 @ Description
4936 From Client let DXE knows what is the WLAN HW(RIVA) power state
4937
4938 @ Parameters
4939 pVoid pDXEContext : DXE Control Block
4940 WLANDXE_PowerStateType powerState
4941
4942 @ Return
4943 wpt_status
4944===========================================================================*/
4945wpt_status WLANDXE_SetPowerState
4946(
4947 void *pDXEContext,
4948 WDTS_PowerStateType powerState,
4949 WDTS_SetPSCbType cBack
4950)
4951{
4952 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4953 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4954 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004955 wpt_msg *rxCompMsg;
4956 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07004957
4958 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004959 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004960 if(NULL == pDXEContext)
4961 {
4962 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4963 "NULL pDXEContext passed by caller", 0, 0, 0);
4964 return eWLAN_PAL_STATUS_E_FAILURE;
4965 }
4966 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
4967
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 switch(powerState)
4969 {
4970 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004971 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
4972 {
4973 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4974 if(NULL == txDescReSyncMsg)
4975 {
4976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4977 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
4978 }
4979 else
4980 {
4981 txDescReSyncMsg->callback = dxeTXReSyncDesc;
4982 txDescReSyncMsg->pContext = pDxeCtrlBlk;
4983 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4984 txDescReSyncMsg);
4985 if(eWLAN_PAL_STATUS_SUCCESS != status)
4986 {
4987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4988 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
4989 }
4990 }
4991 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 hostPowerState = WLANDXE_POWER_STATE_FULL;
4993 break;
4994 case WDTS_POWER_STATE_BMPS:
4995 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
4996 hostPowerState = WLANDXE_POWER_STATE_BMPS;
4997 break;
4998 case WDTS_POWER_STATE_IMPS:
4999 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5000 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5001 break;
5002 case WDTS_POWER_STATE_DOWN:
5003 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5004 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5005 break;
5006 default:
5007 hostPowerState = WLANDXE_POWER_STATE_MAX;
5008 }
5009
5010 // A callback i.e. ACK back is needed only when we want to enable BMPS
5011 // and the data/management path is active because we want to ensure
5012 // DXE registers are not accessed when RIVA may be power-collapsed. So
5013 // we need a callback in enter_bmps_req (the request to RIVA is sent
5014 // only after ACK back from TX thread). A callback is not needed in
5015 // finish_scan_req during BMPS since data-path is resumed only in
5016 // finish_scan_rsp and no management frames are sent in between. No
5017 // callback is needed when going from BMPS enabled to BMPS suspended/
5018 // disabled when it is known that RIVA is awake and cannot enter power
5019 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5020 // init_scan_rsp
5021 if ( cBack )
5022 {
5023 //serialize through Rx thread
5024 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5025 if(NULL == rxCompMsg)
5026 {
5027 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5028 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5029 return eWLAN_PAL_STATUS_E_RESOURCES;
5030 }
5031
5032 /* Event type, where it must be defined???? */
5033 /* THIS MUST BE CLEARED ASAP
5034 txCompMsg->type = TX_COMPLETE; */
5035 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5036 rxCompMsg->pContext = pDxeCtrlBlk;
5037 rxCompMsg->val = hostPowerState;
5038 rxCompMsg->ptr = cBack;
5039 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5040 rxCompMsg);
5041 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5042 {
5043 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5044 "Rx thread Set power state req serialize fail status=%d",
5045 status, 0, 0);
5046 }
5047 }
5048 else
5049 {
5050 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5051 {
5052 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5053 {
5054 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5055 }
5056 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5057 {
5058 /* Requested Full power from exit IMPS, reenable the interrupts*/
5059 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5060 {
5061 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5062 /* Enable RX interrupt at here, if new PS is not IMPS */
5063 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5064 if(eWLAN_PAL_STATUS_SUCCESS != status)
5065 {
5066 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005067 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005068 return status;
5069 }
5070 }
5071 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5072 {
5073 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005074 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005075 /* Enable RX interrupt at here, if new PS is not IMPS */
5076 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5077 if(eWLAN_PAL_STATUS_SUCCESS != status)
5078 {
5079 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005080 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005081 return status;
5082 }
5083 }
5084 }
5085 pDxeCtrlBlk->hostPowerState = hostPowerState;
5086 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5087 }
5088 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5089 {
5090 pDxeCtrlBlk->hostPowerState = hostPowerState;
5091 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5092 }
5093 else
5094 {
5095 HDXE_ASSERT(0);
5096 }
5097 }
5098
5099 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005100 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005101
5102 return status;
5103}
5104
5105/*==========================================================================
5106 @ Function Name
5107 WLANDXE_GetFreeTxDataResNumber
5108
5109 @ Description
5110 Returns free descriptor numbers for TX data channel (TX high priority)
5111
5112 @ Parameters
5113 pVoid pDXEContext : DXE Control Block
5114
5115 @ Return
5116 wpt_uint32 Free descriptor number of TX high pri ch
5117===========================================================================*/
5118wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5119(
5120 void *pDXEContext
5121)
5122{
5123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005124 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005125
5126 if(NULL == pDXEContext)
5127 {
5128 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5129 "NULL parameter passed by caller", 0, 0, 0);
5130 return (0);
5131 }
5132
5133 return
5134 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5135}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005136
5137/*==========================================================================
5138 @ Function Name
5139 WLANDXE_ChannelDebug
5140
5141 @ Description
5142 Display DXE Channel debugging information
5143 User may request to display DXE channel snapshot
5144 Or if host driver detects any abnormal stcuk may display
5145
5146 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005147 displaySnapshot : Display DXE snapshot option
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005148 enableStallDetect : Enable stall detect feature
5149 This feature will take effect to data performance
5150 Not integrate till fully verification
5151
5152 @ Return
5153 NONE
5154
5155===========================================================================*/
5156void WLANDXE_ChannelDebug
5157(
5158 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005159 wpt_boolean enableStallDetect
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005160)
5161{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005162 wpt_msg *channelDebugMsg;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005163 wpt_uint32 regValue;
5164 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5165
5166 /* Debug Type 1, Display current snapshot */
5167 if(displaySnapshot)
5168 {
5169 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5170 * This will not simply wakeup RIVA
5171 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005172 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005173 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5174 "Host power state %d, RIVA power state %d",
5175 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
5176 /* Get free BD count */
5177 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
5178 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5179 "TX Pending frames count %d, Current available BD %d",
5180 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005181
5182 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5183 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005184 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005185 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5186 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5187 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005188 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005189
5190 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5191 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5192 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005193 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005194 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5195 "Tx thread Set power state req serialize fail status=%d",
5196 status, 0, 0);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005197 }
5198 }
5199
5200 /* Debug Type 2, toggling stall detect enable/disable */
5201 if(enableStallDetect)
5202 {
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005203 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5204 "DXE TX Stall detect",
5205 0, 0, 0);
5206 /* Start Stall detect timer and detect stall */
5207 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5208 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005209 }
5210 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005211}