blob: cfd6750534b61eecefa06dae4049020419bfb7ce [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 */
Leo Changac1d3612013-07-01 15:15:51 -07002904 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002905
2906 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002907 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002908
Leo Changac1d3612013-07-01 15:15:51 -07002909 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
2910 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2911 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07002912 {
Leo Changac1d3612013-07-01 15:15:51 -07002913 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002914 }
2915
2916 channelEntry->numFragmentCurrentChain = 0;
2917 currentCtrlBlk = channelEntry->headCtrlBlk;
2918
2919 /* Initialize interator, TX is fragmented */
2920#ifdef FEATURE_R33D
2921 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2922 status = wpalPrepareTxFrame(palPacket,
2923 &frameVector,
2924 &Va);
2925#else
2926 status = wpalLockPacketForTransfer(palPacket);
2927 if(eWLAN_PAL_STATUS_SUCCESS != status)
2928 {
2929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2930 "dxeTXPushFrame unable to lock packet");
2931 return status;
2932 }
2933
2934 status = wpalIteratorInit(&iterator, palPacket);
2935#endif /* FEATURE_R33D */
2936 if(eWLAN_PAL_STATUS_SUCCESS != status)
2937 {
2938 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2939 "dxeTXPushFrame iterator init fail");
2940 return status;
2941 }
2942
2943 /* !!!! Revisit break condition !!!!!!! */
2944 while(1)
2945 {
2946 /* Get current descriptor pointer from current control block */
2947 currentDesc = currentCtrlBlk->linkedDesc;
2948 if(NULL == firstDesc)
2949 {
2950 firstDesc = currentCtrlBlk->linkedDesc;
2951 }
2952 /* All control block will have same palPacket Pointer
2953 * to make logic simpler */
2954 currentCtrlBlk->xfrFrame = palPacket;
2955
2956 /* Get next fragment physical address and fragment size
2957 * if this is the first trial, will get first physical address
2958 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2959#ifdef FEATURE_R33D
2960 if(fragCount == frameVector.num_frg)
2961 {
2962 break;
2963 }
2964 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2965 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2966 xferSize = frameVector.frg[fragCount].size;
2967 fragCount++;
2968 HDXE_ASSERT(0 != xferSize);
2969 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2970#else
2971 status = wpalIteratorNext(&iterator,
2972 palPacket,
2973 &sourcePhysicalAddress,
2974 &xferSize);
2975 if((NULL == sourcePhysicalAddress) ||
2976 (0 == xferSize))
2977 {
2978 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2979 "dxeTXPushFrame end of current frame");
2980 break;
2981 }
2982 if(eWLAN_PAL_STATUS_SUCCESS != status)
2983 {
2984 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2985 "dxeTXPushFrame Get next frame fail");
2986 return status;
2987 }
2988#endif /* FEATURE_R33D */
2989
2990 /* This is the LAST descriptor valid for this transaction */
2991 LastDesc = currentCtrlBlk->linkedDesc;
2992
2993 /* Program DXE descriptor */
2994 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2995 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2996
2997 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2998 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2999 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3000 {
3001 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3002 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3003 }
3004 else
3005 {
3006 /* Test specific H2H transfer, destination address already set
3007 * Do Nothing */
3008 }
3009 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3010
3011 /* Program channel control register */
3012 /* First frame not set VAL bit, why ??? */
3013 if(0 == channelEntry->numFragmentCurrentChain)
3014 {
3015 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3016 }
3017 else
3018 {
3019 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3020 }
3021
3022 /* Update statistics */
3023 channelEntry->numFragmentCurrentChain++;
3024 channelEntry->numFreeDesc--;
3025 channelEntry->numRsvdDesc++;
3026
3027 /* Get next control block */
3028 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3029 }
3030 channelEntry->numTotalFrame++;
3031 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3032 "NUM TX FRAG %d, Total Frame %d",
3033 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3034
3035 /* Program Channel control register
3036 * Set as end of packet
3037 * Enable interrupt also for first code lock down
3038 * performace optimization, this will be revisited */
3039 if(NULL == LastDesc)
3040 {
3041 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3042 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3043 return eWLAN_PAL_STATUS_E_FAULT;
3044 }
3045 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3046 /* Now First one also Valid ????
3047 * this procedure will prevent over handle descriptor from previous
3048 * TX trigger */
3049 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3050
3051 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3052 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3053 {
3054 /* Update channel head as next avaliable linked slot */
3055 channelEntry->headCtrlBlk = currentCtrlBlk;
Leo Changac1d3612013-07-01 15:15:51 -07003056 if(isEmpty)
3057 {
3058 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3059 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3060 "SMSM_ret LO=%d HI=%d",
3061 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3062 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3063 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3064 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
3065 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003066 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003067 }
3068
3069 /* If DXE use external descriptor, registers are not needed to be programmed
3070 * Just after finish to program descriptor, tirigger to send */
3071 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3072 {
3073 /* Issue a dummy read from the DXE descriptor DDR location to
3074 ensure that any previously posted write to the descriptor
3075 completes. */
3076 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3077 {
3078 //HDXE_ASSERT(0);
3079 }
3080
3081 /* Everything is ready
3082 * Trigger to start DMA */
3083 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3084 channelEntry->extraConfig.chan_mask);
3085 if(eWLAN_PAL_STATUS_SUCCESS != status)
3086 {
3087 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3088 "dxeTXPushFrame Write Channel Ctrl Register fail");
3089 return status;
3090 }
3091
3092 /* Update channel head as next avaliable linked slot */
3093 channelEntry->headCtrlBlk = currentCtrlBlk;
3094
3095 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003096 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003097 return status;
3098 }
3099
3100 /* If DXE not use external descriptor, program each registers */
3101 /* Circular buffer handle not need to program DESC register???
3102 * GEN5 code not programed RING buffer case
3103 * REVISIT THIS !!!!!! */
3104 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3105 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3106 {
3107 /* Destination address, assigned Work Q */
3108 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3109 channelEntry->channelConfig.refWQ);
3110 if(eWLAN_PAL_STATUS_SUCCESS != status)
3111 {
3112 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3113 "dxeTXPushFrame Program dest address register fail");
3114 return status;
3115 }
3116 /* If descriptor format is SHORT */
3117 if(channelEntry->channelConfig.useShortDescFmt)
3118 {
3119 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3120 0);
3121 if(eWLAN_PAL_STATUS_SUCCESS != status)
3122 {
3123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3124 "dxeTXPushFrame Program dest address register fail");
3125 return status;
3126 }
3127 }
3128 else
3129 {
3130 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3131 "dxeTXPushFrame LONG Descriptor Format!!!");
3132 }
3133 }
3134#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3135 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3136 {
3137 /* Destination address, Physical memory address */
3138 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3139 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3140 if(eWLAN_PAL_STATUS_SUCCESS != status)
3141 {
3142 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3143 "dxeTXPushFrame Program dest address register fail");
3144 return status;
3145 }
3146 /* If descriptor format is SHORT */
3147 if(channelEntry->channelConfig.useShortDescFmt)
3148 {
3149 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3150 0);
3151 if(eWLAN_PAL_STATUS_SUCCESS != status)
3152 {
3153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3154 "dxeTXPushFrame Program dest address register fail");
3155 return status;
3156 }
3157 }
3158 else
3159 {
3160 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3161 "dxeTXPushFrame LONG Descriptor Format!!!");
3162 }
3163 }
3164#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3165
3166 /* Program Source address register
3167 * This address is already programmed into DXE Descriptor
3168 * But register also upadte */
3169 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3170 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3171 if(eWLAN_PAL_STATUS_SUCCESS != status)
3172 {
3173 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3174 "dxeTXPushFrame Program src address register fail");
3175 return status;
3176 }
3177 /* If descriptor format is SHORT */
3178 if(channelEntry->channelConfig.useShortDescFmt)
3179 {
3180 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3181 0);
3182 if(eWLAN_PAL_STATUS_SUCCESS != status)
3183 {
3184 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3185 "dxeTXPushFrame Program dest address register fail");
3186 return status;
3187 }
3188 }
3189 else
3190 {
3191 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3192 "dxeTXPushFrame LONG Descriptor Format!!!");
3193 }
3194
3195 /* Linked list Descriptor pointer */
3196 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3197 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3198 if(eWLAN_PAL_STATUS_SUCCESS != status)
3199 {
3200 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3201 "dxeTXPushFrame Write DESC Address register fail");
3202 return status;
3203 }
3204 /* If descriptor format is SHORT */
3205 if(channelEntry->channelConfig.useShortDescFmt)
3206 {
3207 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3208 0);
3209 if(eWLAN_PAL_STATUS_SUCCESS != status)
3210 {
3211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3212 "dxeTXPushFrame Program dest address register fail");
3213 return status;
3214 }
3215 }
3216 else
3217 {
3218 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3219 "dxeTXPushFrame LONG Descriptor Format!!!");
3220 }
3221
3222 /* Transfer Size */
3223 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3224 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3225 xferSize);
3226 if(eWLAN_PAL_STATUS_SUCCESS != status)
3227 {
3228 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3229 "dxeTXPushFrame Write DESC Address register fail");
3230 return status;
3231 }
3232
3233 /* Everything is ready
3234 * Trigger to start DMA */
3235 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3236 channelEntry->extraConfig.chan_mask);
3237 if(eWLAN_PAL_STATUS_SUCCESS != status)
3238 {
3239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3240 "dxeTXPushFrame Write Channel Ctrl Register fail");
3241 return status;
3242 }
3243
3244 /* Update channel head as next avaliable linked slot */
3245 channelEntry->headCtrlBlk = currentCtrlBlk;
3246
3247 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003248 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003249 return status;
3250}
3251
3252/*==========================================================================
3253 @ Function Name
3254 dxeTXCompFrame
3255
3256 @ Description
3257 TX Frame transfer complete event handler
3258
3259 @ Parameters
3260 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3261 DXE host driver main control block
3262 WLANDXE_ChannelCBType *channelEntry
3263 Channel specific control block
3264
3265 @ Return
3266 PAL_STATUS_T
3267===========================================================================*/
3268static wpt_status dxeTXCompFrame
3269(
3270 WLANDXE_CtrlBlkType *hostCtxt,
3271 WLANDXE_ChannelCBType *channelEntry
3272)
3273{
3274 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3275 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3276 WLANDXE_DescType *currentDesc = NULL;
3277 wpt_uint32 descCtrlValue = 0;
3278 unsigned int *lowThreshold = NULL;
3279
3280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003281 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003282
3283 /* Sanity */
3284 if((NULL == hostCtxt) || (NULL == channelEntry))
3285 {
3286 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3287 "dxeTXCompFrame Invalid ARG");
3288 return eWLAN_PAL_STATUS_E_INVAL;
3289 }
3290
3291 if(NULL == hostCtxt->txCompCB)
3292 {
3293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3294 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003295 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003296 }
3297
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003298 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3299 if(eWLAN_PAL_STATUS_SUCCESS != status)
3300 {
3301 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3302 "dxeTXCompFrame Mutex Acquire fail");
3303 return status;
3304 }
3305
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 currentCtrlBlk = channelEntry->tailCtrlBlk;
3307 currentDesc = currentCtrlBlk->linkedDesc;
3308
3309 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3310 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003311 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3312 if(eWLAN_PAL_STATUS_SUCCESS != status)
3313 {
3314 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3315 "dxeTXCompFrame Mutex Release fail");
3316 return status;
3317 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003318 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003319 }
3320
3321 /* */
3322 while(1)
3323 {
3324// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3325 descCtrlValue = currentDesc->descCtrl.ctrl;
3326 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3327 {
3328 /* caught up with head, bail out */
3329 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3330 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3331 break;
3332 }
3333
3334 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
3335 channelEntry->numFreeDesc++;
3336 channelEntry->numRsvdDesc--;
3337
3338 /* Send Frame TX Complete notification with frame start fragment location */
3339 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3340 {
3341 hostCtxt->txCompletedFrames--;
3342#ifdef FEATURE_R33D
3343 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3344#else
3345 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3346 if (eWLAN_PAL_STATUS_SUCCESS != status)
3347 {
3348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3349 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003350 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3351 if(eWLAN_PAL_STATUS_SUCCESS != status)
3352 {
3353 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3354 "dxeTXCompFrame Mutex Release fail");
3355 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003356 return status;
3357 }
3358#endif /* FEATURE_R33D */
3359 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3360 currentCtrlBlk->xfrFrame,
3361 eWLAN_PAL_STATUS_SUCCESS);
3362 channelEntry->numFragmentCurrentChain = 0;
3363 }
3364 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3365 currentDesc = currentCtrlBlk->linkedDesc;
3366
3367 /* Break condition
3368 * Head control block is the control block must be programed for the next TX
3369 * so, head control block is not programmed control block yet
3370 * if loop encounte head control block, stop to complete
3371 * in theory, COMP CB must be called already ??? */
3372 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3373 {
3374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3375 "dxeTXCompFrame caught up with head ptr");
3376 break;
3377 }
3378 /* VALID Bit check ???? */
3379 }
3380
3381 /* Tail and Head Control block must be same */
3382 channelEntry->tailCtrlBlk = currentCtrlBlk;
3383
3384 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3385 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3386 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3387
3388 /* If specific channel hit low resource condition send notification to upper layer */
3389 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3390 (channelEntry->numFreeDesc > *lowThreshold))
3391 {
3392 /* Change it back if we raised it for fetching a remaining packet from TL */
3393 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3394 {
3395 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3396 }
3397
3398 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3399 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3400 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3401 channelEntry->channelType,
3402 eWLAN_PAL_TRUE);
3403 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003404 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003405 }
3406
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003407 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3408 if(eWLAN_PAL_STATUS_SUCCESS != status)
3409 {
3410 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3411 "dxeTXCompFrame Mutex Release fail");
3412 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003413
3414 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003415 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003416 return status;
3417}
3418
3419/*==========================================================================
3420 @ Function Name
3421 dxeTXEventHandler
3422
3423 @ Description
3424 If DXE HW sends TX related interrupt, this event handler will be called
3425 Handle higher priority channel first
3426 Figureout why interrupt happen and call appropriate final even handler
3427 TX complete or error happen
3428
3429 @ Parameters
3430 void *msgPtr
3431 Even MSG
3432
3433 @ Return
3434 PAL_STATUS_T
3435===========================================================================*/
3436void dxeTXEventHandler
3437(
3438 wpt_msg *msgPtr
3439)
3440{
3441 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3442 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3443 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3444 wpt_uint32 intSrc = 0;
3445 wpt_uint32 chStat = 0;
3446 WLANDXE_ChannelCBType *channelCb = NULL;
3447
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003448 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003449 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003450
3451 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003452 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003453
3454 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003455 dxeCtxt->ucTxMsgCnt = 0;
3456
3457 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3458 {
3459 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3460 "wlan: TX COMP WLAN Driver re-loading in progress");
3461 return;
3462 }
3463
Jeff Johnson295189b2012-06-20 16:38:30 -07003464 /* Return from here if the RIVA is in IMPS, to avoid register access */
3465 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3466 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003467 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003468 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003469 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003470 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3471 if(eWLAN_PAL_STATUS_SUCCESS != status)
3472 {
3473 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003474 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003475 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003476
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003477 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3478 if(eWLAN_PAL_STATUS_SUCCESS != status)
3479 {
3480 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3481 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3482 }
3483
3484 if(((dxeCtxt->txCompletedFrames) &&
3485 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3486 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003487 {
3488 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3489 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003491 "TX COMP INT Enabled, remain TX frame count on ring %d",
3492 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003493 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3494 the posibility of a race*/
3495 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3496 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003497 else
3498 {
3499 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3500 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3501 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3502 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3503 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003504 return;
3505 }
3506
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003507 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3509 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3510 {
3511 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3512 "DXE already stopped in TX event handler. Just return");
3513 return;
3514 }
3515
Jeff Johnson295189b2012-06-20 16:38:30 -07003516 /* Disable device interrupt */
3517 /* Read whole interrupt mask register and exclusive only this channel int */
3518 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3519 &intSrc);
3520 if(eWLAN_PAL_STATUS_SUCCESS != status)
3521 {
3522 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3523 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3524 return;
3525 }
3526 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3527 "TX Event Handler INT Source 0x%x", intSrc);
3528
3529 /* Test High Priority Channel is the INT source or not */
3530 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3531 if(intSrc & (1 << channelCb->assignedDMAChannel))
3532 {
3533 status = dxeChannelCleanInt(channelCb, &chStat);
3534 if(eWLAN_PAL_STATUS_SUCCESS != status)
3535 {
3536 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3537 "dxeTXEventHandler INT Clean up fail");
3538 return;
3539 }
3540
3541 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3542 {
3543 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003544 "%11s : 0x%x Error Reported, Reload Driver",
3545 channelType[channelCb->channelType], chStat);
3546 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3547 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003548 }
3549 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3550 {
3551 /* Handle TX complete for high priority channel */
3552 status = dxeTXCompFrame(dxeCtxt,
3553 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003554 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003555 }
3556 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3557 {
3558 /* Handle TX complete for high priority channel */
3559 status = dxeTXCompFrame(dxeCtxt,
3560 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003561 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003562 }
3563 else
3564 {
3565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3566 "dxeTXEventHandler TX HI status=%x", chStat);
3567 }
3568
3569 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3570 {
3571 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3572 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3573 }
3574
3575 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3576 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3577 }
3578
3579 /* Test Low Priority Channel interrupt is enabled or not */
3580 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3581 if(intSrc & (1 << channelCb->assignedDMAChannel))
3582 {
3583 status = dxeChannelCleanInt(channelCb, &chStat);
3584 if(eWLAN_PAL_STATUS_SUCCESS != status)
3585 {
3586 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3587 "dxeTXEventHandler INT Clean up fail");
3588 return;
3589 }
3590
3591 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3592 {
3593 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003594 "%11s : 0x%x Error Reported, Reload Driver",
3595 channelType[channelCb->channelType], chStat);
3596 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3597 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003598 }
3599 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3600 {
3601 /* Handle TX complete for low priority channel */
3602 status = dxeTXCompFrame(dxeCtxt,
3603 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003604 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003605 }
3606 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3607 {
3608 /* Handle TX complete for low priority channel */
3609 status = dxeTXCompFrame(dxeCtxt,
3610 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003611 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003612 }
3613 else
3614 {
3615 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3616 "dxeTXEventHandler TX LO status=%x", chStat);
3617 }
3618
3619 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3620 {
3621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3622 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3623 }
3624 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3625 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3626 }
3627
3628
3629#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3630 /* Test H2H TX Channel interrupt is enabled or not */
3631 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3632 if(intSrc & (1 << channelCb->assignedDMAChannel))
3633 {
3634 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3635 &chStat);
3636 if(eWLAN_PAL_STATUS_SUCCESS != status)
3637 {
3638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3639 "dxeChannelCleanInt Read CH STAT register fail");
3640 return;
3641 }
3642
3643 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3644 {
3645 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003646 "%11s : 0x%x Error Reported, Reload Driver",
3647 channelType[channelCb->channelType], chStat);
3648 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3649 wpalWlanReload();
Jeff Johnson295189b2012-06-20 16:38:30 -07003650 }
3651 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3652 {
3653 /* Handle TX complete for high priority channel */
3654 status = dxeTXCompFrame(dxeCtxt,
3655 channelCb);
3656 if(eWLAN_PAL_STATUS_SUCCESS != status)
3657 {
3658 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3659 "dxeTXEventHandler INT Clean up fail");
3660 return;
3661 }
3662 }
3663 else
3664 {
3665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3666 "unexpected channel state %d", chStat);
3667 }
3668 }
3669#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3670
3671 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3672 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3673 {
3674 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3675 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003676 if(0 != dxeCtxt->txCompletedFrames)
3677 {
3678 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3679 "TX COMP INT Enabled, remain TX frame count on ring %d",
3680 dxeCtxt->txCompletedFrames);
3681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 }
3683
3684 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3685 the posibility of a race*/
3686 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3687
3688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003689 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 return;
3691}
3692
3693
3694/*==========================================================================
3695 @ Function Name
3696 dxeTXCompleteProcessing
3697
3698 @ Description
3699 If DXE HW sends TX related interrupt, this event handler will be called
3700 Handle higher priority channel first
3701 Figureout why interrupt happen and call appropriate final even handler
3702 TX complete or error happen
3703
3704 @ Parameters
3705 dxeCtxt DXE context
3706
3707 @ Return
3708 PAL_STATUS_T
3709===========================================================================*/
3710void dxeTXCompleteProcessing
3711(
3712 WLANDXE_CtrlBlkType *dxeCtxt
3713)
3714{
3715 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3716 WLANDXE_ChannelCBType *channelCb = NULL;
3717
3718 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003719 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003720
3721 /* Test High Priority Channel is the INT source or not */
3722 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3723
3724 /* Handle TX complete for high priority channel */
3725 status = dxeTXCompFrame(dxeCtxt, channelCb);
3726
3727 /* Test Low Priority Channel interrupt is enabled or not */
3728 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3729
3730 /* Handle TX complete for low priority channel */
3731 status = dxeTXCompFrame(dxeCtxt, channelCb);
3732
3733 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3734 ((dxeCtxt->txCompletedFrames > 0) ||
3735 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3736 {
3737 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3738 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3739 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003740 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3742 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3743 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3744 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07003745
3746 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
3747 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
3748 {
3749 /* After TX Comp processing, still remaining frame on the DXE TX ring
3750 * And when push frame, RING was not empty marked
3751 * Then when push frame, no SMSM toggle happen
3752 * To avoid permanent TX stall, SMSM toggle is needed at here
3753 * With this toggle, host should gaurantee SMSM state should be changed */
3754 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
3755 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003757 }
3758
3759 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3760 the posibility of a race*/
3761 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3762
3763 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003764 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003765 return;
3766}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003767
3768/*==========================================================================
3769 @ Function Name
3770 dxeTXReSyncDesc
3771
3772 @ Description
3773 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3774 And HW programmed descriptor.
3775 If any async happen between HW/SW TX stall will happen
3776
3777 @ Parameters
3778 void *msgPtr
3779 Message pointer to sync with TX thread
3780
3781 @ Return
3782 NONE
3783===========================================================================*/
3784void dxeTXReSyncDesc
3785(
3786 wpt_msg *msgPtr
3787)
3788{
3789 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3790 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3791 wpt_uint32 nextDescReg;
3792 WLANDXE_ChannelCBType *channelEntry;
3793 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3794 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003795 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003796
3797 if(NULL == msgContent)
3798 {
3799 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3800 "dxeTXReSyncDesc Invalid Control Block");
3801 return;
3802 }
3803
3804 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3805 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3806 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3807
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003808 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003809 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003810 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3811 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3812 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3813 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3814 &nextDescReg);
3815 /* Async detect without TX pending frame */
3816 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003817 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003818 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003819 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003820 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3821 "TX Async no Pending frame");
3822 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry);
3823 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!");
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003824 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003825 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003826 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003827 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003828 /* Async detect with some TX pending frames
3829 * next descriptor register should sync with first valid descriptor */
3830 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003831 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003832 validCtrlBlk = channelEntry->tailCtrlBlk;
3833 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003834 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003835 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3836 {
3837 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3838 {
3839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3840 "TX Async");
3841 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3842 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3843 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3844 validCtrlBlk->linkedDescPhyAddr);
3845 }
3846 break;
3847 }
3848 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3849 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3850 {
3851 /* Finished to test till head control blcok, but could not find valid descriptor
3852 * from head to tail all descriptors are invalidated
3853 * host point of view head descriptor is next TX candidate
3854 * So, next descriptor control have to be programmed with head descriptor
3855 * check */
3856 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3857 {
3858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08003859 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003860 dxeChannelMonitor("!!! TX Async !!!", channelEntry);
3861 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!");
3862 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3863 validCtrlBlk->linkedDescPhyAddr);
3864 }
3865 break;
3866 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003867 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003868 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003869 }
3870
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003871 /* HW/SW descriptor resync is done.
3872 * Next if there are any valid descriptor in chain, Push to HW again */
3873 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3874 {
3875 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3876 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3877 {
3878 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3879 "%11s : No TX Pending frame",
3880 channelType[channelEntry->channelType]);
3881 /* No Pending frame, Do nothing */
3882 }
3883 else
3884 {
3885 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3886 "%11s : TX Pending frame, process it",
3887 channelType[channelEntry->channelType]);
3888 validCtrlBlk = channelEntry->tailCtrlBlk;
3889 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3890 {
3891 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3892 {
3893 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3894 "%11s : when exit IMPS found valid descriptor",
3895 channelType[channelEntry->channelType]);
3896
3897 /* Found valid descriptor, kick DXE */
3898 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3899 channelEntry->extraConfig.chan_mask);
3900 break;
3901 }
3902 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3903 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3904 {
3905 /* Finished to test till head control blcok, but could not find valid descriptor
3906 * from head to tail all descriptors are invalidated */
3907 break;
3908 }
3909 }
3910 }
3911 }
3912
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003913 wpalMemoryFree(msgPtr);
3914 return;
3915}
3916
Jeff Johnson295189b2012-06-20 16:38:30 -07003917/*==========================================================================
3918 @ Function Name
3919 dxeTXISR
3920
3921 @ Description
3922 TX interrupt ISR
3923 Platform will call this function if INT is happen
3924 This function must be registered into platform interrupt module
3925
3926 @ Parameters
3927 void *hostCtxt
3928 DXE host driver control context,
3929 pre registerd during interrupt registration
3930
3931 @ Return
3932 PAL_STATUS_T
3933===========================================================================*/
3934static void dxeTXISR
3935(
3936 void *hostCtxt
3937)
3938{
3939 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3940 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3941#ifdef FEATURE_R33D
3942 wpt_uint32 regValue;
3943#endif /* FEATURE_R33D */
3944
3945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003946 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003947
3948 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003949 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003950 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003951 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003952 /* Disable interrupt at here,
3953 IMPS or IMPS Pending state should not access RIVA register */
3954 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3955 if(eWLAN_PAL_STATUS_SUCCESS != status)
3956 {
3957 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3958 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3959 return;
3960 }
3961 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3962 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003963 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07003964 return;
3965 }
3966
3967#ifdef FEATURE_R33D
3968 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3969 &regValue);
3970 if(eWLAN_PAL_STATUS_SUCCESS != status)
3971 {
3972 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3973 "dxeTXCompISR Read INT_SRC_RAW fail");
3974 return;
3975 }
3976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3977 "INT_SRC_RAW 0x%x", regValue);
3978 if(0 == regValue)
3979 {
3980 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3981 "This is not DXE Interrupt, Reject it");
3982 return;
3983 }
3984#endif /* FEATURE_R33D */
3985
3986 /* Disable TX Complete Interrupt at here */
3987 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3988 if(eWLAN_PAL_STATUS_SUCCESS != status)
3989 {
3990 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3991 "dxeTXCompISR Disable TX complete interrupt fail");
3992 return;
3993 }
3994 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3995
3996
3997 if( dxeCtxt->ucTxMsgCnt )
3998 {
3999 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4000 "Avoiding serializing TX Complete event");
4001 return;
4002 }
4003
4004 dxeCtxt->ucTxMsgCnt = 1;
4005
4006 /* Serialize TX complete interrupt upon TX thread */
4007 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
4008 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4009 dxeCtxt->txIsrMsg);
4010 if(eWLAN_PAL_STATUS_SUCCESS != status)
4011 {
4012 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4013 "dxeTXCompISR interrupt serialize fail status=%d", status);
4014 }
4015
4016 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004017 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004018 return;
4019}
4020
4021/*-------------------------------------------------------------------------
4022 * Global Function
4023 *-------------------------------------------------------------------------*/
4024/*==========================================================================
4025 @ Function Name
4026 WLANDXE_Open
4027
4028 @ Description
4029 Open host DXE driver, allocate DXE resources
4030 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4031
4032 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004033 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004034
4035 @ Return
4036 pVoid DXE local module control block pointer
4037===========================================================================*/
4038void *WLANDXE_Open
4039(
4040 void
4041)
4042{
4043 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4044 unsigned int idx;
4045 WLANDXE_ChannelCBType *currentChannel = NULL;
4046 int smsmInitState;
4047#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4048 wpt_uint32 sIdx;
4049 WLANDXE_ChannelCBType *channel = NULL;
4050 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4051 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4052#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4053
4054 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004055 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004056
4057 /* This is temporary allocation */
4058 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4059 if(NULL == tempDxeCtrlBlk)
4060 {
4061 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4062 "WLANDXE_Open Control Block Alloc Fail");
4063 return NULL;
4064 }
4065 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4066
4067 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4068 if(eWLAN_PAL_STATUS_SUCCESS != status)
4069 {
4070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4071 "WLANDXE_Open Common Configuration Fail");
4072 WLANDXE_Close(tempDxeCtrlBlk);
4073 return NULL;
4074 }
4075
4076 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4077 {
4078 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4079 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4080 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
4081 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
4082 {
4083 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
4084 }
4085 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
4086 {
4087 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
4088 }
4089 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
4090 {
4091 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
4092 }
4093 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
4094 {
4095 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
4096 }
4097#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4098 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
4099 {
4100 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
4101 }
4102 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
4103 {
4104 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
4105 }
4106#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4107
4108 /* Config individual channels from channel default setup table */
4109 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4110 currentChannel);
4111 if(eWLAN_PAL_STATUS_SUCCESS != status)
4112 {
4113 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4114 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4115 WLANDXE_Close(tempDxeCtrlBlk);
4116 return NULL;
4117 }
4118
4119 /* Allocate DXE Control Block will be used by host DXE driver */
4120 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4121 if(eWLAN_PAL_STATUS_SUCCESS != status)
4122 {
4123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4124 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4125
4126 WLANDXE_Close(tempDxeCtrlBlk);
4127 return NULL;
4128 }
4129 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4130 if(eWLAN_PAL_STATUS_SUCCESS != status)
4131 {
4132 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4133 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4134 WLANDXE_Close(tempDxeCtrlBlk);
4135 return NULL;
4136 }
4137
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004138 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4139 dxeHealthMonitorTimeout,
4140 (void *)currentChannel);
4141 if(eWLAN_PAL_STATUS_SUCCESS != status)
4142 {
4143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4144 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4145 WLANDXE_Close(tempDxeCtrlBlk);
4146 return NULL;
4147 }
4148
4149 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4150 if(NULL == currentChannel->healthMonitorMsg)
4151 {
4152 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4153 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4154 WLANDXE_Close(tempDxeCtrlBlk);
4155 return NULL;
4156 }
4157 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4158 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4159 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4162 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4163 }
4164
4165 /* Allocate and Init RX READY ISR Serialize Buffer */
4166 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4167 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4168 {
4169 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4170 "WLANDXE_Open Alloc RX ISR Fail");
4171 WLANDXE_Close(tempDxeCtrlBlk);
4172 return NULL;
4173 }
4174 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4175 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4176 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4177
4178 /* Allocate and Init TX COMP ISR Serialize Buffer */
4179 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4180 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4181 {
4182 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4183 "WLANDXE_Open Alloc TX ISR Fail");
4184 WLANDXE_Close(tempDxeCtrlBlk);
4185 return NULL;
4186 }
4187 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4188 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4189 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4190
4191 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4192 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4193 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4194 {
4195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4196 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4197 WLANDXE_Close(tempDxeCtrlBlk);
4198 return NULL;
4199 }
4200 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4201 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4202 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4203
4204 tempDxeCtrlBlk->freeRXPacket = NULL;
4205 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4206 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4207 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004208 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004209 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004210
4211 /* Initialize SMSM state
4212 * Init State is
4213 * Clear TX Enable
4214 * RING EMPTY STATE */
4215 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4216 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4217 if(0 != smsmInitState)
4218 {
4219 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4220 "SMSM Channel init fail %d", smsmInitState);
4221 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4222 {
4223 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4224 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004225 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4226 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004227 wpalMemoryFree(tempDxeCtrlBlk);
4228 return NULL;
4229 }
4230
4231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4232 "WLANDXE_Open Success");
4233 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004234 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 return (void *)tempDxeCtrlBlk;
4236}
4237
4238/*==========================================================================
4239 @ Function Name
4240 WLANDXE_ClientRegistration
4241
4242 @ Description
4243 Make callback functions registration into DXE driver from DXE driver client
4244
4245 @ Parameters
4246 pVoid pDXEContext : DXE module control block
4247 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4248 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4249 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4250 void *userContext : DXE Cliennt control block
4251
4252 @ Return
4253 wpt_status
4254===========================================================================*/
4255wpt_status WLANDXE_ClientRegistration
4256(
4257 void *pDXEContext,
4258 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4259 WLANDXE_TxCompleteCbType txCompleteCB,
4260 WLANDXE_LowResourceCbType lowResourceCB,
4261 void *userContext
4262)
4263{
4264 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4265 WLANDXE_CtrlBlkType *dxeCtxt;
4266
4267 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004268 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004269
4270 /* Sanity */
4271 if(NULL == pDXEContext)
4272 {
4273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4274 "WLANDXE_ClientRegistration Invalid DXE CB");
4275 return eWLAN_PAL_STATUS_E_INVAL;
4276 }
4277
4278 if(NULL == rxFrameReadyCB)
4279 {
4280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4281 "WLANDXE_ClientRegistration Invalid RX READY CB");
4282 return eWLAN_PAL_STATUS_E_INVAL;
4283 }
4284
4285 if(NULL == txCompleteCB)
4286 {
4287 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4288 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4289 return eWLAN_PAL_STATUS_E_INVAL;
4290 }
4291
4292 if(NULL == lowResourceCB)
4293 {
4294 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4295 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4296 return eWLAN_PAL_STATUS_E_INVAL;
4297 }
4298
4299 if(NULL == userContext)
4300 {
4301 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4302 "WLANDXE_ClientRegistration Invalid userContext");
4303 return eWLAN_PAL_STATUS_E_INVAL;
4304 }
4305
4306 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4307
4308 /* Assign */
4309 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4310 dxeCtxt->txCompCB = txCompleteCB;
4311 dxeCtxt->lowResourceCB = lowResourceCB;
4312 dxeCtxt->clientCtxt = userContext;
4313
4314 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004315 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004316 return status;
4317}
4318
4319/*==========================================================================
4320 @ Function Name
4321 WLANDXE_Start
4322
4323 @ Description
4324 Start Host DXE driver
4325 Initialize DXE channels and start channel
4326
4327 @ Parameters
4328 pVoid pDXEContext : DXE module control block
4329
4330 @ Return
4331 wpt_status
4332===========================================================================*/
4333wpt_status WLANDXE_Start
4334(
4335 void *pDXEContext
4336)
4337{
4338 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4339 wpt_uint32 idx;
4340 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4341
4342 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004343 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004344
4345 /* Sanity */
4346 if(NULL == pDXEContext)
4347 {
4348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4349 "WLANDXE_Start Invalid DXE CB");
4350 return eWLAN_PAL_STATUS_E_INVAL;
4351 }
4352 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4353
4354 /* WLANDXE_Start called means DXE engine already initiates
4355 * And DXE HW is reset and init finished
4356 * But here to make sure HW is initialized, reset again */
4357 status = dxeEngineCoreStart(dxeCtxt);
4358 if(eWLAN_PAL_STATUS_SUCCESS != status)
4359 {
4360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4361 "WLANDXE_Start DXE HW init Fail");
4362 return status;
4363 }
4364
4365 /* Individual Channel Start */
4366 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4367 {
4368 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4369 "WLANDXE_Start Channel %s Start", channelType[idx]);
4370
4371 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4372 /* Make connection between DXE descriptor and DXE control block */
4373 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &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 Alloc DXE Descriptor Fail for channel %d", idx);
4378 return status;
4379 }
4380
4381 /* Program each channel register with configuration arguments */
4382 status = dxeChannelInitProgram(dxeCtxt,
4383 &dxeCtxt->dxeChannel[idx]);
4384 if(eWLAN_PAL_STATUS_SUCCESS != status)
4385 {
4386 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4387 "WLANDXE_Start %d Program DMA channel Fail", idx);
4388 return status;
4389 }
4390
4391 /* ??? Trigger to start DMA channel
4392 * This must be seperated from ??? */
4393 status = dxeChannelStart(dxeCtxt,
4394 &dxeCtxt->dxeChannel[idx]);
4395 if(eWLAN_PAL_STATUS_SUCCESS != status)
4396 {
4397 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4398 "WLANDXE_Start %d Channel Start Fail", idx);
4399 return status;
4400 }
4401 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4402 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4403 }
4404
4405 /* Register ISR to OS */
4406 /* Register TX complete interrupt into platform */
4407 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4408 dxeTXISR,
4409 dxeCtxt);
4410 if(eWLAN_PAL_STATUS_SUCCESS != status)
4411 {
4412 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4413 "WLANDXE_Start TX comp interrupt registration Fail");
4414 return status;
4415 }
4416
4417 /* Register RX ready interrupt into platform */
4418 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4419 dxeRXISR,
4420 dxeCtxt);
4421 if(eWLAN_PAL_STATUS_SUCCESS != status)
4422 {
4423 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4424 "WLANDXE_Start RX Ready interrupt registration Fail");
4425 return status;
4426 }
4427
4428 /* Enable system level ISR */
4429 /* Enable RX ready Interrupt at here */
4430 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4431 if(eWLAN_PAL_STATUS_SUCCESS != status)
4432 {
4433 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4434 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4435 return status;
4436 }
4437
4438 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004439 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004440 return status;
4441}
4442
4443/*==========================================================================
4444 @ Function Name
4445 WLANDXE_TXFrame
4446
4447 @ Description
4448 Trigger frame transmit from host to RIVA
4449
4450 @ Parameters
4451 pVoid pDXEContext : DXE Control Block
4452 wpt_packet pPacket : transmit packet structure
4453 WDTS_ChannelType channel : TX channel
4454
4455 @ Return
4456 wpt_status
4457===========================================================================*/
4458wpt_status WLANDXE_TxFrame
4459(
4460 void *pDXEContext,
4461 wpt_packet *pPacket,
4462 WDTS_ChannelType channel
4463)
4464{
4465 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4466 WLANDXE_ChannelCBType *currentChannel = NULL;
4467 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4468 unsigned int *lowThreshold = NULL;
4469
4470 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004471 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004472
4473 /* Sanity */
4474 if(NULL == pDXEContext)
4475 {
4476 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4477 "WLANDXE_Start Invalid DXE CB");
4478 return eWLAN_PAL_STATUS_E_INVAL;
4479 }
4480
4481 if(NULL == pPacket)
4482 {
4483 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4484 "WLANDXE_Start Invalid pPacket");
4485 return eWLAN_PAL_STATUS_E_INVAL;
4486 }
4487
4488 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4489 {
4490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4491 "WLANDXE_Start Invalid channel");
4492 return eWLAN_PAL_STATUS_E_INVAL;
4493 }
4494
4495 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4496
4497 currentChannel = &dxeCtxt->dxeChannel[channel];
4498
4499
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004500 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4501 if(eWLAN_PAL_STATUS_SUCCESS != status)
4502 {
4503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4504 "WLANDXE_TxFrame Mutex Acquire fail");
4505 return status;
4506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004507
4508 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4509 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4510 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4511
4512 /* Decide have to activate TX complete event or not */
4513 switch(dxeCtxt->txCompInt.txIntEnable)
4514 {
4515 /* TX complete interrupt will be activated when low DXE resource */
4516 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4517 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4518 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4519 {
4520 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4521 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4522 channel,
4523 eWLAN_PAL_FALSE);
4524 }
4525 break;
4526
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004527 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004528 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4529 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4530 {
4531 currentChannel->numFrameBeforeInt++;
4532 }
4533 break;
4534
4535 /* TX complete interrupt will be activated periodically */
4536 case WLANDXE_TX_COMP_INT_TIMER:
4537 break;
4538 }
4539
4540 dxeCtxt->txCompletedFrames++;
4541
4542 /* Update DXE descriptor, this is frame based
4543 * if a frame consist of N fragments, N Descriptor will be programed */
4544 status = dxeTXPushFrame(currentChannel, pPacket);
4545 if(eWLAN_PAL_STATUS_SUCCESS != status)
4546 {
4547 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4548 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004549 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4550 if(eWLAN_PAL_STATUS_SUCCESS != status)
4551 {
4552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4553 "WLANDXE_TxFrame Mutex Release fail");
4554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 return status;
4556 }
4557
4558 /* If specific channel hit low resource condition, send notification to upper layer */
4559 if(currentChannel->numFreeDesc <= *lowThreshold)
4560 {
4561 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4562 channel,
4563 eWLAN_PAL_FALSE);
4564 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004565
4566 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4567 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4568 channelType[currentChannel->channelType],
4569 currentChannel->numRsvdDesc);
4570 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4571 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4572 wpalTimerStart(&currentChannel->healthMonitorTimer,
4573 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004574 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004575 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4576 if(eWLAN_PAL_STATUS_SUCCESS != status)
4577 {
4578 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4579 "WLANDXE_TxFrame Mutex Release fail");
4580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004581
4582 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004583 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004584 return status;
4585}
4586
4587/*==========================================================================
4588 @ Function Name
4589 WLANDXE_CompleteTX
4590
4591 @ Description
4592 Informs DXE that the current series of Tx packets is complete
4593
4594 @ Parameters
4595 pContext pDXEContext : DXE Control Block
4596 ucTxResReq TX resource number required by TL/WDI
4597
4598 @ Return
4599 wpt_status
4600===========================================================================*/
4601wpt_status
4602WLANDXE_CompleteTX
4603(
4604 void* pContext,
4605 wpt_uint32 ucTxResReq
4606)
4607{
4608 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4609 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4610 WLANDXE_ChannelCBType *channelCb = NULL;
4611 wpt_boolean inLowRes;
4612
4613 /* Sanity Check */
4614 if( NULL == pContext )
4615 {
4616 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4617 "WLANDXE_CompleteTX invalid param");
4618 return eWLAN_PAL_STATUS_E_INVAL;
4619 }
4620
4621 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4622 inLowRes = channelCb->hitLowResource;
4623
4624 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4625 {
4626 /* Raise threshold temporarily if necessary */
4627 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4628
4629 if(eWLAN_PAL_FALSE == inLowRes)
4630 {
4631 /* Put the channel to low resource condition */
4632 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4633 WDTS_CHANNEL_TX_LOW_PRI,
4634 eWLAN_PAL_FALSE);
4635 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004636 wpalTimerStart(&channelCb->healthMonitorTimer,
4637 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004638 }
4639 }
4640
4641 /*Try to reclaim resources*/
4642 dxeTXCompleteProcessing(dxeCtxt);
4643
4644 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4645 because its fragment size is larger than DXE free resource. */
4646 if(0 < ucTxResReq)
4647 {
4648 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4649 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4650 {
4651 /* DXE has not been in low resource condition. DXE forces to kick off
4652 TX tranmit */
4653 if((eWLAN_PAL_FALSE == inLowRes) &&
4654 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4655 {
4656 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4657 WDTS_CHANNEL_TX_LOW_PRI,
4658 eWLAN_PAL_FALSE);
4659 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4660 WDTS_CHANNEL_TX_LOW_PRI,
4661 eWLAN_PAL_TRUE);
4662 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4663 }
4664 }
4665 else
4666 {
4667 /* DXE doesn't have enough free DXE resources. Put the channel
4668 to low resource condition. */
4669 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4670 {
4671 /* Put the channel to low resource condition */
4672 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4673 WDTS_CHANNEL_TX_LOW_PRI,
4674 eWLAN_PAL_FALSE);
4675 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004676 wpalTimerStart(&channelCb->healthMonitorTimer,
4677 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 }
4679 }
4680 }
4681
4682 return status;
4683}
4684
4685/*==========================================================================
4686 @ Function Name
4687 WLANDXE_Stop
4688
4689 @ Description
4690 Stop DXE channels and DXE engine operations
4691 Disable all channel interrupt
4692 Stop all channel operation
4693
4694 @ Parameters
4695 pVoid pDXEContext : DXE Control Block
4696
4697 @ Return
4698 wpt_status
4699===========================================================================*/
4700wpt_status WLANDXE_Stop
4701(
4702 void *pDXEContext
4703)
4704{
4705 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4706 wpt_uint32 idx;
4707 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4708
4709 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004710 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004711
4712 /* Sanity */
4713 if(NULL == pDXEContext)
4714 {
4715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4716 "WLANDXE_Stop Invalid DXE CB");
4717 return eWLAN_PAL_STATUS_E_INVAL;
4718 }
4719
4720 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4721 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4722 {
Yue Ma7faf58c2013-04-25 12:04:13 -07004723 if(VOS_TIMER_STATE_RUNNING == wpalTimerGetCurStatus(&dxeCtxt->dxeChannel[idx].healthMonitorTimer))
4724 {
4725 wpalTimerStop(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4726 }
4727
Jeff Johnson295189b2012-06-20 16:38:30 -07004728 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4729 if(eWLAN_PAL_STATUS_SUCCESS != status)
4730 {
4731 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4732 "WLANDXE_Stop Channel %d Stop Fail", idx);
4733 return status;
4734 }
4735 }
4736
4737 /* During Stop unregister interrupt */
4738 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4739 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4740
4741 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004742 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004743 return status;
4744}
4745
4746/*==========================================================================
4747 @ Function Name
4748 WLANDXE_Close
4749
4750 @ Description
4751 Close DXE channels
4752 Free DXE related resources
4753 DXE descriptor free
4754 Descriptor control block free
4755 Pre allocated RX buffer free
4756
4757 @ Parameters
4758 pVoid pDXEContext : DXE Control Block
4759
4760 @ Return
4761 wpt_status
4762===========================================================================*/
4763wpt_status WLANDXE_Close
4764(
4765 void *pDXEContext
4766)
4767{
4768 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4769 wpt_uint32 idx;
4770 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4771#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4772 wpt_uint32 sIdx;
4773 WLANDXE_ChannelCBType *channel = NULL;
4774 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4775 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4776#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4777
4778 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004779 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004780
4781 /* Sanity */
4782 if(NULL == pDXEContext)
4783 {
4784 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4785 "WLANDXE_Stop Invalid DXE CB");
4786 return eWLAN_PAL_STATUS_E_INVAL;
4787 }
4788
4789 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4790 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4791 {
4792 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004793 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
4794 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
4795 {
4796 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
4797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004798 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4799#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4800 channel = &dxeCtxt->dxeChannel[idx];
4801 crntDescCB = channel->headCtrlBlk;
4802 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4803 {
4804 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4805 wpalMemoryFree((void *)crntDescCB);
4806 crntDescCB = nextDescCB;
4807 if(NULL == crntDescCB)
4808 {
4809 break;
4810 }
4811 }
4812#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4813 }
4814
4815 if(NULL != dxeCtxt->rxIsrMsg)
4816 {
4817 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4818 }
4819 if(NULL != dxeCtxt->txIsrMsg)
4820 {
4821 wpalMemoryFree(dxeCtxt->txIsrMsg);
4822 }
4823 if(NULL != dxeCtxt->rxPktAvailMsg)
4824 {
4825 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4826 }
4827
4828 wpalMemoryFree(pDXEContext);
4829
4830 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004831 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 return status;
4833}
4834
4835/*==========================================================================
4836 @ Function Name
4837 WLANDXE_TriggerTX
4838
4839 @ Description
4840 TBD
4841
4842 @ Parameters
4843 pVoid pDXEContext : DXE Control Block
4844
4845 @ Return
4846 wpt_status
4847===========================================================================*/
4848wpt_status WLANDXE_TriggerTX
4849(
4850 void *pDXEContext
4851)
4852{
4853 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4854
4855 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004856 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004857
4858 /* TBD */
4859
4860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004861 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004862 return status;
4863}
4864
4865/*==========================================================================
4866 @ Function Name
4867 dxeTxThreadSetPowerStateEventHandler
4868
4869 @ Description
4870 If WDI sends set power state req, this event handler will be called in Tx
4871 thread context
4872
4873 @ Parameters
4874 void *msgPtr
4875 Event MSG
4876
4877 @ Return
4878 None
4879===========================================================================*/
4880void dxeTxThreadSetPowerStateEventHandler
4881(
4882 wpt_msg *msgPtr
4883)
4884{
4885 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4886 WLANDXE_CtrlBlkType *dxeCtxt;
4887 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4888 WLANDXE_PowerStateType reqPowerState;
4889
4890 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004891 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004892
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4894 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4895 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4896
4897 switch(reqPowerState)
4898 {
4899 case WLANDXE_POWER_STATE_BMPS:
4900 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4901 {
4902 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4903 //based on amount of TX and RX activity - during this time any received
4904 // management frames will remain un-processed consuming RX buffers
4905 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4906 dxeCtxt->hostPowerState = reqPowerState;
4907 }
4908 else
4909 {
4910 status = eWLAN_PAL_STATUS_E_INVAL;
4911 }
4912 break;
4913 case WLANDXE_POWER_STATE_IMPS:
4914 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4915 {
4916 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4917 }
4918 else
4919 {
4920 status = eWLAN_PAL_STATUS_E_INVAL;
4921 }
4922 break;
4923 case WLANDXE_POWER_STATE_FULL:
4924 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4925 {
4926 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4927 }
4928 dxeCtxt->hostPowerState = reqPowerState;
4929 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4930 break;
4931 case WLANDXE_POWER_STATE_DOWN:
4932 WLANDXE_Stop((void *)dxeCtxt);
4933 break;
4934 default:
4935 //assert
4936 break;
4937 }
4938
4939 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4940 {
4941 dxeCtxt->setPowerStateCb(status,
4942 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4943 }
Ravali85acf6b2012-12-12 14:01:38 -08004944 else
4945 {
4946 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4947 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
4948 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 /* Free MSG buffer */
4950 wpalMemoryFree(msgPtr);
4951 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004952 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 return;
4954}
4955
4956
4957/*==========================================================================
4958 @ Function Name
4959 dxeRxThreadSetPowerStateEventHandler
4960
4961 @ Description
4962 If WDI sends set power state req, this event handler will be called in Rx
4963 thread context
4964
4965 @ Parameters
4966 void *msgPtr
4967 Event MSG
4968
4969 @ Return
4970 None
4971===========================================================================*/
4972void dxeRxThreadSetPowerStateEventHandler
4973(
4974 wpt_msg *msgPtr
4975)
4976{
4977 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4978
4979 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004980 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004981
4982 /* Now serialise the message through Tx thread also to make sure
4983 * no register access when RIVA is in powersave */
4984 /*Use the same message pointer just change the call back function */
4985 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4986 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4987 msgPtr);
4988 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4989 {
4990 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4991 "Tx thread Set power state req serialize fail status=%d",
4992 status, 0, 0);
4993 }
4994
4995 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004996 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004997}
4998
4999/*==========================================================================
5000 @ Function Name
5001 WLANDXE_SetPowerState
5002
5003 @ Description
5004 From Client let DXE knows what is the WLAN HW(RIVA) power state
5005
5006 @ Parameters
5007 pVoid pDXEContext : DXE Control Block
5008 WLANDXE_PowerStateType powerState
5009
5010 @ Return
5011 wpt_status
5012===========================================================================*/
5013wpt_status WLANDXE_SetPowerState
5014(
5015 void *pDXEContext,
5016 WDTS_PowerStateType powerState,
5017 WDTS_SetPSCbType cBack
5018)
5019{
5020 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5021 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5022 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005023 wpt_msg *rxCompMsg;
5024 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005025
5026 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005027 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 if(NULL == pDXEContext)
5029 {
5030 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5031 "NULL pDXEContext passed by caller", 0, 0, 0);
5032 return eWLAN_PAL_STATUS_E_FAILURE;
5033 }
5034 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5035
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 switch(powerState)
5037 {
5038 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005039 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5040 {
5041 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5042 if(NULL == txDescReSyncMsg)
5043 {
5044 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5045 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5046 }
5047 else
5048 {
5049 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5050 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5051 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5052 txDescReSyncMsg);
5053 if(eWLAN_PAL_STATUS_SUCCESS != status)
5054 {
5055 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5056 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5057 }
5058 }
5059 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005060 hostPowerState = WLANDXE_POWER_STATE_FULL;
5061 break;
5062 case WDTS_POWER_STATE_BMPS:
5063 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5064 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5065 break;
5066 case WDTS_POWER_STATE_IMPS:
5067 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5068 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5069 break;
5070 case WDTS_POWER_STATE_DOWN:
5071 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5072 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5073 break;
5074 default:
5075 hostPowerState = WLANDXE_POWER_STATE_MAX;
5076 }
5077
5078 // A callback i.e. ACK back is needed only when we want to enable BMPS
5079 // and the data/management path is active because we want to ensure
5080 // DXE registers are not accessed when RIVA may be power-collapsed. So
5081 // we need a callback in enter_bmps_req (the request to RIVA is sent
5082 // only after ACK back from TX thread). A callback is not needed in
5083 // finish_scan_req during BMPS since data-path is resumed only in
5084 // finish_scan_rsp and no management frames are sent in between. No
5085 // callback is needed when going from BMPS enabled to BMPS suspended/
5086 // disabled when it is known that RIVA is awake and cannot enter power
5087 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5088 // init_scan_rsp
5089 if ( cBack )
5090 {
5091 //serialize through Rx thread
5092 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5093 if(NULL == rxCompMsg)
5094 {
5095 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5096 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5097 return eWLAN_PAL_STATUS_E_RESOURCES;
5098 }
5099
5100 /* Event type, where it must be defined???? */
5101 /* THIS MUST BE CLEARED ASAP
5102 txCompMsg->type = TX_COMPLETE; */
5103 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5104 rxCompMsg->pContext = pDxeCtrlBlk;
5105 rxCompMsg->val = hostPowerState;
5106 rxCompMsg->ptr = cBack;
5107 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5108 rxCompMsg);
5109 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5110 {
5111 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5112 "Rx thread Set power state req serialize fail status=%d",
5113 status, 0, 0);
5114 }
5115 }
5116 else
5117 {
5118 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5119 {
5120 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5121 {
5122 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5123 }
5124 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5125 {
5126 /* Requested Full power from exit IMPS, reenable the interrupts*/
5127 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5128 {
5129 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5130 /* Enable RX interrupt at here, if new PS is not IMPS */
5131 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5132 if(eWLAN_PAL_STATUS_SUCCESS != status)
5133 {
5134 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005135 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005136 return status;
5137 }
5138 }
5139 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5140 {
5141 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005142 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005143 /* Enable RX interrupt at here, if new PS is not IMPS */
5144 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5145 if(eWLAN_PAL_STATUS_SUCCESS != status)
5146 {
5147 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005148 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005149 return status;
5150 }
5151 }
5152 }
5153 pDxeCtrlBlk->hostPowerState = hostPowerState;
5154 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5155 }
5156 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5157 {
5158 pDxeCtrlBlk->hostPowerState = hostPowerState;
5159 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5160 }
5161 else
5162 {
5163 HDXE_ASSERT(0);
5164 }
5165 }
5166
5167 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005168 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005169
5170 return status;
5171}
5172
5173/*==========================================================================
5174 @ Function Name
5175 WLANDXE_GetFreeTxDataResNumber
5176
5177 @ Description
5178 Returns free descriptor numbers for TX data channel (TX high priority)
5179
5180 @ Parameters
5181 pVoid pDXEContext : DXE Control Block
5182
5183 @ Return
5184 wpt_uint32 Free descriptor number of TX high pri ch
5185===========================================================================*/
5186wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5187(
5188 void *pDXEContext
5189)
5190{
5191 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005192 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005193
5194 if(NULL == pDXEContext)
5195 {
5196 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5197 "NULL parameter passed by caller", 0, 0, 0);
5198 return (0);
5199 }
5200
5201 return
5202 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5203}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005204
5205/*==========================================================================
5206 @ Function Name
5207 WLANDXE_ChannelDebug
5208
5209 @ Description
5210 Display DXE Channel debugging information
5211 User may request to display DXE channel snapshot
5212 Or if host driver detects any abnormal stcuk may display
5213
5214 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005215 displaySnapshot : Display DXE snapshot option
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005216 enableStallDetect : Enable stall detect feature
5217 This feature will take effect to data performance
5218 Not integrate till fully verification
5219
5220 @ Return
5221 NONE
5222
5223===========================================================================*/
5224void WLANDXE_ChannelDebug
5225(
5226 wpt_boolean displaySnapshot,
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005227 wpt_boolean enableStallDetect
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005228)
5229{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005230 wpt_msg *channelDebugMsg;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005231 wpt_uint32 regValue;
5232 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5233
5234 /* Debug Type 1, Display current snapshot */
5235 if(displaySnapshot)
5236 {
5237 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5238 * This will not simply wakeup RIVA
5239 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005240 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005241 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5242 "Host power state %d, RIVA power state %d",
5243 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState);
5244 /* Get free BD count */
5245 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
5246 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5247 "TX Pending frames count %d, Current available BD %d",
5248 tempDxeCtrlBlk->txCompletedFrames, (int)regValue);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005249
5250 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5251 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005252 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005253 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5254 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5255 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005256 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005257
5258 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5259 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5260 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005261 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005262 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5263 "Tx thread Set power state req serialize fail status=%d",
5264 status, 0, 0);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005265 }
5266 }
5267
5268 /* Debug Type 2, toggling stall detect enable/disable */
5269 if(enableStallDetect)
5270 {
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005271 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5272 "DXE TX Stall detect",
5273 0, 0, 0);
5274 /* Start Stall detect timer and detect stall */
5275 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5276 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005277 }
5278 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005279}