blob: 2e586c86477b2312c7b6eaaf01d18024228d686c [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * 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.
Leo Chang416afe02013-07-01 13:58:13 -070020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Jeff Johnson295189b2012-06-20 16:38:30 -070028/**=========================================================================
29
30 @file wlan_qct_dxe.c
31
32 @brief
33
34 This file contains the external API exposed by the wlan data transfer abstraction layer module.
Jeff Johnson295189b2012-06-20 16:38:30 -070035========================================================================*/
36
37/*===========================================================================
38
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45
46 $Header:$ $DateTime: $ $Author: $
47
48
49when who what, where, why
50-------- --- ----------------------------------------------------------
5108/03/10 schang Created module.
52
53===========================================================================*/
54
55/*===========================================================================
56
57 INCLUDE FILES FOR MODULE
58
59===========================================================================*/
60
61/*----------------------------------------------------------------------------
62 * Include Files
63 * -------------------------------------------------------------------------*/
64#include "wlan_qct_dxe.h"
65#include "wlan_qct_dxe_i.h"
66#include "wlan_qct_pal_device.h"
67#ifdef FEATURE_R33D
68#include "wlan_qct_pal_bus.h"
69#endif /* FEATURE_R33D */
70
71/*----------------------------------------------------------------------------
72 * Local Definitions
73 * -------------------------------------------------------------------------*/
74//#define WLANDXE_DEBUG_CH_INFO_DUMP
75
76/* Temporary configuration defines
77 * Have to find out permanent solution */
78#define T_WLANDXE_MAX_DESCRIPTOR_COUNT 40
79#define T_WLANDXE_MAX_FRAME_SIZE 2000
80#define T_WLANDXE_TX_INT_ENABLE_FCOUNT 1
81#define T_WLANDXE_MEMDUMP_BYTE_PER_LINE 16
82#define T_WLANDXE_MAX_RX_PACKET_WAIT 6000
Mihir Shetefdc9f532014-01-09 15:03:02 +053083#define T_WLANDXE_SSR_TIMEOUT 5000
Leo Chang5edb2d32013-04-03 13:32:58 -070084#define T_WLANDXE_PERIODIC_HEALTH_M_TIME 2500
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -070085#define T_WLANDXE_MAX_HW_ACCESS_WAIT 2000
Jeff Johnsone7245742012-09-05 17:12:55 -070086#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -070087
Leo Chang094ece82013-04-23 17:57:41 -070088#define WLANPAL_RX_INTERRUPT_PRO_MASK 0x20
89#define WLANDXE_RX_INTERRUPT_PRO_UNMASK 0x5F
Leo Chang00708f62013-12-03 20:21:51 -080090
91/* 1msec busy wait in case CSR is not valid */
92#define WLANDXE_CSR_NEXT_READ_WAIT 1000
93/* CSR max retry count */
94#define WLANDXE_CSR_MAX_READ_COUNT 30
95
96
Jeff Johnson295189b2012-06-20 16:38:30 -070097/* This is temporary fot the compile
98 * WDI will release official version
99 * This must be removed */
100#define WDI_GET_PAL_CTX() NULL
101
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103/*-------------------------------------------------------------------------
104 * Local Varables
105 *-------------------------------------------------------------------------*/
106/* This is temp, someone have to allocate for me, and must be part of global context */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700107static WLANDXE_CtrlBlkType *tempDxeCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -0700108static char *channelType[WDTS_CHANNEL_MAX] =
109 {
110 "TX_LOW_PRI",
111 "TX_HIGH_PRI",
112 "RX_LOW_PRI",
113#ifndef WLANDXE_TEST_CHANNEL_ENABLE
114 "RX_HIGH_PRI",
115#else
116 "H2H_TEST_TX",
117 "H2H_TEST_RX"
118#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
119 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700120static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700121
122/*-------------------------------------------------------------------------
123 * External Function Proto Type
124 *-------------------------------------------------------------------------*/
125
126/*-------------------------------------------------------------------------
127 * Local Function Proto Type
128 *-------------------------------------------------------------------------*/
129static wpt_status dxeRXFrameSingleBufferAlloc
130(
131 WLANDXE_CtrlBlkType *dxeCtxt,
132 WLANDXE_ChannelCBType *channelEntry,
133 WLANDXE_DescCtrlBlkType *currentCtrlBlock
134);
135
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700136static wpt_status dxeNotifySmsm
137(
138 wpt_boolean kickDxe,
139 wpt_boolean ringEmpty
140);
141
Mihir Shetefdc9f532014-01-09 15:03:02 +0530142static void dxeStartSSRTimer
143(
144 WLANDXE_CtrlBlkType *dxeCtxt
145);
146
Jeff Johnson295189b2012-06-20 16:38:30 -0700147/*-------------------------------------------------------------------------
148 * Local Function
149 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700150/*==========================================================================
151 @ Function Name
152 dxeChannelMonitor
153
154 @ Description
155
156 @ Parameters
157 WLANDXE_ChannelCBType *channelEntry
158 Channel specific control block
159
160 @ Return
161 wpt_status
162
163===========================================================================*/
164static wpt_status dxeChannelMonitor
165(
166 char *monitorDescription,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530167 WLANDXE_ChannelCBType *channelEntry,
168 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700169)
170{
171 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
172
Jeff Johnsone7245742012-09-05 17:12:55 -0700173 if((NULL == monitorDescription) || (NULL == channelEntry))
174 {
175 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
176 "INVALID Input ARG");
177 return eWLAN_PAL_STATUS_E_INVAL;
178 }
179
180 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
181 {
182 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
183 "INVALID Channel type");
184 return eWLAN_PAL_STATUS_E_INVAL;
185 }
186
Leo Chang345ef992013-07-12 10:17:29 -0700187 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
188 "%11s : HCBO %d, HCBDP 0x%x, HCBDC 0x%x,",
189 channelType[channelEntry->channelType],
190 channelEntry->headCtrlBlk->ctrlBlkOrder,
191 channelEntry->headCtrlBlk->linkedDescPhyAddr,
192 channelEntry->headCtrlBlk->linkedDesc->descCtrl.ctrl);
193 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
194 "%11s : TCBO %d, TCBDP 0x%x, TCBDC 0x%x",
195 channelType[channelEntry->channelType],
196 channelEntry->tailCtrlBlk->ctrlBlkOrder,
197 channelEntry->tailCtrlBlk->linkedDescPhyAddr,
198 channelEntry->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
199 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
200 "%11s : FDC %d, RDC %d, TFC %d",
201 channelType[channelEntry->channelType],
202 channelEntry->numFreeDesc,
203 channelEntry->numRsvdDesc,
204 channelEntry->numTotalFrame);
Jeff Johnson295189b2012-06-20 16:38:30 -0700205
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700206 if(channelLog)
207 {
208 channelLog->numDesc = channelEntry->numDesc;
209 channelLog->numFreeDesc = channelEntry->numFreeDesc;
210 channelLog->numRsvdDesc = channelEntry->numRsvdDesc;
211 channelLog->headDescOrder = channelEntry->headCtrlBlk->ctrlBlkOrder;
212 channelLog->tailDescOrder = channelEntry->tailCtrlBlk->ctrlBlkOrder;
213 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530214
Jeff Johnson295189b2012-06-20 16:38:30 -0700215 return status;
216}
217
Jeff Johnsone7245742012-09-05 17:12:55 -0700218#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700219/*==========================================================================
220 @ Function Name
221 dxeMemoryDump
222
223 @ Description
224
225 @ Parameters
226 WLANDXE_ChannelCBType *channelEntry
227 Channel specific control block
228
229 @ Return
230 wpt_status
231
232===========================================================================*/
233static wpt_status dxeMemoryDump
234(
235 wpt_uint8 *dumpPointer,
236 wpt_uint32 dumpSize,
237 char *dumpTarget
238)
239{
240 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
241 wpt_uint32 numBytes = 0;
242 wpt_uint32 idx;
243
Jeff Johnsone7245742012-09-05 17:12:55 -0700244 if((NULL == dumpPointer) ||
245 (NULL == dumpTarget))
246 {
247 return status;
248 }
249
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
251 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
253 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
254
255 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
256 for(idx = 0; idx < dumpSize; idx++)
257 {
258 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
259 "0x%2x ", dumpPointer[idx]);
260 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
261 {
262 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
263 }
264 }
265 if(0 != numBytes)
266 {
267 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
268 }
269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
270 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
271
272 return status;
273}
Jeff Johnsone7245742012-09-05 17:12:55 -0700274#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700275
276/*==========================================================================
277 @ Function Name
278 dxeDescriptorDump
279
280 @ Description
281
282 @ Parameters
283 WLANDXE_ChannelCBType *channelEntry
284 Channel specific control block
285
286 @ Return
287 wpt_status
288
289===========================================================================*/
290wpt_status dxeDescriptorDump
291(
292 WLANDXE_ChannelCBType *channelEntry,
293 WLANDXE_DescType *targetDesc,
294 wpt_uint32 fragmentOrder
295)
296{
297 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
298
299
Jeff Johnsone7245742012-09-05 17:12:55 -0700300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
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,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700303 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700305 fragmentOrder + 1,
306 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700307
Jeff Johnsone7245742012-09-05 17:12:55 -0700308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 "CTRL WORD 0x%x, TransferSize %d",
310 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
311 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
314 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
315 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
316 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700317 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
319
320 return status;
321}
322
323/*==========================================================================
324 @ Function Name
325 dxeChannelRegisterDump
326
327 @ Description
328
329 @ Parameters
330 WLANDXE_ChannelCBType *channelEntry
331 Channel specific control block
332
333 @ Return
334 wpt_status
335
336===========================================================================*/
337wpt_status dxeChannelRegisterDump
338(
339 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530340 char *dumpTarget,
341 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700342)
343{
Leo Chang345ef992013-07-12 10:17:29 -0700344 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
345 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
346
347 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
348 * This will not simply wakeup RIVA
349 * Just incase TX not wanted stuck, Trigger TX again */
350 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
351 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
352 wpalSleep(10);
Jeff Johnson295189b2012-06-20 16:38:30 -0700353
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700354 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
355 {
356 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
357 "INVALID Channel type");
358 return eWLAN_PAL_STATUS_E_INVAL;
359 }
360
Leo Chang345ef992013-07-12 10:17:29 -0700361 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &chDescReg);
362 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
363 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &chControlReg);
364 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &chStatusReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365
Leo Chang345ef992013-07-12 10:17:29 -0700366 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
367 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x",
368 channelType[channelEntry->channelType],
369 chControlReg, chStatusReg, chDescReg, chLDescReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700371 if(channelLog)
372 {
373 channelLog->ctrlRegVal = chControlReg;
374 channelLog->statRegVal = chStatusReg;
375 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700376
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 return status;
378}
Jeff Johnsone7245742012-09-05 17:12:55 -0700379
380/*==========================================================================
381 @ Function Name
382 dxeChannelAllDescDump
383
384 @ Description
385 Dump all DXE descriptors within assigned channe;
386
387 @ Parameters
388 WLANDXE_ChannelCBType *channelEntry
389
390 @ Return
391 NONE
392
393===========================================================================*/
394void dxeChannelAllDescDump
395(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700396 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530397 WDTS_ChannelType channel,
398 wpt_log_data_stall_channel_type *channelLog
Jeff Johnsone7245742012-09-05 17:12:55 -0700399)
400{
401 wpt_uint32 channelLoop;
402 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700403 wpt_uint32 previousCtrlValue = 0;
Leo Chang345ef992013-07-12 10:17:29 -0700404 wpt_uint32 previousCtrlValid = 0;
405 wpt_uint32 currentCtrlValid = 0;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700406 wpt_uint32 valDescCount = 0;
407 wpt_uint32 invalDescCount = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700408
409 targetCtrlBlk = channelEntry->headCtrlBlk;
410
411 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Leo Chang345ef992013-07-12 10:17:29 -0700412 "%11s : %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700413 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700414 channelEntry->numDesc,
415 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700416 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
417
418 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
419 (WDTS_CHANNEL_RX_HIGH_PRI == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700420 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700421 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700422 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700423 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
424 {
425 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
426 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
427 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
428 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700429 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
430 {
431 valDescCount++;
432 }
433 else
434 {
435 invalDescCount++;
436 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700437 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
438 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700439 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700440 }
441 else
442 {
Leo Chang345ef992013-07-12 10:17:29 -0700443 /* Head Descriptor is valid or not */
444 previousCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
445 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700446 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
447 {
Leo Chang345ef992013-07-12 10:17:29 -0700448 currentCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700449 if(currentCtrlValid)
450 {
451 valDescCount++;
452 }
453 else
454 {
455 invalDescCount++;
456 }
Leo Chang345ef992013-07-12 10:17:29 -0700457 if(currentCtrlValid != previousCtrlValid)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700458 {
459 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
460 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
461 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
462 }
Leo Chang345ef992013-07-12 10:17:29 -0700463 previousCtrlValid = currentCtrlValid;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700464 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
465 }
466 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530467
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700468 if(channelLog)
469 {
470 channelLog->numValDesc = valDescCount;
471 channelLog->numInvalDesc = invalDescCount;
472 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530473
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700474 return;
475}
476
477/*==========================================================================
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530478 @ Function Name
479 dxeErrChannelDebug
480
481 @ Description
482 Dump channel information for which Error interrupt has occured
483
484 @ Parameters
485 WLANDXE_ChannelCBType *channelCb
486
487 @ Return
488 NONE
489
490===========================================================================*/
491void dxeErrChannelDebug
492(
Mihir Shete79d6b582014-03-12 17:54:07 +0530493 WLANDXE_ChannelCBType *channelCb,
494 wpt_uint32 chStatusReg
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530495)
496{
497 wpt_log_data_stall_channel_type channelLog;
Mihir Shete79d6b582014-03-12 17:54:07 +0530498 wpt_uint32 chLDescReg, channelLoop;
499 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530500
501 dxeChannelMonitor("INT_ERR", channelCb, &channelLog);
502 dxeDescriptorDump(channelCb, channelCb->headCtrlBlk->linkedDesc, 0);
503 dxeChannelRegisterDump(channelCb, "INT_ERR", &channelLog);
504 dxeChannelAllDescDump(channelCb, channelCb->channelType, &channelLog);
505 wpalMemoryCopy(channelLog.channelName,
506 "INT_ERR",
507 WPT_TRPT_CHANNEL_NAME);
508 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelCb->channelType);
509#ifdef FEATURE_WLAN_DIAG_SUPPORT
510 wpalPacketStallDumpLog();
511#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Mihir Shete79d6b582014-03-12 17:54:07 +0530512 switch ((chStatusReg & WLANDXE_CH_STAT_ERR_CODE_MASK) >>
513 WLANDXE_CH_STAT_ERR_CODE_OFFSET)
514 {
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530515
Mihir Shete79d6b582014-03-12 17:54:07 +0530516 case WLANDXE_ERROR_PRG_INV_B2H_SRC_QID:
517 case WLANDXE_ERROR_PRG_INV_B2H_DST_QID:
518 case WLANDXE_ERROR_PRG_INV_B2H_SRC_IDX:
519 case WLANDXE_ERROR_PRG_INV_H2B_SRC_QID:
520 case WLANDXE_ERROR_PRG_INV_H2B_DST_QID:
521 case WLANDXE_ERROR_PRG_INV_H2B_DST_IDX:
522 {
523 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
524 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
525 wpalSleep(10);
526
527 if(channelCb->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
528 {
529 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
530 "%s: Invalid Channel", __func__);
531 break;
532 }
533
534 wpalReadRegister(channelCb->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
535
536 targetCtrlBlk = channelCb->headCtrlBlk;
537
538 for(channelLoop = 0; channelLoop < channelCb->numDesc; channelLoop++)
539 {
540 if (targetCtrlBlk->linkedDescPhyAddr == chLDescReg)
541 {
542 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
543 "%11s :CHx_DESCL: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
544 channelType[channelCb->channelType],
545 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
546 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
547 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
548 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
549
550 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
551
552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
553 "%11s :Next Desc: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
554 channelType[channelCb->channelType],
555 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
556 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
557 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
558 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
559 break;
560 }
561 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
562 }
563 break;
564 }
565 default:
566 {
567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
568 "%s: No Debug Inormation", __func__);
569 break;
570 }
571
572 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530573 wpalFwDumpReq(17, 0, 0, 0, 0);
574}
575/*==========================================================================
576 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700577 dxeTxThreadChannelDebugHandler
578
579 @ Description
580 Dump TX channel information
581
582 @ Parameters
583 Wwpt_msg *msgPtr
584
585 @ Return
586 NONE
587
588===========================================================================*/
589void dxeTxThreadChannelDebugHandler
590(
591 wpt_msg *msgPtr
592)
593{
594 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700595 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700596
597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700598 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700599
600 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
601 * This will not simply wakeup RIVA
602 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700603 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
604 {
605 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530606 &tempDxeCtrlBlk->dxeChannel[channelLoop],
607 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700608 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530609 "Abnormal successive empty interrupt",
610 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700611 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530612 channelLoop,
613 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700614
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700615 wpalMemoryCopy(channelLog.channelName,
616 channelType[channelLoop],
617 WPT_TRPT_CHANNEL_NAME);
618 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700619 }
620
Leo Chang345ef992013-07-12 10:17:29 -0700621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700622 "================== DXE Dump End ======================");
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700623 wpalMemoryFree(msgPtr);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700624
625#ifdef FEATURE_WLAN_DIAG_SUPPORT
626 wpalPacketStallDumpLog();
627#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700628 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700629 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700630 return;
631}
632
633/*==========================================================================
634 @ Function Name
635 dxeRxThreadChannelDebugHandler
636
637 @ Description
638 Dump RX channel information
639
640 @ Parameters
641 Wwpt_msg *msgPtr
642
643 @ Return
644 NONE
645
646===========================================================================*/
647void dxeRxThreadChannelDebugHandler
648(
649 wpt_msg *msgPtr
650)
651{
652 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
653 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700654 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700655
656 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700657 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700658
659 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
660 * This will not simply wakeup RIVA
661 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700662 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
663 {
664 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530665 &tempDxeCtrlBlk->dxeChannel[channelLoop],
666 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700667 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530668 "Abnormal successive empty interrupt",
669 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700670 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530671 channelLoop, &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700672
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700673 wpalMemoryCopy(channelLog.channelName,
674 channelType[channelLoop],
675 WPT_TRPT_CHANNEL_NAME);
676 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530677
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700678 }
679
680 /* Now serialise the message through Tx thread also to make sure
681 * no register access when RIVA is in powersave */
682 /*Use the same message pointer just change the call back function */
683 msgPtr->callback = dxeTxThreadChannelDebugHandler;
684 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
685 msgPtr);
686 if ( eWLAN_PAL_STATUS_SUCCESS != status )
687 {
688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700689 "Tx thread state dump req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700690 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700691 }
692
693 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700694 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700695 return;
696}
Jeff Johnson295189b2012-06-20 16:38:30 -0700697
698/*==========================================================================
699 @ Function Name
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700700 dxeRXHealthMonitor
701
702 @ Description
703 Monitoring RX channel healthy stataus
704 If detect any problem, try to recover
705
706 @ Parameters
707 healthMonitorMsg MSG pointer.
708 will have low resource TX channel context
709
710 @ Return
711 NONE
712
713===========================================================================*/
714void dxeRXHealthMonitor
715(
716 wpt_msg *healthMonitorMsg
717)
718{
719 WLANDXE_ChannelCBType *channelCtrlBlk;
720 WLANDXE_ChannelCBType *testCHCtrlBlk;
721 wpt_uint32 regValue;
722 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
723 wpt_uint32 hwWakeLoop, chLoop;
724
725 if(NULL == healthMonitorMsg)
726 {
727 return;
728 }
729
730 /* Make wake up HW */
731 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
732 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Chang5edb2d32013-04-03 13:32:58 -0700733 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700734
735 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
736 {
737 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
738 if(0 != regValue)
739 {
740 break;
741 }
742 }
743
744 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
745 "Scheduled RX, num free BD/PDU %d, loop Count %d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700746 regValue, hwWakeLoop);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700747
748 for(chLoop = WDTS_CHANNEL_RX_LOW_PRI; chLoop < WDTS_CHANNEL_MAX; chLoop++)
749 {
750 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
751 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
752 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
753 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
754 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
755
756 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
757 "%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",
758 channelType[chLoop],
759 chControlReg, chStatusReg, chDescReg, chLDescReg,
760 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
761 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
762 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
763 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
764
765 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
766 (chLDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
767 {
768 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
769 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
770 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
771 channelType[chLoop],
772 chControlReg, chStatusReg, chDescReg, chLDescReg,
773 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
774 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
775 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
776 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
777 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700778 "%11s : RX CH EN Descriptor Async, resync it", channelType[chLoop]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700779 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
780 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
781 }
782 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
783 (chDescReg != testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr))
784 {
785 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
786 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
787 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
788 channelType[chLoop],
789 chControlReg, chStatusReg, chDescReg, chLDescReg,
790 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
791 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
792 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
793 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700795 "%11s : RX CH DIS Descriptor Async, resync it", channelType[chLoop]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700796 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
797 testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr);
798 }
799 }
800
801 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
802 if(channelCtrlBlk->hitLowResource)
803 {
804 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
805 "%11s : Still Low Resource, kick DXE TX and restart timer",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700806 channelType[channelCtrlBlk->channelType]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700807 /* Still Low Resource, Kick DXE again and start timer again */
808 wpalTimerStart(&channelCtrlBlk->healthMonitorTimer,
809 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
810 }
811 else
812 {
813 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
814 "%11s : Out from Low resource condition, do nothing",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700815 channelType[channelCtrlBlk->channelType]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700816 /* Recovered from low resource condition
817 * Not need to do anything */
818 }
819
820 return;
821}
822
823/*==========================================================================
824 @ Function Name
825 dxeTXHealthMonitor
826
827 @ Description
828 Monitoring TX channel healthy stataus
829 If detect any problem, try to recover
830
831 @ Parameters
832 healthMonitorMsg MSG pointer.
833 will have low resource TX channel context
834
835 @ Return
836 NONE
837
838===========================================================================*/
839void dxeTXHealthMonitor
840(
841 wpt_msg *healthMonitorMsg
842)
843{
844 WLANDXE_ChannelCBType *channelCtrlBlk;
845 WLANDXE_ChannelCBType *testCHCtrlBlk;
846 wpt_uint32 regValue;
847 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
848 wpt_uint32 hwWakeLoop, chLoop;
849 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
850
851 if(NULL == healthMonitorMsg)
852 {
853 return;
854 }
855
856 /* First of all kick TX channel
857 * This will fix if there is any problem with SMSM state */
858 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
859 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Chang5edb2d32013-04-03 13:32:58 -0700860 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700861
862 /* Wait till RIVA up */
863 for(hwWakeLoop = 0; hwWakeLoop < T_WLANDXE_MAX_HW_ACCESS_WAIT; hwWakeLoop++)
864 {
865 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
866 if(0 != regValue)
867 {
868 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
869 "num free BD/PDU %d, loop Count %d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700870 regValue, hwWakeLoop);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700871 break;
872 }
873 }
874
875 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
876 "Scheduled TX, num free BD/PDU %d, loop Count %d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700877 regValue, hwWakeLoop);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700878
879 for(chLoop = 0; chLoop < WDTS_CHANNEL_RX_LOW_PRI; chLoop++)
880 {
881 testCHCtrlBlk = &tempDxeCtrlBlk->dxeChannel[chLoop];
882 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXECtrlRegAddr, &chControlReg);
883 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEStatusRegAddr, &chStatusReg);
884 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr, &chDescReg);
885 wpalReadRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
886
887 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
888 "%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",
889 channelType[chLoop],
890 chControlReg, chStatusReg, chDescReg, chLDescReg,
891 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
892 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
893 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
894 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
895
896 if((chControlReg & WLANDXE_DESC_CTRL_VALID) &&
897 (chLDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
898 {
899 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
900 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
901 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
902 channelType[chLoop],
903 chControlReg, chStatusReg, chDescReg, chLDescReg,
904 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
905 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
906 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
907 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
908 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700909 "%11s : TX CH EN Descriptor Async, resync it", channelType[chLoop]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700910 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXELstDesclRegAddr,
911 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
912 }
913 else if(!(chControlReg & WLANDXE_DESC_CTRL_VALID) &&
914 (chDescReg != testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr))
915 {
916 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
917 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x, "
918 "HCBO %d, HCBDP 0x%x, HCBDC 0x%x, TCBO %d,TCBDP 0x%x, TCBDC 0x%x",
919 channelType[chLoop],
920 chControlReg, chStatusReg, chDescReg, chLDescReg,
921 testCHCtrlBlk->headCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->headCtrlBlk->linkedDescPhyAddr,
922 testCHCtrlBlk->headCtrlBlk->linkedDesc->descCtrl.ctrl,
923 testCHCtrlBlk->tailCtrlBlk->ctrlBlkOrder, testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr,
924 testCHCtrlBlk->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700926 "%11s : TX CH DIS Descriptor Async, resync it", channelType[chLoop]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700927 wpalWriteRegister(testCHCtrlBlk->channelRegister.chDXEDesclRegAddr,
928 testCHCtrlBlk->tailCtrlBlk->linkedDescPhyAddr);
929 }
930 }
931
932 /* TX channel test done, test RX channels */
933 channelCtrlBlk = (WLANDXE_ChannelCBType *)healthMonitorMsg->pContext;
934 channelCtrlBlk->healthMonitorMsg->callback = dxeRXHealthMonitor;
935 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
936 channelCtrlBlk->healthMonitorMsg);
937 if (eWLAN_PAL_STATUS_SUCCESS != status)
938 {
939 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700940 "TX Low resource Kick DXE MSG Serialize fail status=%d",
941 status);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700942 }
943
944 return;
945}
946
947/*==========================================================================
948 @ Function Name
949 dxeHealthMonitorTimeout
950
951 @ Description
952 Health Monitor timer started when TX channel low resource condition
953 And if reciovered from low resource condition, timer would not fired
954 Timer fired means during certain time, TX CH could not be recovered
955
956 @ Parameters
957 channelCtxt Low resource condition happen Channel context
958
959 @ Return
960 NONE
961
962===========================================================================*/
963void dxeHealthMonitorTimeout
964(
965 void *channelCtxt
966)
967{
968 WLANDXE_ChannelCBType *channelCtrlBlk;
969 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
970
971 if(NULL == channelCtxt)
972 {
973 return;
974 }
975
976 /* Timeout Fired, DXE TX should kick on TX thread
977 * Serailize to TX Thread */
978 channelCtrlBlk = (WLANDXE_ChannelCBType *)channelCtxt;
979 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
980 "%11s : Health Monitor timer expired",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700981 channelType[channelCtrlBlk->channelType]);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700982
983 channelCtrlBlk->healthMonitorMsg->callback = dxeTXHealthMonitor;
984 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
985 channelCtrlBlk->healthMonitorMsg);
986 if (eWLAN_PAL_STATUS_SUCCESS != status)
987 {
988 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700989 "TX Low resource Kick DXE MSG Serialize fail status=%d",
990 status);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -0700991 }
992
993 return;
994}
995
996/*==========================================================================
997 @ Function Name
Jeff Johnson295189b2012-06-20 16:38:30 -0700998 dxeCtrlBlkAlloc
999
1000 @ Description
1001 Allocate DXE Control block
1002 DXE control block will used by Host DXE driver only, internal structure
1003 Will make ring linked list
1004
1005 @ Parameters
1006 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1007 DXE host driver main control block
1008 WLANDXE_ChannelCBType *channelEntry
1009 Channel specific control block
1010
1011 @ Return
1012 wpt_status
1013
1014===========================================================================*/
1015static wpt_status dxeCtrlBlkAlloc
1016(
1017 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1018 WLANDXE_ChannelCBType *channelEntry
1019)
1020{
1021 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1022 unsigned int idx, fIdx;
1023 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1024 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
1025 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
1026 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1027
1028 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001029 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001030
1031 /* Sanity check */
1032 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1033 {
1034 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1035 "dxeCtrlBlkAlloc Channel Entry is not valid");
1036 return eWLAN_PAL_STATUS_E_INVAL;
1037 }
1038
1039 /* Allocate pre asigned number of control blocks */
1040 for(idx = 0; idx < channelEntry->numDesc; idx++)
1041 {
1042 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
1043 if(NULL == currentCtrlBlk)
1044 {
1045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1046 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
1047 channelEntry->channelType);
1048 freeCtrlBlk = channelEntry->headCtrlBlk;
1049 for(fIdx = 0; fIdx < idx; fIdx++)
1050 {
1051 if(NULL == freeCtrlBlk)
1052 {
1053 break;
1054 }
1055
1056 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
1057 wpalMemoryFree((void *)freeCtrlBlk);
1058 freeCtrlBlk = nextCtrlBlk;
1059 }
1060 return eWLAN_PAL_STATUS_E_FAULT;
1061 }
1062
1063 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
1064 /* Initialize common elements first */
1065 currentCtrlBlk->xfrFrame = NULL;
1066 currentCtrlBlk->linkedDesc = NULL;
1067 currentCtrlBlk->linkedDescPhyAddr = 0;
1068 currentCtrlBlk->ctrlBlkOrder = idx;
1069
1070 /* This is the first control block allocated
1071 * Next Control block is not allocated yet
1072 * head and tail must be first control block */
1073 if(0 == idx)
1074 {
1075 currentCtrlBlk->nextCtrlBlk = NULL;
1076 channelEntry->headCtrlBlk = currentCtrlBlk;
1077 channelEntry->tailCtrlBlk = currentCtrlBlk;
1078 }
1079 /* This is not first, not last control block
1080 * previous control block may has next linked block */
1081 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
1082 {
1083 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
1084 }
1085 /* This is last control blocl
1086 * next control block for the last control block is head, first control block
1087 * then whole linked list made RING */
1088 else if((channelEntry->numDesc - 1) == idx)
1089 {
1090 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
1091 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
1092 }
1093 else
1094 {
1095 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1096 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
1097 channelEntry->channelType);
1098 wpalMemoryFree(currentCtrlBlk);
1099 return eWLAN_PAL_STATUS_E_FAULT;
1100 }
1101
1102 prevCtrlBlk = currentCtrlBlk;
1103 channelEntry->numFreeDesc++;
1104 }
1105
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001106 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 return status;
1108}
1109
1110/*==========================================================================
1111 @ Function Name
1112 dxeDescLinkAlloc
1113
1114 @ Description
1115 Allocate DXE descriptor
1116 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
1117 Will make RING linked list
1118 Will be linked with Descriptor control block one by one
1119
1120 @ Parameters
1121 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1122 DXE host driver main control block
1123 WLANDXE_ChannelCBType *channelEntry
1124 Channel specific control block
1125 @ Return
1126 wpt_status
1127
1128===========================================================================*/
1129static wpt_status dxeDescAllocAndLink
1130(
1131 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1132 WLANDXE_ChannelCBType *channelEntry
1133)
1134{
1135 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1136 WLANDXE_DescType *currentDesc = NULL;
1137 WLANDXE_DescType *prevDesc = NULL;
1138 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1139 unsigned int idx;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301140 void *physAddressAlloc = NULL;
1141 wpt_uint32 physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07001142#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1143 WLANDXE_ChannelCBType *testTXChannelCB = &dxeCtrlBlk->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
1144 WLANDXE_DescCtrlBlkType *currDescCtrlBlk = testTXChannelCB->headCtrlBlk;
1145#endif /* WLANDXE_TEST_CHANNEL_ENABLE*/
1146
1147 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001148 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001149
1150 /* Sanity Check */
1151 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1152 {
1153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1154 "dxeDescLinkAlloc Channel Entry is not valid");
1155 return eWLAN_PAL_STATUS_E_INVAL;
1156 }
1157
1158 currentCtrlBlk = channelEntry->headCtrlBlk;
1159
1160#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1161 /* allocate all DXE descriptors for this channel in one chunk */
1162 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
1163 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301164 &physAddressAlloc);
1165 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 if(NULL == channelEntry->descriptorAllocation)
1167 {
1168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1169 "dxeDescLinkAlloc Descriptor Alloc Fail");
1170 return eWLAN_PAL_STATUS_E_RESOURCES;
1171 }
1172 currentDesc = channelEntry->descriptorAllocation;
1173#endif
1174
1175 /* Allocate pre asigned number of descriptor */
1176 for(idx = 0; idx < channelEntry->numDesc; idx++)
1177 {
1178#ifndef FEATURE_R33D
1179#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1180 // descriptors were allocated in a chunk -- use the current one
1181 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1182 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301183 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001184#else
1185 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1186 {
1187 // allocate a descriptor
1188 currentDesc = (WLANDXE_DescType *)wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType),
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301189 &physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301191 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001192 }
1193 else
1194 {
1195 currentDesc = currDescCtrlBlk->linkedDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301196 physAddress = currDescCtrlBlk->linkedDescPhyAddr;
Jeff Johnson295189b2012-06-20 16:38:30 -07001197 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1198 }
1199#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1200#else
1201#ifndef WLANDXE_TEST_CHANNEL_ENABLE
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301202 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1204 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301205 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
1206 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001207#else
1208 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
1209 {
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301210 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
1212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301213 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
1214 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 }
1216 else
1217 {
1218 currentDesc = currDescCtrlBlk->linkedDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301219 physAddress = currDescCtrlBlk->linkedDescPhyAddr;
Jeff Johnson295189b2012-06-20 16:38:30 -07001220 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
1221 }
1222#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1223#endif /* FEATURE_R33D */
1224 if(NULL == currentDesc)
1225 {
1226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1227 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
1228 channelEntry->channelType);
1229 return eWLAN_PAL_STATUS_E_FAULT;
1230 }
1231
Jeff Johnson295189b2012-06-20 16:38:30 -07001232 currentCtrlBlk->linkedDesc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301233 currentCtrlBlk->linkedDescPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07001234 /* First descriptor, next none
1235 * descriptor bottom location is first descriptor address */
1236 if(0 == idx)
1237 {
1238 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
1239 channelEntry->DescBottomLoc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301240 channelEntry->descBottomLocPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 }
1242 /* Not first, not last descriptor
1243 * may make link for previous descriptor with current descriptor
1244 * ENDIAN SWAP needed ????? */
1245 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
1246 {
1247 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301248 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07001249 }
1250 /* Last descriptor
1251 * make a ring by asign next pointer as first descriptor
1252 * ENDIAN SWAP NEEDED ??? */
1253 else if((channelEntry->numDesc - 1) == idx)
1254 {
1255 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301256 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07001257 currentDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301258 WLANDXE_U32_SWAP_ENDIAN(channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 }
1260
1261 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
1262 * Pre allocated and physical address must be assigned into
1263 * Corresponding DXE Descriptor */
1264#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1265 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1266 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1267 (WDTS_CHANNEL_H2H_TEST_RX == channelEntry->channelType))
1268#else
1269 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1270 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1271#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1272 {
1273 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
1274 channelEntry,
1275 currentCtrlBlk);
1276 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1277 {
1278 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1279 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1280 channelEntry->channelType);
1281 return status;
1282 }
1283 --channelEntry->numFreeDesc;
1284 }
1285
Leo Chang7e05f212013-07-01 19:54:15 -07001286 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1287 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1288 {
1289 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1290 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1291 }
1292 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1293 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1294 {
1295 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1296 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1297 }
1298 else
1299 {
1300 /* Just in case. H2H Test RX channel, do nothing
1301 * By Definition this must not happen */
1302 }
1303
Jeff Johnson295189b2012-06-20 16:38:30 -07001304 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1305 prevDesc = currentDesc;
1306
1307#ifndef FEATURE_R33D
1308#ifndef WLANDXE_TEST_CHANNEL_ENABLE
1309 // advance to the next pre-allocated descriptor in the chunk
1310 currentDesc++;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301311 physAddress = (physAddress + sizeof(WLANDXE_DescType));
Jeff Johnson295189b2012-06-20 16:38:30 -07001312#endif
1313#endif
1314 }
1315
1316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001317 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001318 return status;
1319}
1320
1321/*==========================================================================
1322 @ Function Name
1323
1324 @ Description
1325
1326 @ Parameters
1327
1328 @ Return
1329 wpt_status
1330
1331===========================================================================*/
1332static wpt_status dxeSetInterruptPath
1333(
1334 WLANDXE_CtrlBlkType *dxeCtrlBlk
1335)
1336{
1337 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1338 wpt_uint32 interruptPath = 0;
1339 wpt_uint32 idx;
1340 WLANDXE_ChannelCBType *channelEntry = NULL;
1341
1342 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001343 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001344
1345 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
1346 {
1347 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
1348#ifdef WLANDXE_TEST_CHANNEL_ENABLE
1349 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1350 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) ||
1351 (WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType))
1352#else
1353 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1354 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1355#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
1356 {
1357 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1358 }
1359 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1360 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1361 {
1362 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1363 }
1364 else
1365 {
1366 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1367 "H2H TEST RX???? %d", channelEntry->channelType);
1368 }
1369 }
1370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1371 "Interrupt Path Must be 0x%x", interruptPath);
1372 dxeCtrlBlk->interruptPath = interruptPath;
1373 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1374
1375 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001376 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001377 return status;
1378}
1379
1380/*==========================================================================
1381 @ Function Name
1382 dxeEngineCoreStart
1383
1384 @ Description
1385 Trigger to start RIVA DXE Hardware
1386
1387 @ Parameters
1388 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1389 DXE host driver main control block
1390
1391 @ Return
1392 wpt_status
1393
1394===========================================================================*/
1395static wpt_status dxeEngineCoreStart
1396(
1397 WLANDXE_CtrlBlkType *dxeCtrlBlk
1398)
1399{
1400 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1401 wpt_uint32 registerData = 0;
Leo Chang00708f62013-12-03 20:21:51 -08001402 wpt_uint8 readRetry;
Jeff Johnson295189b2012-06-20 16:38:30 -07001403
1404 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001405 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001406
Leo Chang00708f62013-12-03 20:21:51 -08001407#ifdef WCN_PRONTO
1408 /* Read default */
1409 wpalReadRegister(WLANDXE_CCU_SOFT_RESET, &registerData);
1410 registerData |= WLANDXE_DMA_CCU_DXE_RESET_MASK;
1411
1412 /* Make reset */
1413 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1414
1415 /* Clear reset */
1416 registerData &= ~WLANDXE_DMA_CCU_DXE_RESET_MASK;
1417 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1418#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001419 /* START This core init is not needed for the integrated system */
1420 /* Reset First */
1421 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1422 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1423 registerData);
Leo Chang00708f62013-12-03 20:21:51 -08001424#endif /* WCN_PRONTO */
Jeff Johnson295189b2012-06-20 16:38:30 -07001425
Leo Chang00708f62013-12-03 20:21:51 -08001426 for(readRetry = 0; readRetry < WLANDXE_CSR_MAX_READ_COUNT; readRetry++)
1427 {
1428 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1429 WLANDXE_CSR_DEFAULT_ENABLE);
1430 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &registerData);
1431 if(!(registerData & WLANDXE_DMA_CSR_EN_MASK))
1432 {
1433 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1434 "%s CSR 0x%x, count %d",
1435 __func__, registerData, readRetry);
1436 /* CSR is not valid value, re-try to write */
1437 wpalBusyWait(WLANDXE_CSR_NEXT_READ_WAIT);
1438 }
1439 else
1440 {
1441 break;
1442 }
1443 }
1444 if(WLANDXE_CSR_MAX_READ_COUNT == readRetry)
1445 {
1446 /* MAX wait, still cannot write correct value
1447 * Panic device */
1448 wpalDevicePanic();
1449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001450
1451 /* Is This needed?
1452 * Not sure, revisit with integrated system */
1453 /* END This core init is not needed for the integrated system */
1454
1455 dxeSetInterruptPath(dxeCtrlBlk);
1456 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001457 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 return status;
1459}
1460
1461/*==========================================================================
1462 @ Function Name
1463 dxeChannelInitProgram
1464
1465 @ Description
1466 Program RIVA DXE engine register with initial value
1467 What must be programmed
1468 - Source Address (SADRL, chDXESadrlRegAddr)
1469 - Destination address (DADRL, chDXEDadrlRegAddr)
1470 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1471 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1472
1473 Not need to program now
1474 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1475 TX : Have to program to trigger send out frame
1476 RX : programmed by DXE engine
1477
1478 @ Parameters
1479 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1480 DXE host driver main control block
1481 WLANDXE_ChannelCBType *channelEntry
1482 Channel specific control block
1483 @ Return
1484 wpt_status
1485
1486===========================================================================*/
1487static wpt_status dxeChannelInitProgram
1488(
1489 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1490 WLANDXE_ChannelCBType *channelEntry
1491)
1492{
1493 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1494 wpt_uint32 idx;
1495 WLANDXE_DescType *currentDesc = NULL;
1496 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1497
1498 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001499 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001500
1501 /* Sanity Check */
1502 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1503 {
1504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1505 "dxeChannelInitProgram Channel Entry is not valid");
1506 return eWLAN_PAL_STATUS_E_INVAL;
1507 }
1508
1509 /* Program Source address and destination adderss */
1510 if(!channelEntry->channelConfig.useShortDescFmt)
1511 {
1512 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1513 "dxeChannelInitProgram Long Descriptor not support yet");
1514 return eWLAN_PAL_STATUS_E_FAILURE;
1515 }
1516
1517 /* Common register area */
1518 /* Next linked list Descriptor pointer */
1519 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1520 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1521 if(eWLAN_PAL_STATUS_SUCCESS != status)
1522 {
1523 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1524 "dxeChannelInitProgram Write DESC Address register fail");
1525 return status;
1526 }
1527
1528 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1529 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1530 {
1531 /* Program default registers */
1532 /* TX DMA channel, DMA destination address is work Q */
1533 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1534 channelEntry->channelConfig.refWQ);
1535 if(eWLAN_PAL_STATUS_SUCCESS != status)
1536 {
1537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1538 "dxeChannelInitProgram Write TX DAddress register fail");
1539 return status;
1540 }
1541 }
1542 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1543 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1544 {
1545 /* Initialize Descriptor control Word First */
1546 currentCtrlBlk = channelEntry->headCtrlBlk;
1547 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1548 {
1549 currentDesc = currentCtrlBlk->linkedDesc;
1550 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1551 }
1552
1553 /* RX DMA channel, DMA source address is work Q */
1554 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1555 channelEntry->channelConfig.refWQ);
1556 if(eWLAN_PAL_STATUS_SUCCESS != status)
1557 {
1558 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1559 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1560 return status;
1561 }
1562
1563 /* RX DMA channel, Program pre allocated destination Address */
1564 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1565 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1566 if(eWLAN_PAL_STATUS_SUCCESS != status)
1567 {
1568 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1569 "dxeChannelInitProgram Write RX DAddress register fail");
1570 return status;
1571 }
1572
1573 /* RX Channels, default Control registers MUST BE ENABLED */
1574 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1575 channelEntry->extraConfig.chan_mask);
1576 if(eWLAN_PAL_STATUS_SUCCESS != status)
1577 {
1578 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1579 "dxeChannelInitProgram Write RX Control register fail");
1580 return status;
1581 }
1582 }
1583 else
1584 {
1585 /* H2H test channel, not use work Q */
1586 /* Program pre allocated destination Address */
1587 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1588 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1589 if(eWLAN_PAL_STATUS_SUCCESS != status)
1590 {
1591 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1592 "dxeChannelInitProgram Write RX DAddress register fail");
1593 return status;
1594 }
1595 }
1596
1597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001598 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001599 return status;
1600}
1601
1602
1603/*==========================================================================
1604 @ Function Name
1605 dxeChannelStart
1606
1607 @ Description
1608 Start Specific Channel
1609
1610 @ Parameters
1611 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1612 DXE host driver main control block
1613 WLANDXE_ChannelCBType *channelEntry
1614 Channel specific control block
1615
1616 @ Return
1617 wpt_status
1618
1619===========================================================================*/
1620static wpt_status dxeChannelStart
1621(
1622 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1623 WLANDXE_ChannelCBType *channelEntry
1624)
1625{
1626 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1627 wpt_uint32 regValue = 0;
1628 wpt_uint32 intMaskVal = 0;
1629
1630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001631 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001632
1633 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1634 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1635
1636 /* Enable individual channel
1637 * not to break current channel setup, first read register */
1638 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1639 &regValue);
1640 if(eWLAN_PAL_STATUS_SUCCESS != status)
1641 {
1642 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1643 "dxeChannelStart Read Channel Enable register fail");
1644 return status;
1645 }
1646
1647 /* Enable Channel specific Interrupt */
1648 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1649 &intMaskVal);
1650 if(eWLAN_PAL_STATUS_SUCCESS != status)
1651 {
1652 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1653 "dxeChannelStart Read INT_MASK register fail");
1654 return status;
1655 }
1656 intMaskVal |= channelEntry->extraConfig.intMask;
1657 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1658 intMaskVal);
1659 if(eWLAN_PAL_STATUS_SUCCESS != status)
1660 {
1661 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1662 "dxeChannelStart Write INT_MASK register fail");
1663 return status;
1664 }
1665
1666 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001667 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 return status;
1669}
1670
1671/*==========================================================================
1672 @ Function Name
1673 dxeChannelStop
1674
1675 @ Description
1676 Stop Specific Channel
1677
1678 @ Parameters
1679 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1680 DXE host driver main control block
1681 WLANDXE_ChannelCBType *channelEntry
1682 Channel specific control block
1683
1684 @ Return
1685 wpt_status
1686
1687===========================================================================*/
1688static wpt_status dxeChannelStop
1689(
1690 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1691 WLANDXE_ChannelCBType *channelEntry
1692)
1693{
1694 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1695 wpt_uint32 intMaskVal = 0;
1696
1697 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001698 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001699
1700 /* Sanity */
1701 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1702 {
1703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1704 "dxeChannelStop Invalid arg input");
1705 return eWLAN_PAL_STATUS_E_INVAL;
1706 }
1707
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001708 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1709 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1710 {
1711 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1712 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001713 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 /* Maskout interrupt */
1716 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1717 &intMaskVal);
1718 if(eWLAN_PAL_STATUS_SUCCESS != status)
1719 {
1720 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1721 "dxeChannelStop Read INT_MASK register fail");
1722 return status;
1723 }
1724 intMaskVal ^= channelEntry->extraConfig.intMask;
1725 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1726 intMaskVal);
1727 if(eWLAN_PAL_STATUS_SUCCESS != status)
1728 {
1729 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1730 "dxeChannelStop Write INT_MASK register fail");
1731 return status;
1732 }
1733
1734 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1735
1736 /* Stop Channel ??? */
1737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001738 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 return status;
1740}
1741
1742/*==========================================================================
1743 @ Function Name
1744 dxeChannelClose
1745
1746 @ Description
1747 Close Specific Channel
1748 Free pre allocated RX frame buffer if RX channel
1749 Free DXE descriptor for each channel
1750 Free Descriptor control block for each channel
1751
1752 @ Parameters
1753 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1754 DXE host driver main control block
1755 WLANDXE_ChannelCBType *channelEntry
1756 Channel specific control block
1757
1758 @ Return
1759 wpt_status
1760
1761===========================================================================*/
1762static wpt_status dxeChannelClose
1763(
1764 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1765 WLANDXE_ChannelCBType *channelEntry
1766)
1767{
1768 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1769 wpt_uint32 idx;
1770 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1771 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1772 WLANDXE_DescType *currentDescriptor = NULL;
1773 WLANDXE_DescType *nextDescriptor = NULL;
1774
1775 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001776 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001777
1778 /* Sanity */
1779 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1780 {
1781 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1782 "dxeChannelStop Invalid arg input");
1783 return eWLAN_PAL_STATUS_E_INVAL;
1784 }
1785
1786 currentCtrlBlk = channelEntry->headCtrlBlk;
1787 if(NULL != currentCtrlBlk)
1788 {
1789 currentDescriptor = currentCtrlBlk->linkedDesc;
1790 for(idx = 0; idx < channelEntry->numDesc; idx++)
1791 {
1792 if (idx + 1 != channelEntry->numDesc)
1793 {
1794 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1795 nextDescriptor = nextCtrlBlk->linkedDesc;
1796 }
1797 else
1798 {
1799 nextCtrlBlk = NULL;
1800 nextDescriptor = NULL;
1801 }
1802 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1803 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1804 {
1805 if (NULL != currentCtrlBlk->xfrFrame)
1806 {
1807 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1808 wpalPacketFree(currentCtrlBlk->xfrFrame);
1809 }
1810 }
1811 /*
1812 * It is the responsibility of DXE to walk through the
1813 * descriptor chain and unlock any pending packets (if
1814 * locked).
1815 */
1816 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1817 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1818 {
1819 if((NULL != currentCtrlBlk->xfrFrame) &&
1820 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1821 {
1822 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1823 wpalPacketFree(currentCtrlBlk->xfrFrame);
1824 }
1825 }
1826#if (defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1827 // descriptors allocated individually so free them individually
1828 wpalDmaMemoryFree(currentDescriptor);
1829#endif
1830 wpalMemoryFree(currentCtrlBlk);
1831
1832 currentCtrlBlk = nextCtrlBlk;
1833 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001834 if(NULL == currentCtrlBlk)
1835 {
1836 /* Already reach last of the control block
1837 * Not need to process anymore, break */
1838 break;
1839 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001840 }
1841 }
1842
1843#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1844 // descriptors were allocated as a single chunk so free the chunk
1845 if(NULL != channelEntry->descriptorAllocation)
1846 {
1847 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1848 }
1849#endif
1850
1851 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001852 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001853 return status;
1854}
1855
1856/*==========================================================================
1857 @ Function Name
1858 dxeChannelCleanInt
1859
1860 @ Description
1861 Clean up interrupt from RIVA HW
1862 After Host finish to handle interrupt, interrupt signal must be cleaned up
1863 Otherwise next interrupt will not be generated
1864
1865 @ Parameters
1866 WLANDXE_ChannelCBType *channelEntry
1867 Channel specific control block
1868 wpt_uint32 *chStat
1869 Channel Status register value
1870
1871 @ Return
1872 wpt_status
1873
1874===========================================================================*/
1875static wpt_status dxeChannelCleanInt
1876(
1877 WLANDXE_ChannelCBType *channelEntry,
1878 wpt_uint32 *chStat
1879)
1880{
1881 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1882
1883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001884 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001885
1886 /* Read Channel Status Register to know why INT Happen */
1887 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1888 chStat);
1889 if(eWLAN_PAL_STATUS_SUCCESS != status)
1890 {
1891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1892 "dxeChannelCleanInt Read CH STAT register fail");
1893 return eWLAN_PAL_STATUS_E_FAULT;
1894 }
1895 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1896 "%s Channel INT Clean, Status 0x%x",
1897 channelType[channelEntry->channelType], *chStat);
1898
1899 /* Clean up all the INT within this channel */
1900 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1901 (1 << channelEntry->assignedDMAChannel));
1902 if(eWLAN_PAL_STATUS_SUCCESS != status)
1903 {
1904 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1905 "dxeChannelCleanInt Write CH Clean register fail");
1906 return eWLAN_PAL_STATUS_E_FAULT;
1907 }
1908
Jeff Johnsone7245742012-09-05 17:12:55 -07001909 /* Clean up Error INT Bit */
1910 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1911 {
1912 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1913 (1 << channelEntry->assignedDMAChannel));
1914 if(eWLAN_PAL_STATUS_SUCCESS != status)
1915 {
1916 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1917 "dxeChannelCleanInt Read CH STAT register fail");
1918 return eWLAN_PAL_STATUS_E_FAULT;
1919 }
1920 }
1921
1922 /* Clean up DONE INT Bit */
1923 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1924 {
1925 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1926 (1 << channelEntry->assignedDMAChannel));
1927 if(eWLAN_PAL_STATUS_SUCCESS != status)
1928 {
1929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1930 "dxeChannelCleanInt Read CH STAT register fail");
1931 return eWLAN_PAL_STATUS_E_FAULT;
1932 }
1933 }
1934
1935 /* Clean up ED INT Bit */
1936 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1937 {
1938 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1939 (1 << channelEntry->assignedDMAChannel));
1940 if(eWLAN_PAL_STATUS_SUCCESS != status)
1941 {
1942 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1943 "dxeChannelCleanInt Read CH STAT register fail");
1944 return eWLAN_PAL_STATUS_E_FAULT;
1945 }
1946 }
1947
Jeff Johnson295189b2012-06-20 16:38:30 -07001948 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001949 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001950 return status;
1951}
1952
Mihir Shete44547fb2014-03-10 14:15:42 +05301953#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Jeff Johnson295189b2012-06-20 16:38:30 -07001954/*==========================================================================
Leo Chang72cdfd32013-10-17 20:36:30 -07001955 @ Function Name
1956 dxeRXResourceAvailableTimerExpHandler
1957
1958 @ Description
1959 During pre-set timeperiod, if free available RX buffer is not allocated
1960 Trigger Driver re-loading to recover RX dead end
1961
1962 @ Parameters
1963 v_VOID_t *usrData
1964 DXE context
1965
1966 @ Return
1967 NONE
1968
1969===========================================================================*/
1970void dxeRXResourceAvailableTimerExpHandler
1971(
1972 void *usrData
1973)
1974{
Katya Nigam93888ff2014-02-10 17:58:11 +05301975 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1976
1977 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1978
Leo Chang72cdfd32013-10-17 20:36:30 -07001979 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1980 "RX Low resource, Durign wait time period %d, RX resource not allocated",
1981 T_WLANDXE_MAX_RX_PACKET_WAIT);
Katya Nigam93888ff2014-02-10 17:58:11 +05301982
1983 if(0 != dxeCtxt)
1984 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
1985
Leo Chang72cdfd32013-10-17 20:36:30 -07001986 wpalWlanReload();
1987
Mihir Shetefdc9f532014-01-09 15:03:02 +05301988 if (NULL != usrData)
1989 dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
1990
1991 return;
1992}
Mihir Shete44547fb2014-03-10 14:15:42 +05301993#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05301994
1995/*==========================================================================
1996 @ Function Name
1997 dxeStartSSRTimer
1998
1999 @ Description
2000 Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip,
2001 this makes sure that if the chip does not respond to the FIQ within
2002 the timeout period the dxeSSRTimer expiration handler will take the
2003 appropriate action.
2004
2005 @ Parameters
2006 NONE
2007
2008 @ Return
2009 NONE
2010
2011===========================================================================*/
2012static void dxeStartSSRTimer
2013(
2014 WLANDXE_CtrlBlkType *dxeCtxt
2015)
2016{
2017 if(VOS_TIMER_STATE_RUNNING !=
2018 wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer))
2019 {
2020 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2021 "%s: Starting SSR Timer",__func__);
2022 wpalTimerStart(&dxeCtxt->dxeSSRTimer,
2023 T_WLANDXE_SSR_TIMEOUT);
2024 }
2025}
2026
2027/*==========================================================================
2028 @ Function Name
2029 dxeSSRTimerExpHandler
2030
2031 @ Description
2032 Issue an explicit subsystem restart of the wcnss subsystem if the
2033 WCN chip does not respond to the FIQ within the timeout period
2034
2035 @ Parameters
2036 v_VOID_t *usrData
2037
2038 @ Return
2039 NONE
2040
2041===========================================================================*/
2042void dxeSSRTimerExpHandler
2043(
2044 void *usrData
2045)
2046{
2047 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2048 "DXE not shutdown %d ms after FIQ!! Issue SSR",
2049 T_WLANDXE_SSR_TIMEOUT);
2050 wpalRivaSubystemRestart();
2051
Leo Chang72cdfd32013-10-17 20:36:30 -07002052 return;
2053}
2054
2055/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 @ Function Name
2057 dxeRXPacketAvailableCB
2058
2059 @ Description
2060 If RX frame handler encounts RX buffer pool empty condition,
2061 DXE RX handle loop will be blocked till get available RX buffer pool.
2062 When new RX buffer pool available, Packet available CB function will
2063 be called.
2064
2065 @ Parameters
2066 wpt_packet *freePacket
2067 Newly allocated RX buffer
2068 v_VOID_t *usrData
2069 DXE context
2070
2071 @ Return
2072 NONE
2073
2074===========================================================================*/
2075void dxeRXPacketAvailableCB
2076(
2077 wpt_packet *freePacket,
2078 v_VOID_t *usrData
2079)
2080{
2081 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2082 wpt_status status;
2083
2084 /* Simple Sanity */
2085 if((NULL == freePacket) || (NULL == usrData))
2086 {
2087 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2088 "Get Free RX Buffer fail, Critical Error");
2089 HDXE_ASSERT(0);
2090 return;
2091 }
2092
2093 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
2094
2095 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
2096 {
2097 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2098 "DXE Context data corrupted, Critical Error");
2099 HDXE_ASSERT(0);
2100 return;
2101 }
2102
2103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2104 "DXE RX packet available, post MSG to RX Thread");
2105
2106 dxeCtxt->freeRXPacket = freePacket;
2107
2108 /* Serialize RX Packet Available message upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08002109 if (NULL == dxeCtxt->rxPktAvailMsg)
2110 {
2111 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2112 "DXE NULL pkt");
2113 HDXE_ASSERT(0);
2114 return;
2115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002116
2117 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2118 dxeCtxt->rxPktAvailMsg);
2119 if(eWLAN_PAL_STATUS_SUCCESS != status)
2120 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2122 "dxeRXPacketAvailableCB serialize fail");
2123 }
2124
2125 return;
2126}
2127
2128/*==========================================================================
2129 @ Function Name
2130 dxeRXFrameSingleBufferAlloc
2131
2132 @ Description
2133 Allocate Platform packet buffer to prepare RX frame
2134 RX frame memory space must be pre allocted and must be asigned to
2135 descriptor
2136 then whenever DMA engine want to tranfer frame from BMU,
2137 buffer must be ready
2138
2139 @ Parameters
2140 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2141 DXE host driver main control block
2142 WLANDXE_ChannelCBType *channelEntry
2143 Channel specific control block
2144 WLANDXE_DescCtrlBlkType currentCtrlBlock
2145 current control block which have to be asigned
2146 frame buffer
2147
2148 @ Return
2149 wpt_status
2150
2151===========================================================================*/
2152static wpt_status dxeRXFrameSingleBufferAlloc
2153(
2154 WLANDXE_CtrlBlkType *dxeCtxt,
2155 WLANDXE_ChannelCBType *channelEntry,
2156 WLANDXE_DescCtrlBlkType *currentCtrlBlock
2157)
2158{
2159 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2160 wpt_packet *currentPalPacketBuffer = NULL;
2161 WLANDXE_DescType *currentDesc = NULL;
2162#ifdef FEATURE_R33D
2163 wpt_uint32 virtualAddressPCIe;
2164 wpt_uint32 physicalAddressPCIe;
2165#else
2166 wpt_iterator iterator;
2167 wpt_uint32 allocatedSize = 0;
2168 void *physAddress = NULL;
2169#endif /* FEATURE_R33D */
2170
Jeff Johnson295189b2012-06-20 16:38:30 -07002171
2172 currentDesc = currentCtrlBlock->linkedDesc;
2173
Leo Chang7e05f212013-07-01 19:54:15 -07002174 if(currentDesc->descCtrl.valid)
2175 {
2176 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2177 "This Descriptor is valid, Do not refill");
2178 return eWLAN_PAL_STATUS_E_EXISTS;
2179 }
2180
Jeff Johnson295189b2012-06-20 16:38:30 -07002181 /* First check if a packet pointer has already been provided by a previously
2182 invoked Rx packet available callback. If so use that packet. */
2183 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
2184 {
2185 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
2186 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
2187 dxeCtxt->freeRXPacket = NULL;
2188 }
2189 else if(!dxeCtxt->rxPalPacketUnavailable)
2190 {
Leo Chang72cdfd32013-10-17 20:36:30 -07002191 /* Allocate platform Packet buffer and OS Frame Buffer at here */
2192 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
2194 dxeRXPacketAvailableCB,
2195 (void *)dxeCtxt);
2196
2197 if(NULL == currentPalPacketBuffer)
2198 {
2199 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
Mihir Shete44547fb2014-03-10 14:15:42 +05302200#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07002201 /* Out of RX free buffer,
2202 * Start timer to recover from RX dead end */
2203 if(VOS_TIMER_STATE_RUNNING !=
2204 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
2205 {
2206 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2207 "RX Low resource, wait available resource");
2208 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
2209 T_WLANDXE_MAX_RX_PACKET_WAIT);
2210 }
Mihir Shete44547fb2014-03-10 14:15:42 +05302211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 }
2213 }
2214
2215 if(NULL == currentPalPacketBuffer)
2216 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 return eWLAN_PAL_STATUS_E_RESOURCES;
2218 }
2219
2220 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
2221 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
2222 currentPalPacketBuffer->pBD = NULL;
2223 currentPalPacketBuffer->pBDPhys = NULL;
2224 currentPalPacketBuffer->BDLength = 0;
2225#ifdef FEATURE_R33D
2226 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
2227 &physicalAddressPCIe,
2228 &virtualAddressPCIe);
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08002229 if((0 == physicalAddressPCIe) || (0 = virtualAddressPCIe))
2230 {
2231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2232 "RX NULL Shadow Memory");
2233 HDXE_ASSERT(0);
2234 return eWLAN_PAL_STATUS_E_FAULT;
2235 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2237 "RX Shadow Memory Va 0x%x, Pa 0x%x",
2238 virtualAddressPCIe, physicalAddressPCIe);
2239 if(eWLAN_PAL_STATUS_SUCCESS != status)
2240 {
2241 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2242 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
2243 return status;
2244 }
2245 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
2246 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
2247 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2248#else
2249 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
2250 if(eWLAN_PAL_STATUS_SUCCESS != status)
2251 {
2252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2253 "dxeRXFrameBufferAlloc unable to lock packet");
2254 return status;
2255 }
2256
2257 /* Init iterator to get physical os buffer address */
2258 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
2259 if(eWLAN_PAL_STATUS_SUCCESS != status)
2260 {
2261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2262 "dxeRXFrameBufferAlloc iterator init fail");
2263 return status;
2264 }
2265 status = wpalIteratorNext(&iterator,
2266 currentPalPacketBuffer,
2267 &physAddress,
2268 &allocatedSize);
2269 if(eWLAN_PAL_STATUS_SUCCESS != status)
2270 {
2271 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2272 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
2273 return status;
2274 }
2275 currentPalPacketBuffer->pBDPhys = physAddress;
2276#endif /* FEATURE_R33D */
2277
2278 /* DXE descriptor must have SWAPPED addres in it's structure
2279 * !!! SWAPPED !!! */
2280 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05302281 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07002282
Jeff Johnson295189b2012-06-20 16:38:30 -07002283 return status;
2284}
2285
2286/*==========================================================================
2287 @ Function Name
2288 dxeRXFrameRefillRing
2289
2290 @ Description
2291 Allocate Platform packet buffers to try to fill up the DXE Rx ring
2292
2293 @ Parameters
2294 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2295 DXE host driver main control block
2296 WLANDXE_ChannelCBType *channelEntry
2297 Channel specific control block
2298
2299 @ Return
2300 wpt_status
2301
2302===========================================================================*/
2303static wpt_status dxeRXFrameRefillRing
2304(
2305 WLANDXE_CtrlBlkType *dxeCtxt,
2306 WLANDXE_ChannelCBType *channelEntry
2307)
2308{
2309 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2310 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2311 WLANDXE_DescType *currentDesc = NULL;
2312
2313 while(channelEntry->numFreeDesc > 0)
2314 {
2315 /* Current Control block is free
2316 * and associated frame buffer is not linked with control block anymore
2317 * allocate new frame buffer for current control block */
2318 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2319 channelEntry,
2320 currentCtrlBlk);
2321
Leo Chang7e05f212013-07-01 19:54:15 -07002322 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2323 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002324 {
2325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2326 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2327 break;
2328 }
2329
Leo Chang7e05f212013-07-01 19:54:15 -07002330 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2331 {
2332 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2333 "dxeRXFrameRefillRing, Descriptor Non-Empry");
2334 }
2335
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 currentDesc = currentCtrlBlk->linkedDesc;
2337 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2338
2339 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2340 that any posted writes are reflected in memory before DXE looks at
2341 the descriptor. */
2342 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2343 {
2344 //HDXE_ASSERT(0);
2345 }
2346
2347 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07002348 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002349 {
2350 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2351 1 << channelEntry->assignedDMAChannel);
2352 }
2353 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07002354 if(eWLAN_PAL_STATUS_E_EXISTS != status)
2355 {
2356 --channelEntry->numFreeDesc;
2357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002358 }
2359
2360 channelEntry->tailCtrlBlk = currentCtrlBlk;
2361
2362 return status;
2363}
2364
2365/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002366 @ Function Name
2367 dxeRXFrameRouteUpperLayer
2368
2369 @ Description
2370 Test DXE descriptors and if any RX frame pending within RING,
2371 Route to upper layer
2372
2373 @ Parameters
2374 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2375 DXE host driver main control block
2376 WLANDXE_ChannelCBType *channelEntry
2377 Channel specific control block
2378 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002379 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002380 0 No frame pulled from RX RING
2381 int number of RX frames pulled from RX ring
2382
2383===========================================================================*/
2384static wpt_int32 dxeRXFrameRouteUpperLayer
2385(
2386 WLANDXE_CtrlBlkType *dxeCtxt,
2387 WLANDXE_ChannelCBType *channelEntry
2388)
2389{
2390 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2391 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2392 WLANDXE_DescType *currentDesc = NULL;
2393 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002394 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002395
2396 currentCtrlBlk = channelEntry->headCtrlBlk;
2397 currentDesc = currentCtrlBlk->linkedDesc;
2398
2399 /* Descriptoe should be SWAPPED ???? */
2400 descCtrl = currentDesc->descCtrl.ctrl;
2401
2402 /* Get frames while VALID bit is not set (DMA complete) and a data
2403 * associated with it */
2404 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2405 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2406 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2407 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2408 {
2409 channelEntry->numTotalFrame++;
2410 channelEntry->numFreeDesc++;
2411#ifdef FEATURE_R33D
2412 /* Transfer Size should be */
2413 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2414 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
2415 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
2416 currentCtrlBlk->shadowBufferVa,
2417 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2418 if(eWLAN_PAL_STATUS_SUCCESS != status)
2419 {
2420 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2421 "dxeRXFrameReady Prepare RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002422 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002423 }
2424 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
2425 if(eWLAN_PAL_STATUS_SUCCESS != status)
2426 {
2427 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2428 "dxeRXFrameReady Free Shadow RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002429 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002430 }
2431
2432#else /* FEATURE_R33D */
2433 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
2434 if (eWLAN_PAL_STATUS_SUCCESS != status)
2435 {
2436 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2437 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002438 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002439 }
2440#endif /* FEATURE_R33D */
2441 /* This Descriptor is valid, so linked Control block is also valid
2442 * Linked Control block has pre allocated packet buffer
2443 * So, just let upper layer knows preallocated frame pointer will be OK */
2444 /* Reap Rx frames */
2445 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2446 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002447 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002448
2449 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Leo Changd6de1c22013-03-21 15:42:41 -07002450 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002451
2452 /* Test next contorl block
2453 * if valid, this control block also has new RX frame must be handled */
2454 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2455 currentDesc = currentCtrlBlk->linkedDesc;
2456 descCtrl = currentDesc->descCtrl.ctrl;
2457 }
2458
2459 /* Update head control block
2460 * current control block's valid bit was 0
2461 * next trial first control block must be current control block */
2462 channelEntry->headCtrlBlk = currentCtrlBlk;
2463
2464 /* Deliver all the reaped RX frames to upper layers */
2465 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002466 while(i < frameCount)
2467 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002468 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2469 i++;
2470 }
2471
2472 return frameCount;
2473}
2474
2475/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002476 @ Function Name
2477 dxeRXFrameReady
2478
2479 @ Description
2480 Pop frame from descriptor and route frame to upper transport layer
2481 Assign new platform packet buffer into used descriptor
2482 Actual frame pop and resource realloc
2483
2484 @ Parameters
2485 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2486 DXE host driver main control block
2487 WLANDXE_ChannelCBType *channelEntry
2488 Channel specific control block
2489
2490 @ Return
2491 wpt_status
2492
2493===========================================================================*/
2494static wpt_status dxeRXFrameReady
2495(
2496 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002497 WLANDXE_ChannelCBType *channelEntry,
2498 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002499)
2500{
2501 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2502 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2503 WLANDXE_DescType *currentDesc = NULL;
2504 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002505 wpt_int32 frameCount = 0;
2506
2507 wpt_uint32 descLoop;
2508 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002509
2510 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002511 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002512
2513 /* Sanity Check */
2514 if((NULL == dxeCtxt) || (NULL == channelEntry))
2515 {
2516 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2517 "dxeRXFrameReady Channel Entry is not valid");
2518 return eWLAN_PAL_STATUS_E_INVAL;
2519 }
2520
Jeff Johnsone7245742012-09-05 17:12:55 -07002521 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002522
Jeff Johnsone7245742012-09-05 17:12:55 -07002523 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002524 {
2525 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002526 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002527 return eWLAN_PAL_STATUS_E_INVAL;
2528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002529
Leo Changd6de1c22013-03-21 15:42:41 -07002530 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002531 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2532 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2533 {
Leo Changd6de1c22013-03-21 15:42:41 -07002534 /* None of the frame handled and CH is not enabled
2535 * RX CH wrap around happen and No RX free frame
2536 * RX side should wait till new free frame available in the pool
2537 * Do not try reload driver at here*/
2538 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2539 {
Leo Changbbf86b72013-06-19 16:13:00 -07002540 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002541 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2542 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002543 /* This is not empty interrupt case
2544 * If handle this as empty interrupt, false SSR might be issued
2545 * Frame count '1' is dummy frame count to avoid SSR */
2546 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002547 return eWLAN_PAL_STATUS_SUCCESS;
2548 }
2549
Jeff Johnsone7245742012-09-05 17:12:55 -07002550 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002551 currentDesc = currentCtrlBlk->linkedDesc;
2552 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002553
2554 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2555 {
2556 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2557 "RX ISR called but no frame handled PWS %d, channel %s",
2558 (int)dxeCtxt->hostPowerState,
2559 channelType[channelEntry->channelType]);
2560 }
2561
2562 /* Current interupt empty and previous interrupt also empty
2563 * detected successive empty interrupt
2564 * or first interrupt empty, this should not happen */
2565 if(0 == channelEntry->numFragmentCurrentChain)
2566 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002567 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2568 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2569 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2570 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002571 /* Abnormal interrupt detected, try to find not validated descriptor */
2572 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2573 {
2574 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2575 {
Leo Chang416afe02013-07-01 13:58:13 -07002576 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002577 "Found Invalidated Descriptor %d", (int)descLoop);
2578 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2579 {
Leo Chang416afe02013-07-01 13:58:13 -07002580 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002581 "Packet locked, Resync Host and HW");
2582 channelEntry->headCtrlBlk = currentCtrlBlk;
2583 invalidatedFound = 1;
2584 break;
2585 }
2586 else
2587 {
Leo Chang416afe02013-07-01 13:58:13 -07002588 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002589 "Packet Not Locked, cannot transfer frame");
2590 }
2591 }
2592 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2593 currentDesc = currentCtrlBlk->linkedDesc;
2594 descCtrl = currentDesc->descCtrl.ctrl;
2595 }
2596
Jeff Johnson32d95a32012-09-10 13:15:23 -07002597 /* Invalidated descriptor found, and that is not head descriptor
2598 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2599 * Try re-sync here */
2600 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002601 {
2602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2603 "Found New Sync location with HW, handle frames from there");
2604 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2605 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2606 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002607 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002608 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002609 /* Successive Empty interrupt
2610 * But this case, first descriptor also invalidated, then it means head descriptor
2611 * is linked with already handled RX frame, then could not unlock RX frame
2612 * This is just Out of RX buffer pool, not need to anything here */
2613 else if((invalidatedFound) && (0 == descLoop))
2614 {
2615 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2616 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2617 }
2618 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002619 else
2620 {
2621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2622 "Could not found invalidated descriptor");
2623 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2624 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2625 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2626 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302627 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002628 }
2629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002630 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002631 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002632 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002633 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002634 return status;
2635}
2636
2637/*==========================================================================
2638 @ Function Name
2639 dxeNotifySmsm
2640
2641 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2642 buffer
2643
2644 @ Parameters
2645
2646 @ Return
2647 wpt_status
2648
2649===========================================================================*/
2650static wpt_status dxeNotifySmsm
2651(
2652 wpt_boolean kickDxe,
2653 wpt_boolean ringEmpty
2654)
2655{
2656 wpt_uint32 clrSt = 0;
2657 wpt_uint32 setSt = 0;
2658
2659 if(kickDxe)
2660 {
2661 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2662
2663 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2664 {
2665 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2666 tempDxeCtrlBlk->lastKickOffDxe = 1;
2667 }
2668 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2669 {
2670 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2671 tempDxeCtrlBlk->lastKickOffDxe = 0;
2672 }
2673 else
2674 {
2675 HDXE_ASSERT(0);
2676 }
2677 }
2678 else
2679 {
2680 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2681 }
2682
2683 if(ringEmpty)
2684 {
2685 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2686 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2687 }
2688 else
2689 {
2690 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2691 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2692 }
2693
2694 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2695
2696 wpalNotifySmsm(clrSt, setSt);
2697
2698 return eWLAN_PAL_STATUS_SUCCESS;
2699}
2700
2701/*==========================================================================
2702 @ Function Name
2703 dxePsComplete
2704
2705 @ Description: Utility function to check the resv desc to deside if we can
2706 get into Power Save mode now
2707
2708 @ Parameters
2709
2710 @ Return
2711 None
2712
2713===========================================================================*/
2714static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2715{
2716 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2717 {
2718 return;
2719 }
2720
2721 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2722 //must have been consumed by RIVA, OK to get into BMPS
2723 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2724 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2725 {
2726 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2727 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2728 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2729 {
2730 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2731 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2732 }
2733 }
2734 else //still more pkts to be served by RIVA
2735 {
2736 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2737
2738 switch(dxeCtxt->rivaPowerState)
2739 {
2740 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2741 //NOP
2742 break;
2743 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2744 if(intr_based)
2745 {
2746 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2747 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2748 }
2749 break;
2750 default:
2751 //assert
2752 break;
2753 }
2754 }
2755}
2756
2757/*==========================================================================
2758 @ Function Name
2759 dxeRXEventHandler
2760
2761 @ Description
2762 Handle serailized RX frame ready event
2763 First disable interrupt then pick up frame from pre allocated buffer
2764 Since frame handle is doen, clear interrupt bit to ready next interrupt
2765 Finally re enable interrupt
2766
2767 @ Parameters
2768 wpt_msg *rxReadyMsg
2769 RX frame ready MSG pointer
2770 include DXE control context
2771
2772 @ Return
2773 NONE
2774
2775===========================================================================*/
2776void dxeRXEventHandler
2777(
2778 wpt_msg *rxReadyMsg
2779)
2780{
2781 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2782 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2783 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2784 wpt_uint32 intSrc = 0;
2785 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002786 wpt_uint32 chHighStat = 0;
2787 wpt_uint32 chLowStat = 0;
Leo Chang094ece82013-04-23 17:57:41 -07002788 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07002789
Jeff Johnsone7245742012-09-05 17:12:55 -07002790 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002791
Jeff Johnsone7245742012-09-05 17:12:55 -07002792 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002793 {
2794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002795 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002796 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 }
2798
Jeff Johnsone7245742012-09-05 17:12:55 -07002799 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2800 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2801 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
2802
Jeff Johnson295189b2012-06-20 16:38:30 -07002803 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2804
2805 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
2806 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
2807 {
2808 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2809 "DXE already stopped in RX event handler. Just return");
2810 return;
2811 }
2812
2813 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2814 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2815 {
2816 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2817 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002818 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002819
2820 /* Not to touch any register, just pull frame directly from chain ring
2821 * First high priority */
2822 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2823 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002824 channelCb,
2825 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002826 if(eWLAN_PAL_STATUS_SUCCESS != status)
2827 {
2828 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2829 "dxeRXEventHandler Pull from RX high channel fail");
2830 }
Leo Chang46f36162014-01-14 21:47:24 -08002831 /* In case FW could not power collapse in IMPS mode
2832 * Next power restore might have empty interrupt
2833 * If IMPS mode has empty interrupt since RX thread race,
2834 * Invalid re-load driver might happen
2835 * To prevent invalid re-load driver,
2836 * IMPS event handler set dummpy frame count */
2837 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002838
2839 /* Second low priority */
2840 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2841 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002842 channelCb,
2843 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002844 if(eWLAN_PAL_STATUS_SUCCESS != status)
2845 {
2846 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2847 "dxeRXEventHandler Pull from RX low channel fail");
2848 }
Leo Chang46f36162014-01-14 21:47:24 -08002849 /* LOW Priority CH same above */
2850 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002851
2852 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2853 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2854
2855 return;
2856 }
2857
2858 /* Disable device interrupt */
2859 /* Read whole interrupt mask register and exclusive only this channel int */
2860 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2861 &intSrc);
2862 if(eWLAN_PAL_STATUS_SUCCESS != status)
2863 {
2864 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2865 "dxeRXEventHandler Read INT_SRC register fail");
2866 return;
2867 }
2868 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2869 "RX Event Handler INT Source 0x%x", intSrc);
2870
2871#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2872 /* Test High Priority Channel interrupt is enabled or not */
2873 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2874 if(intSrc & (1 << channelCb->assignedDMAChannel))
2875 {
2876 status = dxeChannelCleanInt(channelCb, &chHighStat);
2877 if(eWLAN_PAL_STATUS_SUCCESS != status)
2878 {
2879 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2880 "dxeRXEventHandler INT Clean up fail");
2881 return;
2882 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002883 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2884 {
2885 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002886 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2887 "%11s : 0x%x Error Reported, Reload Driver",
2888 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302889
Mihir Shete79d6b582014-03-12 17:54:07 +05302890 dxeErrChannelDebug(channelCb, chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302891
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002892 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2893 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302894 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002895 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002896 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2897 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002898 {
2899 /* Handle RX Ready for high priority channel */
2900 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002901 channelCb,
2902 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002903 }
2904 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2905 {
2906 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002907 channelCb,
2908 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 }
2910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2911 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002912 /* Update the Rx DONE histogram */
2913 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2914 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2915 {
2916 channelCb->rxDoneHistogram |= 1;
2917 }
2918 else
2919 {
2920 channelCb->rxDoneHistogram &= ~1;
2921 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002922 }
2923#else
2924 /* Test H2H Test interrupt is enabled or not */
2925 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2926 if(intSrc & (1 << channelCb->assignedDMAChannel))
2927 {
2928 status = dxeChannelCleanInt(channelCb, &chStat);
2929 if(eWLAN_PAL_STATUS_SUCCESS != status)
2930 {
2931 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2932 "dxeRXEventHandler INT Clean up fail");
2933 return;
2934 }
2935
2936 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2937 {
2938 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002939 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2940 "%11s : 0x%x Error Reported, Reload Driver",
2941 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302942
Mihir Shete79d6b582014-03-12 17:54:07 +05302943 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302944
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002945 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2946 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302947 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002948 }
2949 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2950 {
2951 /* Handle RX Ready for high priority channel */
2952 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002953 channelCb,
2954 chStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 }
2956 /* Update the Rx DONE histogram */
2957 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2958 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2959 {
2960 channelCb->rxDoneHistogram |= 1;
2961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2962 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2963 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2964 }
2965 else
2966 {
2967 channelCb->rxDoneHistogram &= ~1;
2968 }
2969 }
2970#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2971
2972 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002973 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 if(intSrc & (1 << channelCb->assignedDMAChannel))
2975 {
2976 status = dxeChannelCleanInt(channelCb, &chLowStat);
2977 if(eWLAN_PAL_STATUS_SUCCESS != status)
2978 {
2979 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2980 "dxeRXEventHandler INT Clean up fail");
2981 return;
2982 }
2983
2984 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2985 {
2986 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2988 "%11s : 0x%x Error Reported, Reload Driver",
2989 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302990
Mihir Shete79d6b582014-03-12 17:54:07 +05302991 dxeErrChannelDebug(channelCb, chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302992
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002993 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2994 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302995 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002996 }
2997 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2998 {
2999 /* Handle RX Ready for low priority channel */
3000 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07003001 channelCb,
3002 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07003003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003004
3005 /* Update the Rx DONE histogram */
3006 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
3007 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
3008 {
3009 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003010 }
3011 else
3012 {
3013 channelCb->rxDoneHistogram &= ~1;
3014 }
3015 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3016 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
3017 }
3018 if(eWLAN_PAL_STATUS_SUCCESS != status)
3019 {
3020 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3021 "dxeRXEventHandler Handle Frame Ready Fail");
3022 return;
3023 }
3024
Jeff Johnson295189b2012-06-20 16:38:30 -07003025 /* Prepare Control Register EN Channel */
3026 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
3027 {
3028 HDXE_ASSERT(0);
3029 }
Leo Chang094ece82013-04-23 17:57:41 -07003030 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
3031 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
Jeff Johnson295189b2012-06-20 16:38:30 -07003032
3033 /* Prepare Control Register EN Channel */
3034 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
3035 {
3036 HDXE_ASSERT(0);
3037 }
Leo Chang094ece82013-04-23 17:57:41 -07003038
3039 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
3040 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
3041
3042 /* Clear Interrupt handle processing bit
3043 * RIVA may power down */
3044 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3045 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
3046 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -07003047
Leo Chang416afe02013-07-01 13:58:13 -07003048 /* Enable system level ISR */
3049 /* Enable RX ready Interrupt at here */
3050 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
3051 if(eWLAN_PAL_STATUS_SUCCESS != status)
3052 {
3053 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3054 "dxeRXEventHandler Enable RX Ready interrupt fail");
3055 return;
3056 }
3057
Jeff Johnson295189b2012-06-20 16:38:30 -07003058 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003059 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003060 return;
3061}
3062
3063/*==========================================================================
3064 @ Function Name
3065 dxeRXPacketAvailableEventHandler
3066
3067 @ Description
3068 Handle serialized RX Packet Available event when the corresponding callback
3069 is invoked by WPAL.
3070 Try to fill up any completed DXE descriptors with available Rx packet buffer
3071 pointers.
3072
3073 @ Parameters
3074 wpt_msg *rxPktAvailMsg
3075 RX frame ready MSG pointer
3076 include DXE control context
3077
3078 @ Return
3079 NONE
3080
3081===========================================================================*/
3082void dxeRXPacketAvailableEventHandler
3083(
3084 wpt_msg *rxPktAvailMsg
3085)
3086{
3087 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3088 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3089 WLANDXE_ChannelCBType *channelCb = NULL;
3090
3091 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003092 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003093
3094 /* Sanity Check */
3095 if(NULL == rxPktAvailMsg)
3096 {
3097 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3098 "dxeRXPacketAvailableEventHandler Context is not valid");
3099 return;
3100 }
3101
3102 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05303103
3104#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07003105 /* Available resource allocated
3106 * Stop timer not needed */
3107 if(VOS_TIMER_STATE_RUNNING ==
3108 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
3109 {
3110 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
3111 }
Mihir Shete44547fb2014-03-10 14:15:42 +05303112#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003113
3114 do
3115 {
3116 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3117 "dxeRXPacketAvailableEventHandler, start refilling ring");
3118
3119 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
3120 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3121
3122 // Wait for another callback to indicate when Rx resources are available
3123 // again.
3124 if(eWLAN_PAL_STATUS_SUCCESS != status)
3125 {
3126 break;
3127 }
3128
3129 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
3130 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3131 if(eWLAN_PAL_STATUS_SUCCESS != status)
3132 {
3133 break;
3134 }
3135 } while(0);
3136
3137 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
3138 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
3139 {
3140 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
3141 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
3142 }
3143}
3144
3145/*==========================================================================
3146 @ Function Name
3147 dxeRXISR
3148
3149 @ Description
3150 RX frame ready interrupt service routine
3151 interrupt entry function, this function called based on ISR context
3152 Must be serialized
3153
3154 @ Parameters
3155 void *hostCtxt
3156 DXE host driver control context,
3157 pre registerd during interrupt registration
3158
3159 @ Return
3160 NONE
3161
3162===========================================================================*/
3163static void dxeRXISR
3164(
3165 void *hostCtxt
3166)
3167{
3168 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3169 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003170 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07003171
3172#ifdef FEATURE_R33D
3173 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3174 &regValue);
3175 if(eWLAN_PAL_STATUS_SUCCESS != status)
3176 {
3177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3178 "dxeTXCompISR Read INT_SRC_RAW fail");
3179 return;
3180 }
3181 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3182 "INT_SRC_RAW 0x%x", regValue);
3183 if(0 == regValue)
3184 {
3185 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3186 "This is not DXE Interrupt, Reject it 0x%x", regValue);
3187 return;
3188 }
3189#endif /* FEATURE_R33D */
3190
Leo Chang094ece82013-04-23 17:57:41 -07003191 /* Set Interrupt processing bit
3192 * During this bit set, WLAN HW may not power collapse */
3193 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3194 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
3195 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3196
Jeff Johnson295189b2012-06-20 16:38:30 -07003197 /* Disable interrupt at here
3198 * Disable RX Ready system level Interrupt at here
3199 * Otherwise infinite loop might happen */
3200 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
3201 if(eWLAN_PAL_STATUS_SUCCESS != status)
3202 {
3203 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3204 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3205 return;
3206 }
3207
3208 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003209 if(NULL == dxeCtxt->rxIsrMsg)
3210 {
3211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3212 "dxeRXFrameReadyISR NULL message");
3213 HDXE_ASSERT(0);
3214 return;
3215 }
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
3218 dxeCtxt->rxIsrMsg);
3219 if(eWLAN_PAL_STATUS_SUCCESS != status)
3220 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3222 "dxeRXFrameReadyISR interrupt serialize fail");
3223 }
3224
Jeff Johnson295189b2012-06-20 16:38:30 -07003225 return;
3226}
3227
3228/*==========================================================================
3229 @ Function Name
3230 dxeTXPushFrame
3231
3232 @ Description
3233 Push TX frame into DXE descriptor and DXE register
3234 Send notification to DXE register that TX frame is ready to transfer
3235
3236 @ Parameters
3237 WLANDXE_ChannelCBType *channelEntry
3238 Channel specific control block
3239 wpt_packet *palPacket
3240 Packet pointer ready to transfer
3241
3242 @ Return
3243 PAL_STATUS_T
3244===========================================================================*/
3245static wpt_status dxeTXPushFrame
3246(
3247 WLANDXE_ChannelCBType *channelEntry,
3248 wpt_packet *palPacket
3249)
3250{
3251 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3252 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3253 WLANDXE_DescType *currentDesc = NULL;
3254 WLANDXE_DescType *firstDesc = NULL;
3255 WLANDXE_DescType *LastDesc = NULL;
3256 void *sourcePhysicalAddress = NULL;
3257 wpt_uint32 xferSize = 0;
3258#ifdef FEATURE_R33D
3259 tx_frm_pcie_vector_t frameVector;
3260 wpt_uint32 Va;
3261 wpt_uint32 fragCount = 0;
3262#else
3263 wpt_iterator iterator;
3264#endif /* FEATURE_R33D */
Leo Changac1d3612013-07-01 15:15:51 -07003265 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003266
3267 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003268 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003269
Leo Changac1d3612013-07-01 15:15:51 -07003270 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3271 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3272 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003273 {
Leo Changac1d3612013-07-01 15:15:51 -07003274 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 }
3276
3277 channelEntry->numFragmentCurrentChain = 0;
3278 currentCtrlBlk = channelEntry->headCtrlBlk;
3279
3280 /* Initialize interator, TX is fragmented */
3281#ifdef FEATURE_R33D
3282 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
3283 status = wpalPrepareTxFrame(palPacket,
3284 &frameVector,
3285 &Va);
3286#else
3287 status = wpalLockPacketForTransfer(palPacket);
3288 if(eWLAN_PAL_STATUS_SUCCESS != status)
3289 {
3290 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3291 "dxeTXPushFrame unable to lock packet");
3292 return status;
3293 }
3294
3295 status = wpalIteratorInit(&iterator, palPacket);
3296#endif /* FEATURE_R33D */
3297 if(eWLAN_PAL_STATUS_SUCCESS != status)
3298 {
3299 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3300 "dxeTXPushFrame iterator init fail");
3301 return status;
3302 }
3303
3304 /* !!!! Revisit break condition !!!!!!! */
3305 while(1)
3306 {
3307 /* Get current descriptor pointer from current control block */
3308 currentDesc = currentCtrlBlk->linkedDesc;
3309 if(NULL == firstDesc)
3310 {
3311 firstDesc = currentCtrlBlk->linkedDesc;
3312 }
3313 /* All control block will have same palPacket Pointer
3314 * to make logic simpler */
3315 currentCtrlBlk->xfrFrame = palPacket;
3316
3317 /* Get next fragment physical address and fragment size
3318 * if this is the first trial, will get first physical address
3319 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
3320#ifdef FEATURE_R33D
3321 if(fragCount == frameVector.num_frg)
3322 {
3323 break;
3324 }
3325 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
3326 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
3327 xferSize = frameVector.frg[fragCount].size;
3328 fragCount++;
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003329 if(0 == xferSize)
3330 {
3331 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3332 "dxeTXPushFrame invalid transfer size");
3333
3334 HDXE_ASSERT(0);
3335 return eWLAN_PAL_STATUS_E_FAILURE;
3336 }
3337 if(NULL == sourcePhysicalAddress)
3338 {
3339 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3340 "dxeTXPushFrame invalid sourcePhysicalAddress");
3341 HDXE_ASSERT(0);
3342 return eWLAN_PAL_STATUS_E_FAILURE;
3343 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003344#else
3345 status = wpalIteratorNext(&iterator,
3346 palPacket,
3347 &sourcePhysicalAddress,
3348 &xferSize);
3349 if((NULL == sourcePhysicalAddress) ||
3350 (0 == xferSize))
3351 {
3352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3353 "dxeTXPushFrame end of current frame");
3354 break;
3355 }
3356 if(eWLAN_PAL_STATUS_SUCCESS != status)
3357 {
3358 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3359 "dxeTXPushFrame Get next frame fail");
3360 return status;
3361 }
3362#endif /* FEATURE_R33D */
3363
3364 /* This is the LAST descriptor valid for this transaction */
3365 LastDesc = currentCtrlBlk->linkedDesc;
3366
3367 /* Program DXE descriptor */
3368 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303369 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003370
3371 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3372 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3373 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3374 {
3375 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3376 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3377 }
3378 else
3379 {
3380 /* Test specific H2H transfer, destination address already set
3381 * Do Nothing */
3382 }
3383 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3384
3385 /* Program channel control register */
3386 /* First frame not set VAL bit, why ??? */
3387 if(0 == channelEntry->numFragmentCurrentChain)
3388 {
3389 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3390 }
3391 else
3392 {
3393 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3394 }
3395
3396 /* Update statistics */
3397 channelEntry->numFragmentCurrentChain++;
3398 channelEntry->numFreeDesc--;
3399 channelEntry->numRsvdDesc++;
3400
3401 /* Get next control block */
3402 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3403 }
3404 channelEntry->numTotalFrame++;
3405 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3406 "NUM TX FRAG %d, Total Frame %d",
3407 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3408
3409 /* Program Channel control register
3410 * Set as end of packet
3411 * Enable interrupt also for first code lock down
3412 * performace optimization, this will be revisited */
3413 if(NULL == LastDesc)
3414 {
3415 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3416 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3417 return eWLAN_PAL_STATUS_E_FAULT;
3418 }
3419 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3420 /* Now First one also Valid ????
3421 * this procedure will prevent over handle descriptor from previous
3422 * TX trigger */
3423 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3424
3425 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3426 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3427 {
3428 /* Update channel head as next avaliable linked slot */
3429 channelEntry->headCtrlBlk = currentCtrlBlk;
Leo Changac1d3612013-07-01 15:15:51 -07003430 if(isEmpty)
3431 {
3432 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3433 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3434 "SMSM_ret LO=%d HI=%d",
3435 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3436 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3437 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3438 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
3439 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003440 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003441 }
3442
3443 /* If DXE use external descriptor, registers are not needed to be programmed
3444 * Just after finish to program descriptor, tirigger to send */
3445 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3446 {
3447 /* Issue a dummy read from the DXE descriptor DDR location to
3448 ensure that any previously posted write to the descriptor
3449 completes. */
3450 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3451 {
3452 //HDXE_ASSERT(0);
3453 }
3454
3455 /* Everything is ready
3456 * Trigger to start DMA */
3457 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3458 channelEntry->extraConfig.chan_mask);
3459 if(eWLAN_PAL_STATUS_SUCCESS != status)
3460 {
3461 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3462 "dxeTXPushFrame Write Channel Ctrl Register fail");
3463 return status;
3464 }
3465
3466 /* Update channel head as next avaliable linked slot */
3467 channelEntry->headCtrlBlk = currentCtrlBlk;
3468
3469 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003470 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003471 return status;
3472 }
3473
3474 /* If DXE not use external descriptor, program each registers */
3475 /* Circular buffer handle not need to program DESC register???
3476 * GEN5 code not programed RING buffer case
3477 * REVISIT THIS !!!!!! */
3478 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3479 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3480 {
3481 /* Destination address, assigned Work Q */
3482 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3483 channelEntry->channelConfig.refWQ);
3484 if(eWLAN_PAL_STATUS_SUCCESS != status)
3485 {
3486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3487 "dxeTXPushFrame Program dest address register fail");
3488 return status;
3489 }
3490 /* If descriptor format is SHORT */
3491 if(channelEntry->channelConfig.useShortDescFmt)
3492 {
3493 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3494 0);
3495 if(eWLAN_PAL_STATUS_SUCCESS != status)
3496 {
3497 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3498 "dxeTXPushFrame Program dest address register fail");
3499 return status;
3500 }
3501 }
3502 else
3503 {
3504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3505 "dxeTXPushFrame LONG Descriptor Format!!!");
3506 }
3507 }
3508#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3509 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3510 {
3511 /* Destination address, Physical memory address */
3512 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3513 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3514 if(eWLAN_PAL_STATUS_SUCCESS != status)
3515 {
3516 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3517 "dxeTXPushFrame Program dest address register fail");
3518 return status;
3519 }
3520 /* If descriptor format is SHORT */
3521 if(channelEntry->channelConfig.useShortDescFmt)
3522 {
3523 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3524 0);
3525 if(eWLAN_PAL_STATUS_SUCCESS != status)
3526 {
3527 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3528 "dxeTXPushFrame Program dest address register fail");
3529 return status;
3530 }
3531 }
3532 else
3533 {
3534 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3535 "dxeTXPushFrame LONG Descriptor Format!!!");
3536 }
3537 }
3538#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3539
3540 /* Program Source address register
3541 * This address is already programmed into DXE Descriptor
3542 * But register also upadte */
3543 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3544 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3545 if(eWLAN_PAL_STATUS_SUCCESS != status)
3546 {
3547 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3548 "dxeTXPushFrame Program src address register fail");
3549 return status;
3550 }
3551 /* If descriptor format is SHORT */
3552 if(channelEntry->channelConfig.useShortDescFmt)
3553 {
3554 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3555 0);
3556 if(eWLAN_PAL_STATUS_SUCCESS != status)
3557 {
3558 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3559 "dxeTXPushFrame Program dest address register fail");
3560 return status;
3561 }
3562 }
3563 else
3564 {
3565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3566 "dxeTXPushFrame LONG Descriptor Format!!!");
3567 }
3568
3569 /* Linked list Descriptor pointer */
3570 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3571 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3572 if(eWLAN_PAL_STATUS_SUCCESS != status)
3573 {
3574 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3575 "dxeTXPushFrame Write DESC Address register fail");
3576 return status;
3577 }
3578 /* If descriptor format is SHORT */
3579 if(channelEntry->channelConfig.useShortDescFmt)
3580 {
3581 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3582 0);
3583 if(eWLAN_PAL_STATUS_SUCCESS != status)
3584 {
3585 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3586 "dxeTXPushFrame Program dest address register fail");
3587 return status;
3588 }
3589 }
3590 else
3591 {
3592 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3593 "dxeTXPushFrame LONG Descriptor Format!!!");
3594 }
3595
3596 /* Transfer Size */
3597 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3598 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3599 xferSize);
3600 if(eWLAN_PAL_STATUS_SUCCESS != status)
3601 {
3602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3603 "dxeTXPushFrame Write DESC Address register fail");
3604 return status;
3605 }
3606
3607 /* Everything is ready
3608 * Trigger to start DMA */
3609 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3610 channelEntry->extraConfig.chan_mask);
3611 if(eWLAN_PAL_STATUS_SUCCESS != status)
3612 {
3613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3614 "dxeTXPushFrame Write Channel Ctrl Register fail");
3615 return status;
3616 }
3617
3618 /* Update channel head as next avaliable linked slot */
3619 channelEntry->headCtrlBlk = currentCtrlBlk;
3620
3621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003622 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003623 return status;
3624}
3625
3626/*==========================================================================
3627 @ Function Name
3628 dxeTXCompFrame
3629
3630 @ Description
3631 TX Frame transfer complete event handler
3632
3633 @ Parameters
3634 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3635 DXE host driver main control block
3636 WLANDXE_ChannelCBType *channelEntry
3637 Channel specific control block
3638
3639 @ Return
3640 PAL_STATUS_T
3641===========================================================================*/
3642static wpt_status dxeTXCompFrame
3643(
3644 WLANDXE_CtrlBlkType *hostCtxt,
3645 WLANDXE_ChannelCBType *channelEntry
3646)
3647{
3648 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3649 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3650 WLANDXE_DescType *currentDesc = NULL;
3651 wpt_uint32 descCtrlValue = 0;
3652 unsigned int *lowThreshold = NULL;
3653
3654 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003655 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003656
3657 /* Sanity */
3658 if((NULL == hostCtxt) || (NULL == channelEntry))
3659 {
3660 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3661 "dxeTXCompFrame Invalid ARG");
3662 return eWLAN_PAL_STATUS_E_INVAL;
3663 }
3664
3665 if(NULL == hostCtxt->txCompCB)
3666 {
3667 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3668 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003669 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003670 }
3671
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003672 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3673 if(eWLAN_PAL_STATUS_SUCCESS != status)
3674 {
3675 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3676 "dxeTXCompFrame Mutex Acquire fail");
3677 return status;
3678 }
3679
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 currentCtrlBlk = channelEntry->tailCtrlBlk;
3681 currentDesc = currentCtrlBlk->linkedDesc;
3682
3683 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3684 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003685 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3686 if(eWLAN_PAL_STATUS_SUCCESS != status)
3687 {
3688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3689 "dxeTXCompFrame Mutex Release fail");
3690 return status;
3691 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003692 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003693 }
3694
Kiet Lam842dad02014-02-18 18:44:02 -08003695
Jeff Johnson295189b2012-06-20 16:38:30 -07003696 while(1)
3697 {
3698// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3699 descCtrlValue = currentDesc->descCtrl.ctrl;
3700 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3701 {
3702 /* caught up with head, bail out */
3703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3704 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3705 break;
3706 }
3707
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003708 if(currentCtrlBlk->xfrFrame == NULL)
3709 {
3710 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3711 "Invalid transfer frame");
3712 HDXE_ASSERT(0);
3713 break;
3714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003715 channelEntry->numFreeDesc++;
3716 channelEntry->numRsvdDesc--;
3717
3718 /* Send Frame TX Complete notification with frame start fragment location */
3719 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3720 {
3721 hostCtxt->txCompletedFrames--;
3722#ifdef FEATURE_R33D
3723 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3724#else
3725 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3726 if (eWLAN_PAL_STATUS_SUCCESS != status)
3727 {
3728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3729 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003730 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3731 if(eWLAN_PAL_STATUS_SUCCESS != status)
3732 {
3733 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3734 "dxeTXCompFrame Mutex Release fail");
3735 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003736 return status;
3737 }
3738#endif /* FEATURE_R33D */
3739 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3740 currentCtrlBlk->xfrFrame,
3741 eWLAN_PAL_STATUS_SUCCESS);
3742 channelEntry->numFragmentCurrentChain = 0;
3743 }
3744 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3745 currentDesc = currentCtrlBlk->linkedDesc;
3746
3747 /* Break condition
3748 * Head control block is the control block must be programed for the next TX
3749 * so, head control block is not programmed control block yet
3750 * if loop encounte head control block, stop to complete
3751 * in theory, COMP CB must be called already ??? */
3752 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3753 {
3754 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3755 "dxeTXCompFrame caught up with head ptr");
3756 break;
3757 }
3758 /* VALID Bit check ???? */
3759 }
3760
3761 /* Tail and Head Control block must be same */
3762 channelEntry->tailCtrlBlk = currentCtrlBlk;
3763
3764 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3765 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3766 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3767
3768 /* If specific channel hit low resource condition send notification to upper layer */
3769 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3770 (channelEntry->numFreeDesc > *lowThreshold))
3771 {
3772 /* Change it back if we raised it for fetching a remaining packet from TL */
3773 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3774 {
3775 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3776 }
3777
3778 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3779 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3780 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3781 channelEntry->channelType,
3782 eWLAN_PAL_TRUE);
3783 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003784 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003785 }
3786
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003787 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3788 if(eWLAN_PAL_STATUS_SUCCESS != status)
3789 {
3790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3791 "dxeTXCompFrame Mutex Release fail");
3792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003793
3794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003795 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003796 return status;
3797}
3798
3799/*==========================================================================
3800 @ Function Name
3801 dxeTXEventHandler
3802
3803 @ Description
3804 If DXE HW sends TX related interrupt, this event handler will be called
3805 Handle higher priority channel first
3806 Figureout why interrupt happen and call appropriate final even handler
3807 TX complete or error happen
3808
3809 @ Parameters
3810 void *msgPtr
3811 Even MSG
3812
3813 @ Return
3814 PAL_STATUS_T
3815===========================================================================*/
3816void dxeTXEventHandler
3817(
3818 wpt_msg *msgPtr
3819)
3820{
3821 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3822 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3823 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3824 wpt_uint32 intSrc = 0;
3825 wpt_uint32 chStat = 0;
3826 WLANDXE_ChannelCBType *channelCb = NULL;
3827
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003828 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003829 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003830
3831 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003832 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003833
3834 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003835 dxeCtxt->ucTxMsgCnt = 0;
3836
3837 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3838 {
3839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3840 "wlan: TX COMP WLAN Driver re-loading in progress");
3841 return;
3842 }
3843
Jeff Johnson295189b2012-06-20 16:38:30 -07003844 /* Return from here if the RIVA is in IMPS, to avoid register access */
3845 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3846 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003847 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003848 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003849 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003850 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3851 if(eWLAN_PAL_STATUS_SUCCESS != status)
3852 {
3853 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003854 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003855 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003856
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003857 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3858 if(eWLAN_PAL_STATUS_SUCCESS != status)
3859 {
3860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3861 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3862 }
3863
3864 if(((dxeCtxt->txCompletedFrames) &&
3865 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3866 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003867 {
3868 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3869 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3870 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003871 "TX COMP INT Enabled, remain TX frame count on ring %d",
3872 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003873 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3874 the posibility of a race*/
3875 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3876 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003877 else
3878 {
3879 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3880 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3881 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3882 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003884 return;
3885 }
3886
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003887 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3889 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3890 {
3891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3892 "DXE already stopped in TX event handler. Just return");
3893 return;
3894 }
3895
Jeff Johnson295189b2012-06-20 16:38:30 -07003896 /* Disable device interrupt */
3897 /* Read whole interrupt mask register and exclusive only this channel int */
3898 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3899 &intSrc);
3900 if(eWLAN_PAL_STATUS_SUCCESS != status)
3901 {
3902 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3903 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3904 return;
3905 }
3906 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3907 "TX Event Handler INT Source 0x%x", intSrc);
3908
3909 /* Test High Priority Channel is the INT source or not */
3910 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3911 if(intSrc & (1 << channelCb->assignedDMAChannel))
3912 {
3913 status = dxeChannelCleanInt(channelCb, &chStat);
3914 if(eWLAN_PAL_STATUS_SUCCESS != status)
3915 {
3916 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3917 "dxeTXEventHandler INT Clean up fail");
3918 return;
3919 }
3920
3921 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3922 {
3923 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003924 "%11s : 0x%x Error Reported, Reload Driver",
3925 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303926
Mihir Shete79d6b582014-03-12 17:54:07 +05303927 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303928
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003929 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3930 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303931 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 }
3933 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3934 {
3935 /* Handle TX complete for high priority channel */
3936 status = dxeTXCompFrame(dxeCtxt,
3937 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003938 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003939 }
3940 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3941 {
3942 /* Handle TX complete for high priority channel */
3943 status = dxeTXCompFrame(dxeCtxt,
3944 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003945 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003946 }
3947 else
3948 {
3949 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3950 "dxeTXEventHandler TX HI status=%x", chStat);
3951 }
3952
3953 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3954 {
3955 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3956 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3957 }
3958
3959 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3960 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3961 }
3962
3963 /* Test Low Priority Channel interrupt is enabled or not */
3964 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3965 if(intSrc & (1 << channelCb->assignedDMAChannel))
3966 {
3967 status = dxeChannelCleanInt(channelCb, &chStat);
3968 if(eWLAN_PAL_STATUS_SUCCESS != status)
3969 {
3970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3971 "dxeTXEventHandler INT Clean up fail");
3972 return;
3973 }
3974
3975 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3976 {
3977 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003978 "%11s : 0x%x Error Reported, Reload Driver",
3979 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303980
Mihir Shete79d6b582014-03-12 17:54:07 +05303981 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303982
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003983 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3984 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303985 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 }
3987 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3988 {
3989 /* Handle TX complete for low priority channel */
3990 status = dxeTXCompFrame(dxeCtxt,
3991 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003992 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003993 }
3994 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3995 {
3996 /* Handle TX complete for low priority channel */
3997 status = dxeTXCompFrame(dxeCtxt,
3998 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003999 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004000 }
4001 else
4002 {
4003 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4004 "dxeTXEventHandler TX LO status=%x", chStat);
4005 }
4006
4007 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4008 {
4009 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4010 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
4011 }
4012 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4013 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4014 }
4015
4016
4017#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4018 /* Test H2H TX Channel interrupt is enabled or not */
4019 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
4020 if(intSrc & (1 << channelCb->assignedDMAChannel))
4021 {
4022 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
4023 &chStat);
4024 if(eWLAN_PAL_STATUS_SUCCESS != status)
4025 {
4026 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4027 "dxeChannelCleanInt Read CH STAT register fail");
4028 return;
4029 }
4030
4031 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4032 {
4033 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004034 "%11s : 0x%x Error Reported, Reload Driver",
4035 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304036
Mihir Shete79d6b582014-03-12 17:54:07 +05304037 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304038
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004039 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4040 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05304041 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 }
4043 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4044 {
4045 /* Handle TX complete for high priority channel */
4046 status = dxeTXCompFrame(dxeCtxt,
4047 channelCb);
4048 if(eWLAN_PAL_STATUS_SUCCESS != status)
4049 {
4050 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4051 "dxeTXEventHandler INT Clean up fail");
4052 return;
4053 }
4054 }
4055 else
4056 {
4057 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4058 "unexpected channel state %d", chStat);
4059 }
4060 }
4061#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4062
4063 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
4064 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4065 {
4066 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4067 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004068 if(0 != dxeCtxt->txCompletedFrames)
4069 {
4070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4071 "TX COMP INT Enabled, remain TX frame count on ring %d",
4072 dxeCtxt->txCompletedFrames);
4073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 }
4075
4076 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4077 the posibility of a race*/
4078 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4079
4080 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004081 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004082 return;
4083}
4084
4085
4086/*==========================================================================
4087 @ Function Name
4088 dxeTXCompleteProcessing
4089
4090 @ Description
4091 If DXE HW sends TX related interrupt, this event handler will be called
4092 Handle higher priority channel first
4093 Figureout why interrupt happen and call appropriate final even handler
4094 TX complete or error happen
4095
4096 @ Parameters
4097 dxeCtxt DXE context
4098
4099 @ Return
4100 PAL_STATUS_T
4101===========================================================================*/
4102void dxeTXCompleteProcessing
4103(
4104 WLANDXE_CtrlBlkType *dxeCtxt
4105)
4106{
4107 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4108 WLANDXE_ChannelCBType *channelCb = NULL;
4109
4110 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004111 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004112
4113 /* Test High Priority Channel is the INT source or not */
4114 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4115
4116 /* Handle TX complete for high priority channel */
4117 status = dxeTXCompFrame(dxeCtxt, channelCb);
4118
4119 /* Test Low Priority Channel interrupt is enabled or not */
4120 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4121
4122 /* Handle TX complete for low priority channel */
4123 status = dxeTXCompFrame(dxeCtxt, channelCb);
4124
4125 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
4126 ((dxeCtxt->txCompletedFrames > 0) ||
4127 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
4128 {
4129 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4130 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4131 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004132 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
4134 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
4135 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
4136 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07004137
4138 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
4139 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
4140 {
4141 /* After TX Comp processing, still remaining frame on the DXE TX ring
4142 * And when push frame, RING was not empty marked
4143 * Then when push frame, no SMSM toggle happen
4144 * To avoid permanent TX stall, SMSM toggle is needed at here
4145 * With this toggle, host should gaurantee SMSM state should be changed */
4146 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4147 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004149 }
4150
4151 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4152 the posibility of a race*/
4153 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
4154
4155 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004156 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 return;
4158}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004159
4160/*==========================================================================
4161 @ Function Name
4162 dxeTXReSyncDesc
4163
4164 @ Description
4165 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
4166 And HW programmed descriptor.
4167 If any async happen between HW/SW TX stall will happen
4168
4169 @ Parameters
4170 void *msgPtr
4171 Message pointer to sync with TX thread
4172
4173 @ Return
4174 NONE
4175===========================================================================*/
4176void dxeTXReSyncDesc
4177(
4178 wpt_msg *msgPtr
4179)
4180{
4181 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4182 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4183 wpt_uint32 nextDescReg;
4184 WLANDXE_ChannelCBType *channelEntry;
4185 WLANDXE_DescCtrlBlkType *validCtrlBlk;
4186 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004187 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004188
4189 if(NULL == msgContent)
4190 {
4191 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4192 "dxeTXReSyncDesc Invalid Control Block");
4193 return;
4194 }
4195
4196 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4197 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
4198 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4199
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004200 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004201 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004202 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4203 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4204 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
4205 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4206 &nextDescReg);
4207 /* Async detect without TX pending frame */
4208 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004209 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004210 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004211 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4213 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304214
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004215 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
4216 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304217
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004218 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004219 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004220 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004221 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004222 /* Async detect with some TX pending frames
4223 * next descriptor register should sync with first valid descriptor */
4224 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004225 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004226 validCtrlBlk = channelEntry->tailCtrlBlk;
4227 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004228 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004229 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4230 {
4231 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
4232 {
4233 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4234 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304235
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004236 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4237 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304238
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004239 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4240 validCtrlBlk->linkedDescPhyAddr);
4241 }
4242 break;
4243 }
4244 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4245 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4246 {
4247 /* Finished to test till head control blcok, but could not find valid descriptor
4248 * from head to tail all descriptors are invalidated
4249 * host point of view head descriptor is next TX candidate
4250 * So, next descriptor control have to be programmed with head descriptor
4251 * check */
4252 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
4253 {
4254 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004255 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304256
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004257 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4258 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304259
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004260 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4261 validCtrlBlk->linkedDescPhyAddr);
4262 }
4263 break;
4264 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004265 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004266 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004267 }
4268
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07004269 /* HW/SW descriptor resync is done.
4270 * Next if there are any valid descriptor in chain, Push to HW again */
4271 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
4272 {
4273 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4274 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
4275 {
4276 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4277 "%11s : No TX Pending frame",
4278 channelType[channelEntry->channelType]);
4279 /* No Pending frame, Do nothing */
4280 }
4281 else
4282 {
4283 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4284 "%11s : TX Pending frame, process it",
4285 channelType[channelEntry->channelType]);
4286 validCtrlBlk = channelEntry->tailCtrlBlk;
4287 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
4288 {
4289 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4290 {
4291 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4292 "%11s : when exit IMPS found valid descriptor",
4293 channelType[channelEntry->channelType]);
4294
4295 /* Found valid descriptor, kick DXE */
4296 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
4297 channelEntry->extraConfig.chan_mask);
4298 break;
4299 }
4300 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4301 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4302 {
4303 /* Finished to test till head control blcok, but could not find valid descriptor
4304 * from head to tail all descriptors are invalidated */
4305 break;
4306 }
4307 }
4308 }
4309 }
4310
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004311 wpalMemoryFree(msgPtr);
4312 return;
4313}
4314
Jeff Johnson295189b2012-06-20 16:38:30 -07004315/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05304316 @ Function Name
4317 dxeDebugTxDescReSync
4318
4319 @ Description
4320 Check DXE Tx channel state and correct it in
4321 case Tx Data stall is detected by calling
4322 %dxeTXReSyncDesc. Also ensure that WCN SS
4323 is not power collapsed before calling
4324 %dxeTXReSyncDesc
4325
4326 @ Parameters
4327 void *msgPtr
4328 Message pointer to sync with TX thread
4329
4330 @ Return
4331 NONE
4332===========================================================================*/
4333void dxeDebugTxDescReSync
4334(
4335 wpt_msg *msgPtr
4336)
4337{
4338 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4339 "%s: Check for DXE TX Async",__func__);
4340 /* Make wake up HW */
4341 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4342 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4343
4344 wpalSleep(10);
4345
4346 dxeTXReSyncDesc(msgPtr);
4347}
4348/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004349 @ Function Name
4350 dxeTXISR
4351
4352 @ Description
4353 TX interrupt ISR
4354 Platform will call this function if INT is happen
4355 This function must be registered into platform interrupt module
4356
4357 @ Parameters
4358 void *hostCtxt
4359 DXE host driver control context,
4360 pre registerd during interrupt registration
4361
4362 @ Return
4363 PAL_STATUS_T
4364===========================================================================*/
4365static void dxeTXISR
4366(
4367 void *hostCtxt
4368)
4369{
4370 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
4371 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4372#ifdef FEATURE_R33D
4373 wpt_uint32 regValue;
4374#endif /* FEATURE_R33D */
4375
4376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004377 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004378
4379 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004380 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004382 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 /* Disable interrupt at here,
4384 IMPS or IMPS Pending state should not access RIVA register */
4385 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4386 if(eWLAN_PAL_STATUS_SUCCESS != status)
4387 {
4388 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4389 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4390 return;
4391 }
4392 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4393 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004394 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004395 return;
4396 }
4397
4398#ifdef FEATURE_R33D
4399 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
4400 &regValue);
4401 if(eWLAN_PAL_STATUS_SUCCESS != status)
4402 {
4403 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4404 "dxeTXCompISR Read INT_SRC_RAW fail");
4405 return;
4406 }
4407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4408 "INT_SRC_RAW 0x%x", regValue);
4409 if(0 == regValue)
4410 {
4411 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4412 "This is not DXE Interrupt, Reject it");
4413 return;
4414 }
4415#endif /* FEATURE_R33D */
4416
4417 /* Disable TX Complete Interrupt at here */
4418 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4419 if(eWLAN_PAL_STATUS_SUCCESS != status)
4420 {
4421 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4422 "dxeTXCompISR Disable TX complete interrupt fail");
4423 return;
4424 }
4425 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4426
4427
4428 if( dxeCtxt->ucTxMsgCnt )
4429 {
4430 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4431 "Avoiding serializing TX Complete event");
4432 return;
4433 }
4434
4435 dxeCtxt->ucTxMsgCnt = 1;
4436
4437 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004438 if(NULL == dxeCtxt->txIsrMsg)
4439 {
4440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4441 "Invalid message");
4442 HDXE_ASSERT(0);
4443 return;
4444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004445 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4446 dxeCtxt->txIsrMsg);
4447 if(eWLAN_PAL_STATUS_SUCCESS != status)
4448 {
4449 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4450 "dxeTXCompISR interrupt serialize fail status=%d", status);
4451 }
4452
4453 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004454 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 return;
4456}
4457
4458/*-------------------------------------------------------------------------
4459 * Global Function
4460 *-------------------------------------------------------------------------*/
4461/*==========================================================================
4462 @ Function Name
4463 WLANDXE_Open
4464
4465 @ Description
4466 Open host DXE driver, allocate DXE resources
4467 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4468
4469 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004470 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004471
4472 @ Return
4473 pVoid DXE local module control block pointer
4474===========================================================================*/
4475void *WLANDXE_Open
4476(
4477 void
4478)
4479{
4480 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4481 unsigned int idx;
4482 WLANDXE_ChannelCBType *currentChannel = NULL;
4483 int smsmInitState;
4484#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4485 wpt_uint32 sIdx;
4486 WLANDXE_ChannelCBType *channel = NULL;
4487 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4488 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4489#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4490
4491 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004492 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004493
4494 /* This is temporary allocation */
4495 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4496 if(NULL == tempDxeCtrlBlk)
4497 {
4498 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4499 "WLANDXE_Open Control Block Alloc Fail");
4500 return NULL;
4501 }
4502 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4503
4504 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4505 if(eWLAN_PAL_STATUS_SUCCESS != status)
4506 {
4507 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4508 "WLANDXE_Open Common Configuration Fail");
4509 WLANDXE_Close(tempDxeCtrlBlk);
4510 return NULL;
4511 }
4512
4513 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4514 {
4515 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4516 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4517 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
4518 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
4519 {
4520 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
4521 }
4522 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
4523 {
4524 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
4525 }
4526 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
4527 {
4528 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
4529 }
4530 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
4531 {
4532 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
4533 }
4534#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4535 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
4536 {
4537 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
4538 }
4539 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
4540 {
4541 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
4542 }
4543#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4544
4545 /* Config individual channels from channel default setup table */
4546 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4547 currentChannel);
4548 if(eWLAN_PAL_STATUS_SUCCESS != status)
4549 {
4550 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4551 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4552 WLANDXE_Close(tempDxeCtrlBlk);
4553 return NULL;
4554 }
4555
4556 /* Allocate DXE Control Block will be used by host DXE driver */
4557 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4558 if(eWLAN_PAL_STATUS_SUCCESS != status)
4559 {
4560 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4561 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4562
4563 WLANDXE_Close(tempDxeCtrlBlk);
4564 return NULL;
4565 }
4566 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4567 if(eWLAN_PAL_STATUS_SUCCESS != status)
4568 {
4569 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4570 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4571 WLANDXE_Close(tempDxeCtrlBlk);
4572 return NULL;
4573 }
4574
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004575 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4576 dxeHealthMonitorTimeout,
4577 (void *)currentChannel);
4578 if(eWLAN_PAL_STATUS_SUCCESS != status)
4579 {
4580 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4581 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4582 WLANDXE_Close(tempDxeCtrlBlk);
4583 return NULL;
4584 }
4585
4586 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4587 if(NULL == currentChannel->healthMonitorMsg)
4588 {
4589 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4590 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4591 WLANDXE_Close(tempDxeCtrlBlk);
4592 return NULL;
4593 }
4594 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4595 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4596 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4597
Jeff Johnson295189b2012-06-20 16:38:30 -07004598 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4599 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4600 }
4601
4602 /* Allocate and Init RX READY ISR Serialize Buffer */
4603 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4604 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4605 {
4606 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4607 "WLANDXE_Open Alloc RX ISR Fail");
4608 WLANDXE_Close(tempDxeCtrlBlk);
4609 return NULL;
4610 }
4611 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4612 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4613 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4614
4615 /* Allocate and Init TX COMP ISR Serialize Buffer */
4616 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4617 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4618 {
4619 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4620 "WLANDXE_Open Alloc TX ISR Fail");
4621 WLANDXE_Close(tempDxeCtrlBlk);
4622 return NULL;
4623 }
4624 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4625 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4626 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4627
4628 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4629 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4630 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4631 {
4632 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4633 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4634 WLANDXE_Close(tempDxeCtrlBlk);
4635 return NULL;
4636 }
4637 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4638 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4639 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4640
4641 tempDxeCtrlBlk->freeRXPacket = NULL;
4642 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4643 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4644 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004645 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004646 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004647
4648 /* Initialize SMSM state
4649 * Init State is
4650 * Clear TX Enable
4651 * RING EMPTY STATE */
4652 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4653 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4654 if(0 != smsmInitState)
4655 {
4656 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4657 "SMSM Channel init fail %d", smsmInitState);
4658 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4659 {
4660 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4661 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004662 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4663 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004664 wpalMemoryFree(tempDxeCtrlBlk);
4665 return NULL;
4666 }
4667
Mihir Shete44547fb2014-03-10 14:15:42 +05304668#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004669 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4670 dxeRXResourceAvailableTimerExpHandler,
4671 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304672#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004673
Mihir Shetefdc9f532014-01-09 15:03:02 +05304674 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4675 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4676
Jeff Johnson295189b2012-06-20 16:38:30 -07004677 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4678 "WLANDXE_Open Success");
4679 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004680 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004681 return (void *)tempDxeCtrlBlk;
4682}
4683
4684/*==========================================================================
4685 @ Function Name
4686 WLANDXE_ClientRegistration
4687
4688 @ Description
4689 Make callback functions registration into DXE driver from DXE driver client
4690
4691 @ Parameters
4692 pVoid pDXEContext : DXE module control block
4693 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4694 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4695 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4696 void *userContext : DXE Cliennt control block
4697
4698 @ Return
4699 wpt_status
4700===========================================================================*/
4701wpt_status WLANDXE_ClientRegistration
4702(
4703 void *pDXEContext,
4704 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4705 WLANDXE_TxCompleteCbType txCompleteCB,
4706 WLANDXE_LowResourceCbType lowResourceCB,
4707 void *userContext
4708)
4709{
4710 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4711 WLANDXE_CtrlBlkType *dxeCtxt;
4712
4713 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004714 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004715
4716 /* Sanity */
4717 if(NULL == pDXEContext)
4718 {
4719 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4720 "WLANDXE_ClientRegistration Invalid DXE CB");
4721 return eWLAN_PAL_STATUS_E_INVAL;
4722 }
4723
4724 if(NULL == rxFrameReadyCB)
4725 {
4726 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4727 "WLANDXE_ClientRegistration Invalid RX READY CB");
4728 return eWLAN_PAL_STATUS_E_INVAL;
4729 }
4730
4731 if(NULL == txCompleteCB)
4732 {
4733 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4734 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4735 return eWLAN_PAL_STATUS_E_INVAL;
4736 }
4737
4738 if(NULL == lowResourceCB)
4739 {
4740 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4741 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4742 return eWLAN_PAL_STATUS_E_INVAL;
4743 }
4744
4745 if(NULL == userContext)
4746 {
4747 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4748 "WLANDXE_ClientRegistration Invalid userContext");
4749 return eWLAN_PAL_STATUS_E_INVAL;
4750 }
4751
4752 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4753
4754 /* Assign */
4755 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4756 dxeCtxt->txCompCB = txCompleteCB;
4757 dxeCtxt->lowResourceCB = lowResourceCB;
4758 dxeCtxt->clientCtxt = userContext;
4759
4760 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004761 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004762 return status;
4763}
4764
4765/*==========================================================================
4766 @ Function Name
4767 WLANDXE_Start
4768
4769 @ Description
4770 Start Host DXE driver
4771 Initialize DXE channels and start channel
4772
4773 @ Parameters
4774 pVoid pDXEContext : DXE module control block
4775
4776 @ Return
4777 wpt_status
4778===========================================================================*/
4779wpt_status WLANDXE_Start
4780(
4781 void *pDXEContext
4782)
4783{
4784 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4785 wpt_uint32 idx;
4786 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4787
4788 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004789 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004790
4791 /* Sanity */
4792 if(NULL == pDXEContext)
4793 {
4794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4795 "WLANDXE_Start Invalid DXE CB");
4796 return eWLAN_PAL_STATUS_E_INVAL;
4797 }
4798 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4799
4800 /* WLANDXE_Start called means DXE engine already initiates
4801 * And DXE HW is reset and init finished
4802 * But here to make sure HW is initialized, reset again */
4803 status = dxeEngineCoreStart(dxeCtxt);
4804 if(eWLAN_PAL_STATUS_SUCCESS != status)
4805 {
4806 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4807 "WLANDXE_Start DXE HW init Fail");
4808 return status;
4809 }
4810
4811 /* Individual Channel Start */
4812 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4813 {
4814 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4815 "WLANDXE_Start Channel %s Start", channelType[idx]);
4816
4817 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4818 /* Make connection between DXE descriptor and DXE control block */
4819 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4820 if(eWLAN_PAL_STATUS_SUCCESS != status)
4821 {
4822 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4823 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4824 return status;
4825 }
4826
4827 /* Program each channel register with configuration arguments */
4828 status = dxeChannelInitProgram(dxeCtxt,
4829 &dxeCtxt->dxeChannel[idx]);
4830 if(eWLAN_PAL_STATUS_SUCCESS != status)
4831 {
4832 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4833 "WLANDXE_Start %d Program DMA channel Fail", idx);
4834 return status;
4835 }
4836
4837 /* ??? Trigger to start DMA channel
4838 * This must be seperated from ??? */
4839 status = dxeChannelStart(dxeCtxt,
4840 &dxeCtxt->dxeChannel[idx]);
4841 if(eWLAN_PAL_STATUS_SUCCESS != status)
4842 {
4843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4844 "WLANDXE_Start %d Channel Start Fail", idx);
4845 return status;
4846 }
4847 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4848 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4849 }
4850
4851 /* Register ISR to OS */
4852 /* Register TX complete interrupt into platform */
4853 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4854 dxeTXISR,
4855 dxeCtxt);
4856 if(eWLAN_PAL_STATUS_SUCCESS != status)
4857 {
4858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4859 "WLANDXE_Start TX comp interrupt registration Fail");
4860 return status;
4861 }
4862
4863 /* Register RX ready interrupt into platform */
4864 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4865 dxeRXISR,
4866 dxeCtxt);
4867 if(eWLAN_PAL_STATUS_SUCCESS != status)
4868 {
4869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4870 "WLANDXE_Start RX Ready interrupt registration Fail");
4871 return status;
4872 }
4873
4874 /* Enable system level ISR */
4875 /* Enable RX ready Interrupt at here */
4876 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4877 if(eWLAN_PAL_STATUS_SUCCESS != status)
4878 {
4879 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4880 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4881 return status;
4882 }
4883
4884 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004885 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004886 return status;
4887}
4888
4889/*==========================================================================
4890 @ Function Name
4891 WLANDXE_TXFrame
4892
4893 @ Description
4894 Trigger frame transmit from host to RIVA
4895
4896 @ Parameters
4897 pVoid pDXEContext : DXE Control Block
4898 wpt_packet pPacket : transmit packet structure
4899 WDTS_ChannelType channel : TX channel
4900
4901 @ Return
4902 wpt_status
4903===========================================================================*/
4904wpt_status WLANDXE_TxFrame
4905(
4906 void *pDXEContext,
4907 wpt_packet *pPacket,
4908 WDTS_ChannelType channel
4909)
4910{
4911 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4912 WLANDXE_ChannelCBType *currentChannel = NULL;
4913 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4914 unsigned int *lowThreshold = NULL;
4915
4916 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004917 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004918
4919 /* Sanity */
4920 if(NULL == pDXEContext)
4921 {
4922 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4923 "WLANDXE_Start Invalid DXE CB");
4924 return eWLAN_PAL_STATUS_E_INVAL;
4925 }
4926
4927 if(NULL == pPacket)
4928 {
4929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4930 "WLANDXE_Start Invalid pPacket");
4931 return eWLAN_PAL_STATUS_E_INVAL;
4932 }
4933
4934 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
4935 {
4936 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4937 "WLANDXE_Start Invalid channel");
4938 return eWLAN_PAL_STATUS_E_INVAL;
4939 }
4940
4941 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4942
4943 currentChannel = &dxeCtxt->dxeChannel[channel];
4944
4945
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004946 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4947 if(eWLAN_PAL_STATUS_SUCCESS != status)
4948 {
4949 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4950 "WLANDXE_TxFrame Mutex Acquire fail");
4951 return status;
4952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004953
4954 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4955 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4956 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4957
4958 /* Decide have to activate TX complete event or not */
4959 switch(dxeCtxt->txCompInt.txIntEnable)
4960 {
4961 /* TX complete interrupt will be activated when low DXE resource */
4962 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4963 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4964 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4965 {
4966 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4967 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4968 channel,
4969 eWLAN_PAL_FALSE);
4970 }
4971 break;
4972
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004973 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4975 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4976 {
4977 currentChannel->numFrameBeforeInt++;
4978 }
4979 break;
4980
4981 /* TX complete interrupt will be activated periodically */
4982 case WLANDXE_TX_COMP_INT_TIMER:
4983 break;
4984 }
4985
4986 dxeCtxt->txCompletedFrames++;
4987
4988 /* Update DXE descriptor, this is frame based
4989 * if a frame consist of N fragments, N Descriptor will be programed */
4990 status = dxeTXPushFrame(currentChannel, pPacket);
4991 if(eWLAN_PAL_STATUS_SUCCESS != status)
4992 {
4993 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4994 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004995 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4996 if(eWLAN_PAL_STATUS_SUCCESS != status)
4997 {
4998 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4999 "WLANDXE_TxFrame Mutex Release fail");
5000 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005001 return status;
5002 }
5003
5004 /* If specific channel hit low resource condition, send notification to upper layer */
5005 if(currentChannel->numFreeDesc <= *lowThreshold)
5006 {
5007 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5008 channel,
5009 eWLAN_PAL_FALSE);
5010 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005011
5012 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5013 "%11s : Low Resource currentChannel->numRsvdDesc %d",
5014 channelType[currentChannel->channelType],
5015 currentChannel->numRsvdDesc);
5016 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5017 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
5018 wpalTimerStart(&currentChannel->healthMonitorTimer,
5019 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005021 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5022 if(eWLAN_PAL_STATUS_SUCCESS != status)
5023 {
5024 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5025 "WLANDXE_TxFrame Mutex Release fail");
5026 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005027
5028 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005029 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005030 return status;
5031}
5032
5033/*==========================================================================
5034 @ Function Name
5035 WLANDXE_CompleteTX
5036
5037 @ Description
5038 Informs DXE that the current series of Tx packets is complete
5039
5040 @ Parameters
5041 pContext pDXEContext : DXE Control Block
5042 ucTxResReq TX resource number required by TL/WDI
5043
5044 @ Return
5045 wpt_status
5046===========================================================================*/
5047wpt_status
5048WLANDXE_CompleteTX
5049(
5050 void* pContext,
5051 wpt_uint32 ucTxResReq
5052)
5053{
5054 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5055 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
5056 WLANDXE_ChannelCBType *channelCb = NULL;
5057 wpt_boolean inLowRes;
5058
5059 /* Sanity Check */
5060 if( NULL == pContext )
5061 {
5062 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5063 "WLANDXE_CompleteTX invalid param");
5064 return eWLAN_PAL_STATUS_E_INVAL;
5065 }
5066
5067 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
5068 inLowRes = channelCb->hitLowResource;
5069
5070 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
5071 {
5072 /* Raise threshold temporarily if necessary */
5073 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
5074
5075 if(eWLAN_PAL_FALSE == inLowRes)
5076 {
5077 /* Put the channel to low resource condition */
5078 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5079 WDTS_CHANNEL_TX_LOW_PRI,
5080 eWLAN_PAL_FALSE);
5081 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005082 wpalTimerStart(&channelCb->healthMonitorTimer,
5083 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 }
5085 }
5086
5087 /*Try to reclaim resources*/
5088 dxeTXCompleteProcessing(dxeCtxt);
5089
5090 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
5091 because its fragment size is larger than DXE free resource. */
5092 if(0 < ucTxResReq)
5093 {
5094 /* DXE successfully claimed enough free DXE resouces for next fetch. */
5095 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
5096 {
5097 /* DXE has not been in low resource condition. DXE forces to kick off
5098 TX tranmit */
5099 if((eWLAN_PAL_FALSE == inLowRes) &&
5100 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
5101 {
5102 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5103 WDTS_CHANNEL_TX_LOW_PRI,
5104 eWLAN_PAL_FALSE);
5105 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5106 WDTS_CHANNEL_TX_LOW_PRI,
5107 eWLAN_PAL_TRUE);
5108 channelCb->hitLowResource = eWLAN_PAL_FALSE;
5109 }
5110 }
5111 else
5112 {
5113 /* DXE doesn't have enough free DXE resources. Put the channel
5114 to low resource condition. */
5115 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
5116 {
5117 /* Put the channel to low resource condition */
5118 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5119 WDTS_CHANNEL_TX_LOW_PRI,
5120 eWLAN_PAL_FALSE);
5121 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005122 wpalTimerStart(&channelCb->healthMonitorTimer,
5123 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 }
5125 }
5126 }
5127
5128 return status;
5129}
5130
5131/*==========================================================================
5132 @ Function Name
5133 WLANDXE_Stop
5134
5135 @ Description
5136 Stop DXE channels and DXE engine operations
5137 Disable all channel interrupt
5138 Stop all channel operation
5139
5140 @ Parameters
5141 pVoid pDXEContext : DXE Control Block
5142
5143 @ Return
5144 wpt_status
5145===========================================================================*/
5146wpt_status WLANDXE_Stop
5147(
5148 void *pDXEContext
5149)
5150{
5151 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5152 wpt_uint32 idx;
5153 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5154
5155 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005156 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005157
5158 /* Sanity */
5159 if(NULL == pDXEContext)
5160 {
5161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5162 "WLANDXE_Stop Invalid DXE CB");
5163 return eWLAN_PAL_STATUS_E_INVAL;
5164 }
5165
5166 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
5167 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
5168 {
Yue Ma7faf58c2013-04-25 12:04:13 -07005169 if(VOS_TIMER_STATE_RUNNING == wpalTimerGetCurStatus(&dxeCtxt->dxeChannel[idx].healthMonitorTimer))
5170 {
5171 wpalTimerStop(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
5172 }
5173
Jeff Johnson295189b2012-06-20 16:38:30 -07005174 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5175 if(eWLAN_PAL_STATUS_SUCCESS != status)
5176 {
5177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5178 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 }
5180 }
5181
5182 /* During Stop unregister interrupt */
5183 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
5184 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
5185
Mihir Shete44547fb2014-03-10 14:15:42 +05305186#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005187 if(VOS_TIMER_STATE_STOPPED !=
5188 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
5189 {
5190 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
5191 }
Mihir Shete44547fb2014-03-10 14:15:42 +05305192#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07005193
Jeff Johnson295189b2012-06-20 16:38:30 -07005194 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005195 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005196 return status;
5197}
5198
5199/*==========================================================================
5200 @ Function Name
5201 WLANDXE_Close
5202
5203 @ Description
5204 Close DXE channels
5205 Free DXE related resources
5206 DXE descriptor free
5207 Descriptor control block free
5208 Pre allocated RX buffer free
5209
5210 @ Parameters
5211 pVoid pDXEContext : DXE Control Block
5212
5213 @ Return
5214 wpt_status
5215===========================================================================*/
5216wpt_status WLANDXE_Close
5217(
5218 void *pDXEContext
5219)
5220{
5221 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5222 wpt_uint32 idx;
5223 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5224#ifdef WLANDXE_TEST_CHANNEL_ENABLE
5225 wpt_uint32 sIdx;
5226 WLANDXE_ChannelCBType *channel = NULL;
5227 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
5228 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
5229#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
5230
5231 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005232 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005233
5234 /* Sanity */
5235 if(NULL == pDXEContext)
5236 {
5237 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5238 "WLANDXE_Stop Invalid DXE CB");
5239 return eWLAN_PAL_STATUS_E_INVAL;
5240 }
5241
5242 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05305243#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005244 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05305245#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05305246 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
5248 {
5249 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005250 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
5251 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
5252 {
5253 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
5254 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005255 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5256#ifdef WLANDXE_TEST_CHANNEL_ENABLE
5257 channel = &dxeCtxt->dxeChannel[idx];
5258 crntDescCB = channel->headCtrlBlk;
5259 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
5260 {
5261 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
5262 wpalMemoryFree((void *)crntDescCB);
5263 crntDescCB = nextDescCB;
5264 if(NULL == crntDescCB)
5265 {
5266 break;
5267 }
5268 }
5269#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
5270 }
5271
5272 if(NULL != dxeCtxt->rxIsrMsg)
5273 {
5274 wpalMemoryFree(dxeCtxt->rxIsrMsg);
5275 }
5276 if(NULL != dxeCtxt->txIsrMsg)
5277 {
5278 wpalMemoryFree(dxeCtxt->txIsrMsg);
5279 }
5280 if(NULL != dxeCtxt->rxPktAvailMsg)
5281 {
5282 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
5283 }
5284
5285 wpalMemoryFree(pDXEContext);
5286
5287 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005288 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005289 return status;
5290}
5291
5292/*==========================================================================
5293 @ Function Name
5294 WLANDXE_TriggerTX
5295
5296 @ Description
5297 TBD
5298
5299 @ Parameters
5300 pVoid pDXEContext : DXE Control Block
5301
5302 @ Return
5303 wpt_status
5304===========================================================================*/
5305wpt_status WLANDXE_TriggerTX
5306(
5307 void *pDXEContext
5308)
5309{
5310 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5311
5312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005313 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005314
5315 /* TBD */
5316
5317 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005318 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 return status;
5320}
5321
5322/*==========================================================================
5323 @ Function Name
5324 dxeTxThreadSetPowerStateEventHandler
5325
5326 @ Description
5327 If WDI sends set power state req, this event handler will be called in Tx
5328 thread context
5329
5330 @ Parameters
5331 void *msgPtr
5332 Event MSG
5333
5334 @ Return
5335 None
5336===========================================================================*/
5337void dxeTxThreadSetPowerStateEventHandler
5338(
5339 wpt_msg *msgPtr
5340)
5341{
5342 wpt_msg *msgContent = (wpt_msg *)msgPtr;
5343 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05305344 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05305346 wpt_int8 i;
5347 WLANDXE_ChannelCBType *channelEntry;
5348 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07005349
5350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005351 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005352
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
5354 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
5355 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
5356
5357 switch(reqPowerState)
5358 {
5359 case WLANDXE_POWER_STATE_BMPS:
5360 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5361 {
5362 //don't block MC waiting for num_rsvd to become 0 since it may take a while
5363 //based on amount of TX and RX activity - during this time any received
5364 // management frames will remain un-processed consuming RX buffers
5365 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5366 dxeCtxt->hostPowerState = reqPowerState;
5367 }
5368 else
5369 {
5370 status = eWLAN_PAL_STATUS_E_INVAL;
5371 }
5372 break;
5373 case WLANDXE_POWER_STATE_IMPS:
5374 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5375 {
Mihir Shetea4306052014-03-25 00:02:54 +05305376
5377 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
5378 {
5379 channelEntry = &dxeCtxt->dxeChannel[i];
5380 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
5381 {
5382 status = eWLAN_PAL_STATUS_E_FAILURE;
5383 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
5384 "%11s : %s :TX Pending frame",
5385 channelType[channelEntry->channelType], __func__);
5386
5387 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
5388 dxeDescriptorDump(channelEntry,
5389 channelEntry->headCtrlBlk->linkedDesc, 0);
5390 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
5391 &channelLog);
5392 dxeChannelAllDescDump(channelEntry,
5393 channelEntry->channelType,
5394 &channelLog);
5395 }
5396 }
5397
5398 if (eWLAN_PAL_STATUS_SUCCESS == status)
5399 {
5400 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
5401 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5402 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 }
5404 else
5405 {
5406 status = eWLAN_PAL_STATUS_E_INVAL;
5407 }
5408 break;
5409 case WLANDXE_POWER_STATE_FULL:
5410 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5411 {
5412 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5413 }
5414 dxeCtxt->hostPowerState = reqPowerState;
5415 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5416 break;
5417 case WLANDXE_POWER_STATE_DOWN:
5418 WLANDXE_Stop((void *)dxeCtxt);
5419 break;
5420 default:
5421 //assert
5422 break;
5423 }
5424
5425 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
5426 {
5427 dxeCtxt->setPowerStateCb(status,
5428 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
5429 }
Ravali85acf6b2012-12-12 14:01:38 -08005430 else
5431 {
5432 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5433 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
5434 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 /* Free MSG buffer */
5436 wpalMemoryFree(msgPtr);
5437 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005438 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 return;
5440}
5441
5442
5443/*==========================================================================
5444 @ Function Name
5445 dxeRxThreadSetPowerStateEventHandler
5446
5447 @ Description
5448 If WDI sends set power state req, this event handler will be called in Rx
5449 thread context
5450
5451 @ Parameters
5452 void *msgPtr
5453 Event MSG
5454
5455 @ Return
5456 None
5457===========================================================================*/
5458void dxeRxThreadSetPowerStateEventHandler
5459(
5460 wpt_msg *msgPtr
5461)
5462{
5463 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5464
5465 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005466 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005467
5468 /* Now serialise the message through Tx thread also to make sure
5469 * no register access when RIVA is in powersave */
5470 /*Use the same message pointer just change the call back function */
5471 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5472 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5473 msgPtr);
5474 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5475 {
5476 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5477 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005478 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 }
5480
5481 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005482 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005483}
5484
5485/*==========================================================================
5486 @ Function Name
5487 WLANDXE_SetPowerState
5488
5489 @ Description
5490 From Client let DXE knows what is the WLAN HW(RIVA) power state
5491
5492 @ Parameters
5493 pVoid pDXEContext : DXE Control Block
5494 WLANDXE_PowerStateType powerState
5495
5496 @ Return
5497 wpt_status
5498===========================================================================*/
5499wpt_status WLANDXE_SetPowerState
5500(
5501 void *pDXEContext,
5502 WDTS_PowerStateType powerState,
5503 WDTS_SetPSCbType cBack
5504)
5505{
5506 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5507 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5508 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005509 wpt_msg *rxCompMsg;
5510 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005511
5512 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005513 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 if(NULL == pDXEContext)
5515 {
5516 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005517 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 return eWLAN_PAL_STATUS_E_FAILURE;
5519 }
5520 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5521
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 switch(powerState)
5523 {
5524 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005525 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5526 {
5527 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5528 if(NULL == txDescReSyncMsg)
5529 {
5530 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5531 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5532 }
5533 else
5534 {
5535 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5536 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5537 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5538 txDescReSyncMsg);
5539 if(eWLAN_PAL_STATUS_SUCCESS != status)
5540 {
5541 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5542 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5543 }
5544 }
5545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 hostPowerState = WLANDXE_POWER_STATE_FULL;
5547 break;
5548 case WDTS_POWER_STATE_BMPS:
5549 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5550 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5551 break;
5552 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5554 break;
5555 case WDTS_POWER_STATE_DOWN:
5556 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5557 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5558 break;
5559 default:
5560 hostPowerState = WLANDXE_POWER_STATE_MAX;
5561 }
5562
5563 // A callback i.e. ACK back is needed only when we want to enable BMPS
5564 // and the data/management path is active because we want to ensure
5565 // DXE registers are not accessed when RIVA may be power-collapsed. So
5566 // we need a callback in enter_bmps_req (the request to RIVA is sent
5567 // only after ACK back from TX thread). A callback is not needed in
5568 // finish_scan_req during BMPS since data-path is resumed only in
5569 // finish_scan_rsp and no management frames are sent in between. No
5570 // callback is needed when going from BMPS enabled to BMPS suspended/
5571 // disabled when it is known that RIVA is awake and cannot enter power
5572 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5573 // init_scan_rsp
5574 if ( cBack )
5575 {
5576 //serialize through Rx thread
5577 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5578 if(NULL == rxCompMsg)
5579 {
5580 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5581 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5582 return eWLAN_PAL_STATUS_E_RESOURCES;
5583 }
5584
5585 /* Event type, where it must be defined???? */
5586 /* THIS MUST BE CLEARED ASAP
5587 txCompMsg->type = TX_COMPLETE; */
5588 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5589 rxCompMsg->pContext = pDxeCtrlBlk;
5590 rxCompMsg->val = hostPowerState;
5591 rxCompMsg->ptr = cBack;
5592 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5593 rxCompMsg);
5594 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5595 {
5596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5597 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005598 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 }
5600 }
5601 else
5602 {
5603 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5604 {
5605 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5606 {
5607 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5608 }
5609 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5610 {
5611 /* Requested Full power from exit IMPS, reenable the interrupts*/
5612 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5613 {
5614 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5615 /* Enable RX interrupt at here, if new PS is not IMPS */
5616 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5617 if(eWLAN_PAL_STATUS_SUCCESS != status)
5618 {
5619 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005620 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 return status;
5622 }
5623 }
5624 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5625 {
5626 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005627 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 /* Enable RX interrupt at here, if new PS is not IMPS */
5629 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5630 if(eWLAN_PAL_STATUS_SUCCESS != status)
5631 {
5632 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005633 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005634 return status;
5635 }
5636 }
5637 }
5638 pDxeCtrlBlk->hostPowerState = hostPowerState;
5639 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5640 }
5641 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5642 {
5643 pDxeCtrlBlk->hostPowerState = hostPowerState;
5644 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5645 }
Mihir Shetea4306052014-03-25 00:02:54 +05305646 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5647 {
5648 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 else
5651 {
5652 HDXE_ASSERT(0);
5653 }
5654 }
5655
5656 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005657 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005658
5659 return status;
5660}
5661
5662/*==========================================================================
5663 @ Function Name
5664 WLANDXE_GetFreeTxDataResNumber
5665
5666 @ Description
5667 Returns free descriptor numbers for TX data channel (TX high priority)
5668
5669 @ Parameters
5670 pVoid pDXEContext : DXE Control Block
5671
5672 @ Return
5673 wpt_uint32 Free descriptor number of TX high pri ch
5674===========================================================================*/
5675wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5676(
5677 void *pDXEContext
5678)
5679{
5680 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005681 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005682
5683 if(NULL == pDXEContext)
5684 {
5685 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005686 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 return (0);
5688 }
5689
5690 return
5691 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5692}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005693
5694/*==========================================================================
5695 @ Function Name
5696 WLANDXE_ChannelDebug
5697
5698 @ Description
5699 Display DXE Channel debugging information
5700 User may request to display DXE channel snapshot
5701 Or if host driver detects any abnormal stcuk may display
5702
5703 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005704 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305705 debugFlags : Enable stall detect features
5706 defined by WPAL_DeviceDebugFlags
5707 These features may effect
5708 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005709
5710 @ Return
5711 NONE
5712
5713===========================================================================*/
5714void WLANDXE_ChannelDebug
5715(
Mihir Shete40a55652014-03-02 14:14:47 +05305716 wpt_boolean displaySnapshot,
5717 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005718)
5719{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005720 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305721 wpt_msg *txDescReSyncMsg ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005722 wpt_uint32 regValue;
5723 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5724
5725 /* Debug Type 1, Display current snapshot */
5726 if(displaySnapshot)
5727 {
5728 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5729 * This will not simply wakeup RIVA
5730 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005731 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5732 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005733 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005734 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005735 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
5736 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Leo Chang345ef992013-07-12 10:17:29 -07005737 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d =====",
5738 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
5739 tempDxeCtrlBlk->txCompletedFrames, regValue);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005740
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005741 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5742 &regValue,
5743 NULL,
5744 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005745
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005746 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5747 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005748 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5750 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5751 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005752 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005753
5754 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5755 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5756 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005757 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5759 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005760 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005761 }
5762 }
5763
Mihir Shete40a55652014-03-02 14:14:47 +05305764 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005765 {
Mihir Shete40a55652014-03-02 14:14:47 +05305766 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5767 if(NULL == txDescReSyncMsg)
5768 {
5769 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5770 "%s: Resync MSG MEM alloc Fail",__func__);
5771 }
5772 else
5773 {
5774 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5775 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5776 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5777 txDescReSyncMsg);
5778 if(eWLAN_PAL_STATUS_SUCCESS != status)
5779 {
5780 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5781 "%s: Post TX re-sync MSG fail",__func__);
5782 }
5783 }
5784 }
5785
5786 if(debugFlags & WPAL_DEBUG_START_HEALTH_TIMER)
5787 {
5788 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005789 "DXE TX Stall detect");
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005790 /* Start Stall detect timer and detect stall */
5791 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5792 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005793 }
5794 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005795}