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