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