blob: 07bc40358ce91bb8cf8c4ee20c65e48b82dfdb03 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Leo Chang416afe02013-07-01 13:58:13 -07002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
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 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
23 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
Leo Changc286cbf2013-06-18 20:32:42 -070042
Jeff Johnson295189b2012-06-20 16:38:30 -070043/**=========================================================================
44
45 @file wlan_qct_dxe.c
46
47 @brief
48
49 This file contains the external API exposed by the wlan data transfer abstraction layer module.
Leo Changc286cbf2013-06-18 20:32:42 -070050 Copyright (c) 2010-2011 Qualcomm Technologies, Inc.
Jeff Johnson295189b2012-06-20 16:38:30 -070051 All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070052========================================================================*/
53
54/*===========================================================================
55
56 EDIT HISTORY FOR FILE
57
58
59 This section contains comments describing changes made to the module.
60 Notice that changes are listed in reverse chronological order.
61
62
63 $Header:$ $DateTime: $ $Author: $
64
65
66when who what, where, why
67-------- --- ----------------------------------------------------------
6808/03/10 schang Created module.
69
70===========================================================================*/
71
72/*===========================================================================
73
74 INCLUDE FILES FOR MODULE
75
76===========================================================================*/
77
78/*----------------------------------------------------------------------------
79 * Include Files
80 * -------------------------------------------------------------------------*/
81#include "wlan_qct_dxe.h"
82#include "wlan_qct_dxe_i.h"
83#include "wlan_qct_pal_device.h"
84#ifdef FEATURE_R33D
85#include "wlan_qct_pal_bus.h"
86#endif /* FEATURE_R33D */
87
88/*----------------------------------------------------------------------------
89 * Local Definitions
90 * -------------------------------------------------------------------------*/
91//#define WLANDXE_DEBUG_CH_INFO_DUMP
92
93/* Temporary configuration defines
94 * Have to find out permanent solution */
95#define T_WLANDXE_MAX_DESCRIPTOR_COUNT 40
96#define T_WLANDXE_MAX_FRAME_SIZE 2000
97#define T_WLANDXE_TX_INT_ENABLE_FCOUNT 1
98#define T_WLANDXE_MEMDUMP_BYTE_PER_LINE 16
99#define T_WLANDXE_MAX_RX_PACKET_WAIT 6000
Leo Chang5edb2d32013-04-03 13:32:58 -0700100#define T_WLANDXE_PERIODIC_HEALTH_M_TIME 2500
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700101#define T_WLANDXE_MAX_HW_ACCESS_WAIT 2000
Jeff Johnsone7245742012-09-05 17:12:55 -0700102#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
Leo Chang094ece82013-04-23 17:57:41 -0700104#define WLANPAL_RX_INTERRUPT_PRO_MASK 0x20
105#define WLANDXE_RX_INTERRUPT_PRO_UNMASK 0x5F
Jeff Johnson295189b2012-06-20 16:38:30 -0700106/* This is temporary fot the compile
107 * WDI will release official version
108 * This must be removed */
109#define WDI_GET_PAL_CTX() NULL
110
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700111
Jeff Johnson295189b2012-06-20 16:38:30 -0700112/*-------------------------------------------------------------------------
113 * Local Varables
114 *-------------------------------------------------------------------------*/
115/* This is temp, someone have to allocate for me, and must be part of global context */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700116static WLANDXE_CtrlBlkType *tempDxeCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -0700117static char *channelType[WDTS_CHANNEL_MAX] =
118 {
119 "TX_LOW_PRI",
120 "TX_HIGH_PRI",
121 "RX_LOW_PRI",
122#ifndef WLANDXE_TEST_CHANNEL_ENABLE
123 "RX_HIGH_PRI",
124#else
125 "H2H_TEST_TX",
126 "H2H_TEST_RX"
127#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
128 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700129static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700130
131/*-------------------------------------------------------------------------
132 * External Function Proto Type
133 *-------------------------------------------------------------------------*/
134
135/*-------------------------------------------------------------------------
136 * Local Function Proto Type
137 *-------------------------------------------------------------------------*/
138static wpt_status dxeRXFrameSingleBufferAlloc
139(
140 WLANDXE_CtrlBlkType *dxeCtxt,
141 WLANDXE_ChannelCBType *channelEntry,
142 WLANDXE_DescCtrlBlkType *currentCtrlBlock
143);
144
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700145static wpt_status dxeNotifySmsm
146(
147 wpt_boolean kickDxe,
148 wpt_boolean ringEmpty
149);
150
Jeff Johnson295189b2012-06-20 16:38:30 -0700151/*-------------------------------------------------------------------------
152 * Local Function
153 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700154/*==========================================================================
155 @ Function Name
156 dxeChannelMonitor
157
158 @ Description
159
160 @ Parameters
161 WLANDXE_ChannelCBType *channelEntry
162 Channel specific control block
163
164 @ Return
165 wpt_status
166
167===========================================================================*/
168static wpt_status dxeChannelMonitor
169(
170 char *monitorDescription,
171 WLANDXE_ChannelCBType *channelEntry
172)
173{
174 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
175
Jeff Johnsone7245742012-09-05 17:12:55 -0700176 if((NULL == monitorDescription) || (NULL == channelEntry))
177 {
178 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
179 "INVALID Input ARG");
180 return eWLAN_PAL_STATUS_E_INVAL;
181 }
182
183 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
184 {
185 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
186 "INVALID Channel type");
187 return eWLAN_PAL_STATUS_E_INVAL;
188 }
189
190 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700191 "=== %s Channel Number %d, Channel Type %s",
192 monitorDescription, channelEntry->assignedDMAChannel, channelType[channelEntry->channelType]);
Jeff Johnsone7245742012-09-05 17:12:55 -0700193 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700194 "numDesc %d, numFreeDesc %d, numResvDesc %d",
195 channelEntry->numDesc, channelEntry->numFreeDesc, channelEntry->numRsvdDesc);
Jeff Johnsone7245742012-09-05 17:12:55 -0700196 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700197 "headCB 0x%x, next 0x%x, DESC 0x%x",
198 channelEntry->headCtrlBlk, channelEntry->headCtrlBlk->nextCtrlBlk, channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700199 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700200 "tailCB 0x%x, next 0x%x, DESC 0x%x",
201 channelEntry->tailCtrlBlk, channelEntry->tailCtrlBlk->nextCtrlBlk, channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700202 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 "headCB Order %d, tailCB Order %d",
204 channelEntry->headCtrlBlk->ctrlBlkOrder, channelEntry->tailCtrlBlk->ctrlBlkOrder);
Jeff Johnsone7245742012-09-05 17:12:55 -0700205 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 "numFragmentCurrentChain %d, numTotalFrame %d ===",
207 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
208
209 return status;
210}
211
Jeff Johnsone7245742012-09-05 17:12:55 -0700212#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700213/*==========================================================================
214 @ Function Name
215 dxeMemoryDump
216
217 @ Description
218
219 @ Parameters
220 WLANDXE_ChannelCBType *channelEntry
221 Channel specific control block
222
223 @ Return
224 wpt_status
225
226===========================================================================*/
227static wpt_status dxeMemoryDump
228(
229 wpt_uint8 *dumpPointer,
230 wpt_uint32 dumpSize,
231 char *dumpTarget
232)
233{
234 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
235 wpt_uint32 numBytes = 0;
236 wpt_uint32 idx;
237
Jeff Johnsone7245742012-09-05 17:12:55 -0700238 if((NULL == dumpPointer) ||
239 (NULL == dumpTarget))
240 {
241 return status;
242 }
243
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
245 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
246 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
247 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
248
249 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
250 for(idx = 0; idx < dumpSize; idx++)
251 {
252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
253 "0x%2x ", dumpPointer[idx]);
254 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
255 {
256 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
257 }
258 }
259 if(0 != numBytes)
260 {
261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
262 }
263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
264 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
265
266 return status;
267}
Jeff Johnsone7245742012-09-05 17:12:55 -0700268#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700269
270/*==========================================================================
271 @ Function Name
272 dxeDescriptorDump
273
274 @ Description
275
276 @ Parameters
277 WLANDXE_ChannelCBType *channelEntry
278 Channel specific control block
279
280 @ Return
281 wpt_status
282
283===========================================================================*/
284wpt_status dxeDescriptorDump
285(
286 WLANDXE_ChannelCBType *channelEntry,
287 WLANDXE_DescType *targetDesc,
288 wpt_uint32 fragmentOrder
289)
290{
291 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
292
293
Jeff Johnsone7245742012-09-05 17:12:55 -0700294 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700295 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700296 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700297 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700299 fragmentOrder + 1,
300 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700301
Jeff Johnsone7245742012-09-05 17:12:55 -0700302 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700303 "CTRL WORD 0x%x, TransferSize %d",
304 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
305 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
308 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
309 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
310 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700311 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
313
314 return status;
315}
316
317/*==========================================================================
318 @ Function Name
319 dxeChannelRegisterDump
320
321 @ Description
322
323 @ Parameters
324 WLANDXE_ChannelCBType *channelEntry
325 Channel specific control block
326
327 @ Return
328 wpt_status
329
330===========================================================================*/
331wpt_status dxeChannelRegisterDump
332(
333 WLANDXE_ChannelCBType *channelEntry,
334 char *dumpTarget
335)
336{
337 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
338 wpt_uint32 regValue = 0;
339
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700340 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
341 {
342 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
343 "INVALID Channel type");
344 return eWLAN_PAL_STATUS_E_INVAL;
345 }
346
Jeff Johnsone7245742012-09-05 17:12:55 -0700347 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 "%s Channel register dump for %s, base address 0x%x",
349 channelType[channelEntry->channelType],
350 dumpTarget,
351 channelEntry->channelRegister.chDXEBaseAddr);
352 regValue = 0;
353 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700354 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700355 "Control Register 0x%x", regValue);
356
357 regValue = 0;
358 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700359 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700360 "Status Register 0x%x", regValue);
361 regValue = 0;
362
363 wpalReadRegister(channelEntry->channelRegister.chDXESadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 "Source Address Register 0x%x", regValue);
366 regValue = 0;
367
368 wpalReadRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700369 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 "Destination Address Register 0x%x", regValue);
371 regValue = 0;
372
373 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700375 "Last Descriptor Address Register 0x%x", regValue);
376
377 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &regValue);
378 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
379 "Next Descriptor Address Register 0x%x", regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -0700380
381 return status;
382}
Jeff Johnsone7245742012-09-05 17:12:55 -0700383
384/*==========================================================================
385 @ Function Name
386 dxeChannelAllDescDump
387
388 @ Description
389 Dump all DXE descriptors within assigned channe;
390
391 @ Parameters
392 WLANDXE_ChannelCBType *channelEntry
393
394 @ Return
395 NONE
396
397===========================================================================*/
398void dxeChannelAllDescDump
399(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700400 WLANDXE_ChannelCBType *channelEntry,
401 WDTS_ChannelType channel
Jeff Johnsone7245742012-09-05 17:12:55 -0700402)
403{
404 wpt_uint32 channelLoop;
405 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700406 wpt_uint32 previousCtrlValue = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700407
408 targetCtrlBlk = channelEntry->headCtrlBlk;
409
410 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700411 "%s %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700412 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700413 channelEntry->numDesc,
414 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700415 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
416
417 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
418 (WDTS_CHANNEL_RX_HIGH_PRI == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700419 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700420 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700421 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700422 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
423 {
424 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
425 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
426 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
427 }
428 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
429 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700430 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700431 }
432 else
433 {
434 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
435 {
436 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
437 {
438 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
439 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
440 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
441 }
442 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
443 }
444 }
445 return;
446}
447
448/*==========================================================================
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700449 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700450 dxeTxThreadChannelDebugHandler
451
452 @ Description
453 Dump TX channel information
454
455 @ Parameters
456 Wwpt_msg *msgPtr
457
458 @ Return
459 NONE
460
461===========================================================================*/
462void dxeTxThreadChannelDebugHandler
463(
464 wpt_msg *msgPtr
465)
466{
467 wpt_uint8 channelLoop;
468
469 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700470 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700471
472 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
473 * This will not simply wakeup RIVA
474 * Just incase TX not wanted stuck, Trigger TX again */
475 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
476 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
477 {
478 dxeChannelMonitor("******** Get Descriptor Snapshot ",
479 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
480 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -0700481 tempDxeCtrlBlk->dxeChannel[channelLoop].tailCtrlBlk->linkedDesc,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700482 0);
483 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
484 "Abnormal successive empty interrupt");
485 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700486 }
487
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700488 wpalMemoryFree(msgPtr);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700490 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700491 return;
492}
493
494/*==========================================================================
495 @ Function Name
496 dxeRxThreadChannelDebugHandler
497
498 @ Description
499 Dump RX channel information
500
501 @ Parameters
502 Wwpt_msg *msgPtr
503
504 @ Return
505 NONE
506
507===========================================================================*/
508void dxeRxThreadChannelDebugHandler
509(
510 wpt_msg *msgPtr
511)
512{
513 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
514 wpt_uint8 channelLoop;
515
516 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700517 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700518
519 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
520 * This will not simply wakeup RIVA
521 * Just incase TX not wanted stuck, Trigger TX again */
522 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_FALSE);
523 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
524 {
525 dxeChannelMonitor("******** Get Descriptor Snapshot ",
526 &tempDxeCtrlBlk->dxeChannel[channelLoop]);
527 dxeDescriptorDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
528 tempDxeCtrlBlk->dxeChannel[channelLoop].headCtrlBlk->linkedDesc,
529 0);
530 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
531 "Abnormal successive empty interrupt");
532 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], channelLoop);
533 }
534
535 /* Now serialise the message through Tx thread also to make sure
536 * no register access when RIVA is in powersave */
537 /*Use the same message pointer just change the call back function */
538 msgPtr->callback = dxeTxThreadChannelDebugHandler;
539 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
540 msgPtr);
541 if ( eWLAN_PAL_STATUS_SUCCESS != status )
542 {
543 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700544 "Tx thread state dump req serialize fail status=%d",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700545 status, 0, 0);
546 }
547
548 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700549 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700550 return;
551}
Jeff Johnson295189b2012-06-20 16:38:30 -0700552
553/*==========================================================================
554 @ Function Name
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700555 dxeRXHealthMonitor
556
557 @ Description
558 Monitoring RX channel healthy stataus
559 If detect any problem, try to recover
560
561 @ Parameters
562 healthMonitorMsg MSG pointer.
563 will have low resource TX channel context
564
565 @ Return
566 NONE
567
568===========================================================================*/
569void dxeRXHealthMonitor
570(
571 wpt_msg *healthMonitorMsg
572)
573{
574 WLANDXE_ChannelCBType *channelCtrlBlk;
575 WLANDXE_ChannelCBType *testCHCtrlBlk;
576 wpt_uint32 regValue;
577 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
578 wpt_uint32 hwWakeLoop, chLoop;
579
580 if(NULL == healthMonitorMsg)
581 {
582 return;
583 }
584
585 /* Make wake up HW */
586 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
587 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Chang5edb2d32013-04-03 13:32:58 -0700588 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700589
590 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
591 {
592 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
593 if(0 != regValue)
594 {
595 break;
596 }
597 }
598
599 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
600 "Scheduled RX, num free BD/PDU %d, loop Count %d",
601 regValue, hwWakeLoop, 0);
602
603 for(chLoop = WDTS_CHANNEL_RX_LOW_PRI; chLoop < WDTS_CHANNEL_MAX; chLoop++)
604 {
605 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
606 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
607 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
608 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
609 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
610
611 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
612 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
613 channelType[chLoop],
614 chControlReg, chStatusReg, chDescReg, chLDescReg,
615 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
616 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
617 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
618 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
619
620 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
621 (chLDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
622 {
623 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
624 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
625 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
626 channelType[chLoop],
627 chControlReg, chStatusReg, chDescReg, chLDescReg,
628 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
629 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
630 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
631 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
632 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
633 "%11s : RX CH EN Descriptor Async, resync it", channelType[chLoop], 0, 0);
634 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
635 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
636 }
637 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
638 (chDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
639 {
640 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
641 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
642 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
643 channelType[chLoop],
644 chControlReg, chStatusReg, chDescReg, chLDescReg,
645 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
646 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
647 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
648 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
649 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
650 "%11s : RX CH DIS Descriptor Async, resync it", channelType[chLoop], 0, 0);
651 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
652 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
653 }
654 }
655
656 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
657 if(channelCtrlBlk->hitLowResource)
658 {
659 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
660 "%11s : Still Low Resource, kick DXE TX and restart timer",
661 channelType[channelCtrlBlk->channelType], 0, 0);
662 /* Still Low Resource, Kick DXE again and start timer again */
663 wpalTimerStart(&channelCtrlBlk->healthMonitorTimer,
664 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
665 }
666 else
667 {
668 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
669 "%11s : Out from Low resource condition, do nothing",
670 channelType[channelCtrlBlk->channelType], 0, 0);
671 /* Recovered from low resource condition
672 * Not need to do anything */
673 }
674
675 return;
676}
677
678/*==========================================================================
679 @ Function Name
680 dxeTXHealthMonitor
681
682 @ Description
683 Monitoring TX channel healthy stataus
684 If detect any problem, try to recover
685
686 @ Parameters
687 healthMonitorMsg MSG pointer.
688 will have low resource TX channel context
689
690 @ Return
691 NONE
692
693===========================================================================*/
694void dxeTXHealthMonitor
695(
696 wpt_msg *healthMonitorMsg
697)
698{
699 WLANDXE_ChannelCBType *channelCtrlBlk;
700 WLANDXE_ChannelCBType *testCHCtrlBlk;
701 wpt_uint32 regValue;
702 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
703 wpt_uint32 hwWakeLoop, chLoop;
704 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
705
706 if(NULL == healthMonitorMsg)
707 {
708 return;
709 }
710
711 /* First of all kick TX channel
712 * This will fix if there is any problem with SMSM state */
713 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
714 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Chang5edb2d32013-04-03 13:32:58 -0700715 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700716
717 /* Wait till RIVA up */
718 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
719 {
720 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
721 if(0 != regValue)
722 {
723 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
724 "num free BD/PDU %d, loop Count %d",
725 regValue, hwWakeLoop, 0);
726 break;
727 }
728 }
729
730 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
731 "Scheduled TX, num free BD/PDU %d, loop Count %d",
732 regValue, hwWakeLoop, 0);
733
734 for(chLoop = 0; chLoop < WDTS_CHANNEL_RX_LOW_PRI; chLoop++)
735 {
736 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
737 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
738 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
739 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
740 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
741
742 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
743 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
744 channelType[chLoop],
745 chControlReg, chStatusReg, chDescReg, chLDescReg,
746 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
747 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
748 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
749 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
750
751 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
752 (chLDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
753 {
754 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
755 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
756 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
757 channelType[chLoop],
758 chControlReg, chStatusReg, chDescReg, chLDescReg,
759 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
760 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
761 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
762 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
763 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
764 "%11s : TX CH EN Descriptor Async, resync it", channelType[chLoop], 0, 0);
765 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
766 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
767 }
768 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
769 (chDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
770 {
771 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
772 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
773 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
774 channelType[chLoop],
775 chControlReg, chStatusReg, chDescReg, chLDescReg,
776 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
777 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
778 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
779 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
780 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
781 "%11s : TX CH DIS Descriptor Async, resync it", channelType[chLoop], 0, 0);
782 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
783 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
784 }
785 }
786
787 /* TX channel test done, test RX channels */
788 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
789 channelCtrlBlk->healthMonitorMsg->callback = dxeRXHealthMonitor;
790 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
791 channelCtrlBlk->healthMonitorMsg);
792 if (eWLAN_PAL_STATUS_SUCCESS != status)
793 {
794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
795 "TX Low resource Kick DXE MSG Serialize fail",
796 status, 0, 0);
797 }
798
799 return;
800}
801
802/*==========================================================================
803 @ Function Name
804 dxeHealthMonitorTimeout
805
806 @ Description
807 Health Monitor timer started when TX channel low resource condition
808 And if reciovered from low resource condition, timer would not fired
809 Timer fired means during certain time, TX CH could not be recovered
810
811 @ Parameters
812 channelCtxt Low resource condition happen Channel context
813
814 @ Return
815 NONE
816
817===========================================================================*/
818void dxeHealthMonitorTimeout
819(
820 void *channelCtxt
821)
822{
823 WLANDXE_ChannelCBType *channelCtrlBlk;
824 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
825
826 if(NULL == channelCtxt)
827 {
828 return;
829 }
830
831 /* Timeout Fired, DXE TX should kick on TX thread
832 * Serailize to TX Thread */
833 channelCtrlBlk = (WLANDXE_ChannelCBType *)channelCtxt;
834 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
835 "%11s : Health Monitor timer expired",
836 channelType[channelCtrlBlk->channelType], 0, 0);
837
838 channelCtrlBlk->healthMonitorMsg->callback = dxeTXHealthMonitor;
839 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
840 channelCtrlBlk->healthMonitorMsg);
841 if (eWLAN_PAL_STATUS_SUCCESS != status)
842 {
843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
844 "TX Low resource Kick DXE MSG Serialize fail",
845 status, 0, 0);
846 }
847
848 return;
849}
850
851/*==========================================================================
852 @ Function Name
Jeff Johnson295189b2012-06-20 16:38:30 -0700853 dxeCtrlBlkAlloc
854
855 @ Description
856 Allocate DXE Control block
857 DXE control block will used by Host DXE driver only, internal structure
858 Will make ring linked list
859
860 @ Parameters
861 WLANDXE_CtrlBlkType *dxeCtrlBlk,
862 DXE host driver main control block
863 WLANDXE_ChannelCBType *channelEntry
864 Channel specific control block
865
866 @ Return
867 wpt_status
868
869===========================================================================*/
870static wpt_status dxeCtrlBlkAlloc
871(
872 WLANDXE_CtrlBlkType *dxeCtrlBlk,
873 WLANDXE_ChannelCBType *channelEntry
874)
875{
876 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
877 unsigned int idx, fIdx;
878 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
879 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
880 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
881 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
882
883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700884 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700885
886 /* Sanity check */
887 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
888 {
889 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
890 "dxeCtrlBlkAlloc Channel Entry is not valid");
891 return eWLAN_PAL_STATUS_E_INVAL;
892 }
893
894 /* Allocate pre asigned number of control blocks */
895 for(idx = 0; idx < channelEntry->numDesc; idx++)
896 {
897 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
898 if(NULL == currentCtrlBlk)
899 {
900 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
901 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
902 channelEntry->channelType);
903 freeCtrlBlk = channelEntry->headCtrlBlk;
904 for(fIdx = 0; fIdx < idx; fIdx++)
905 {
906 if(NULL == freeCtrlBlk)
907 {
908 break;
909 }
910
911 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
912 wpalMemoryFree((void *)freeCtrlBlk);
913 freeCtrlBlk = nextCtrlBlk;
914 }
915 return eWLAN_PAL_STATUS_E_FAULT;
916 }
917
918 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
919 /* Initialize common elements first */
920 currentCtrlBlk->xfrFrame = NULL;
921 currentCtrlBlk->linkedDesc = NULL;
922 currentCtrlBlk->linkedDescPhyAddr = 0;
923 currentCtrlBlk->ctrlBlkOrder = idx;
924
925 /* This is the first control block allocated
926 * Next Control block is not allocated yet
927 * head and tail must be first control block */
928 if(0 == idx)
929 {
930 currentCtrlBlk->nextCtrlBlk = NULL;
931 channelEntry->headCtrlBlk = currentCtrlBlk;
932 channelEntry->tailCtrlBlk = currentCtrlBlk;
933 }
934 /* This is not first, not last control block
935 * previous control block may has next linked block */
936 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
937 {
938 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
939 }
940 /* This is last control blocl
941 * next control block for the last control block is head, first control block
942 * then whole linked list made RING */
943 else if((channelEntry->numDesc - 1) == idx)
944 {
945 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
946 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
947 }
948 else
949 {
950 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
951 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
952 channelEntry->channelType);
953 wpalMemoryFree(currentCtrlBlk);
954 return eWLAN_PAL_STATUS_E_FAULT;
955 }
956
957 prevCtrlBlk = currentCtrlBlk;
958 channelEntry->numFreeDesc++;
959 }
960
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 return status;
963}
964
965/*==========================================================================
966 @ Function Name
967 dxeDescLinkAlloc
968
969 @ Description
970 Allocate DXE descriptor
971 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
972 Will make RING linked list
973 Will be linked with Descriptor control block one by one
974
975 @ Parameters
976 WLANDXE_CtrlBlkType *dxeCtrlBlk,
977 DXE host driver main control block
978 WLANDXE_ChannelCBType *channelEntry
979 Channel specific control block
980 @ Return
981 wpt_status
982
983===========================================================================*/
984static wpt_status dxeDescAllocAndLink
985(
986 WLANDXE_CtrlBlkType *dxeCtrlBlk,
987 WLANDXE_ChannelCBType *channelEntry
988)
989{
990 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
991 WLANDXE_DescType *currentDesc = NULL;
992 WLANDXE_DescType *prevDesc = NULL;
993 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
994 unsigned int idx;
995 void *physAddress = NULL;
996#ifdef WLANDXE_TEST_CHANNEL_ENABLE
997 WLANDXE_ChannelCBType *testTXChannelCB = &dxeCtrlBlk->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
998 WLANDXE_DescCtrlBlkType *currDescCtrlBlk = testTXChannelCB->headCtrlBlk;
999#endif /* WLANDXE_TEST_CHANNEL_ENABLE*/
1000
1001 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001002 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001003
1004 /* Sanity Check */
1005 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1006 {
1007 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1008 "dxeDescLinkAlloc Channel Entry is not valid");
1009 return eWLAN_PAL_STATUS_E_INVAL;
1010 }
1011
1012 currentCtrlBlk = channelEntry->headCtrlBlk;
1013
1014#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1015 /* allocate all DXE descriptors for this channel in one chunk */
1016 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
1017 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
1018 &physAddress);
1019 if(NULL == channelEntry->descriptorAllocation)
1020 {
1021 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1022 "dxeDescLinkAlloc Descriptor Alloc Fail");
1023 return eWLAN_PAL_STATUS_E_RESOURCES;
1024 }
1025 currentDesc = channelEntry->descriptorAllocation;
1026#endif
1027
1028 /* Allocate pre asigned number of descriptor */
1029 for(idx = 0; idx < channelEntry->numDesc; idx++)
1030 {
1031#ifndef FEATURE_R33D
1032#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1033 // descriptors were allocated in a chunk -- use the current one
1034 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1035 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1036 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1037#else
1038 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1039 {
1040 // allocate a descriptor
1041 currentDesc = (WLANDXE_DescType *)wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType),
1042 &physAddress);
1043 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1044 }
1045 else
1046 {
1047 currentDesc = currDescCtrlBlk->linkedDesc;
1048 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
1049 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1050 }
1051#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1052#else
1053#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1054 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
1055 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1056 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1057 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1058#else
1059 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1060 {
1061 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
1062 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1063 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1064 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
1065 }
1066 else
1067 {
1068 currentDesc = currDescCtrlBlk->linkedDesc;
1069 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
1070 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1071 }
1072#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1073#endif /* FEATURE_R33D */
1074 if(NULL == currentDesc)
1075 {
1076 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1077 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
1078 channelEntry->channelType);
1079 return eWLAN_PAL_STATUS_E_FAULT;
1080 }
1081
1082 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1083 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1084 {
1085 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1086 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1087 }
1088 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1089 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1090 {
1091 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1092 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1093 }
1094 else
1095 {
1096 /* Just in case. H2H Test RX channel, do nothing
1097 * By Definition this must not happen */
1098 }
1099
1100 currentCtrlBlk->linkedDesc = currentDesc;
1101 currentCtrlBlk->linkedDescPhyAddr = (unsigned int)physAddress;
1102 /* First descriptor, next none
1103 * descriptor bottom location is first descriptor address */
1104 if(0 == idx)
1105 {
1106 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
1107 channelEntry->DescBottomLoc = currentDesc;
1108 channelEntry->descBottomLocPhyAddr = (unsigned int)physAddress;
1109 }
1110 /* Not first, not last descriptor
1111 * may make link for previous descriptor with current descriptor
1112 * ENDIAN SWAP needed ????? */
1113 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
1114 {
1115 prevDesc->dxedesc.dxe_short_desc.phyNextL =
1116 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
1117 }
1118 /* Last descriptor
1119 * make a ring by asign next pointer as first descriptor
1120 * ENDIAN SWAP NEEDED ??? */
1121 else if((channelEntry->numDesc - 1) == idx)
1122 {
1123 prevDesc->dxedesc.dxe_short_desc.phyNextL =
1124 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
1125 currentDesc->dxedesc.dxe_short_desc.phyNextL =
1126 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)channelEntry->headCtrlBlk->linkedDescPhyAddr);
1127 }
1128
1129 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
1130 * Pre allocated and physical address must be assigned into
1131 * Corresponding DXE Descriptor */
1132#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1133 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1134 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1135 (WDTS_CHANNEL_H2H_TEST_RX == channelEntry->channelType))
1136#else
1137 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1138 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1139#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1140 {
1141 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
1142 channelEntry,
1143 currentCtrlBlk);
1144 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1145 {
1146 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1147 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1148 channelEntry->channelType);
1149 return status;
1150 }
1151 --channelEntry->numFreeDesc;
1152 }
1153
1154 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1155 prevDesc = currentDesc;
1156
1157#ifndef FEATURE_R33D
1158#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1159 // advance to the next pre-allocated descriptor in the chunk
1160 currentDesc++;
1161 physAddress = ((wpt_int8 *)physAddress) + sizeof(WLANDXE_DescType);
1162#endif
1163#endif
1164 }
1165
1166 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001167 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001168 return status;
1169}
1170
1171/*==========================================================================
1172 @ Function Name
1173
1174 @ Description
1175
1176 @ Parameters
1177
1178 @ Return
1179 wpt_status
1180
1181===========================================================================*/
1182static wpt_status dxeSetInterruptPath
1183(
1184 WLANDXE_CtrlBlkType *dxeCtrlBlk
1185)
1186{
1187 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1188 wpt_uint32 interruptPath = 0;
1189 wpt_uint32 idx;
1190 WLANDXE_ChannelCBType *channelEntry = NULL;
1191
1192 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001193 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001194
1195 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
1196 {
1197 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
1198#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1199 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1200 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) ||
1201 (WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType))
1202#else
1203 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1204 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1205#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1206 {
1207 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1208 }
1209 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1210 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1211 {
1212 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1213 }
1214 else
1215 {
1216 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1217 "H2H TEST RX???? %d", channelEntry->channelType);
1218 }
1219 }
1220 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1221 "Interrupt Path Must be 0x%x", interruptPath);
1222 dxeCtrlBlk->interruptPath = interruptPath;
1223 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1224
1225 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001226 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 return status;
1228}
1229
1230/*==========================================================================
1231 @ Function Name
1232 dxeEngineCoreStart
1233
1234 @ Description
1235 Trigger to start RIVA DXE Hardware
1236
1237 @ Parameters
1238 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1239 DXE host driver main control block
1240
1241 @ Return
1242 wpt_status
1243
1244===========================================================================*/
1245static wpt_status dxeEngineCoreStart
1246(
1247 WLANDXE_CtrlBlkType *dxeCtrlBlk
1248)
1249{
1250 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1251 wpt_uint32 registerData = 0;
1252
1253 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001254 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001255
1256 /* START This core init is not needed for the integrated system */
1257 /* Reset First */
1258 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1259 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1260 registerData);
1261
1262 registerData = WLANDXE_DMA_CSR_EN_MASK;
1263 registerData |= WLANDXE_DMA_CSR_ECTR_EN_MASK;
1264 registerData |= WLANDXE_DMA_CSR_TSTMP_EN_MASK;
1265 registerData |= WLANDXE_DMA_CSR_H2H_SYNC_EN_MASK;
1266
1267 registerData = 0x00005c89;
1268 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1269 registerData);
1270
1271 /* Is This needed?
1272 * Not sure, revisit with integrated system */
1273 /* END This core init is not needed for the integrated system */
1274
1275 dxeSetInterruptPath(dxeCtrlBlk);
1276 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001277 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001278 return status;
1279}
1280
1281/*==========================================================================
1282 @ Function Name
1283 dxeChannelInitProgram
1284
1285 @ Description
1286 Program RIVA DXE engine register with initial value
1287 What must be programmed
1288 - Source Address (SADRL, chDXESadrlRegAddr)
1289 - Destination address (DADRL, chDXEDadrlRegAddr)
1290 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1291 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1292
1293 Not need to program now
1294 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1295 TX : Have to program to trigger send out frame
1296 RX : programmed by DXE engine
1297
1298 @ Parameters
1299 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1300 DXE host driver main control block
1301 WLANDXE_ChannelCBType *channelEntry
1302 Channel specific control block
1303 @ Return
1304 wpt_status
1305
1306===========================================================================*/
1307static wpt_status dxeChannelInitProgram
1308(
1309 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1310 WLANDXE_ChannelCBType *channelEntry
1311)
1312{
1313 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1314 wpt_uint32 idx;
1315 WLANDXE_DescType *currentDesc = NULL;
1316 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1317
1318 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001319 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001320
1321 /* Sanity Check */
1322 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1323 {
1324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1325 "dxeChannelInitProgram Channel Entry is not valid");
1326 return eWLAN_PAL_STATUS_E_INVAL;
1327 }
1328
1329 /* Program Source address and destination adderss */
1330 if(!channelEntry->channelConfig.useShortDescFmt)
1331 {
1332 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1333 "dxeChannelInitProgram Long Descriptor not support yet");
1334 return eWLAN_PAL_STATUS_E_FAILURE;
1335 }
1336
1337 /* Common register area */
1338 /* Next linked list Descriptor pointer */
1339 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1340 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1341 if(eWLAN_PAL_STATUS_SUCCESS != status)
1342 {
1343 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1344 "dxeChannelInitProgram Write DESC Address register fail");
1345 return status;
1346 }
1347
1348 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1349 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1350 {
1351 /* Program default registers */
1352 /* TX DMA channel, DMA destination address is work Q */
1353 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1354 channelEntry->channelConfig.refWQ);
1355 if(eWLAN_PAL_STATUS_SUCCESS != status)
1356 {
1357 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1358 "dxeChannelInitProgram Write TX DAddress register fail");
1359 return status;
1360 }
1361 }
1362 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1363 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1364 {
1365 /* Initialize Descriptor control Word First */
1366 currentCtrlBlk = channelEntry->headCtrlBlk;
1367 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1368 {
1369 currentDesc = currentCtrlBlk->linkedDesc;
1370 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1371 }
1372
1373 /* RX DMA channel, DMA source address is work Q */
1374 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1375 channelEntry->channelConfig.refWQ);
1376 if(eWLAN_PAL_STATUS_SUCCESS != status)
1377 {
1378 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1379 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1380 return status;
1381 }
1382
1383 /* RX DMA channel, Program pre allocated destination Address */
1384 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1385 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1386 if(eWLAN_PAL_STATUS_SUCCESS != status)
1387 {
1388 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1389 "dxeChannelInitProgram Write RX DAddress register fail");
1390 return status;
1391 }
1392
1393 /* RX Channels, default Control registers MUST BE ENABLED */
1394 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1395 channelEntry->extraConfig.chan_mask);
1396 if(eWLAN_PAL_STATUS_SUCCESS != status)
1397 {
1398 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1399 "dxeChannelInitProgram Write RX Control register fail");
1400 return status;
1401 }
1402 }
1403 else
1404 {
1405 /* H2H test channel, not use work Q */
1406 /* Program pre allocated destination Address */
1407 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1408 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1409 if(eWLAN_PAL_STATUS_SUCCESS != status)
1410 {
1411 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1412 "dxeChannelInitProgram Write RX DAddress register fail");
1413 return status;
1414 }
1415 }
1416
1417 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001418 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001419 return status;
1420}
1421
1422
1423/*==========================================================================
1424 @ Function Name
1425 dxeChannelStart
1426
1427 @ Description
1428 Start Specific Channel
1429
1430 @ Parameters
1431 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1432 DXE host driver main control block
1433 WLANDXE_ChannelCBType *channelEntry
1434 Channel specific control block
1435
1436 @ Return
1437 wpt_status
1438
1439===========================================================================*/
1440static wpt_status dxeChannelStart
1441(
1442 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1443 WLANDXE_ChannelCBType *channelEntry
1444)
1445{
1446 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1447 wpt_uint32 regValue = 0;
1448 wpt_uint32 intMaskVal = 0;
1449
1450 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001451 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001452
1453 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1454 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1455
1456 /* Enable individual channel
1457 * not to break current channel setup, first read register */
1458 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1459 &regValue);
1460 if(eWLAN_PAL_STATUS_SUCCESS != status)
1461 {
1462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1463 "dxeChannelStart Read Channel Enable register fail");
1464 return status;
1465 }
1466
1467 /* Enable Channel specific Interrupt */
1468 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1469 &intMaskVal);
1470 if(eWLAN_PAL_STATUS_SUCCESS != status)
1471 {
1472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1473 "dxeChannelStart Read INT_MASK register fail");
1474 return status;
1475 }
1476 intMaskVal |= channelEntry->extraConfig.intMask;
1477 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1478 intMaskVal);
1479 if(eWLAN_PAL_STATUS_SUCCESS != status)
1480 {
1481 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1482 "dxeChannelStart Write INT_MASK register fail");
1483 return status;
1484 }
1485
1486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001487 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001488 return status;
1489}
1490
1491/*==========================================================================
1492 @ Function Name
1493 dxeChannelStop
1494
1495 @ Description
1496 Stop Specific Channel
1497
1498 @ Parameters
1499 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1500 DXE host driver main control block
1501 WLANDXE_ChannelCBType *channelEntry
1502 Channel specific control block
1503
1504 @ Return
1505 wpt_status
1506
1507===========================================================================*/
1508static wpt_status dxeChannelStop
1509(
1510 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1511 WLANDXE_ChannelCBType *channelEntry
1512)
1513{
1514 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1515 wpt_uint32 intMaskVal = 0;
1516
1517 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001518 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001519
1520 /* Sanity */
1521 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1522 {
1523 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1524 "dxeChannelStop Invalid arg input");
1525 return eWLAN_PAL_STATUS_E_INVAL;
1526 }
1527
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001528 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1529 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1530 {
1531 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1532 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001533 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001535 /* Maskout interrupt */
1536 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1537 &intMaskVal);
1538 if(eWLAN_PAL_STATUS_SUCCESS != status)
1539 {
1540 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1541 "dxeChannelStop Read INT_MASK register fail");
1542 return status;
1543 }
1544 intMaskVal ^= channelEntry->extraConfig.intMask;
1545 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1546 intMaskVal);
1547 if(eWLAN_PAL_STATUS_SUCCESS != status)
1548 {
1549 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1550 "dxeChannelStop Write INT_MASK register fail");
1551 return status;
1552 }
1553
1554 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1555
1556 /* Stop Channel ??? */
1557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001558 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 return status;
1560}
1561
1562/*==========================================================================
1563 @ Function Name
1564 dxeChannelClose
1565
1566 @ Description
1567 Close Specific Channel
1568 Free pre allocated RX frame buffer if RX channel
1569 Free DXE descriptor for each channel
1570 Free Descriptor control block for each channel
1571
1572 @ Parameters
1573 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1574 DXE host driver main control block
1575 WLANDXE_ChannelCBType *channelEntry
1576 Channel specific control block
1577
1578 @ Return
1579 wpt_status
1580
1581===========================================================================*/
1582static wpt_status dxeChannelClose
1583(
1584 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1585 WLANDXE_ChannelCBType *channelEntry
1586)
1587{
1588 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1589 wpt_uint32 idx;
1590 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1591 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1592 WLANDXE_DescType *currentDescriptor = NULL;
1593 WLANDXE_DescType *nextDescriptor = NULL;
1594
1595 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001596 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001597
1598 /* Sanity */
1599 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1600 {
1601 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1602 "dxeChannelStop Invalid arg input");
1603 return eWLAN_PAL_STATUS_E_INVAL;
1604 }
1605
1606 currentCtrlBlk = channelEntry->headCtrlBlk;
1607 if(NULL != currentCtrlBlk)
1608 {
1609 currentDescriptor = currentCtrlBlk->linkedDesc;
1610 for(idx = 0; idx < channelEntry->numDesc; idx++)
1611 {
1612 if (idx + 1 != channelEntry->numDesc)
1613 {
1614 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1615 nextDescriptor = nextCtrlBlk->linkedDesc;
1616 }
1617 else
1618 {
1619 nextCtrlBlk = NULL;
1620 nextDescriptor = NULL;
1621 }
1622 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1623 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1624 {
1625 if (NULL != currentCtrlBlk->xfrFrame)
1626 {
1627 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1628 wpalPacketFree(currentCtrlBlk->xfrFrame);
1629 }
1630 }
1631 /*
1632 * It is the responsibility of DXE to walk through the
1633 * descriptor chain and unlock any pending packets (if
1634 * locked).
1635 */
1636 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1637 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1638 {
1639 if((NULL != currentCtrlBlk->xfrFrame) &&
1640 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1641 {
1642 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1643 wpalPacketFree(currentCtrlBlk->xfrFrame);
1644 }
1645 }
1646#if (defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1647 // descriptors allocated individually so free them individually
1648 wpalDmaMemoryFree(currentDescriptor);
1649#endif
1650 wpalMemoryFree(currentCtrlBlk);
1651
1652 currentCtrlBlk = nextCtrlBlk;
1653 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001654 if(NULL == currentCtrlBlk)
1655 {
1656 /* Already reach last of the control block
1657 * Not need to process anymore, break */
1658 break;
1659 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 }
1661 }
1662
1663#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1664 // descriptors were allocated as a single chunk so free the chunk
1665 if(NULL != channelEntry->descriptorAllocation)
1666 {
1667 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1668 }
1669#endif
1670
1671 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001672 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 return status;
1674}
1675
1676/*==========================================================================
1677 @ Function Name
1678 dxeChannelCleanInt
1679
1680 @ Description
1681 Clean up interrupt from RIVA HW
1682 After Host finish to handle interrupt, interrupt signal must be cleaned up
1683 Otherwise next interrupt will not be generated
1684
1685 @ Parameters
1686 WLANDXE_ChannelCBType *channelEntry
1687 Channel specific control block
1688 wpt_uint32 *chStat
1689 Channel Status register value
1690
1691 @ Return
1692 wpt_status
1693
1694===========================================================================*/
1695static wpt_status dxeChannelCleanInt
1696(
1697 WLANDXE_ChannelCBType *channelEntry,
1698 wpt_uint32 *chStat
1699)
1700{
1701 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1702
1703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001704 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001705
1706 /* Read Channel Status Register to know why INT Happen */
1707 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1708 chStat);
1709 if(eWLAN_PAL_STATUS_SUCCESS != status)
1710 {
1711 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1712 "dxeChannelCleanInt Read CH STAT register fail");
1713 return eWLAN_PAL_STATUS_E_FAULT;
1714 }
1715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1716 "%s Channel INT Clean, Status 0x%x",
1717 channelType[channelEntry->channelType], *chStat);
1718
1719 /* Clean up all the INT within this channel */
1720 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1721 (1 << channelEntry->assignedDMAChannel));
1722 if(eWLAN_PAL_STATUS_SUCCESS != status)
1723 {
1724 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1725 "dxeChannelCleanInt Write CH Clean register fail");
1726 return eWLAN_PAL_STATUS_E_FAULT;
1727 }
1728
Jeff Johnsone7245742012-09-05 17:12:55 -07001729 /* Clean up Error INT Bit */
1730 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1731 {
1732 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1733 (1 << channelEntry->assignedDMAChannel));
1734 if(eWLAN_PAL_STATUS_SUCCESS != status)
1735 {
1736 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1737 "dxeChannelCleanInt Read CH STAT register fail");
1738 return eWLAN_PAL_STATUS_E_FAULT;
1739 }
1740 }
1741
1742 /* Clean up DONE INT Bit */
1743 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1744 {
1745 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1746 (1 << channelEntry->assignedDMAChannel));
1747 if(eWLAN_PAL_STATUS_SUCCESS != status)
1748 {
1749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1750 "dxeChannelCleanInt Read CH STAT register fail");
1751 return eWLAN_PAL_STATUS_E_FAULT;
1752 }
1753 }
1754
1755 /* Clean up ED INT Bit */
1756 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1757 {
1758 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1759 (1 << channelEntry->assignedDMAChannel));
1760 if(eWLAN_PAL_STATUS_SUCCESS != status)
1761 {
1762 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1763 "dxeChannelCleanInt Read CH STAT register fail");
1764 return eWLAN_PAL_STATUS_E_FAULT;
1765 }
1766 }
1767
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001769 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001770 return status;
1771}
1772
1773/*==========================================================================
1774 @ Function Name
1775 dxeRXPacketAvailableCB
1776
1777 @ Description
1778 If RX frame handler encounts RX buffer pool empty condition,
1779 DXE RX handle loop will be blocked till get available RX buffer pool.
1780 When new RX buffer pool available, Packet available CB function will
1781 be called.
1782
1783 @ Parameters
1784 wpt_packet *freePacket
1785 Newly allocated RX buffer
1786 v_VOID_t *usrData
1787 DXE context
1788
1789 @ Return
1790 NONE
1791
1792===========================================================================*/
1793void dxeRXPacketAvailableCB
1794(
1795 wpt_packet *freePacket,
1796 v_VOID_t *usrData
1797)
1798{
1799 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1800 wpt_status status;
1801
1802 /* Simple Sanity */
1803 if((NULL == freePacket) || (NULL == usrData))
1804 {
1805 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1806 "Get Free RX Buffer fail, Critical Error");
1807 HDXE_ASSERT(0);
1808 return;
1809 }
1810
1811 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1812
1813 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1814 {
1815 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1816 "DXE Context data corrupted, Critical Error");
1817 HDXE_ASSERT(0);
1818 return;
1819 }
1820
1821 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1822 "DXE RX packet available, post MSG to RX Thread");
1823
1824 dxeCtxt->freeRXPacket = freePacket;
1825
1826 /* Serialize RX Packet Available message upon RX thread */
1827 HDXE_ASSERT(NULL != dxeCtxt->rxPktAvailMsg);
1828
1829 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1830 dxeCtxt->rxPktAvailMsg);
1831 if(eWLAN_PAL_STATUS_SUCCESS != status)
1832 {
1833 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
1834 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1835 "dxeRXPacketAvailableCB serialize fail");
1836 }
1837
1838 return;
1839}
1840
1841/*==========================================================================
1842 @ Function Name
1843 dxeRXFrameSingleBufferAlloc
1844
1845 @ Description
1846 Allocate Platform packet buffer to prepare RX frame
1847 RX frame memory space must be pre allocted and must be asigned to
1848 descriptor
1849 then whenever DMA engine want to tranfer frame from BMU,
1850 buffer must be ready
1851
1852 @ Parameters
1853 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1854 DXE host driver main control block
1855 WLANDXE_ChannelCBType *channelEntry
1856 Channel specific control block
1857 WLANDXE_DescCtrlBlkType currentCtrlBlock
1858 current control block which have to be asigned
1859 frame buffer
1860
1861 @ Return
1862 wpt_status
1863
1864===========================================================================*/
1865static wpt_status dxeRXFrameSingleBufferAlloc
1866(
1867 WLANDXE_CtrlBlkType *dxeCtxt,
1868 WLANDXE_ChannelCBType *channelEntry,
1869 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1870)
1871{
1872 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1873 wpt_packet *currentPalPacketBuffer = NULL;
1874 WLANDXE_DescType *currentDesc = NULL;
1875#ifdef FEATURE_R33D
1876 wpt_uint32 virtualAddressPCIe;
1877 wpt_uint32 physicalAddressPCIe;
1878#else
1879 wpt_iterator iterator;
1880 wpt_uint32 allocatedSize = 0;
1881 void *physAddress = NULL;
1882#endif /* FEATURE_R33D */
1883
Jeff Johnson295189b2012-06-20 16:38:30 -07001884
1885 currentDesc = currentCtrlBlock->linkedDesc;
1886
1887 /* First check if a packet pointer has already been provided by a previously
1888 invoked Rx packet available callback. If so use that packet. */
1889 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1890 {
1891 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1892 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1893 dxeCtxt->freeRXPacket = NULL;
1894 }
1895 else if(!dxeCtxt->rxPalPacketUnavailable)
1896 {
1897 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1898 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
1899 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1900 dxeRXPacketAvailableCB,
1901 (void *)dxeCtxt);
1902
1903 if(NULL == currentPalPacketBuffer)
1904 {
1905 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
1906 }
1907 }
1908
1909 if(NULL == currentPalPacketBuffer)
1910 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001911 return eWLAN_PAL_STATUS_E_RESOURCES;
1912 }
1913
1914 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1915 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1916 currentPalPacketBuffer->pBD = NULL;
1917 currentPalPacketBuffer->pBDPhys = NULL;
1918 currentPalPacketBuffer->BDLength = 0;
1919#ifdef FEATURE_R33D
1920 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
1921 &physicalAddressPCIe,
1922 &virtualAddressPCIe);
1923 HDXE_ASSERT(0 != physicalAddressPCIe);
1924 HDXE_ASSERT(0 != virtualAddressPCIe);
1925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
1926 "RX Shadow Memory Va 0x%x, Pa 0x%x",
1927 virtualAddressPCIe, physicalAddressPCIe);
1928 if(eWLAN_PAL_STATUS_SUCCESS != status)
1929 {
1930 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1931 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
1932 return status;
1933 }
1934 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
1935 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
1936 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1937#else
1938 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
1939 if(eWLAN_PAL_STATUS_SUCCESS != status)
1940 {
1941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1942 "dxeRXFrameBufferAlloc unable to lock packet");
1943 return status;
1944 }
1945
1946 /* Init iterator to get physical os buffer address */
1947 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1948 if(eWLAN_PAL_STATUS_SUCCESS != status)
1949 {
1950 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1951 "dxeRXFrameBufferAlloc iterator init fail");
1952 return status;
1953 }
1954 status = wpalIteratorNext(&iterator,
1955 currentPalPacketBuffer,
1956 &physAddress,
1957 &allocatedSize);
1958 if(eWLAN_PAL_STATUS_SUCCESS != status)
1959 {
1960 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1961 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1962 return status;
1963 }
1964 currentPalPacketBuffer->pBDPhys = physAddress;
1965#endif /* FEATURE_R33D */
1966
1967 /* DXE descriptor must have SWAPPED addres in it's structure
1968 * !!! SWAPPED !!! */
1969 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
1970 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)currentPalPacketBuffer->pBDPhys);
1971
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 return status;
1973}
1974
1975/*==========================================================================
1976 @ Function Name
1977 dxeRXFrameRefillRing
1978
1979 @ Description
1980 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1981
1982 @ Parameters
1983 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1984 DXE host driver main control block
1985 WLANDXE_ChannelCBType *channelEntry
1986 Channel specific control block
1987
1988 @ Return
1989 wpt_status
1990
1991===========================================================================*/
1992static wpt_status dxeRXFrameRefillRing
1993(
1994 WLANDXE_CtrlBlkType *dxeCtxt,
1995 WLANDXE_ChannelCBType *channelEntry
1996)
1997{
1998 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1999 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2000 WLANDXE_DescType *currentDesc = NULL;
2001
2002 while(channelEntry->numFreeDesc > 0)
2003 {
2004 /* Current Control block is free
2005 * and associated frame buffer is not linked with control block anymore
2006 * allocate new frame buffer for current control block */
2007 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2008 channelEntry,
2009 currentCtrlBlk);
2010
2011 if(eWLAN_PAL_STATUS_SUCCESS != status)
2012 {
2013 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2014 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2015 break;
2016 }
2017
2018 currentDesc = currentCtrlBlk->linkedDesc;
2019 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2020
2021 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2022 that any posted writes are reflected in memory before DXE looks at
2023 the descriptor. */
2024 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2025 {
2026 //HDXE_ASSERT(0);
2027 }
2028
2029 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07002030 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 {
2032 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2033 1 << channelEntry->assignedDMAChannel);
2034 }
2035 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2036 --channelEntry->numFreeDesc;
2037 }
2038
2039 channelEntry->tailCtrlBlk = currentCtrlBlk;
2040
2041 return status;
2042}
2043
2044/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002045 @ Function Name
2046 dxeRXFrameRouteUpperLayer
2047
2048 @ Description
2049 Test DXE descriptors and if any RX frame pending within RING,
2050 Route to upper layer
2051
2052 @ Parameters
2053 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2054 DXE host driver main control block
2055 WLANDXE_ChannelCBType *channelEntry
2056 Channel specific control block
2057 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002058 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002059 0 No frame pulled from RX RING
2060 int number of RX frames pulled from RX ring
2061
2062===========================================================================*/
2063static wpt_int32 dxeRXFrameRouteUpperLayer
2064(
2065 WLANDXE_CtrlBlkType *dxeCtxt,
2066 WLANDXE_ChannelCBType *channelEntry
2067)
2068{
2069 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2070 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2071 WLANDXE_DescType *currentDesc = NULL;
2072 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002073 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002074
2075 currentCtrlBlk = channelEntry->headCtrlBlk;
2076 currentDesc = currentCtrlBlk->linkedDesc;
2077
2078 /* Descriptoe should be SWAPPED ???? */
2079 descCtrl = currentDesc->descCtrl.ctrl;
2080
2081 /* Get frames while VALID bit is not set (DMA complete) and a data
2082 * associated with it */
2083 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2084 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2085 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2086 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2087 {
2088 channelEntry->numTotalFrame++;
2089 channelEntry->numFreeDesc++;
2090#ifdef FEATURE_R33D
2091 /* Transfer Size should be */
2092 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2093 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
2094 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
2095 currentCtrlBlk->shadowBufferVa,
2096 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2097 if(eWLAN_PAL_STATUS_SUCCESS != status)
2098 {
2099 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2100 "dxeRXFrameReady Prepare RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002101 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002102 }
2103 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
2104 if(eWLAN_PAL_STATUS_SUCCESS != status)
2105 {
2106 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2107 "dxeRXFrameReady Free Shadow RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002108 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002109 }
2110
2111#else /* FEATURE_R33D */
2112 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
2113 if (eWLAN_PAL_STATUS_SUCCESS != status)
2114 {
2115 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2116 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002117 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002118 }
2119#endif /* FEATURE_R33D */
2120 /* This Descriptor is valid, so linked Control block is also valid
2121 * Linked Control block has pre allocated packet buffer
2122 * So, just let upper layer knows preallocated frame pointer will be OK */
2123 /* Reap Rx frames */
2124 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2125 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002126 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002127
2128 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Leo Changd6de1c22013-03-21 15:42:41 -07002129 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002130
2131 /* Test next contorl block
2132 * if valid, this control block also has new RX frame must be handled */
2133 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2134 currentDesc = currentCtrlBlk->linkedDesc;
2135 descCtrl = currentDesc->descCtrl.ctrl;
2136 }
2137
2138 /* Update head control block
2139 * current control block's valid bit was 0
2140 * next trial first control block must be current control block */
2141 channelEntry->headCtrlBlk = currentCtrlBlk;
2142
2143 /* Deliver all the reaped RX frames to upper layers */
2144 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002145 while(i < frameCount)
2146 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002147 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2148 i++;
2149 }
2150
2151 return frameCount;
2152}
2153
2154/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 @ Function Name
2156 dxeRXFrameReady
2157
2158 @ Description
2159 Pop frame from descriptor and route frame to upper transport layer
2160 Assign new platform packet buffer into used descriptor
2161 Actual frame pop and resource realloc
2162
2163 @ Parameters
2164 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2165 DXE host driver main control block
2166 WLANDXE_ChannelCBType *channelEntry
2167 Channel specific control block
2168
2169 @ Return
2170 wpt_status
2171
2172===========================================================================*/
2173static wpt_status dxeRXFrameReady
2174(
2175 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002176 WLANDXE_ChannelCBType *channelEntry,
2177 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002178)
2179{
2180 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2181 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2182 WLANDXE_DescType *currentDesc = NULL;
2183 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002184 wpt_int32 frameCount = 0;
2185
2186 wpt_uint32 descLoop;
2187 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002188
2189 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002190 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002191
2192 /* Sanity Check */
2193 if((NULL == dxeCtxt) || (NULL == channelEntry))
2194 {
2195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2196 "dxeRXFrameReady Channel Entry is not valid");
2197 return eWLAN_PAL_STATUS_E_INVAL;
2198 }
2199
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002201
Jeff Johnsone7245742012-09-05 17:12:55 -07002202 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002203 {
2204 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002205 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002206 return eWLAN_PAL_STATUS_E_INVAL;
2207 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002208
Leo Changd6de1c22013-03-21 15:42:41 -07002209 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002210 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2211 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2212 {
Leo Changd6de1c22013-03-21 15:42:41 -07002213 /* None of the frame handled and CH is not enabled
2214 * RX CH wrap around happen and No RX free frame
2215 * RX side should wait till new free frame available in the pool
2216 * Do not try reload driver at here*/
2217 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2218 {
Leo Changbbf86b72013-06-19 16:13:00 -07002219 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002220 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2221 channelType[channelEntry->channelType], chStat);
2222 channelEntry->numFragmentCurrentChain = 0;
2223 return eWLAN_PAL_STATUS_SUCCESS;
2224 }
2225
Jeff Johnsone7245742012-09-05 17:12:55 -07002226 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 currentDesc = currentCtrlBlk->linkedDesc;
2228 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002229
2230 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2231 {
2232 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2233 "RX ISR called but no frame handled PWS %d, channel %s",
2234 (int)dxeCtxt->hostPowerState,
2235 channelType[channelEntry->channelType]);
2236 }
2237
2238 /* Current interupt empty and previous interrupt also empty
2239 * detected successive empty interrupt
2240 * or first interrupt empty, this should not happen */
2241 if(0 == channelEntry->numFragmentCurrentChain)
2242 {
2243 dxeChannelMonitor("RX Ready", channelEntry);
2244 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2245 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt");
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07002246 dxeChannelAllDescDump(channelEntry, channelEntry->channelType);
Jeff Johnsone7245742012-09-05 17:12:55 -07002247
2248 /* Abnormal interrupt detected, try to find not validated descriptor */
2249 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2250 {
2251 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2252 {
Leo Chang416afe02013-07-01 13:58:13 -07002253 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002254 "Found Invalidated Descriptor %d", (int)descLoop);
2255 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2256 {
Leo Chang416afe02013-07-01 13:58:13 -07002257 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002258 "Packet locked, Resync Host and HW");
2259 channelEntry->headCtrlBlk = currentCtrlBlk;
2260 invalidatedFound = 1;
2261 break;
2262 }
2263 else
2264 {
Leo Chang416afe02013-07-01 13:58:13 -07002265 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002266 "Packet Not Locked, cannot transfer frame");
2267 }
2268 }
2269 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2270 currentDesc = currentCtrlBlk->linkedDesc;
2271 descCtrl = currentDesc->descCtrl.ctrl;
2272 }
2273
Jeff Johnson32d95a32012-09-10 13:15:23 -07002274 /* Invalidated descriptor found, and that is not head descriptor
2275 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2276 * Try re-sync here */
2277 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002278 {
2279 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2280 "Found New Sync location with HW, handle frames from there");
2281 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2282 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2283 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002284 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002285 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002286 /* Successive Empty interrupt
2287 * But this case, first descriptor also invalidated, then it means head descriptor
2288 * is linked with already handled RX frame, then could not unlock RX frame
2289 * This is just Out of RX buffer pool, not need to anything here */
2290 else if((invalidatedFound) && (0 == descLoop))
2291 {
2292 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2293 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2294 }
2295 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002296 else
2297 {
2298 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2299 "Could not found invalidated descriptor");
2300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2301 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2302 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2303 wpalWlanReload();
2304 }
2305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002306 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002307 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002309 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 return status;
2311}
2312
2313/*==========================================================================
2314 @ Function Name
2315 dxeNotifySmsm
2316
2317 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2318 buffer
2319
2320 @ Parameters
2321
2322 @ Return
2323 wpt_status
2324
2325===========================================================================*/
2326static wpt_status dxeNotifySmsm
2327(
2328 wpt_boolean kickDxe,
2329 wpt_boolean ringEmpty
2330)
2331{
2332 wpt_uint32 clrSt = 0;
2333 wpt_uint32 setSt = 0;
2334
2335 if(kickDxe)
2336 {
2337 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2338
2339 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2340 {
2341 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2342 tempDxeCtrlBlk->lastKickOffDxe = 1;
2343 }
2344 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2345 {
2346 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2347 tempDxeCtrlBlk->lastKickOffDxe = 0;
2348 }
2349 else
2350 {
2351 HDXE_ASSERT(0);
2352 }
2353 }
2354 else
2355 {
2356 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2357 }
2358
2359 if(ringEmpty)
2360 {
2361 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2362 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2363 }
2364 else
2365 {
2366 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2367 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2368 }
2369
2370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2371
2372 wpalNotifySmsm(clrSt, setSt);
2373
2374 return eWLAN_PAL_STATUS_SUCCESS;
2375}
2376
2377/*==========================================================================
2378 @ Function Name
2379 dxePsComplete
2380
2381 @ Description: Utility function to check the resv desc to deside if we can
2382 get into Power Save mode now
2383
2384 @ Parameters
2385
2386 @ Return
2387 None
2388
2389===========================================================================*/
2390static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2391{
2392 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2393 {
2394 return;
2395 }
2396
2397 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2398 //must have been consumed by RIVA, OK to get into BMPS
2399 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2400 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2401 {
2402 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2403 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2404 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2405 {
2406 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2407 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2408 }
2409 }
2410 else //still more pkts to be served by RIVA
2411 {
2412 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2413
2414 switch(dxeCtxt->rivaPowerState)
2415 {
2416 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2417 //NOP
2418 break;
2419 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2420 if(intr_based)
2421 {
2422 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2423 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2424 }
2425 break;
2426 default:
2427 //assert
2428 break;
2429 }
2430 }
2431}
2432
2433/*==========================================================================
2434 @ Function Name
2435 dxeRXEventHandler
2436
2437 @ Description
2438 Handle serailized RX frame ready event
2439 First disable interrupt then pick up frame from pre allocated buffer
2440 Since frame handle is doen, clear interrupt bit to ready next interrupt
2441 Finally re enable interrupt
2442
2443 @ Parameters
2444 wpt_msg *rxReadyMsg
2445 RX frame ready MSG pointer
2446 include DXE control context
2447
2448 @ Return
2449 NONE
2450
2451===========================================================================*/
2452void dxeRXEventHandler
2453(
2454 wpt_msg *rxReadyMsg
2455)
2456{
2457 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2458 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2459 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2460 wpt_uint32 intSrc = 0;
2461 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002462 wpt_uint32 chHighStat = 0;
2463 wpt_uint32 chLowStat = 0;
Leo Chang094ece82013-04-23 17:57:41 -07002464 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07002465
Jeff Johnsone7245742012-09-05 17:12:55 -07002466 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002467
Jeff Johnsone7245742012-09-05 17:12:55 -07002468 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002469 {
2470 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002471 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002472 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002473 }
2474
Jeff Johnsone7245742012-09-05 17:12:55 -07002475 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2476 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2477 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
2478
Jeff Johnson295189b2012-06-20 16:38:30 -07002479 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2480
2481 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
2482 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
2483 {
2484 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2485 "DXE already stopped in RX event handler. Just return");
2486 return;
2487 }
2488
2489 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2490 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2491 {
2492 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2493 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002494 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002495
2496 /* Not to touch any register, just pull frame directly from chain ring
2497 * First high priority */
2498 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2499 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002500 channelCb,
2501 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002502 if(eWLAN_PAL_STATUS_SUCCESS != status)
2503 {
2504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2505 "dxeRXEventHandler Pull from RX high channel fail");
2506 }
2507
2508 /* Second low priority */
2509 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2510 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002511 channelCb,
2512 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 if(eWLAN_PAL_STATUS_SUCCESS != status)
2514 {
2515 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2516 "dxeRXEventHandler Pull from RX low channel fail");
2517 }
2518
2519 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2520 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2521
2522 return;
2523 }
2524
2525 /* Disable device interrupt */
2526 /* Read whole interrupt mask register and exclusive only this channel int */
2527 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2528 &intSrc);
2529 if(eWLAN_PAL_STATUS_SUCCESS != status)
2530 {
2531 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2532 "dxeRXEventHandler Read INT_SRC register fail");
2533 return;
2534 }
2535 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2536 "RX Event Handler INT Source 0x%x", intSrc);
2537
2538#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2539 /* Test High Priority Channel interrupt is enabled or not */
2540 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2541 if(intSrc & (1 << channelCb->assignedDMAChannel))
2542 {
2543 status = dxeChannelCleanInt(channelCb, &chHighStat);
2544 if(eWLAN_PAL_STATUS_SUCCESS != status)
2545 {
2546 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2547 "dxeRXEventHandler INT Clean up fail");
2548 return;
2549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002550 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2551 {
2552 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2554 "%11s : 0x%x Error Reported, Reload Driver",
2555 channelType[channelCb->channelType], chHighStat);
2556 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2557 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002559 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2560 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002561 {
2562 /* Handle RX Ready for high priority channel */
2563 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002564 channelCb,
2565 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002566 }
2567 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2568 {
2569 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002570 channelCb,
2571 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002572 }
2573 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2574 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002575 /* Update the Rx DONE histogram */
2576 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2577 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2578 {
2579 channelCb->rxDoneHistogram |= 1;
2580 }
2581 else
2582 {
2583 channelCb->rxDoneHistogram &= ~1;
2584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002585 }
2586#else
2587 /* Test H2H Test interrupt is enabled or not */
2588 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2589 if(intSrc & (1 << channelCb->assignedDMAChannel))
2590 {
2591 status = dxeChannelCleanInt(channelCb, &chStat);
2592 if(eWLAN_PAL_STATUS_SUCCESS != status)
2593 {
2594 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2595 "dxeRXEventHandler INT Clean up fail");
2596 return;
2597 }
2598
2599 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2600 {
2601 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2603 "%11s : 0x%x Error Reported, Reload Driver",
2604 channelType[channelCb->channelType], chStat);
2605 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2606 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 }
2608 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2609 {
2610 /* Handle RX Ready for high priority channel */
2611 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002612 channelCb,
2613 chStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002614 }
2615 /* Update the Rx DONE histogram */
2616 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2617 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2618 {
2619 channelCb->rxDoneHistogram |= 1;
2620 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2621 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2622 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2623 }
2624 else
2625 {
2626 channelCb->rxDoneHistogram &= ~1;
2627 }
2628 }
2629#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2630
2631 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002632 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002633 if(intSrc & (1 << channelCb->assignedDMAChannel))
2634 {
2635 status = dxeChannelCleanInt(channelCb, &chLowStat);
2636 if(eWLAN_PAL_STATUS_SUCCESS != status)
2637 {
2638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2639 "dxeRXEventHandler INT Clean up fail");
2640 return;
2641 }
2642
2643 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2644 {
2645 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2647 "%11s : 0x%x Error Reported, Reload Driver",
2648 channelType[channelCb->channelType], chLowStat);
2649 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2650 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07002651 }
2652 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2653 {
2654 /* Handle RX Ready for low priority channel */
2655 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002656 channelCb,
2657 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07002658 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002659
2660 /* Update the Rx DONE histogram */
2661 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2662 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2663 {
2664 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002665 }
2666 else
2667 {
2668 channelCb->rxDoneHistogram &= ~1;
2669 }
2670 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2671 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2672 }
2673 if(eWLAN_PAL_STATUS_SUCCESS != status)
2674 {
2675 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2676 "dxeRXEventHandler Handle Frame Ready Fail");
2677 return;
2678 }
2679
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 /* Prepare Control Register EN Channel */
2681 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2682 {
2683 HDXE_ASSERT(0);
2684 }
Leo Chang094ece82013-04-23 17:57:41 -07002685 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
2686 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002687
2688 /* Prepare Control Register EN Channel */
2689 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2690 {
2691 HDXE_ASSERT(0);
2692 }
Leo Chang094ece82013-04-23 17:57:41 -07002693
2694 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
2695 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
2696
2697 /* Clear Interrupt handle processing bit
2698 * RIVA may power down */
2699 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
2700 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
2701 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -07002702
Leo Chang416afe02013-07-01 13:58:13 -07002703 /* Enable system level ISR */
2704 /* Enable RX ready Interrupt at here */
2705 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2706 if(eWLAN_PAL_STATUS_SUCCESS != status)
2707 {
2708 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2709 "dxeRXEventHandler Enable RX Ready interrupt fail");
2710 return;
2711 }
2712
Jeff Johnson295189b2012-06-20 16:38:30 -07002713 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002714 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002715 return;
2716}
2717
2718/*==========================================================================
2719 @ Function Name
2720 dxeRXPacketAvailableEventHandler
2721
2722 @ Description
2723 Handle serialized RX Packet Available event when the corresponding callback
2724 is invoked by WPAL.
2725 Try to fill up any completed DXE descriptors with available Rx packet buffer
2726 pointers.
2727
2728 @ Parameters
2729 wpt_msg *rxPktAvailMsg
2730 RX frame ready MSG pointer
2731 include DXE control context
2732
2733 @ Return
2734 NONE
2735
2736===========================================================================*/
2737void dxeRXPacketAvailableEventHandler
2738(
2739 wpt_msg *rxPktAvailMsg
2740)
2741{
2742 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2743 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2744 WLANDXE_ChannelCBType *channelCb = NULL;
2745
2746 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002747 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002748
2749 /* Sanity Check */
2750 if(NULL == rxPktAvailMsg)
2751 {
2752 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2753 "dxeRXPacketAvailableEventHandler Context is not valid");
2754 return;
2755 }
2756
2757 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
2758
2759 do
2760 {
2761 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2762 "dxeRXPacketAvailableEventHandler, start refilling ring");
2763
2764 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2765 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2766
2767 // Wait for another callback to indicate when Rx resources are available
2768 // again.
2769 if(eWLAN_PAL_STATUS_SUCCESS != status)
2770 {
2771 break;
2772 }
2773
2774 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2775 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2776 if(eWLAN_PAL_STATUS_SUCCESS != status)
2777 {
2778 break;
2779 }
2780 } while(0);
2781
2782 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2783 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2784 {
2785 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2786 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2787 }
2788}
2789
2790/*==========================================================================
2791 @ Function Name
2792 dxeRXISR
2793
2794 @ Description
2795 RX frame ready interrupt service routine
2796 interrupt entry function, this function called based on ISR context
2797 Must be serialized
2798
2799 @ Parameters
2800 void *hostCtxt
2801 DXE host driver control context,
2802 pre registerd during interrupt registration
2803
2804 @ Return
2805 NONE
2806
2807===========================================================================*/
2808static void dxeRXISR
2809(
2810 void *hostCtxt
2811)
2812{
2813 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2814 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002815 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07002816
2817#ifdef FEATURE_R33D
2818 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2819 &regValue);
2820 if(eWLAN_PAL_STATUS_SUCCESS != status)
2821 {
2822 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2823 "dxeTXCompISR Read INT_SRC_RAW fail");
2824 return;
2825 }
2826 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2827 "INT_SRC_RAW 0x%x", regValue);
2828 if(0 == regValue)
2829 {
2830 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2831 "This is not DXE Interrupt, Reject it 0x%x", regValue);
2832 return;
2833 }
2834#endif /* FEATURE_R33D */
2835
Leo Chang094ece82013-04-23 17:57:41 -07002836 /* Set Interrupt processing bit
2837 * During this bit set, WLAN HW may not power collapse */
2838 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
2839 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
2840 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
2841
Jeff Johnson295189b2012-06-20 16:38:30 -07002842 /* Disable interrupt at here
2843 * Disable RX Ready system level Interrupt at here
2844 * Otherwise infinite loop might happen */
2845 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2846 if(eWLAN_PAL_STATUS_SUCCESS != status)
2847 {
2848 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2849 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2850 return;
2851 }
2852
2853 /* Serialize RX Ready interrupt upon RX thread */
2854 HDXE_ASSERT(NULL != dxeCtxt->rxIsrMsg);
2855 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2856 dxeCtxt->rxIsrMsg);
2857 if(eWLAN_PAL_STATUS_SUCCESS != status)
2858 {
2859 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
2860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2861 "dxeRXFrameReadyISR interrupt serialize fail");
2862 }
2863
Jeff Johnson295189b2012-06-20 16:38:30 -07002864 return;
2865}
2866
2867/*==========================================================================
2868 @ Function Name
2869 dxeTXPushFrame
2870
2871 @ Description
2872 Push TX frame into DXE descriptor and DXE register
2873 Send notification to DXE register that TX frame is ready to transfer
2874
2875 @ Parameters
2876 WLANDXE_ChannelCBType *channelEntry
2877 Channel specific control block
2878 wpt_packet *palPacket
2879 Packet pointer ready to transfer
2880
2881 @ Return
2882 PAL_STATUS_T
2883===========================================================================*/
2884static wpt_status dxeTXPushFrame
2885(
2886 WLANDXE_ChannelCBType *channelEntry,
2887 wpt_packet *palPacket
2888)
2889{
2890 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2891 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2892 WLANDXE_DescType *currentDesc = NULL;
2893 WLANDXE_DescType *firstDesc = NULL;
2894 WLANDXE_DescType *LastDesc = NULL;
2895 void *sourcePhysicalAddress = NULL;
2896 wpt_uint32 xferSize = 0;
2897#ifdef FEATURE_R33D
2898 tx_frm_pcie_vector_t frameVector;
2899 wpt_uint32 Va;
2900 wpt_uint32 fragCount = 0;
2901#else
2902 wpt_iterator iterator;
2903#endif /* FEATURE_R33D */
2904
2905 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002906 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002907
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002908 if(WLANDXE_POWER_STATE_BMPS == tempDxeCtrlBlk->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 {
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07002910 tempDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2911 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07002912 }
2913
2914 channelEntry->numFragmentCurrentChain = 0;
2915 currentCtrlBlk = channelEntry->headCtrlBlk;
2916
2917 /* Initialize interator, TX is fragmented */
2918#ifdef FEATURE_R33D
2919 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2920 status = wpalPrepareTxFrame(palPacket,
2921 &frameVector,
2922 &Va);
2923#else
2924 status = wpalLockPacketForTransfer(palPacket);
2925 if(eWLAN_PAL_STATUS_SUCCESS != status)
2926 {
2927 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2928 "dxeTXPushFrame unable to lock packet");
2929 return status;
2930 }
2931
2932 status = wpalIteratorInit(&iterator, palPacket);
2933#endif /* FEATURE_R33D */
2934 if(eWLAN_PAL_STATUS_SUCCESS != status)
2935 {
2936 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2937 "dxeTXPushFrame iterator init fail");
2938 return status;
2939 }
2940
2941 /* !!!! Revisit break condition !!!!!!! */
2942 while(1)
2943 {
2944 /* Get current descriptor pointer from current control block */
2945 currentDesc = currentCtrlBlk->linkedDesc;
2946 if(NULL == firstDesc)
2947 {
2948 firstDesc = currentCtrlBlk->linkedDesc;
2949 }
2950 /* All control block will have same palPacket Pointer
2951 * to make logic simpler */
2952 currentCtrlBlk->xfrFrame = palPacket;
2953
2954 /* Get next fragment physical address and fragment size
2955 * if this is the first trial, will get first physical address
2956 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2957#ifdef FEATURE_R33D
2958 if(fragCount == frameVector.num_frg)
2959 {
2960 break;
2961 }
2962 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2963 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2964 xferSize = frameVector.frg[fragCount].size;
2965 fragCount++;
2966 HDXE_ASSERT(0 != xferSize);
2967 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2968#else
2969 status = wpalIteratorNext(&iterator,
2970 palPacket,
2971 &sourcePhysicalAddress,
2972 &xferSize);
2973 if((NULL == sourcePhysicalAddress) ||
2974 (0 == xferSize))
2975 {
2976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2977 "dxeTXPushFrame end of current frame");
2978 break;
2979 }
2980 if(eWLAN_PAL_STATUS_SUCCESS != status)
2981 {
2982 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2983 "dxeTXPushFrame Get next frame fail");
2984 return status;
2985 }
2986#endif /* FEATURE_R33D */
2987
2988 /* This is the LAST descriptor valid for this transaction */
2989 LastDesc = currentCtrlBlk->linkedDesc;
2990
2991 /* Program DXE descriptor */
2992 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2993 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2994
2995 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2996 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2997 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2998 {
2999 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3000 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3001 }
3002 else
3003 {
3004 /* Test specific H2H transfer, destination address already set
3005 * Do Nothing */
3006 }
3007 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3008
3009 /* Program channel control register */
3010 /* First frame not set VAL bit, why ??? */
3011 if(0 == channelEntry->numFragmentCurrentChain)
3012 {
3013 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3014 }
3015 else
3016 {
3017 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3018 }
3019
3020 /* Update statistics */
3021 channelEntry->numFragmentCurrentChain++;
3022 channelEntry->numFreeDesc--;
3023 channelEntry->numRsvdDesc++;
3024
3025 /* Get next control block */
3026 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3027 }
3028 channelEntry->numTotalFrame++;
3029 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3030 "NUM TX FRAG %d, Total Frame %d",
3031 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3032
3033 /* Program Channel control register
3034 * Set as end of packet
3035 * Enable interrupt also for first code lock down
3036 * performace optimization, this will be revisited */
3037 if(NULL == LastDesc)
3038 {
3039 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3040 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3041 return eWLAN_PAL_STATUS_E_FAULT;
3042 }
3043 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3044 /* Now First one also Valid ????
3045 * this procedure will prevent over handle descriptor from previous
3046 * TX trigger */
3047 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3048
3049 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3050 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3051 {
3052 /* Update channel head as next avaliable linked slot */
3053 channelEntry->headCtrlBlk = currentCtrlBlk;
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003054 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3055 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,
3056 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3057 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3058 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003059 }
3060
3061 /* If DXE use external descriptor, registers are not needed to be programmed
3062 * Just after finish to program descriptor, tirigger to send */
3063 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3064 {
3065 /* Issue a dummy read from the DXE descriptor DDR location to
3066 ensure that any previously posted write to the descriptor
3067 completes. */
3068 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3069 {
3070 //HDXE_ASSERT(0);
3071 }
3072
3073 /* Everything is ready
3074 * Trigger to start DMA */
3075 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3076 channelEntry->extraConfig.chan_mask);
3077 if(eWLAN_PAL_STATUS_SUCCESS != status)
3078 {
3079 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3080 "dxeTXPushFrame Write Channel Ctrl Register fail");
3081 return status;
3082 }
3083
3084 /* Update channel head as next avaliable linked slot */
3085 channelEntry->headCtrlBlk = currentCtrlBlk;
3086
3087 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003088 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 return status;
3090 }
3091
3092 /* If DXE not use external descriptor, program each registers */
3093 /* Circular buffer handle not need to program DESC register???
3094 * GEN5 code not programed RING buffer case
3095 * REVISIT THIS !!!!!! */
3096 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3097 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3098 {
3099 /* Destination address, assigned Work Q */
3100 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3101 channelEntry->channelConfig.refWQ);
3102 if(eWLAN_PAL_STATUS_SUCCESS != status)
3103 {
3104 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3105 "dxeTXPushFrame Program dest address register fail");
3106 return status;
3107 }
3108 /* If descriptor format is SHORT */
3109 if(channelEntry->channelConfig.useShortDescFmt)
3110 {
3111 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3112 0);
3113 if(eWLAN_PAL_STATUS_SUCCESS != status)
3114 {
3115 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3116 "dxeTXPushFrame Program dest address register fail");
3117 return status;
3118 }
3119 }
3120 else
3121 {
3122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3123 "dxeTXPushFrame LONG Descriptor Format!!!");
3124 }
3125 }
3126#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3127 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3128 {
3129 /* Destination address, Physical memory address */
3130 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3131 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3132 if(eWLAN_PAL_STATUS_SUCCESS != status)
3133 {
3134 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3135 "dxeTXPushFrame Program dest address register fail");
3136 return status;
3137 }
3138 /* If descriptor format is SHORT */
3139 if(channelEntry->channelConfig.useShortDescFmt)
3140 {
3141 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3142 0);
3143 if(eWLAN_PAL_STATUS_SUCCESS != status)
3144 {
3145 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3146 "dxeTXPushFrame Program dest address register fail");
3147 return status;
3148 }
3149 }
3150 else
3151 {
3152 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3153 "dxeTXPushFrame LONG Descriptor Format!!!");
3154 }
3155 }
3156#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3157
3158 /* Program Source address register
3159 * This address is already programmed into DXE Descriptor
3160 * But register also upadte */
3161 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3162 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3163 if(eWLAN_PAL_STATUS_SUCCESS != status)
3164 {
3165 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3166 "dxeTXPushFrame Program src address register fail");
3167 return status;
3168 }
3169 /* If descriptor format is SHORT */
3170 if(channelEntry->channelConfig.useShortDescFmt)
3171 {
3172 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3173 0);
3174 if(eWLAN_PAL_STATUS_SUCCESS != status)
3175 {
3176 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3177 "dxeTXPushFrame Program dest address register fail");
3178 return status;
3179 }
3180 }
3181 else
3182 {
3183 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3184 "dxeTXPushFrame LONG Descriptor Format!!!");
3185 }
3186
3187 /* Linked list Descriptor pointer */
3188 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3189 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3190 if(eWLAN_PAL_STATUS_SUCCESS != status)
3191 {
3192 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3193 "dxeTXPushFrame Write DESC Address register fail");
3194 return status;
3195 }
3196 /* If descriptor format is SHORT */
3197 if(channelEntry->channelConfig.useShortDescFmt)
3198 {
3199 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3200 0);
3201 if(eWLAN_PAL_STATUS_SUCCESS != status)
3202 {
3203 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3204 "dxeTXPushFrame Program dest address register fail");
3205 return status;
3206 }
3207 }
3208 else
3209 {
3210 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3211 "dxeTXPushFrame LONG Descriptor Format!!!");
3212 }
3213
3214 /* Transfer Size */
3215 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3216 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3217 xferSize);
3218 if(eWLAN_PAL_STATUS_SUCCESS != status)
3219 {
3220 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3221 "dxeTXPushFrame Write DESC Address register fail");
3222 return status;
3223 }
3224
3225 /* Everything is ready
3226 * Trigger to start DMA */
3227 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3228 channelEntry->extraConfig.chan_mask);
3229 if(eWLAN_PAL_STATUS_SUCCESS != status)
3230 {
3231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3232 "dxeTXPushFrame Write Channel Ctrl Register fail");
3233 return status;
3234 }
3235
3236 /* Update channel head as next avaliable linked slot */
3237 channelEntry->headCtrlBlk = currentCtrlBlk;
3238
3239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003240 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003241 return status;
3242}
3243
3244/*==========================================================================
3245 @ Function Name
3246 dxeTXCompFrame
3247
3248 @ Description
3249 TX Frame transfer complete event handler
3250
3251 @ Parameters
3252 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3253 DXE host driver main control block
3254 WLANDXE_ChannelCBType *channelEntry
3255 Channel specific control block
3256
3257 @ Return
3258 PAL_STATUS_T
3259===========================================================================*/
3260static wpt_status dxeTXCompFrame
3261(
3262 WLANDXE_CtrlBlkType *hostCtxt,
3263 WLANDXE_ChannelCBType *channelEntry
3264)
3265{
3266 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3267 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3268 WLANDXE_DescType *currentDesc = NULL;
3269 wpt_uint32 descCtrlValue = 0;
3270 unsigned int *lowThreshold = NULL;
3271
3272 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003273 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003274
3275 /* Sanity */
3276 if((NULL == hostCtxt) || (NULL == channelEntry))
3277 {
3278 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3279 "dxeTXCompFrame Invalid ARG");
3280 return eWLAN_PAL_STATUS_E_INVAL;
3281 }
3282
3283 if(NULL == hostCtxt->txCompCB)
3284 {
3285 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3286 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003287 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003288 }
3289
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003290 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3291 if(eWLAN_PAL_STATUS_SUCCESS != status)
3292 {
3293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3294 "dxeTXCompFrame Mutex Acquire fail");
3295 return status;
3296 }
3297
Jeff Johnson295189b2012-06-20 16:38:30 -07003298 currentCtrlBlk = channelEntry->tailCtrlBlk;
3299 currentDesc = currentCtrlBlk->linkedDesc;
3300
3301 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3302 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003303 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3304 if(eWLAN_PAL_STATUS_SUCCESS != status)
3305 {
3306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3307 "dxeTXCompFrame Mutex Release fail");
3308 return status;
3309 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003310 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003311 }
3312
3313 /* */
3314 while(1)
3315 {
3316// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3317 descCtrlValue = currentDesc->descCtrl.ctrl;
3318 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3319 {
3320 /* caught up with head, bail out */
3321 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3322 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3323 break;
3324 }
3325
3326 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
3327 channelEntry->numFreeDesc++;
3328 channelEntry->numRsvdDesc--;
3329
3330 /* Send Frame TX Complete notification with frame start fragment location */
3331 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3332 {
3333 hostCtxt->txCompletedFrames--;
3334#ifdef FEATURE_R33D
3335 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3336#else
3337 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3338 if (eWLAN_PAL_STATUS_SUCCESS != status)
3339 {
3340 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3341 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003342 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3343 if(eWLAN_PAL_STATUS_SUCCESS != status)
3344 {
3345 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3346 "dxeTXCompFrame Mutex Release fail");
3347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003348 return status;
3349 }
3350#endif /* FEATURE_R33D */
3351 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3352 currentCtrlBlk->xfrFrame,
3353 eWLAN_PAL_STATUS_SUCCESS);
3354 channelEntry->numFragmentCurrentChain = 0;
3355 }
3356 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3357 currentDesc = currentCtrlBlk->linkedDesc;
3358
3359 /* Break condition
3360 * Head control block is the control block must be programed for the next TX
3361 * so, head control block is not programmed control block yet
3362 * if loop encounte head control block, stop to complete
3363 * in theory, COMP CB must be called already ??? */
3364 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3365 {
3366 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3367 "dxeTXCompFrame caught up with head ptr");
3368 break;
3369 }
3370 /* VALID Bit check ???? */
3371 }
3372
3373 /* Tail and Head Control block must be same */
3374 channelEntry->tailCtrlBlk = currentCtrlBlk;
3375
3376 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3377 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3378 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3379
3380 /* If specific channel hit low resource condition send notification to upper layer */
3381 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3382 (channelEntry->numFreeDesc > *lowThreshold))
3383 {
3384 /* Change it back if we raised it for fetching a remaining packet from TL */
3385 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3386 {
3387 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3388 }
3389
3390 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3391 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3392 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3393 channelEntry->channelType,
3394 eWLAN_PAL_TRUE);
3395 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003396 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003397 }
3398
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003399 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3400 if(eWLAN_PAL_STATUS_SUCCESS != status)
3401 {
3402 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3403 "dxeTXCompFrame Mutex Release fail");
3404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003405
3406 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003407 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 return status;
3409}
3410
3411/*==========================================================================
3412 @ Function Name
3413 dxeTXEventHandler
3414
3415 @ Description
3416 If DXE HW sends TX related interrupt, this event handler will be called
3417 Handle higher priority channel first
3418 Figureout why interrupt happen and call appropriate final even handler
3419 TX complete or error happen
3420
3421 @ Parameters
3422 void *msgPtr
3423 Even MSG
3424
3425 @ Return
3426 PAL_STATUS_T
3427===========================================================================*/
3428void dxeTXEventHandler
3429(
3430 wpt_msg *msgPtr
3431)
3432{
3433 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3434 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3435 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3436 wpt_uint32 intSrc = 0;
3437 wpt_uint32 chStat = 0;
3438 WLANDXE_ChannelCBType *channelCb = NULL;
3439
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003440 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003441 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003442
3443 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003444 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003445
3446 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003447 dxeCtxt->ucTxMsgCnt = 0;
3448
3449 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3450 {
3451 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3452 "wlan: TX COMP WLAN Driver re-loading in progress");
3453 return;
3454 }
3455
Jeff Johnson295189b2012-06-20 16:38:30 -07003456 /* Return from here if the RIVA is in IMPS, to avoid register access */
3457 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3458 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003459 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003460 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003461 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003462 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3463 if(eWLAN_PAL_STATUS_SUCCESS != status)
3464 {
3465 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003466 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003467 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003468
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003469 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3470 if(eWLAN_PAL_STATUS_SUCCESS != status)
3471 {
3472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3473 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3474 }
3475
3476 if(((dxeCtxt->txCompletedFrames) &&
3477 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3478 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003479 {
3480 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3481 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3482 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003483 "TX COMP INT Enabled, remain TX frame count on ring %d",
3484 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003485 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3486 the posibility of a race*/
3487 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3488 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003489 else
3490 {
3491 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3492 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3493 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3494 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003496 return;
3497 }
3498
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003499 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003500 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3501 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3502 {
3503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3504 "DXE already stopped in TX event handler. Just return");
3505 return;
3506 }
3507
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 /* Disable device interrupt */
3509 /* Read whole interrupt mask register and exclusive only this channel int */
3510 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3511 &intSrc);
3512 if(eWLAN_PAL_STATUS_SUCCESS != status)
3513 {
3514 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3515 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3516 return;
3517 }
3518 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3519 "TX Event Handler INT Source 0x%x", intSrc);
3520
3521 /* Test High Priority Channel is the INT source or not */
3522 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3523 if(intSrc & (1 << channelCb->assignedDMAChannel))
3524 {
3525 status = dxeChannelCleanInt(channelCb, &chStat);
3526 if(eWLAN_PAL_STATUS_SUCCESS != status)
3527 {
3528 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3529 "dxeTXEventHandler INT Clean up fail");
3530 return;
3531 }
3532
3533 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3534 {
3535 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003536 "%11s : 0x%x Error Reported, Reload Driver",
3537 channelType[channelCb->channelType], chStat);
3538 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3539 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003540 }
3541 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3542 {
3543 /* Handle TX complete for high priority channel */
3544 status = dxeTXCompFrame(dxeCtxt,
3545 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003546 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003547 }
3548 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3549 {
3550 /* Handle TX complete for high priority channel */
3551 status = dxeTXCompFrame(dxeCtxt,
3552 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003553 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003554 }
3555 else
3556 {
3557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3558 "dxeTXEventHandler TX HI status=%x", chStat);
3559 }
3560
3561 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3562 {
3563 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3564 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3565 }
3566
3567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3568 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3569 }
3570
3571 /* Test Low Priority Channel interrupt is enabled or not */
3572 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3573 if(intSrc & (1 << channelCb->assignedDMAChannel))
3574 {
3575 status = dxeChannelCleanInt(channelCb, &chStat);
3576 if(eWLAN_PAL_STATUS_SUCCESS != status)
3577 {
3578 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3579 "dxeTXEventHandler INT Clean up fail");
3580 return;
3581 }
3582
3583 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3584 {
3585 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003586 "%11s : 0x%x Error Reported, Reload Driver",
3587 channelType[channelCb->channelType], chStat);
3588 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3589 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003590 }
3591 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3592 {
3593 /* Handle TX complete for low priority channel */
3594 status = dxeTXCompFrame(dxeCtxt,
3595 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003596 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003597 }
3598 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3599 {
3600 /* Handle TX complete for low priority channel */
3601 status = dxeTXCompFrame(dxeCtxt,
3602 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003603 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003604 }
3605 else
3606 {
3607 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3608 "dxeTXEventHandler TX LO status=%x", chStat);
3609 }
3610
3611 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3612 {
3613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3614 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3615 }
3616 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3617 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3618 }
3619
3620
3621#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3622 /* Test H2H TX Channel interrupt is enabled or not */
3623 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3624 if(intSrc & (1 << channelCb->assignedDMAChannel))
3625 {
3626 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3627 &chStat);
3628 if(eWLAN_PAL_STATUS_SUCCESS != status)
3629 {
3630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3631 "dxeChannelCleanInt Read CH STAT register fail");
3632 return;
3633 }
3634
3635 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3636 {
3637 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003638 "%11s : 0x%x Error Reported, Reload Driver",
3639 channelType[channelCb->channelType], chStat);
3640 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3641 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003642 }
3643 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3644 {
3645 /* Handle TX complete for high priority channel */
3646 status = dxeTXCompFrame(dxeCtxt,
3647 channelCb);
3648 if(eWLAN_PAL_STATUS_SUCCESS != status)
3649 {
3650 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3651 "dxeTXEventHandler INT Clean up fail");
3652 return;
3653 }
3654 }
3655 else
3656 {
3657 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3658 "unexpected channel state %d", chStat);
3659 }
3660 }
3661#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3662
3663 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3664 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3665 {
3666 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3667 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003668 if(0 != dxeCtxt->txCompletedFrames)
3669 {
3670 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3671 "TX COMP INT Enabled, remain TX frame count on ring %d",
3672 dxeCtxt->txCompletedFrames);
3673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003674 }
3675
3676 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3677 the posibility of a race*/
3678 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3679
3680 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003681 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 return;
3683}
3684
3685
3686/*==========================================================================
3687 @ Function Name
3688 dxeTXCompleteProcessing
3689
3690 @ Description
3691 If DXE HW sends TX related interrupt, this event handler will be called
3692 Handle higher priority channel first
3693 Figureout why interrupt happen and call appropriate final even handler
3694 TX complete or error happen
3695
3696 @ Parameters
3697 dxeCtxt DXE context
3698
3699 @ Return
3700 PAL_STATUS_T
3701===========================================================================*/
3702void dxeTXCompleteProcessing
3703(
3704 WLANDXE_CtrlBlkType *dxeCtxt
3705)
3706{
3707 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3708 WLANDXE_ChannelCBType *channelCb = NULL;
3709
3710 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003711 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003712
3713 /* Test High Priority Channel is the INT source or not */
3714 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3715
3716 /* Handle TX complete for high priority channel */
3717 status = dxeTXCompFrame(dxeCtxt, channelCb);
3718
3719 /* Test Low Priority Channel interrupt is enabled or not */
3720 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3721
3722 /* Handle TX complete for low priority channel */
3723 status = dxeTXCompFrame(dxeCtxt, channelCb);
3724
3725 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3726 ((dxeCtxt->txCompletedFrames > 0) ||
3727 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3728 {
3729 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3730 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3731 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003732 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003733 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3734 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3735 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3736 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
3737 }
3738
3739 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3740 the posibility of a race*/
3741 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3742
3743 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003744 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003745 return;
3746}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003747
3748/*==========================================================================
3749 @ Function Name
3750 dxeTXReSyncDesc
3751
3752 @ Description
3753 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3754 And HW programmed descriptor.
3755 If any async happen between HW/SW TX stall will happen
3756
3757 @ Parameters
3758 void *msgPtr
3759 Message pointer to sync with TX thread
3760
3761 @ Return
3762 NONE
3763===========================================================================*/
3764void dxeTXReSyncDesc
3765(
3766 wpt_msg *msgPtr
3767)
3768{
3769 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3770 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3771 wpt_uint32 nextDescReg;
3772 WLANDXE_ChannelCBType *channelEntry;
3773 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3774 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003775 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003776
3777 if(NULL == msgContent)
3778 {
3779 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3780 "dxeTXReSyncDesc Invalid Control Block");
3781 return;
3782 }
3783
3784 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3785 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3786 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3787
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003788 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003789 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003790 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3791 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3792 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3793 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3794 &nextDescReg);
3795 /* Async detect without TX pending frame */
3796 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003797 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003798 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003799 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003800 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3801 "TX Async no Pending frame");
3802 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry);
3803 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!");
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003804 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003805 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003806 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003807 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003808 /* Async detect with some TX pending frames
3809 * next descriptor register should sync with first valid descriptor */
3810 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003811 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003812 validCtrlBlk = channelEntry->tailCtrlBlk;
3813 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003814 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003815 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3816 {
3817 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3818 {
3819 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3820 "TX Async");
3821 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3822 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3823 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3824 validCtrlBlk->linkedDescPhyAddr);
3825 }
3826 break;
3827 }
3828 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3829 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3830 {
3831 /* Finished to test till head control blcok, but could not find valid descriptor
3832 * from head to tail all descriptors are invalidated
3833 * host point of view head descriptor is next TX candidate
3834 * So, next descriptor control have to be programmed with head descriptor
3835 * check */
3836 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3837 {
3838 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08003839 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003840 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3841 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3842 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3843 validCtrlBlk->linkedDescPhyAddr);
3844 }
3845 break;
3846 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003847 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003848 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003849 }
3850
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003851 /* HW/SW descriptor resync is done.
3852 * Next if there are any valid descriptor in chain, Push to HW again */
3853 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3854 {
3855 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3856 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3857 {
3858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3859 "%11s : No TX Pending frame",
3860 channelType[channelEntry->channelType]);
3861 /* No Pending frame, Do nothing */
3862 }
3863 else
3864 {
3865 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3866 "%11s : TX Pending frame, process it",
3867 channelType[channelEntry->channelType]);
3868 validCtrlBlk = channelEntry->tailCtrlBlk;
3869 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3870 {
3871 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3872 {
3873 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3874 "%11s : when exit IMPS found valid descriptor",
3875 channelType[channelEntry->channelType]);
3876
3877 /* Found valid descriptor, kick DXE */
3878 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3879 channelEntry->extraConfig.chan_mask);
3880 break;
3881 }
3882 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3883 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3884 {
3885 /* Finished to test till head control blcok, but could not find valid descriptor
3886 * from head to tail all descriptors are invalidated */
3887 break;
3888 }
3889 }
3890 }
3891 }
3892
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003893 wpalMemoryFree(msgPtr);
3894 return;
3895}
3896
Jeff Johnson295189b2012-06-20 16:38:30 -07003897/*==========================================================================
3898 @ Function Name
3899 dxeTXISR
3900
3901 @ Description
3902 TX interrupt ISR
3903 Platform will call this function if INT is happen
3904 This function must be registered into platform interrupt module
3905
3906 @ Parameters
3907 void *hostCtxt
3908 DXE host driver control context,
3909 pre registerd during interrupt registration
3910
3911 @ Return
3912 PAL_STATUS_T
3913===========================================================================*/
3914static void dxeTXISR
3915(
3916 void *hostCtxt
3917)
3918{
3919 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3920 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3921#ifdef FEATURE_R33D
3922 wpt_uint32 regValue;
3923#endif /* FEATURE_R33D */
3924
3925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003926 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003927
3928 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003929 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003931 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 /* Disable interrupt at here,
3933 IMPS or IMPS Pending state should not access RIVA register */
3934 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3935 if(eWLAN_PAL_STATUS_SUCCESS != status)
3936 {
3937 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3938 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3939 return;
3940 }
3941 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3942 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003943 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003944 return;
3945 }
3946
3947#ifdef FEATURE_R33D
3948 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3949 &regValue);
3950 if(eWLAN_PAL_STATUS_SUCCESS != status)
3951 {
3952 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3953 "dxeTXCompISR Read INT_SRC_RAW fail");
3954 return;
3955 }
3956 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3957 "INT_SRC_RAW 0x%x", regValue);
3958 if(0 == regValue)
3959 {
3960 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3961 "This is not DXE Interrupt, Reject it");
3962 return;
3963 }
3964#endif /* FEATURE_R33D */
3965
3966 /* Disable TX Complete Interrupt at here */
3967 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3968 if(eWLAN_PAL_STATUS_SUCCESS != status)
3969 {
3970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3971 "dxeTXCompISR Disable TX complete interrupt fail");
3972 return;
3973 }
3974 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3975
3976
3977 if( dxeCtxt->ucTxMsgCnt )
3978 {
3979 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3980 "Avoiding serializing TX Complete event");
3981 return;
3982 }
3983
3984 dxeCtxt->ucTxMsgCnt = 1;
3985
3986 /* Serialize TX complete interrupt upon TX thread */
3987 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3988 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3989 dxeCtxt->txIsrMsg);
3990 if(eWLAN_PAL_STATUS_SUCCESS != status)
3991 {
3992 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3993 "dxeTXCompISR interrupt serialize fail status=%d", status);
3994 }
3995
3996 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003997 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003998 return;
3999}
4000
4001/*-------------------------------------------------------------------------
4002 * Global Function
4003 *-------------------------------------------------------------------------*/
4004/*==========================================================================
4005 @ Function Name
4006 WLANDXE_Open
4007
4008 @ Description
4009 Open host DXE driver, allocate DXE resources
4010 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4011
4012 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004013 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004014
4015 @ Return
4016 pVoid DXE local module control block pointer
4017===========================================================================*/
4018void *WLANDXE_Open
4019(
4020 void
4021)
4022{
4023 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4024 unsigned int idx;
4025 WLANDXE_ChannelCBType *currentChannel = NULL;
4026 int smsmInitState;
4027#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4028 wpt_uint32 sIdx;
4029 WLANDXE_ChannelCBType *channel = NULL;
4030 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4031 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4032#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4033
4034 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004035 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004036
4037 /* This is temporary allocation */
4038 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4039 if(NULL == tempDxeCtrlBlk)
4040 {
4041 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4042 "WLANDXE_Open Control Block Alloc Fail");
4043 return NULL;
4044 }
4045 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4046
4047 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4048 if(eWLAN_PAL_STATUS_SUCCESS != status)
4049 {
4050 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4051 "WLANDXE_Open Common Configuration Fail");
4052 WLANDXE_Close(tempDxeCtrlBlk);
4053 return NULL;
4054 }
4055
4056 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4057 {
4058 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4059 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4060 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
4061 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
4062 {
4063 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
4064 }
4065 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
4066 {
4067 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
4068 }
4069 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
4070 {
4071 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
4072 }
4073 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
4074 {
4075 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
4076 }
4077#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4078 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
4079 {
4080 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
4081 }
4082 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
4083 {
4084 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
4085 }
4086#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4087
4088 /* Config individual channels from channel default setup table */
4089 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4090 currentChannel);
4091 if(eWLAN_PAL_STATUS_SUCCESS != status)
4092 {
4093 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4094 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4095 WLANDXE_Close(tempDxeCtrlBlk);
4096 return NULL;
4097 }
4098
4099 /* Allocate DXE Control Block will be used by host DXE driver */
4100 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4101 if(eWLAN_PAL_STATUS_SUCCESS != status)
4102 {
4103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4104 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4105
4106 WLANDXE_Close(tempDxeCtrlBlk);
4107 return NULL;
4108 }
4109 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4110 if(eWLAN_PAL_STATUS_SUCCESS != status)
4111 {
4112 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4113 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4114 WLANDXE_Close(tempDxeCtrlBlk);
4115 return NULL;
4116 }
4117
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004118 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4119 dxeHealthMonitorTimeout,
4120 (void *)currentChannel);
4121 if(eWLAN_PAL_STATUS_SUCCESS != status)
4122 {
4123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4124 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4125 WLANDXE_Close(tempDxeCtrlBlk);
4126 return NULL;
4127 }
4128
4129 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4130 if(NULL == currentChannel->healthMonitorMsg)
4131 {
4132 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4133 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4134 WLANDXE_Close(tempDxeCtrlBlk);
4135 return NULL;
4136 }
4137 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4138 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4139 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4140
Jeff Johnson295189b2012-06-20 16:38:30 -07004141 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4142 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4143 }
4144
4145 /* Allocate and Init RX READY ISR Serialize Buffer */
4146 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4147 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4148 {
4149 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4150 "WLANDXE_Open Alloc RX ISR Fail");
4151 WLANDXE_Close(tempDxeCtrlBlk);
4152 return NULL;
4153 }
4154 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4155 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4156 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4157
4158 /* Allocate and Init TX COMP ISR Serialize Buffer */
4159 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4160 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4161 {
4162 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4163 "WLANDXE_Open Alloc TX ISR Fail");
4164 WLANDXE_Close(tempDxeCtrlBlk);
4165 return NULL;
4166 }
4167 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4168 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4169 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4170
4171 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4172 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4173 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4174 {
4175 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4176 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4177 WLANDXE_Close(tempDxeCtrlBlk);
4178 return NULL;
4179 }
4180 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4181 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4182 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4183
4184 tempDxeCtrlBlk->freeRXPacket = NULL;
4185 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4186 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4187 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004188 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004189
4190 /* Initialize SMSM state
4191 * Init State is
4192 * Clear TX Enable
4193 * RING EMPTY STATE */
4194 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4195 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4196 if(0 != smsmInitState)
4197 {
4198 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4199 "SMSM Channel init fail %d", smsmInitState);
4200 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4201 {
4202 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4203 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004204 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4205 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 wpalMemoryFree(tempDxeCtrlBlk);
4207 return NULL;
4208 }
4209
4210 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4211 "WLANDXE_Open Success");
4212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004213 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004214 return (void *)tempDxeCtrlBlk;
4215}
4216
4217/*==========================================================================
4218 @ Function Name
4219 WLANDXE_ClientRegistration
4220
4221 @ Description
4222 Make callback functions registration into DXE driver from DXE driver client
4223
4224 @ Parameters
4225 pVoid pDXEContext : DXE module control block
4226 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4227 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4228 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4229 void *userContext : DXE Cliennt control block
4230
4231 @ Return
4232 wpt_status
4233===========================================================================*/
4234wpt_status WLANDXE_ClientRegistration
4235(
4236 void *pDXEContext,
4237 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4238 WLANDXE_TxCompleteCbType txCompleteCB,
4239 WLANDXE_LowResourceCbType lowResourceCB,
4240 void *userContext
4241)
4242{
4243 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4244 WLANDXE_CtrlBlkType *dxeCtxt;
4245
4246 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004247 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004248
4249 /* Sanity */
4250 if(NULL == pDXEContext)
4251 {
4252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4253 "WLANDXE_ClientRegistration Invalid DXE CB");
4254 return eWLAN_PAL_STATUS_E_INVAL;
4255 }
4256
4257 if(NULL == rxFrameReadyCB)
4258 {
4259 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4260 "WLANDXE_ClientRegistration Invalid RX READY CB");
4261 return eWLAN_PAL_STATUS_E_INVAL;
4262 }
4263
4264 if(NULL == txCompleteCB)
4265 {
4266 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4267 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4268 return eWLAN_PAL_STATUS_E_INVAL;
4269 }
4270
4271 if(NULL == lowResourceCB)
4272 {
4273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4274 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4275 return eWLAN_PAL_STATUS_E_INVAL;
4276 }
4277
4278 if(NULL == userContext)
4279 {
4280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4281 "WLANDXE_ClientRegistration Invalid userContext");
4282 return eWLAN_PAL_STATUS_E_INVAL;
4283 }
4284
4285 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4286
4287 /* Assign */
4288 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4289 dxeCtxt->txCompCB = txCompleteCB;
4290 dxeCtxt->lowResourceCB = lowResourceCB;
4291 dxeCtxt->clientCtxt = userContext;
4292
4293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004294 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004295 return status;
4296}
4297
4298/*==========================================================================
4299 @ Function Name
4300 WLANDXE_Start
4301
4302 @ Description
4303 Start Host DXE driver
4304 Initialize DXE channels and start channel
4305
4306 @ Parameters
4307 pVoid pDXEContext : DXE module control block
4308
4309 @ Return
4310 wpt_status
4311===========================================================================*/
4312wpt_status WLANDXE_Start
4313(
4314 void *pDXEContext
4315)
4316{
4317 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4318 wpt_uint32 idx;
4319 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4320
4321 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004322 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004323
4324 /* Sanity */
4325 if(NULL == pDXEContext)
4326 {
4327 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4328 "WLANDXE_Start Invalid DXE CB");
4329 return eWLAN_PAL_STATUS_E_INVAL;
4330 }
4331 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4332
4333 /* WLANDXE_Start called means DXE engine already initiates
4334 * And DXE HW is reset and init finished
4335 * But here to make sure HW is initialized, reset again */
4336 status = dxeEngineCoreStart(dxeCtxt);
4337 if(eWLAN_PAL_STATUS_SUCCESS != status)
4338 {
4339 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4340 "WLANDXE_Start DXE HW init Fail");
4341 return status;
4342 }
4343
4344 /* Individual Channel Start */
4345 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4346 {
4347 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4348 "WLANDXE_Start Channel %s Start", channelType[idx]);
4349
4350 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4351 /* Make connection between DXE descriptor and DXE control block */
4352 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4353 if(eWLAN_PAL_STATUS_SUCCESS != status)
4354 {
4355 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4356 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4357 return status;
4358 }
4359
4360 /* Program each channel register with configuration arguments */
4361 status = dxeChannelInitProgram(dxeCtxt,
4362 &dxeCtxt->dxeChannel[idx]);
4363 if(eWLAN_PAL_STATUS_SUCCESS != status)
4364 {
4365 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4366 "WLANDXE_Start %d Program DMA channel Fail", idx);
4367 return status;
4368 }
4369
4370 /* ??? Trigger to start DMA channel
4371 * This must be seperated from ??? */
4372 status = dxeChannelStart(dxeCtxt,
4373 &dxeCtxt->dxeChannel[idx]);
4374 if(eWLAN_PAL_STATUS_SUCCESS != status)
4375 {
4376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4377 "WLANDXE_Start %d Channel Start Fail", idx);
4378 return status;
4379 }
4380 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4381 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4382 }
4383
4384 /* Register ISR to OS */
4385 /* Register TX complete interrupt into platform */
4386 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4387 dxeTXISR,
4388 dxeCtxt);
4389 if(eWLAN_PAL_STATUS_SUCCESS != status)
4390 {
4391 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4392 "WLANDXE_Start TX comp interrupt registration Fail");
4393 return status;
4394 }
4395
4396 /* Register RX ready interrupt into platform */
4397 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4398 dxeRXISR,
4399 dxeCtxt);
4400 if(eWLAN_PAL_STATUS_SUCCESS != status)
4401 {
4402 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4403 "WLANDXE_Start RX Ready interrupt registration Fail");
4404 return status;
4405 }
4406
4407 /* Enable system level ISR */
4408 /* Enable RX ready Interrupt at here */
4409 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4410 if(eWLAN_PAL_STATUS_SUCCESS != status)
4411 {
4412 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4413 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4414 return status;
4415 }
4416
4417 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004418 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004419 return status;
4420}
4421
4422/*==========================================================================
4423 @ Function Name
4424 WLANDXE_TXFrame
4425
4426 @ Description
4427 Trigger frame transmit from host to RIVA
4428
4429 @ Parameters
4430 pVoid pDXEContext : DXE Control Block
4431 wpt_packet pPacket : transmit packet structure
4432 WDTS_ChannelType channel : TX channel
4433
4434 @ Return
4435 wpt_status
4436===========================================================================*/
4437wpt_status WLANDXE_TxFrame
4438(
4439 void *pDXEContext,
4440 wpt_packet *pPacket,
4441 WDTS_ChannelType channel
4442)
4443{
4444 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4445 WLANDXE_ChannelCBType *currentChannel = NULL;
4446 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4447 unsigned int *lowThreshold = NULL;
4448
4449 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004450 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004451
4452 /* Sanity */
4453 if(NULL == pDXEContext)
4454 {
4455 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4456 "WLANDXE_Start Invalid DXE CB");
4457 return eWLAN_PAL_STATUS_E_INVAL;
4458 }
4459
4460 if(NULL == pPacket)
4461 {
4462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4463 "WLANDXE_Start Invalid pPacket");
4464 return eWLAN_PAL_STATUS_E_INVAL;
4465 }
4466
4467 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4468 {
4469 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4470 "WLANDXE_Start Invalid channel");
4471 return eWLAN_PAL_STATUS_E_INVAL;
4472 }
4473
4474 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4475
4476 currentChannel = &dxeCtxt->dxeChannel[channel];
4477
4478
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004479 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4480 if(eWLAN_PAL_STATUS_SUCCESS != status)
4481 {
4482 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4483 "WLANDXE_TxFrame Mutex Acquire fail");
4484 return status;
4485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004486
4487 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4488 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4489 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4490
4491 /* Decide have to activate TX complete event or not */
4492 switch(dxeCtxt->txCompInt.txIntEnable)
4493 {
4494 /* TX complete interrupt will be activated when low DXE resource */
4495 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4496 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4497 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4498 {
4499 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4500 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4501 channel,
4502 eWLAN_PAL_FALSE);
4503 }
4504 break;
4505
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004506 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004507 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4508 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4509 {
4510 currentChannel->numFrameBeforeInt++;
4511 }
4512 break;
4513
4514 /* TX complete interrupt will be activated periodically */
4515 case WLANDXE_TX_COMP_INT_TIMER:
4516 break;
4517 }
4518
4519 dxeCtxt->txCompletedFrames++;
4520
4521 /* Update DXE descriptor, this is frame based
4522 * if a frame consist of N fragments, N Descriptor will be programed */
4523 status = dxeTXPushFrame(currentChannel, pPacket);
4524 if(eWLAN_PAL_STATUS_SUCCESS != status)
4525 {
4526 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4527 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004528 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4529 if(eWLAN_PAL_STATUS_SUCCESS != status)
4530 {
4531 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4532 "WLANDXE_TxFrame Mutex Release fail");
4533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004534 return status;
4535 }
4536
4537 /* If specific channel hit low resource condition, send notification to upper layer */
4538 if(currentChannel->numFreeDesc <= *lowThreshold)
4539 {
4540 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4541 channel,
4542 eWLAN_PAL_FALSE);
4543 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004544
4545 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4546 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4547 channelType[currentChannel->channelType],
4548 currentChannel->numRsvdDesc);
4549 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4550 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4551 wpalTimerStart(&currentChannel->healthMonitorTimer,
4552 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004554 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4555 if(eWLAN_PAL_STATUS_SUCCESS != status)
4556 {
4557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4558 "WLANDXE_TxFrame Mutex Release fail");
4559 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004560
4561 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004562 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004563 return status;
4564}
4565
4566/*==========================================================================
4567 @ Function Name
4568 WLANDXE_CompleteTX
4569
4570 @ Description
4571 Informs DXE that the current series of Tx packets is complete
4572
4573 @ Parameters
4574 pContext pDXEContext : DXE Control Block
4575 ucTxResReq TX resource number required by TL/WDI
4576
4577 @ Return
4578 wpt_status
4579===========================================================================*/
4580wpt_status
4581WLANDXE_CompleteTX
4582(
4583 void* pContext,
4584 wpt_uint32 ucTxResReq
4585)
4586{
4587 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4588 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4589 WLANDXE_ChannelCBType *channelCb = NULL;
4590 wpt_boolean inLowRes;
4591
4592 /* Sanity Check */
4593 if( NULL == pContext )
4594 {
4595 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4596 "WLANDXE_CompleteTX invalid param");
4597 return eWLAN_PAL_STATUS_E_INVAL;
4598 }
4599
4600 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4601 inLowRes = channelCb->hitLowResource;
4602
4603 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4604 {
4605 /* Raise threshold temporarily if necessary */
4606 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4607
4608 if(eWLAN_PAL_FALSE == inLowRes)
4609 {
4610 /* Put the channel to low resource condition */
4611 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4612 WDTS_CHANNEL_TX_LOW_PRI,
4613 eWLAN_PAL_FALSE);
4614 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004615 wpalTimerStart(&channelCb->healthMonitorTimer,
4616 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004617 }
4618 }
4619
4620 /*Try to reclaim resources*/
4621 dxeTXCompleteProcessing(dxeCtxt);
4622
4623 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4624 because its fragment size is larger than DXE free resource. */
4625 if(0 < ucTxResReq)
4626 {
4627 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4628 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4629 {
4630 /* DXE has not been in low resource condition. DXE forces to kick off
4631 TX tranmit */
4632 if((eWLAN_PAL_FALSE == inLowRes) &&
4633 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4634 {
4635 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4636 WDTS_CHANNEL_TX_LOW_PRI,
4637 eWLAN_PAL_FALSE);
4638 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4639 WDTS_CHANNEL_TX_LOW_PRI,
4640 eWLAN_PAL_TRUE);
4641 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4642 }
4643 }
4644 else
4645 {
4646 /* DXE doesn't have enough free DXE resources. Put the channel
4647 to low resource condition. */
4648 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4649 {
4650 /* Put the channel to low resource condition */
4651 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4652 WDTS_CHANNEL_TX_LOW_PRI,
4653 eWLAN_PAL_FALSE);
4654 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004655 wpalTimerStart(&channelCb->healthMonitorTimer,
4656 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004657 }
4658 }
4659 }
4660
4661 return status;
4662}
4663
4664/*==========================================================================
4665 @ Function Name
4666 WLANDXE_Stop
4667
4668 @ Description
4669 Stop DXE channels and DXE engine operations
4670 Disable all channel interrupt
4671 Stop all channel operation
4672
4673 @ Parameters
4674 pVoid pDXEContext : DXE Control Block
4675
4676 @ Return
4677 wpt_status
4678===========================================================================*/
4679wpt_status WLANDXE_Stop
4680(
4681 void *pDXEContext
4682)
4683{
4684 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4685 wpt_uint32 idx;
4686 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4687
4688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004689 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004690
4691 /* Sanity */
4692 if(NULL == pDXEContext)
4693 {
4694 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4695 "WLANDXE_Stop Invalid DXE CB");
4696 return eWLAN_PAL_STATUS_E_INVAL;
4697 }
4698
4699 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4700 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4701 {
Yue Ma7faf58c2013-04-25 12:04:13 -07004702 if(VOS_TIMER_STATE_RUNNING == wpalTimerGetCurStatus(&dxeCtxt->dxeChannel[idx].healthMonitorTimer))
4703 {
4704 wpalTimerStop(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4705 }
4706
Jeff Johnson295189b2012-06-20 16:38:30 -07004707 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4708 if(eWLAN_PAL_STATUS_SUCCESS != status)
4709 {
4710 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4711 "WLANDXE_Stop Channel %d Stop Fail", idx);
4712 return status;
4713 }
4714 }
4715
4716 /* During Stop unregister interrupt */
4717 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4718 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4719
4720 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004721 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004722 return status;
4723}
4724
4725/*==========================================================================
4726 @ Function Name
4727 WLANDXE_Close
4728
4729 @ Description
4730 Close DXE channels
4731 Free DXE related resources
4732 DXE descriptor free
4733 Descriptor control block free
4734 Pre allocated RX buffer free
4735
4736 @ Parameters
4737 pVoid pDXEContext : DXE Control Block
4738
4739 @ Return
4740 wpt_status
4741===========================================================================*/
4742wpt_status WLANDXE_Close
4743(
4744 void *pDXEContext
4745)
4746{
4747 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4748 wpt_uint32 idx;
4749 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4750#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4751 wpt_uint32 sIdx;
4752 WLANDXE_ChannelCBType *channel = NULL;
4753 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4754 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4755#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4756
4757 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004758 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004759
4760 /* Sanity */
4761 if(NULL == pDXEContext)
4762 {
4763 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4764 "WLANDXE_Stop Invalid DXE CB");
4765 return eWLAN_PAL_STATUS_E_INVAL;
4766 }
4767
4768 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4769 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4770 {
4771 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004772 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4773 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
4774 {
4775 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
4776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004777 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4778#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4779 channel = &dxeCtxt->dxeChannel[idx];
4780 crntDescCB = channel->headCtrlBlk;
4781 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4782 {
4783 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4784 wpalMemoryFree((void *)crntDescCB);
4785 crntDescCB = nextDescCB;
4786 if(NULL == crntDescCB)
4787 {
4788 break;
4789 }
4790 }
4791#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4792 }
4793
4794 if(NULL != dxeCtxt->rxIsrMsg)
4795 {
4796 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4797 }
4798 if(NULL != dxeCtxt->txIsrMsg)
4799 {
4800 wpalMemoryFree(dxeCtxt->txIsrMsg);
4801 }
4802 if(NULL != dxeCtxt->rxPktAvailMsg)
4803 {
4804 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4805 }
4806
4807 wpalMemoryFree(pDXEContext);
4808
4809 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004810 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004811 return status;
4812}
4813
4814/*==========================================================================
4815 @ Function Name
4816 WLANDXE_TriggerTX
4817
4818 @ Description
4819 TBD
4820
4821 @ Parameters
4822 pVoid pDXEContext : DXE Control Block
4823
4824 @ Return
4825 wpt_status
4826===========================================================================*/
4827wpt_status WLANDXE_TriggerTX
4828(
4829 void *pDXEContext
4830)
4831{
4832 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4833
4834 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004835 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004836
4837 /* TBD */
4838
4839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004840 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 return status;
4842}
4843
4844/*==========================================================================
4845 @ Function Name
4846 dxeTxThreadSetPowerStateEventHandler
4847
4848 @ Description
4849 If WDI sends set power state req, this event handler will be called in Tx
4850 thread context
4851
4852 @ Parameters
4853 void *msgPtr
4854 Event MSG
4855
4856 @ Return
4857 None
4858===========================================================================*/
4859void dxeTxThreadSetPowerStateEventHandler
4860(
4861 wpt_msg *msgPtr
4862)
4863{
4864 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4865 WLANDXE_CtrlBlkType *dxeCtxt;
4866 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4867 WLANDXE_PowerStateType reqPowerState;
4868
4869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004870 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004871
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4873 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4874 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4875
4876 switch(reqPowerState)
4877 {
4878 case WLANDXE_POWER_STATE_BMPS:
4879 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4880 {
4881 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4882 //based on amount of TX and RX activity - during this time any received
4883 // management frames will remain un-processed consuming RX buffers
4884 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4885 dxeCtxt->hostPowerState = reqPowerState;
4886 }
4887 else
4888 {
4889 status = eWLAN_PAL_STATUS_E_INVAL;
4890 }
4891 break;
4892 case WLANDXE_POWER_STATE_IMPS:
4893 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4894 {
4895 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4896 }
4897 else
4898 {
4899 status = eWLAN_PAL_STATUS_E_INVAL;
4900 }
4901 break;
4902 case WLANDXE_POWER_STATE_FULL:
4903 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4904 {
4905 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4906 }
4907 dxeCtxt->hostPowerState = reqPowerState;
4908 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4909 break;
4910 case WLANDXE_POWER_STATE_DOWN:
4911 WLANDXE_Stop((void *)dxeCtxt);
4912 break;
4913 default:
4914 //assert
4915 break;
4916 }
4917
4918 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4919 {
4920 dxeCtxt->setPowerStateCb(status,
4921 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4922 }
Ravali85acf6b2012-12-12 14:01:38 -08004923 else
4924 {
4925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4926 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
4927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004928 /* Free MSG buffer */
4929 wpalMemoryFree(msgPtr);
4930 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004931 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 return;
4933}
4934
4935
4936/*==========================================================================
4937 @ Function Name
4938 dxeRxThreadSetPowerStateEventHandler
4939
4940 @ Description
4941 If WDI sends set power state req, this event handler will be called in Rx
4942 thread context
4943
4944 @ Parameters
4945 void *msgPtr
4946 Event MSG
4947
4948 @ Return
4949 None
4950===========================================================================*/
4951void dxeRxThreadSetPowerStateEventHandler
4952(
4953 wpt_msg *msgPtr
4954)
4955{
4956 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4957
4958 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004959 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004960
4961 /* Now serialise the message through Tx thread also to make sure
4962 * no register access when RIVA is in powersave */
4963 /*Use the same message pointer just change the call back function */
4964 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4965 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4966 msgPtr);
4967 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4968 {
4969 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4970 "Tx thread Set power state req serialize fail status=%d",
4971 status, 0, 0);
4972 }
4973
4974 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004975 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004976}
4977
4978/*==========================================================================
4979 @ Function Name
4980 WLANDXE_SetPowerState
4981
4982 @ Description
4983 From Client let DXE knows what is the WLAN HW(RIVA) power state
4984
4985 @ Parameters
4986 pVoid pDXEContext : DXE Control Block
4987 WLANDXE_PowerStateType powerState
4988
4989 @ Return
4990 wpt_status
4991===========================================================================*/
4992wpt_status WLANDXE_SetPowerState
4993(
4994 void *pDXEContext,
4995 WDTS_PowerStateType powerState,
4996 WDTS_SetPSCbType cBack
4997)
4998{
4999 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5000 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5001 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005002 wpt_msg *rxCompMsg;
5003 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005004
5005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005006 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 if(NULL == pDXEContext)
5008 {
5009 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5010 "NULL pDXEContext passed by caller", 0, 0, 0);
5011 return eWLAN_PAL_STATUS_E_FAILURE;
5012 }
5013 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5014
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 switch(powerState)
5016 {
5017 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005018 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5019 {
5020 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5021 if(NULL == txDescReSyncMsg)
5022 {
5023 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5024 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5025 }
5026 else
5027 {
5028 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5029 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5030 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5031 txDescReSyncMsg);
5032 if(eWLAN_PAL_STATUS_SUCCESS != status)
5033 {
5034 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5035 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5036 }
5037 }
5038 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 hostPowerState = WLANDXE_POWER_STATE_FULL;
5040 break;
5041 case WDTS_POWER_STATE_BMPS:
5042 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5043 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5044 break;
5045 case WDTS_POWER_STATE_IMPS:
5046 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5047 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5048 break;
5049 case WDTS_POWER_STATE_DOWN:
5050 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5051 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5052 break;
5053 default:
5054 hostPowerState = WLANDXE_POWER_STATE_MAX;
5055 }
5056
5057 // A callback i.e. ACK back is needed only when we want to enable BMPS
5058 // and the data/management path is active because we want to ensure
5059 // DXE registers are not accessed when RIVA may be power-collapsed. So
5060 // we need a callback in enter_bmps_req (the request to RIVA is sent
5061 // only after ACK back from TX thread). A callback is not needed in
5062 // finish_scan_req during BMPS since data-path is resumed only in
5063 // finish_scan_rsp and no management frames are sent in between. No
5064 // callback is needed when going from BMPS enabled to BMPS suspended/
5065 // disabled when it is known that RIVA is awake and cannot enter power
5066 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5067 // init_scan_rsp
5068 if ( cBack )
5069 {
5070 //serialize through Rx thread
5071 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5072 if(NULL == rxCompMsg)
5073 {
5074 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5075 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5076 return eWLAN_PAL_STATUS_E_RESOURCES;
5077 }
5078
5079 /* Event type, where it must be defined???? */
5080 /* THIS MUST BE CLEARED ASAP
5081 txCompMsg->type = TX_COMPLETE; */
5082 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5083 rxCompMsg->pContext = pDxeCtrlBlk;
5084 rxCompMsg->val = hostPowerState;
5085 rxCompMsg->ptr = cBack;
5086 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5087 rxCompMsg);
5088 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5089 {
5090 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5091 "Rx thread Set power state req serialize fail status=%d",
5092 status, 0, 0);
5093 }
5094 }
5095 else
5096 {
5097 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5098 {
5099 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5100 {
5101 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5102 }
5103 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5104 {
5105 /* Requested Full power from exit IMPS, reenable the interrupts*/
5106 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5107 {
5108 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5109 /* Enable RX interrupt at here, if new PS is not IMPS */
5110 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5111 if(eWLAN_PAL_STATUS_SUCCESS != status)
5112 {
5113 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005114 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005115 return status;
5116 }
5117 }
5118 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5119 {
5120 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005121 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005122 /* Enable RX interrupt at here, if new PS is not IMPS */
5123 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5124 if(eWLAN_PAL_STATUS_SUCCESS != status)
5125 {
5126 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005127 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005128 return status;
5129 }
5130 }
5131 }
5132 pDxeCtrlBlk->hostPowerState = hostPowerState;
5133 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5134 }
5135 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5136 {
5137 pDxeCtrlBlk->hostPowerState = hostPowerState;
5138 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5139 }
5140 else
5141 {
5142 HDXE_ASSERT(0);
5143 }
5144 }
5145
5146 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005147 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005148
5149 return status;
5150}
5151
5152/*==========================================================================
5153 @ Function Name
5154 WLANDXE_GetFreeTxDataResNumber
5155
5156 @ Description
5157 Returns free descriptor numbers for TX data channel (TX high priority)
5158
5159 @ Parameters
5160 pVoid pDXEContext : DXE Control Block
5161
5162 @ Return
5163 wpt_uint32 Free descriptor number of TX high pri ch
5164===========================================================================*/
5165wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5166(
5167 void *pDXEContext
5168)
5169{
5170 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005171 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005172
5173 if(NULL == pDXEContext)
5174 {
5175 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5176 "NULL parameter passed by caller", 0, 0, 0);
5177 return (0);
5178 }
5179
5180 return
5181 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5182}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005183
5184/*==========================================================================
5185 @ Function Name
5186 WLANDXE_ChannelDebug
5187
5188 @ Description
5189 Display DXE Channel debugging information
5190 User may request to display DXE channel snapshot
5191 Or if host driver detects any abnormal stcuk may display
5192
5193 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005194 displaySnapshot : Display DXE snapshot option
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005195 enableStallDetect : Enable stall detect feature
5196 This feature will take effect to data performance
5197 Not integrate till fully verification
5198
5199 @ Return
5200 NONE
5201
5202===========================================================================*/
5203void WLANDXE_ChannelDebug
5204(
5205 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005206 wpt_boolean enableStallDetect
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005207)
5208{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005209 wpt_msg *channelDebugMsg;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005210 wpt_uint32 regValue;
5211 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5212
5213 /* Debug Type 1, Display current snapshot */
5214 if(displaySnapshot)
5215 {
5216 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5217 * This will not simply wakeup RIVA
5218 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005219 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005220 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5221 "Host power state %d, RIVA power state %d",
5222 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
5223 /* Get free BD count */
5224 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
5225 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5226 "TX Pending frames count %d, Current available BD %d",
5227 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005228
5229 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5230 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005231 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005232 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5233 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5234 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005235 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005236
5237 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5238 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5239 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005240 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005241 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5242 "Tx thread Set power state req serialize fail status=%d",
5243 status, 0, 0);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005244 }
5245 }
5246
5247 /* Debug Type 2, toggling stall detect enable/disable */
5248 if(enableStallDetect)
5249 {
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005250 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5251 "DXE TX Stall detect",
5252 0, 0, 0);
5253 /* Start Stall detect timer and detect stall */
5254 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5255 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005256 }
5257 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005258}