blob: 6b2c44c80f4a93d3407631948318a44918f6da32 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Katya Nigama6fbf662015-03-17 18:35:47 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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 }
Siddharth Bhal68115602015-01-18 20:44:55 +0530573 wpalFwDumpReq(17, 0, 0, 0, 0, 0);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530574}
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;
Mihir Shete058fcff2014-06-26 18:54:06 +05301976 wpt_uint32 numRxFreePackets;
Mihir Sheted183cef2014-09-26 19:17:56 +05301977 wpt_uint32 numAllocFailures;
Katya Nigam93888ff2014-02-10 17:58:11 +05301978
1979 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1980
Leo Chang72cdfd32013-10-17 20:36:30 -07001981 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1982 "RX Low resource, Durign wait time period %d, RX resource not allocated",
Katya Nigama6fbf662015-03-17 18:35:47 +05301983 wpalGetDxeReplenishRXTimerVal());
Katya Nigam93888ff2014-02-10 17:58:11 +05301984
Mihir Shete058fcff2014-06-26 18:54:06 +05301985 //This API wil also try to replenish packets
1986 wpalGetNumRxFreePacket(&numRxFreePackets);
Mihir Sheted183cef2014-09-26 19:17:56 +05301987 wpalGetNumRxPacketAllocFailures(&numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301988
Mihir Sheted183cef2014-09-26 19:17:56 +05301989 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1990 "Free Packets: %u, Alloc Failures: %u",
1991 numRxFreePackets, numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301992 if (numRxFreePackets > 0)
1993 {
1994 /* If no. of free packets is greater than 0, it means
1995 * that some packets were replenished and can be used
1996 * by DXE to receive frames. So try to restart the
1997 * resourceAvailable timer here, it will be stopped
1998 * by the DXE's low resource callback if atleast one
1999 * free packet reaches DXE.
2000 */
2001 if (NULL != dxeCtxt)
2002 {
2003 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2004 "%s: Replenish successful. Restart the Rx Low resource timer",
2005 __func__);
2006 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05302007 wpalGetDxeReplenishRXTimerVal());
Mihir Shete058fcff2014-06-26 18:54:06 +05302008 return;
2009 }
2010 }
Katya Nigama6fbf662015-03-17 18:35:47 +05302011 if(wpalIsDxeSSREnable())
2012 {
2013 if (NULL != dxeCtxt)
2014 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
Mihir Shete058fcff2014-06-26 18:54:06 +05302015
Katya Nigama6fbf662015-03-17 18:35:47 +05302016 wpalWlanReload();
Katya Nigam93888ff2014-02-10 17:58:11 +05302017
Katya Nigama6fbf662015-03-17 18:35:47 +05302018 if (NULL != usrData)
2019 dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
2020 }
2021 else
2022 {
2023 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
2024 wpalGetDxeReplenishRXTimerVal());
2025 }
Mihir Shetefdc9f532014-01-09 15:03:02 +05302026 return;
2027}
Mihir Shete44547fb2014-03-10 14:15:42 +05302028#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05302029
2030/*==========================================================================
2031 @ Function Name
2032 dxeStartSSRTimer
2033
2034 @ Description
2035 Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip,
2036 this makes sure that if the chip does not respond to the FIQ within
2037 the timeout period the dxeSSRTimer expiration handler will take the
2038 appropriate action.
2039
2040 @ Parameters
2041 NONE
2042
2043 @ Return
2044 NONE
2045
2046===========================================================================*/
2047static void dxeStartSSRTimer
2048(
2049 WLANDXE_CtrlBlkType *dxeCtxt
2050)
2051{
2052 if(VOS_TIMER_STATE_RUNNING !=
2053 wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer))
2054 {
2055 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2056 "%s: Starting SSR Timer",__func__);
2057 wpalTimerStart(&dxeCtxt->dxeSSRTimer,
2058 T_WLANDXE_SSR_TIMEOUT);
2059 }
2060}
2061
2062/*==========================================================================
2063 @ Function Name
2064 dxeSSRTimerExpHandler
2065
2066 @ Description
2067 Issue an explicit subsystem restart of the wcnss subsystem if the
2068 WCN chip does not respond to the FIQ within the timeout period
2069
2070 @ Parameters
2071 v_VOID_t *usrData
2072
2073 @ Return
2074 NONE
2075
2076===========================================================================*/
2077void dxeSSRTimerExpHandler
2078(
2079 void *usrData
2080)
2081{
2082 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2083 "DXE not shutdown %d ms after FIQ!! Issue SSR",
2084 T_WLANDXE_SSR_TIMEOUT);
2085 wpalRivaSubystemRestart();
2086
Leo Chang72cdfd32013-10-17 20:36:30 -07002087 return;
2088}
2089
2090/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 @ Function Name
2092 dxeRXPacketAvailableCB
2093
2094 @ Description
2095 If RX frame handler encounts RX buffer pool empty condition,
2096 DXE RX handle loop will be blocked till get available RX buffer pool.
2097 When new RX buffer pool available, Packet available CB function will
2098 be called.
2099
2100 @ Parameters
2101 wpt_packet *freePacket
2102 Newly allocated RX buffer
2103 v_VOID_t *usrData
2104 DXE context
2105
2106 @ Return
2107 NONE
2108
2109===========================================================================*/
2110void dxeRXPacketAvailableCB
2111(
2112 wpt_packet *freePacket,
2113 v_VOID_t *usrData
2114)
2115{
2116 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2117 wpt_status status;
2118
2119 /* Simple Sanity */
2120 if((NULL == freePacket) || (NULL == usrData))
2121 {
2122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2123 "Get Free RX Buffer fail, Critical Error");
2124 HDXE_ASSERT(0);
2125 return;
2126 }
2127
2128 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
2129
2130 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
2131 {
2132 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2133 "DXE Context data corrupted, Critical Error");
2134 HDXE_ASSERT(0);
2135 return;
2136 }
2137
2138 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2139 "DXE RX packet available, post MSG to RX Thread");
2140
2141 dxeCtxt->freeRXPacket = freePacket;
2142
2143 /* Serialize RX Packet Available message upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08002144 if (NULL == dxeCtxt->rxPktAvailMsg)
2145 {
2146 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2147 "DXE NULL pkt");
2148 HDXE_ASSERT(0);
2149 return;
2150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002151
2152 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2153 dxeCtxt->rxPktAvailMsg);
2154 if(eWLAN_PAL_STATUS_SUCCESS != status)
2155 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2157 "dxeRXPacketAvailableCB serialize fail");
2158 }
2159
2160 return;
2161}
2162
2163/*==========================================================================
2164 @ Function Name
2165 dxeRXFrameSingleBufferAlloc
2166
2167 @ Description
2168 Allocate Platform packet buffer to prepare RX frame
2169 RX frame memory space must be pre allocted and must be asigned to
2170 descriptor
2171 then whenever DMA engine want to tranfer frame from BMU,
2172 buffer must be ready
2173
2174 @ Parameters
2175 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2176 DXE host driver main control block
2177 WLANDXE_ChannelCBType *channelEntry
2178 Channel specific control block
2179 WLANDXE_DescCtrlBlkType currentCtrlBlock
2180 current control block which have to be asigned
2181 frame buffer
2182
2183 @ Return
2184 wpt_status
2185
2186===========================================================================*/
2187static wpt_status dxeRXFrameSingleBufferAlloc
2188(
2189 WLANDXE_CtrlBlkType *dxeCtxt,
2190 WLANDXE_ChannelCBType *channelEntry,
2191 WLANDXE_DescCtrlBlkType *currentCtrlBlock
2192)
2193{
2194 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2195 wpt_packet *currentPalPacketBuffer = NULL;
2196 WLANDXE_DescType *currentDesc = NULL;
2197#ifdef FEATURE_R33D
2198 wpt_uint32 virtualAddressPCIe;
2199 wpt_uint32 physicalAddressPCIe;
2200#else
2201 wpt_iterator iterator;
2202 wpt_uint32 allocatedSize = 0;
2203 void *physAddress = NULL;
2204#endif /* FEATURE_R33D */
2205
Jeff Johnson295189b2012-06-20 16:38:30 -07002206
2207 currentDesc = currentCtrlBlock->linkedDesc;
2208
Leo Chang7e05f212013-07-01 19:54:15 -07002209 if(currentDesc->descCtrl.valid)
2210 {
2211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2212 "This Descriptor is valid, Do not refill");
2213 return eWLAN_PAL_STATUS_E_EXISTS;
2214 }
2215
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 /* First check if a packet pointer has already been provided by a previously
2217 invoked Rx packet available callback. If so use that packet. */
2218 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
2219 {
2220 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
2221 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
2222 dxeCtxt->freeRXPacket = NULL;
Mihir Sheted183cef2014-09-26 19:17:56 +05302223
2224 if (channelEntry->doneIntDisabled)
2225 {
2226 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
2227 channelEntry->extraConfig.chan_mask);
2228 channelEntry->doneIntDisabled = 0;
2229 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002230 }
2231 else if(!dxeCtxt->rxPalPacketUnavailable)
2232 {
Leo Chang72cdfd32013-10-17 20:36:30 -07002233 /* Allocate platform Packet buffer and OS Frame Buffer at here */
2234 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
2236 dxeRXPacketAvailableCB,
2237 (void *)dxeCtxt);
2238
2239 if(NULL == currentPalPacketBuffer)
2240 {
2241 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
Mihir Shete44547fb2014-03-10 14:15:42 +05302242#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07002243 /* Out of RX free buffer,
2244 * Start timer to recover from RX dead end */
2245 if(VOS_TIMER_STATE_RUNNING !=
2246 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
2247 {
2248 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2249 "RX Low resource, wait available resource");
2250 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05302251 wpalGetDxeReplenishRXTimerVal());
Leo Chang72cdfd32013-10-17 20:36:30 -07002252 }
Mihir Shete44547fb2014-03-10 14:15:42 +05302253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002254 }
2255 }
2256
2257 if(NULL == currentPalPacketBuffer)
2258 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 return eWLAN_PAL_STATUS_E_RESOURCES;
2260 }
2261
2262 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
2263 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
2264 currentPalPacketBuffer->pBD = NULL;
2265 currentPalPacketBuffer->pBDPhys = NULL;
2266 currentPalPacketBuffer->BDLength = 0;
2267#ifdef FEATURE_R33D
2268 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
2269 &physicalAddressPCIe,
2270 &virtualAddressPCIe);
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08002271 if((0 == physicalAddressPCIe) || (0 = virtualAddressPCIe))
2272 {
2273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2274 "RX NULL Shadow Memory");
2275 HDXE_ASSERT(0);
2276 return eWLAN_PAL_STATUS_E_FAULT;
2277 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002278 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2279 "RX Shadow Memory Va 0x%x, Pa 0x%x",
2280 virtualAddressPCIe, physicalAddressPCIe);
2281 if(eWLAN_PAL_STATUS_SUCCESS != status)
2282 {
2283 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2284 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
2285 return status;
2286 }
2287 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
2288 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
2289 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2290#else
2291 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
2292 if(eWLAN_PAL_STATUS_SUCCESS != status)
2293 {
2294 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2295 "dxeRXFrameBufferAlloc unable to lock packet");
2296 return status;
2297 }
2298
2299 /* Init iterator to get physical os buffer address */
2300 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
2301 if(eWLAN_PAL_STATUS_SUCCESS != status)
2302 {
2303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2304 "dxeRXFrameBufferAlloc iterator init fail");
2305 return status;
2306 }
2307 status = wpalIteratorNext(&iterator,
2308 currentPalPacketBuffer,
2309 &physAddress,
2310 &allocatedSize);
2311 if(eWLAN_PAL_STATUS_SUCCESS != status)
2312 {
2313 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2314 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
2315 return status;
2316 }
2317 currentPalPacketBuffer->pBDPhys = physAddress;
2318#endif /* FEATURE_R33D */
2319
2320 /* DXE descriptor must have SWAPPED addres in it's structure
2321 * !!! SWAPPED !!! */
2322 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05302323 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07002324
Jeff Johnson295189b2012-06-20 16:38:30 -07002325 return status;
2326}
2327
2328/*==========================================================================
2329 @ Function Name
2330 dxeRXFrameRefillRing
2331
2332 @ Description
2333 Allocate Platform packet buffers to try to fill up the DXE Rx ring
2334
2335 @ Parameters
2336 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2337 DXE host driver main control block
2338 WLANDXE_ChannelCBType *channelEntry
2339 Channel specific control block
2340
2341 @ Return
2342 wpt_status
2343
2344===========================================================================*/
2345static wpt_status dxeRXFrameRefillRing
2346(
2347 WLANDXE_CtrlBlkType *dxeCtxt,
2348 WLANDXE_ChannelCBType *channelEntry
2349)
2350{
2351 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2352 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2353 WLANDXE_DescType *currentDesc = NULL;
2354
2355 while(channelEntry->numFreeDesc > 0)
2356 {
2357 /* Current Control block is free
2358 * and associated frame buffer is not linked with control block anymore
2359 * allocate new frame buffer for current control block */
2360 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2361 channelEntry,
2362 currentCtrlBlk);
2363
Leo Chang7e05f212013-07-01 19:54:15 -07002364 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2365 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 {
2367 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2368 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2369 break;
2370 }
2371
Leo Chang7e05f212013-07-01 19:54:15 -07002372 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2373 {
2374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2375 "dxeRXFrameRefillRing, Descriptor Non-Empry");
2376 }
2377
Jeff Johnson295189b2012-06-20 16:38:30 -07002378 currentDesc = currentCtrlBlk->linkedDesc;
2379 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2380
2381 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2382 that any posted writes are reflected in memory before DXE looks at
2383 the descriptor. */
2384 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2385 {
2386 //HDXE_ASSERT(0);
2387 }
2388
2389 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07002390 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002391 {
2392 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2393 1 << channelEntry->assignedDMAChannel);
2394 }
2395 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07002396 if(eWLAN_PAL_STATUS_E_EXISTS != status)
2397 {
2398 --channelEntry->numFreeDesc;
2399 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002400 }
2401
2402 channelEntry->tailCtrlBlk = currentCtrlBlk;
2403
2404 return status;
2405}
2406
2407/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002408 @ Function Name
2409 dxeRXFrameRouteUpperLayer
2410
2411 @ Description
2412 Test DXE descriptors and if any RX frame pending within RING,
2413 Route to upper layer
2414
2415 @ Parameters
2416 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2417 DXE host driver main control block
2418 WLANDXE_ChannelCBType *channelEntry
2419 Channel specific control block
2420 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002421 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002422 0 No frame pulled from RX RING
2423 int number of RX frames pulled from RX ring
2424
2425===========================================================================*/
2426static wpt_int32 dxeRXFrameRouteUpperLayer
2427(
2428 WLANDXE_CtrlBlkType *dxeCtxt,
2429 WLANDXE_ChannelCBType *channelEntry
2430)
2431{
2432 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2433 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2434 WLANDXE_DescType *currentDesc = NULL;
2435 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002436 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002437
2438 currentCtrlBlk = channelEntry->headCtrlBlk;
2439 currentDesc = currentCtrlBlk->linkedDesc;
2440
2441 /* Descriptoe should be SWAPPED ???? */
2442 descCtrl = currentDesc->descCtrl.ctrl;
2443
2444 /* Get frames while VALID bit is not set (DMA complete) and a data
2445 * associated with it */
2446 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2447 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2448 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2449 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2450 {
2451 channelEntry->numTotalFrame++;
2452 channelEntry->numFreeDesc++;
2453#ifdef FEATURE_R33D
2454 /* Transfer Size should be */
2455 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2456 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
2457 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
2458 currentCtrlBlk->shadowBufferVa,
2459 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
2460 if(eWLAN_PAL_STATUS_SUCCESS != status)
2461 {
2462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2463 "dxeRXFrameReady Prepare RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002464 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002465 }
2466 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
2467 if(eWLAN_PAL_STATUS_SUCCESS != status)
2468 {
2469 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2470 "dxeRXFrameReady Free Shadow RX Frame fail");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002471 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002472 }
2473
2474#else /* FEATURE_R33D */
2475 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
2476 if (eWLAN_PAL_STATUS_SUCCESS != status)
2477 {
2478 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2479 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002480 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002481 }
2482#endif /* FEATURE_R33D */
2483 /* This Descriptor is valid, so linked Control block is also valid
2484 * Linked Control block has pre allocated packet buffer
2485 * So, just let upper layer knows preallocated frame pointer will be OK */
2486 /* Reap Rx frames */
2487 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2488 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002489 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002490
2491 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Leo Changd6de1c22013-03-21 15:42:41 -07002492 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002493
2494 /* Test next contorl block
2495 * if valid, this control block also has new RX frame must be handled */
2496 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2497 currentDesc = currentCtrlBlk->linkedDesc;
2498 descCtrl = currentDesc->descCtrl.ctrl;
2499 }
2500
2501 /* Update head control block
2502 * current control block's valid bit was 0
2503 * next trial first control block must be current control block */
2504 channelEntry->headCtrlBlk = currentCtrlBlk;
2505
2506 /* Deliver all the reaped RX frames to upper layers */
2507 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002508 while(i < frameCount)
2509 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002510 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2511 i++;
2512 }
2513
2514 return frameCount;
2515}
2516
2517/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 @ Function Name
2519 dxeRXFrameReady
2520
2521 @ Description
2522 Pop frame from descriptor and route frame to upper transport layer
2523 Assign new platform packet buffer into used descriptor
2524 Actual frame pop and resource realloc
2525
2526 @ Parameters
2527 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2528 DXE host driver main control block
2529 WLANDXE_ChannelCBType *channelEntry
2530 Channel specific control block
2531
2532 @ Return
2533 wpt_status
2534
2535===========================================================================*/
2536static wpt_status dxeRXFrameReady
2537(
2538 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002539 WLANDXE_ChannelCBType *channelEntry,
2540 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002541)
2542{
2543 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2544 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2545 WLANDXE_DescType *currentDesc = NULL;
2546 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002547 wpt_int32 frameCount = 0;
2548
2549 wpt_uint32 descLoop;
2550 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002551
2552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002553 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002554
2555 /* Sanity Check */
2556 if((NULL == dxeCtxt) || (NULL == channelEntry))
2557 {
2558 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2559 "dxeRXFrameReady Channel Entry is not valid");
2560 return eWLAN_PAL_STATUS_E_INVAL;
2561 }
2562
Jeff Johnsone7245742012-09-05 17:12:55 -07002563 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002564
Jeff Johnsone7245742012-09-05 17:12:55 -07002565 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002566 {
2567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002568 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002569 return eWLAN_PAL_STATUS_E_INVAL;
2570 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002571
Leo Changd6de1c22013-03-21 15:42:41 -07002572 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002573 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2574 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2575 {
Leo Changd6de1c22013-03-21 15:42:41 -07002576 /* None of the frame handled and CH is not enabled
2577 * RX CH wrap around happen and No RX free frame
2578 * RX side should wait till new free frame available in the pool
2579 * Do not try reload driver at here*/
2580 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2581 {
Leo Changbbf86b72013-06-19 16:13:00 -07002582 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002583 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2584 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002585 /* This is not empty interrupt case
2586 * If handle this as empty interrupt, false SSR might be issued
2587 * Frame count '1' is dummy frame count to avoid SSR */
2588 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002589 return eWLAN_PAL_STATUS_SUCCESS;
2590 }
2591
Jeff Johnsone7245742012-09-05 17:12:55 -07002592 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 currentDesc = currentCtrlBlk->linkedDesc;
2594 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002595
2596 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2597 {
2598 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2599 "RX ISR called but no frame handled PWS %d, channel %s",
2600 (int)dxeCtxt->hostPowerState,
2601 channelType[channelEntry->channelType]);
2602 }
2603
2604 /* Current interupt empty and previous interrupt also empty
2605 * detected successive empty interrupt
2606 * or first interrupt empty, this should not happen */
2607 if(0 == channelEntry->numFragmentCurrentChain)
2608 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002609 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2610 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2611 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2612 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002613 /* Abnormal interrupt detected, try to find not validated descriptor */
2614 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2615 {
2616 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2617 {
Leo Chang416afe02013-07-01 13:58:13 -07002618 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002619 "Found Invalidated Descriptor %d", (int)descLoop);
2620 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2621 {
Leo Chang416afe02013-07-01 13:58:13 -07002622 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002623 "Packet locked, Resync Host and HW");
2624 channelEntry->headCtrlBlk = currentCtrlBlk;
2625 invalidatedFound = 1;
2626 break;
2627 }
2628 else
2629 {
Leo Chang416afe02013-07-01 13:58:13 -07002630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002631 "Packet Not Locked, cannot transfer frame");
2632 }
2633 }
2634 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2635 currentDesc = currentCtrlBlk->linkedDesc;
2636 descCtrl = currentDesc->descCtrl.ctrl;
2637 }
2638
Jeff Johnson32d95a32012-09-10 13:15:23 -07002639 /* Invalidated descriptor found, and that is not head descriptor
2640 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2641 * Try re-sync here */
2642 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002643 {
2644 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2645 "Found New Sync location with HW, handle frames from there");
2646 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2647 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2648 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002649 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002650 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002651 /* Successive Empty interrupt
2652 * But this case, first descriptor also invalidated, then it means head descriptor
2653 * is linked with already handled RX frame, then could not unlock RX frame
2654 * This is just Out of RX buffer pool, not need to anything here */
2655 else if((invalidatedFound) && (0 == descLoop))
2656 {
2657 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2658 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2659 }
2660 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002661 else
2662 {
2663 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2664 "Could not found invalidated descriptor");
2665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2666 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2667 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2668 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302669 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002670 }
2671 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002672 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002673 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002674 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002675 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002676 return status;
2677}
2678
2679/*==========================================================================
2680 @ Function Name
2681 dxeNotifySmsm
2682
2683 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2684 buffer
2685
2686 @ Parameters
2687
2688 @ Return
2689 wpt_status
2690
2691===========================================================================*/
2692static wpt_status dxeNotifySmsm
2693(
2694 wpt_boolean kickDxe,
2695 wpt_boolean ringEmpty
2696)
2697{
2698 wpt_uint32 clrSt = 0;
2699 wpt_uint32 setSt = 0;
2700
2701 if(kickDxe)
2702 {
2703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2704
2705 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2706 {
2707 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2708 tempDxeCtrlBlk->lastKickOffDxe = 1;
2709 }
2710 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2711 {
2712 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2713 tempDxeCtrlBlk->lastKickOffDxe = 0;
2714 }
2715 else
2716 {
2717 HDXE_ASSERT(0);
2718 }
2719 }
2720 else
2721 {
2722 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2723 }
2724
Mihir Shete68ed77a2014-10-10 10:47:12 +05302725 tempDxeCtrlBlk->txRingsEmpty = ringEmpty;
Jeff Johnson295189b2012-06-20 16:38:30 -07002726 if(ringEmpty)
2727 {
2728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2729 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2730 }
2731 else
2732 {
2733 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2734 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2735 }
2736
2737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2738
2739 wpalNotifySmsm(clrSt, setSt);
2740
2741 return eWLAN_PAL_STATUS_SUCCESS;
2742}
2743
2744/*==========================================================================
2745 @ Function Name
2746 dxePsComplete
2747
2748 @ Description: Utility function to check the resv desc to deside if we can
2749 get into Power Save mode now
2750
2751 @ Parameters
2752
2753 @ Return
2754 None
2755
2756===========================================================================*/
2757static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2758{
2759 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2760 {
2761 return;
2762 }
2763
2764 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2765 //must have been consumed by RIVA, OK to get into BMPS
2766 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2767 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2768 {
2769 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2770 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2771 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2772 {
2773 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2774 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2775 }
2776 }
2777 else //still more pkts to be served by RIVA
2778 {
2779 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2780
2781 switch(dxeCtxt->rivaPowerState)
2782 {
2783 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2784 //NOP
2785 break;
2786 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2787 if(intr_based)
2788 {
2789 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2790 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2791 }
2792 break;
2793 default:
2794 //assert
2795 break;
2796 }
2797 }
2798}
2799
2800/*==========================================================================
2801 @ Function Name
2802 dxeRXEventHandler
2803
2804 @ Description
2805 Handle serailized RX frame ready event
2806 First disable interrupt then pick up frame from pre allocated buffer
2807 Since frame handle is doen, clear interrupt bit to ready next interrupt
2808 Finally re enable interrupt
2809
2810 @ Parameters
2811 wpt_msg *rxReadyMsg
2812 RX frame ready MSG pointer
2813 include DXE control context
2814
2815 @ Return
2816 NONE
2817
2818===========================================================================*/
2819void dxeRXEventHandler
2820(
2821 wpt_msg *rxReadyMsg
2822)
2823{
2824 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2825 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2826 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2827 wpt_uint32 intSrc = 0;
2828 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002829 wpt_uint32 chHighStat = 0;
2830 wpt_uint32 chLowStat = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302831 wpt_uint32 regValue, chanMask;
Jeff Johnson295189b2012-06-20 16:38:30 -07002832
Jeff Johnsone7245742012-09-05 17:12:55 -07002833 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002834
Jeff Johnsone7245742012-09-05 17:12:55 -07002835 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 {
2837 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002838 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002839 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 }
2841
Jeff Johnsone7245742012-09-05 17:12:55 -07002842 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2843 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2844 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
2845
Jeff Johnson295189b2012-06-20 16:38:30 -07002846 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2847
2848 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
2849 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
2850 {
2851 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2852 "DXE already stopped in RX event handler. Just return");
2853 return;
2854 }
2855
2856 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2857 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2858 {
2859 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2860 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002861 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002862
2863 /* Not to touch any register, just pull frame directly from chain ring
2864 * First high priority */
2865 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2866 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002867 channelCb,
2868 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002869 if(eWLAN_PAL_STATUS_SUCCESS != status)
2870 {
2871 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2872 "dxeRXEventHandler Pull from RX high channel fail");
2873 }
Leo Chang46f36162014-01-14 21:47:24 -08002874 /* In case FW could not power collapse in IMPS mode
2875 * Next power restore might have empty interrupt
2876 * If IMPS mode has empty interrupt since RX thread race,
2877 * Invalid re-load driver might happen
2878 * To prevent invalid re-load driver,
2879 * IMPS event handler set dummpy frame count */
2880 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002881
2882 /* Second low priority */
2883 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2884 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002885 channelCb,
2886 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 if(eWLAN_PAL_STATUS_SUCCESS != status)
2888 {
2889 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2890 "dxeRXEventHandler Pull from RX low channel fail");
2891 }
Leo Chang46f36162014-01-14 21:47:24 -08002892 /* LOW Priority CH same above */
2893 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002894
2895 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2896 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2897
2898 return;
2899 }
2900
2901 /* Disable device interrupt */
2902 /* Read whole interrupt mask register and exclusive only this channel int */
2903 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2904 &intSrc);
2905 if(eWLAN_PAL_STATUS_SUCCESS != status)
2906 {
2907 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2908 "dxeRXEventHandler Read INT_SRC register fail");
2909 return;
2910 }
2911 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2912 "RX Event Handler INT Source 0x%x", intSrc);
2913
2914#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2915 /* Test High Priority Channel interrupt is enabled or not */
2916 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2917 if(intSrc & (1 << channelCb->assignedDMAChannel))
2918 {
2919 status = dxeChannelCleanInt(channelCb, &chHighStat);
2920 if(eWLAN_PAL_STATUS_SUCCESS != status)
2921 {
2922 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2923 "dxeRXEventHandler INT Clean up fail");
2924 return;
2925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002926 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2927 {
2928 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2930 "%11s : 0x%x Error Reported, Reload Driver",
2931 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302932
Mihir Shete79d6b582014-03-12 17:54:07 +05302933 dxeErrChannelDebug(channelCb, chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302934
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002935 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2936 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302937 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002939 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2940 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002941 {
2942 /* Handle RX Ready for high priority channel */
2943 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002944 channelCb,
2945 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002946 }
2947 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2948 {
2949 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002950 channelCb,
2951 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002952 }
2953 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2954 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002955 /* Update the Rx DONE histogram */
2956 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2957 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2958 {
2959 channelCb->rxDoneHistogram |= 1;
2960 }
2961 else
2962 {
2963 channelCb->rxDoneHistogram &= ~1;
2964 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002965 }
2966#else
2967 /* Test H2H Test interrupt is enabled or not */
2968 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2969 if(intSrc & (1 << channelCb->assignedDMAChannel))
2970 {
2971 status = dxeChannelCleanInt(channelCb, &chStat);
2972 if(eWLAN_PAL_STATUS_SUCCESS != status)
2973 {
2974 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2975 "dxeRXEventHandler INT Clean up fail");
2976 return;
2977 }
2978
2979 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2980 {
2981 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002982 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2983 "%11s : 0x%x Error Reported, Reload Driver",
2984 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302985
Mihir Shete79d6b582014-03-12 17:54:07 +05302986 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302987
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002988 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2989 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302990 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002991 }
2992 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2993 {
2994 /* Handle RX Ready for high priority channel */
2995 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002996 channelCb,
2997 chStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002998 }
2999 /* Update the Rx DONE histogram */
3000 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
3001 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3002 {
3003 channelCb->rxDoneHistogram |= 1;
3004 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3005 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
3006 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
3007 }
3008 else
3009 {
3010 channelCb->rxDoneHistogram &= ~1;
3011 }
3012 }
3013#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3014
3015 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07003016 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07003017 if(intSrc & (1 << channelCb->assignedDMAChannel))
3018 {
3019 status = dxeChannelCleanInt(channelCb, &chLowStat);
3020 if(eWLAN_PAL_STATUS_SUCCESS != status)
3021 {
3022 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3023 "dxeRXEventHandler INT Clean up fail");
3024 return;
3025 }
3026
3027 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
3028 {
3029 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003030 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3031 "%11s : 0x%x Error Reported, Reload Driver",
3032 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303033
Mihir Shete79d6b582014-03-12 17:54:07 +05303034 dxeErrChannelDebug(channelCb, chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303035
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003036 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3037 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303038 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003039 }
Mihir Shetef2000552014-05-12 16:21:34 +05303040 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) ||
3041 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07003042 {
3043 /* Handle RX Ready for low priority channel */
3044 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07003045 channelCb,
3046 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07003047 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003048
3049 /* Update the Rx DONE histogram */
3050 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
3051 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
3052 {
3053 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003054 }
3055 else
3056 {
3057 channelCb->rxDoneHistogram &= ~1;
3058 }
3059 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3060 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
3061 }
3062 if(eWLAN_PAL_STATUS_SUCCESS != status)
3063 {
3064 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3065 "dxeRXEventHandler Handle Frame Ready Fail");
3066 return;
3067 }
3068
Jeff Johnson295189b2012-06-20 16:38:30 -07003069 /* Prepare Control Register EN Channel */
3070 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
3071 {
3072 HDXE_ASSERT(0);
3073 }
Mihir Shetef2000552014-05-12 16:21:34 +05303074
3075 if (dxeCtxt->rxPalPacketUnavailable &&
3076 (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat))
3077 {
3078 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask &
3079 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05303080 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05303081 }
3082 else
3083 {
3084 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05303085 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05303086 }
Leo Chang094ece82013-04-23 17:57:41 -07003087 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05303088 chanMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07003089
3090 /* Prepare Control Register EN Channel */
3091 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
3092 {
3093 HDXE_ASSERT(0);
3094 }
Leo Chang094ece82013-04-23 17:57:41 -07003095
Mihir Shetef2000552014-05-12 16:21:34 +05303096 if (dxeCtxt->rxPalPacketUnavailable &&
3097 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
3098 {
3099 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask &
3100 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05303101 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05303102 }
3103 else
3104 {
3105 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05303106 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05303107 }
Leo Chang094ece82013-04-23 17:57:41 -07003108 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05303109 chanMask);
3110
Leo Chang094ece82013-04-23 17:57:41 -07003111
3112 /* Clear Interrupt handle processing bit
3113 * RIVA may power down */
3114 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3115 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
3116 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
Jeff Johnson295189b2012-06-20 16:38:30 -07003117
Leo Chang416afe02013-07-01 13:58:13 -07003118 /* Enable system level ISR */
3119 /* Enable RX ready Interrupt at here */
3120 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
3121 if(eWLAN_PAL_STATUS_SUCCESS != status)
3122 {
3123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3124 "dxeRXEventHandler Enable RX Ready interrupt fail");
3125 return;
3126 }
3127
Jeff Johnson295189b2012-06-20 16:38:30 -07003128 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003129 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003130 return;
3131}
3132
3133/*==========================================================================
3134 @ Function Name
3135 dxeRXPacketAvailableEventHandler
3136
3137 @ Description
3138 Handle serialized RX Packet Available event when the corresponding callback
3139 is invoked by WPAL.
3140 Try to fill up any completed DXE descriptors with available Rx packet buffer
3141 pointers.
3142
3143 @ Parameters
3144 wpt_msg *rxPktAvailMsg
3145 RX frame ready MSG pointer
3146 include DXE control context
3147
3148 @ Return
3149 NONE
3150
3151===========================================================================*/
3152void dxeRXPacketAvailableEventHandler
3153(
3154 wpt_msg *rxPktAvailMsg
3155)
3156{
3157 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3158 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3159 WLANDXE_ChannelCBType *channelCb = NULL;
3160
3161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003162 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003163
3164 /* Sanity Check */
3165 if(NULL == rxPktAvailMsg)
3166 {
3167 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3168 "dxeRXPacketAvailableEventHandler Context is not valid");
3169 return;
3170 }
3171
3172 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05303173
3174#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07003175 /* Available resource allocated
3176 * Stop timer not needed */
3177 if(VOS_TIMER_STATE_RUNNING ==
3178 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
3179 {
3180 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
3181 }
Mihir Shete44547fb2014-03-10 14:15:42 +05303182#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003183
3184 do
3185 {
3186 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3187 "dxeRXPacketAvailableEventHandler, start refilling ring");
3188
3189 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
3190 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3191
3192 // Wait for another callback to indicate when Rx resources are available
3193 // again.
3194 if(eWLAN_PAL_STATUS_SUCCESS != status)
3195 {
3196 break;
3197 }
3198
3199 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
3200 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3201 if(eWLAN_PAL_STATUS_SUCCESS != status)
3202 {
3203 break;
3204 }
3205 } while(0);
3206
3207 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
3208 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
3209 {
3210 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
3211 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
3212 }
3213}
3214
3215/*==========================================================================
3216 @ Function Name
3217 dxeRXISR
3218
3219 @ Description
3220 RX frame ready interrupt service routine
3221 interrupt entry function, this function called based on ISR context
3222 Must be serialized
3223
3224 @ Parameters
3225 void *hostCtxt
3226 DXE host driver control context,
3227 pre registerd during interrupt registration
3228
3229 @ Return
3230 NONE
3231
3232===========================================================================*/
3233static void dxeRXISR
3234(
3235 void *hostCtxt
3236)
3237{
3238 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3239 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003240 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07003241
3242#ifdef FEATURE_R33D
3243 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3244 &regValue);
3245 if(eWLAN_PAL_STATUS_SUCCESS != status)
3246 {
3247 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3248 "dxeTXCompISR Read INT_SRC_RAW fail");
3249 return;
3250 }
3251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3252 "INT_SRC_RAW 0x%x", regValue);
3253 if(0 == regValue)
3254 {
3255 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3256 "This is not DXE Interrupt, Reject it 0x%x", regValue);
3257 return;
3258 }
3259#endif /* FEATURE_R33D */
3260
Leo Chang094ece82013-04-23 17:57:41 -07003261 /* Set Interrupt processing bit
3262 * During this bit set, WLAN HW may not power collapse */
3263 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3264 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
3265 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3266
Jeff Johnson295189b2012-06-20 16:38:30 -07003267 /* Disable interrupt at here
3268 * Disable RX Ready system level Interrupt at here
3269 * Otherwise infinite loop might happen */
3270 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
3271 if(eWLAN_PAL_STATUS_SUCCESS != status)
3272 {
3273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3274 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3275 return;
3276 }
3277
3278 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003279 if(NULL == dxeCtxt->rxIsrMsg)
3280 {
3281 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3282 "dxeRXFrameReadyISR NULL message");
3283 HDXE_ASSERT(0);
3284 return;
3285 }
3286
Jeff Johnson295189b2012-06-20 16:38:30 -07003287 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
3288 dxeCtxt->rxIsrMsg);
3289 if(eWLAN_PAL_STATUS_SUCCESS != status)
3290 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003291 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3292 "dxeRXFrameReadyISR interrupt serialize fail");
3293 }
3294
Jeff Johnson295189b2012-06-20 16:38:30 -07003295 return;
3296}
3297
3298/*==========================================================================
3299 @ Function Name
3300 dxeTXPushFrame
3301
3302 @ Description
3303 Push TX frame into DXE descriptor and DXE register
3304 Send notification to DXE register that TX frame is ready to transfer
3305
3306 @ Parameters
3307 WLANDXE_ChannelCBType *channelEntry
3308 Channel specific control block
3309 wpt_packet *palPacket
3310 Packet pointer ready to transfer
3311
3312 @ Return
3313 PAL_STATUS_T
3314===========================================================================*/
3315static wpt_status dxeTXPushFrame
3316(
3317 WLANDXE_ChannelCBType *channelEntry,
3318 wpt_packet *palPacket
3319)
3320{
3321 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3322 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3323 WLANDXE_DescType *currentDesc = NULL;
3324 WLANDXE_DescType *firstDesc = NULL;
3325 WLANDXE_DescType *LastDesc = NULL;
3326 void *sourcePhysicalAddress = NULL;
3327 wpt_uint32 xferSize = 0;
3328#ifdef FEATURE_R33D
3329 tx_frm_pcie_vector_t frameVector;
3330 wpt_uint32 Va;
3331 wpt_uint32 fragCount = 0;
3332#else
3333 wpt_iterator iterator;
3334#endif /* FEATURE_R33D */
Leo Changac1d3612013-07-01 15:15:51 -07003335 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003336
3337 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003338 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003339
Leo Changac1d3612013-07-01 15:15:51 -07003340 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3341 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3342 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003343 {
Leo Changac1d3612013-07-01 15:15:51 -07003344 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003345 }
3346
3347 channelEntry->numFragmentCurrentChain = 0;
3348 currentCtrlBlk = channelEntry->headCtrlBlk;
3349
3350 /* Initialize interator, TX is fragmented */
3351#ifdef FEATURE_R33D
3352 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
3353 status = wpalPrepareTxFrame(palPacket,
3354 &frameVector,
3355 &Va);
3356#else
3357 status = wpalLockPacketForTransfer(palPacket);
3358 if(eWLAN_PAL_STATUS_SUCCESS != status)
3359 {
3360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3361 "dxeTXPushFrame unable to lock packet");
3362 return status;
3363 }
3364
3365 status = wpalIteratorInit(&iterator, palPacket);
3366#endif /* FEATURE_R33D */
3367 if(eWLAN_PAL_STATUS_SUCCESS != status)
3368 {
3369 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3370 "dxeTXPushFrame iterator init fail");
3371 return status;
3372 }
3373
3374 /* !!!! Revisit break condition !!!!!!! */
3375 while(1)
3376 {
3377 /* Get current descriptor pointer from current control block */
3378 currentDesc = currentCtrlBlk->linkedDesc;
3379 if(NULL == firstDesc)
3380 {
3381 firstDesc = currentCtrlBlk->linkedDesc;
3382 }
3383 /* All control block will have same palPacket Pointer
3384 * to make logic simpler */
3385 currentCtrlBlk->xfrFrame = palPacket;
3386
3387 /* Get next fragment physical address and fragment size
3388 * if this is the first trial, will get first physical address
3389 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
3390#ifdef FEATURE_R33D
3391 if(fragCount == frameVector.num_frg)
3392 {
3393 break;
3394 }
3395 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
3396 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
3397 xferSize = frameVector.frg[fragCount].size;
3398 fragCount++;
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003399 if(0 == xferSize)
3400 {
3401 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3402 "dxeTXPushFrame invalid transfer size");
3403
3404 HDXE_ASSERT(0);
3405 return eWLAN_PAL_STATUS_E_FAILURE;
3406 }
3407 if(NULL == sourcePhysicalAddress)
3408 {
3409 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3410 "dxeTXPushFrame invalid sourcePhysicalAddress");
3411 HDXE_ASSERT(0);
3412 return eWLAN_PAL_STATUS_E_FAILURE;
3413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003414#else
3415 status = wpalIteratorNext(&iterator,
3416 palPacket,
3417 &sourcePhysicalAddress,
3418 &xferSize);
3419 if((NULL == sourcePhysicalAddress) ||
3420 (0 == xferSize))
3421 {
3422 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3423 "dxeTXPushFrame end of current frame");
3424 break;
3425 }
3426 if(eWLAN_PAL_STATUS_SUCCESS != status)
3427 {
3428 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3429 "dxeTXPushFrame Get next frame fail");
3430 return status;
3431 }
3432#endif /* FEATURE_R33D */
3433
3434 /* This is the LAST descriptor valid for this transaction */
3435 LastDesc = currentCtrlBlk->linkedDesc;
3436
3437 /* Program DXE descriptor */
3438 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303439 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003440
3441 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3442 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3443 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3444 {
3445 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3446 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3447 }
3448 else
3449 {
3450 /* Test specific H2H transfer, destination address already set
3451 * Do Nothing */
3452 }
3453 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3454
3455 /* Program channel control register */
3456 /* First frame not set VAL bit, why ??? */
3457 if(0 == channelEntry->numFragmentCurrentChain)
3458 {
3459 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3460 }
3461 else
3462 {
3463 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3464 }
3465
3466 /* Update statistics */
3467 channelEntry->numFragmentCurrentChain++;
3468 channelEntry->numFreeDesc--;
3469 channelEntry->numRsvdDesc++;
3470
3471 /* Get next control block */
3472 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3473 }
3474 channelEntry->numTotalFrame++;
3475 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3476 "NUM TX FRAG %d, Total Frame %d",
3477 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3478
3479 /* Program Channel control register
3480 * Set as end of packet
3481 * Enable interrupt also for first code lock down
3482 * performace optimization, this will be revisited */
3483 if(NULL == LastDesc)
3484 {
3485 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3486 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3487 return eWLAN_PAL_STATUS_E_FAULT;
3488 }
3489 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3490 /* Now First one also Valid ????
3491 * this procedure will prevent over handle descriptor from previous
3492 * TX trigger */
3493 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3494
3495 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3496 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3497 {
3498 /* Update channel head as next avaliable linked slot */
3499 channelEntry->headCtrlBlk = currentCtrlBlk;
Leo Changac1d3612013-07-01 15:15:51 -07003500 if(isEmpty)
3501 {
3502 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3504 "SMSM_ret LO=%d HI=%d",
3505 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3506 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3507 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3508 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
3509 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003510 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 }
3512
3513 /* If DXE use external descriptor, registers are not needed to be programmed
3514 * Just after finish to program descriptor, tirigger to send */
3515 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3516 {
3517 /* Issue a dummy read from the DXE descriptor DDR location to
3518 ensure that any previously posted write to the descriptor
3519 completes. */
3520 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3521 {
3522 //HDXE_ASSERT(0);
3523 }
3524
3525 /* Everything is ready
3526 * Trigger to start DMA */
3527 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3528 channelEntry->extraConfig.chan_mask);
3529 if(eWLAN_PAL_STATUS_SUCCESS != status)
3530 {
3531 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3532 "dxeTXPushFrame Write Channel Ctrl Register fail");
3533 return status;
3534 }
3535
3536 /* Update channel head as next avaliable linked slot */
3537 channelEntry->headCtrlBlk = currentCtrlBlk;
3538
3539 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003540 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003541 return status;
3542 }
3543
3544 /* If DXE not use external descriptor, program each registers */
3545 /* Circular buffer handle not need to program DESC register???
3546 * GEN5 code not programed RING buffer case
3547 * REVISIT THIS !!!!!! */
3548 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3549 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3550 {
3551 /* Destination address, assigned Work Q */
3552 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3553 channelEntry->channelConfig.refWQ);
3554 if(eWLAN_PAL_STATUS_SUCCESS != status)
3555 {
3556 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3557 "dxeTXPushFrame Program dest address register fail");
3558 return status;
3559 }
3560 /* If descriptor format is SHORT */
3561 if(channelEntry->channelConfig.useShortDescFmt)
3562 {
3563 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3564 0);
3565 if(eWLAN_PAL_STATUS_SUCCESS != status)
3566 {
3567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3568 "dxeTXPushFrame Program dest address register fail");
3569 return status;
3570 }
3571 }
3572 else
3573 {
3574 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3575 "dxeTXPushFrame LONG Descriptor Format!!!");
3576 }
3577 }
3578#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3579 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
3580 {
3581 /* Destination address, Physical memory address */
3582 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3583 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
3584 if(eWLAN_PAL_STATUS_SUCCESS != status)
3585 {
3586 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3587 "dxeTXPushFrame Program dest address register fail");
3588 return status;
3589 }
3590 /* If descriptor format is SHORT */
3591 if(channelEntry->channelConfig.useShortDescFmt)
3592 {
3593 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3594 0);
3595 if(eWLAN_PAL_STATUS_SUCCESS != status)
3596 {
3597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3598 "dxeTXPushFrame Program dest address register fail");
3599 return status;
3600 }
3601 }
3602 else
3603 {
3604 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3605 "dxeTXPushFrame LONG Descriptor Format!!!");
3606 }
3607 }
3608#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3609
3610 /* Program Source address register
3611 * This address is already programmed into DXE Descriptor
3612 * But register also upadte */
3613 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3614 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3615 if(eWLAN_PAL_STATUS_SUCCESS != status)
3616 {
3617 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3618 "dxeTXPushFrame Program src address register fail");
3619 return status;
3620 }
3621 /* If descriptor format is SHORT */
3622 if(channelEntry->channelConfig.useShortDescFmt)
3623 {
3624 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3625 0);
3626 if(eWLAN_PAL_STATUS_SUCCESS != status)
3627 {
3628 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3629 "dxeTXPushFrame Program dest address register fail");
3630 return status;
3631 }
3632 }
3633 else
3634 {
3635 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3636 "dxeTXPushFrame LONG Descriptor Format!!!");
3637 }
3638
3639 /* Linked list Descriptor pointer */
3640 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3641 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3642 if(eWLAN_PAL_STATUS_SUCCESS != status)
3643 {
3644 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3645 "dxeTXPushFrame Write DESC Address register fail");
3646 return status;
3647 }
3648 /* If descriptor format is SHORT */
3649 if(channelEntry->channelConfig.useShortDescFmt)
3650 {
3651 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3652 0);
3653 if(eWLAN_PAL_STATUS_SUCCESS != status)
3654 {
3655 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3656 "dxeTXPushFrame Program dest address register fail");
3657 return status;
3658 }
3659 }
3660 else
3661 {
3662 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3663 "dxeTXPushFrame LONG Descriptor Format!!!");
3664 }
3665
3666 /* Transfer Size */
3667 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3668 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3669 xferSize);
3670 if(eWLAN_PAL_STATUS_SUCCESS != status)
3671 {
3672 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3673 "dxeTXPushFrame Write DESC Address register fail");
3674 return status;
3675 }
3676
3677 /* Everything is ready
3678 * Trigger to start DMA */
3679 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3680 channelEntry->extraConfig.chan_mask);
3681 if(eWLAN_PAL_STATUS_SUCCESS != status)
3682 {
3683 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3684 "dxeTXPushFrame Write Channel Ctrl Register fail");
3685 return status;
3686 }
3687
3688 /* Update channel head as next avaliable linked slot */
3689 channelEntry->headCtrlBlk = currentCtrlBlk;
3690
3691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003692 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003693 return status;
3694}
3695
3696/*==========================================================================
3697 @ Function Name
3698 dxeTXCompFrame
3699
3700 @ Description
3701 TX Frame transfer complete event handler
3702
3703 @ Parameters
3704 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3705 DXE host driver main control block
3706 WLANDXE_ChannelCBType *channelEntry
3707 Channel specific control block
3708
3709 @ Return
3710 PAL_STATUS_T
3711===========================================================================*/
3712static wpt_status dxeTXCompFrame
3713(
3714 WLANDXE_CtrlBlkType *hostCtxt,
3715 WLANDXE_ChannelCBType *channelEntry
3716)
3717{
3718 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3719 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3720 WLANDXE_DescType *currentDesc = NULL;
3721 wpt_uint32 descCtrlValue = 0;
3722 unsigned int *lowThreshold = NULL;
3723
3724 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003725 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003726
3727 /* Sanity */
3728 if((NULL == hostCtxt) || (NULL == channelEntry))
3729 {
3730 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3731 "dxeTXCompFrame Invalid ARG");
3732 return eWLAN_PAL_STATUS_E_INVAL;
3733 }
3734
3735 if(NULL == hostCtxt->txCompCB)
3736 {
3737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3738 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003739 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003740 }
3741
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003742 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3743 if(eWLAN_PAL_STATUS_SUCCESS != status)
3744 {
3745 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3746 "dxeTXCompFrame Mutex Acquire fail");
3747 return status;
3748 }
3749
Jeff Johnson295189b2012-06-20 16:38:30 -07003750 currentCtrlBlk = channelEntry->tailCtrlBlk;
3751 currentDesc = currentCtrlBlk->linkedDesc;
3752
3753 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3754 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003755 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3756 if(eWLAN_PAL_STATUS_SUCCESS != status)
3757 {
3758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3759 "dxeTXCompFrame Mutex Release fail");
3760 return status;
3761 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003762 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003763 }
3764
Kiet Lam842dad02014-02-18 18:44:02 -08003765
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 while(1)
3767 {
3768// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3769 descCtrlValue = currentDesc->descCtrl.ctrl;
3770 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3771 {
3772 /* caught up with head, bail out */
3773 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3774 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3775 break;
3776 }
3777
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003778 if(currentCtrlBlk->xfrFrame == NULL)
3779 {
3780 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3781 "Invalid transfer frame");
3782 HDXE_ASSERT(0);
3783 break;
3784 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003785 channelEntry->numFreeDesc++;
3786 channelEntry->numRsvdDesc--;
3787
3788 /* Send Frame TX Complete notification with frame start fragment location */
3789 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3790 {
3791 hostCtxt->txCompletedFrames--;
3792#ifdef FEATURE_R33D
3793 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
3794#else
3795 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3796 if (eWLAN_PAL_STATUS_SUCCESS != status)
3797 {
3798 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3799 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003800 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3801 if(eWLAN_PAL_STATUS_SUCCESS != status)
3802 {
3803 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3804 "dxeTXCompFrame Mutex Release fail");
3805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003806 return status;
3807 }
3808#endif /* FEATURE_R33D */
3809 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3810 currentCtrlBlk->xfrFrame,
3811 eWLAN_PAL_STATUS_SUCCESS);
3812 channelEntry->numFragmentCurrentChain = 0;
3813 }
3814 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3815 currentDesc = currentCtrlBlk->linkedDesc;
3816
3817 /* Break condition
3818 * Head control block is the control block must be programed for the next TX
3819 * so, head control block is not programmed control block yet
3820 * if loop encounte head control block, stop to complete
3821 * in theory, COMP CB must be called already ??? */
3822 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3823 {
3824 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3825 "dxeTXCompFrame caught up with head ptr");
3826 break;
3827 }
3828 /* VALID Bit check ???? */
3829 }
3830
3831 /* Tail and Head Control block must be same */
3832 channelEntry->tailCtrlBlk = currentCtrlBlk;
3833
3834 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3835 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3836 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3837
3838 /* If specific channel hit low resource condition send notification to upper layer */
3839 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3840 (channelEntry->numFreeDesc > *lowThreshold))
3841 {
3842 /* Change it back if we raised it for fetching a remaining packet from TL */
3843 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3844 {
3845 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3846 }
3847
3848 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3849 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3850 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3851 channelEntry->channelType,
3852 eWLAN_PAL_TRUE);
3853 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07003854 wpalTimerStop(&channelEntry->healthMonitorTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 }
3856
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003857 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3858 if(eWLAN_PAL_STATUS_SUCCESS != status)
3859 {
3860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3861 "dxeTXCompFrame Mutex Release fail");
3862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003863
3864 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003865 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003866 return status;
3867}
3868
3869/*==========================================================================
3870 @ Function Name
3871 dxeTXEventHandler
3872
3873 @ Description
3874 If DXE HW sends TX related interrupt, this event handler will be called
3875 Handle higher priority channel first
3876 Figureout why interrupt happen and call appropriate final even handler
3877 TX complete or error happen
3878
3879 @ Parameters
3880 void *msgPtr
3881 Even MSG
3882
3883 @ Return
3884 PAL_STATUS_T
3885===========================================================================*/
3886void dxeTXEventHandler
3887(
3888 wpt_msg *msgPtr
3889)
3890{
3891 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3892 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3893 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3894 wpt_uint32 intSrc = 0;
3895 wpt_uint32 chStat = 0;
3896 WLANDXE_ChannelCBType *channelCb = NULL;
3897
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003898 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003899 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003900
3901 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003902 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003903
3904 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003905 dxeCtxt->ucTxMsgCnt = 0;
3906
3907 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3908 {
3909 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3910 "wlan: TX COMP WLAN Driver re-loading in progress");
3911 return;
3912 }
3913
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 /* Return from here if the RIVA is in IMPS, to avoid register access */
3915 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3916 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003917 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003918 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003919 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003920 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3921 if(eWLAN_PAL_STATUS_SUCCESS != status)
3922 {
3923 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003924 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003925 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003926
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003927 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3928 if(eWLAN_PAL_STATUS_SUCCESS != status)
3929 {
3930 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3931 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3932 }
3933
3934 if(((dxeCtxt->txCompletedFrames) &&
3935 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3936 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003937 {
3938 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3939 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3940 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003941 "TX COMP INT Enabled, remain TX frame count on ring %d",
3942 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003943 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3944 the posibility of a race*/
3945 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3946 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003947 else
3948 {
3949 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3950 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3951 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3952 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003954 return;
3955 }
3956
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003957 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3959 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3960 {
3961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3962 "DXE already stopped in TX event handler. Just return");
3963 return;
3964 }
3965
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 /* Disable device interrupt */
3967 /* Read whole interrupt mask register and exclusive only this channel int */
3968 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3969 &intSrc);
3970 if(eWLAN_PAL_STATUS_SUCCESS != status)
3971 {
3972 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3973 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3974 return;
3975 }
3976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3977 "TX Event Handler INT Source 0x%x", intSrc);
3978
3979 /* Test High Priority Channel is the INT source or not */
3980 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3981 if(intSrc & (1 << channelCb->assignedDMAChannel))
3982 {
3983 status = dxeChannelCleanInt(channelCb, &chStat);
3984 if(eWLAN_PAL_STATUS_SUCCESS != status)
3985 {
3986 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3987 "dxeTXEventHandler INT Clean up fail");
3988 return;
3989 }
3990
3991 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3992 {
3993 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003994 "%11s : 0x%x Error Reported, Reload Driver",
3995 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303996
Mihir Shete79d6b582014-03-12 17:54:07 +05303997 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303998
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003999 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4000 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05304001 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004002 }
4003 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4004 {
4005 /* Handle TX complete for high priority channel */
4006 status = dxeTXCompFrame(dxeCtxt,
4007 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004008 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004009 }
4010 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4011 {
4012 /* Handle TX complete for high priority channel */
4013 status = dxeTXCompFrame(dxeCtxt,
4014 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004015 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 }
4017 else
4018 {
4019 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4020 "dxeTXEventHandler TX HI status=%x", chStat);
4021 }
4022
4023 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4024 {
4025 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4026 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
4027 }
4028
4029 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4030 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4031 }
4032
4033 /* Test Low Priority Channel interrupt is enabled or not */
4034 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4035 if(intSrc & (1 << channelCb->assignedDMAChannel))
4036 {
4037 status = dxeChannelCleanInt(channelCb, &chStat);
4038 if(eWLAN_PAL_STATUS_SUCCESS != status)
4039 {
4040 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4041 "dxeTXEventHandler INT Clean up fail");
4042 return;
4043 }
4044
4045 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4046 {
4047 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004048 "%11s : 0x%x Error Reported, Reload Driver",
4049 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304050
Mihir Shete79d6b582014-03-12 17:54:07 +05304051 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304052
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004053 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4054 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05304055 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004056 }
4057 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4058 {
4059 /* Handle TX complete for low priority channel */
4060 status = dxeTXCompFrame(dxeCtxt,
4061 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004062 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 }
4064 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4065 {
4066 /* Handle TX complete for low priority channel */
4067 status = dxeTXCompFrame(dxeCtxt,
4068 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004069 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004070 }
4071 else
4072 {
4073 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4074 "dxeTXEventHandler TX LO status=%x", chStat);
4075 }
4076
4077 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4078 {
4079 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4080 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
4081 }
4082 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4083 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4084 }
4085
4086
4087#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4088 /* Test H2H TX Channel interrupt is enabled or not */
4089 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
4090 if(intSrc & (1 << channelCb->assignedDMAChannel))
4091 {
4092 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
4093 &chStat);
4094 if(eWLAN_PAL_STATUS_SUCCESS != status)
4095 {
4096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4097 "dxeChannelCleanInt Read CH STAT register fail");
4098 return;
4099 }
4100
4101 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4102 {
4103 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004104 "%11s : 0x%x Error Reported, Reload Driver",
4105 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304106
Mihir Shete79d6b582014-03-12 17:54:07 +05304107 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304108
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004109 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4110 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05304111 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004112 }
4113 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4114 {
4115 /* Handle TX complete for high priority channel */
4116 status = dxeTXCompFrame(dxeCtxt,
4117 channelCb);
4118 if(eWLAN_PAL_STATUS_SUCCESS != status)
4119 {
4120 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4121 "dxeTXEventHandler INT Clean up fail");
4122 return;
4123 }
4124 }
4125 else
4126 {
4127 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4128 "unexpected channel state %d", chStat);
4129 }
4130 }
4131#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4132
4133 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
4134 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4135 {
4136 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4137 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004138 if(0 != dxeCtxt->txCompletedFrames)
4139 {
4140 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4141 "TX COMP INT Enabled, remain TX frame count on ring %d",
4142 dxeCtxt->txCompletedFrames);
4143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004144 }
4145
4146 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4147 the posibility of a race*/
4148 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4149
4150 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004151 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 return;
4153}
4154
4155
4156/*==========================================================================
4157 @ Function Name
4158 dxeTXCompleteProcessing
4159
4160 @ Description
4161 If DXE HW sends TX related interrupt, this event handler will be called
4162 Handle higher priority channel first
4163 Figureout why interrupt happen and call appropriate final even handler
4164 TX complete or error happen
4165
4166 @ Parameters
4167 dxeCtxt DXE context
4168
4169 @ Return
4170 PAL_STATUS_T
4171===========================================================================*/
4172void dxeTXCompleteProcessing
4173(
4174 WLANDXE_CtrlBlkType *dxeCtxt
4175)
4176{
4177 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4178 WLANDXE_ChannelCBType *channelCb = NULL;
4179
4180 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004181 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004182
4183 /* Test High Priority Channel is the INT source or not */
4184 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4185
4186 /* Handle TX complete for high priority channel */
4187 status = dxeTXCompFrame(dxeCtxt, channelCb);
4188
4189 /* Test Low Priority Channel interrupt is enabled or not */
4190 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4191
4192 /* Handle TX complete for low priority channel */
4193 status = dxeTXCompFrame(dxeCtxt, channelCb);
4194
4195 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
4196 ((dxeCtxt->txCompletedFrames > 0) ||
4197 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
4198 {
4199 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4200 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4201 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004202 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004203 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
4204 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
4205 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
4206 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07004207
4208 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
4209 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
4210 {
4211 /* After TX Comp processing, still remaining frame on the DXE TX ring
4212 * And when push frame, RING was not empty marked
4213 * Then when push frame, no SMSM toggle happen
4214 * To avoid permanent TX stall, SMSM toggle is needed at here
4215 * With this toggle, host should gaurantee SMSM state should be changed */
Mihir Shete68ed77a2014-10-10 10:47:12 +05304216 dxeNotifySmsm(eWLAN_PAL_TRUE, dxeCtxt->txRingsEmpty);
Leo Changac1d3612013-07-01 15:15:51 -07004217 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 }
4219
4220 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4221 the posibility of a race*/
4222 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
4223
4224 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004225 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004226 return;
4227}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004228
4229/*==========================================================================
4230 @ Function Name
4231 dxeTXReSyncDesc
4232
4233 @ Description
4234 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
4235 And HW programmed descriptor.
4236 If any async happen between HW/SW TX stall will happen
4237
4238 @ Parameters
4239 void *msgPtr
4240 Message pointer to sync with TX thread
4241
4242 @ Return
4243 NONE
4244===========================================================================*/
4245void dxeTXReSyncDesc
4246(
4247 wpt_msg *msgPtr
4248)
4249{
4250 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4251 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4252 wpt_uint32 nextDescReg;
4253 WLANDXE_ChannelCBType *channelEntry;
4254 WLANDXE_DescCtrlBlkType *validCtrlBlk;
4255 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004256 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004257
4258 if(NULL == msgContent)
4259 {
4260 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4261 "dxeTXReSyncDesc Invalid Control Block");
4262 return;
4263 }
4264
4265 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4266 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
4267 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4268
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004269 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004270 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004271 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4272 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4273 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
4274 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4275 &nextDescReg);
4276 /* Async detect without TX pending frame */
4277 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004278 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004279 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004280 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004281 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4282 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304283
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004284 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
4285 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304286
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004287 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004288 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004289 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004290 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004291 /* Async detect with some TX pending frames
4292 * next descriptor register should sync with first valid descriptor */
4293 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004294 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004295 validCtrlBlk = channelEntry->tailCtrlBlk;
4296 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004297 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004298 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4299 {
4300 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
4301 {
4302 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4303 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304304
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004305 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4306 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304307
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004308 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4309 validCtrlBlk->linkedDescPhyAddr);
4310 }
4311 break;
4312 }
4313 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4314 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4315 {
4316 /* Finished to test till head control blcok, but could not find valid descriptor
4317 * from head to tail all descriptors are invalidated
4318 * host point of view head descriptor is next TX candidate
4319 * So, next descriptor control have to be programmed with head descriptor
4320 * check */
4321 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
4322 {
4323 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004324 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304325
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004326 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4327 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304328
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004329 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4330 validCtrlBlk->linkedDescPhyAddr);
4331 }
4332 break;
4333 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004334 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004335 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004336 }
4337
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07004338 /* HW/SW descriptor resync is done.
4339 * Next if there are any valid descriptor in chain, Push to HW again */
4340 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
4341 {
4342 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4343 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
4344 {
4345 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4346 "%11s : No TX Pending frame",
4347 channelType[channelEntry->channelType]);
4348 /* No Pending frame, Do nothing */
4349 }
4350 else
4351 {
4352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4353 "%11s : TX Pending frame, process it",
4354 channelType[channelEntry->channelType]);
4355 validCtrlBlk = channelEntry->tailCtrlBlk;
4356 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
4357 {
4358 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4359 {
4360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4361 "%11s : when exit IMPS found valid descriptor",
4362 channelType[channelEntry->channelType]);
4363
4364 /* Found valid descriptor, kick DXE */
4365 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
4366 channelEntry->extraConfig.chan_mask);
4367 break;
4368 }
4369 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4370 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4371 {
4372 /* Finished to test till head control blcok, but could not find valid descriptor
4373 * from head to tail all descriptors are invalidated */
4374 break;
4375 }
4376 }
4377 }
4378 }
4379
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004380 wpalMemoryFree(msgPtr);
4381 return;
4382}
4383
Jeff Johnson295189b2012-06-20 16:38:30 -07004384/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05304385 @ Function Name
4386 dxeDebugTxDescReSync
4387
4388 @ Description
4389 Check DXE Tx channel state and correct it in
4390 case Tx Data stall is detected by calling
4391 %dxeTXReSyncDesc. Also ensure that WCN SS
4392 is not power collapsed before calling
4393 %dxeTXReSyncDesc
4394
4395 @ Parameters
4396 void *msgPtr
4397 Message pointer to sync with TX thread
4398
4399 @ Return
4400 NONE
4401===========================================================================*/
4402void dxeDebugTxDescReSync
4403(
4404 wpt_msg *msgPtr
4405)
4406{
4407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4408 "%s: Check for DXE TX Async",__func__);
4409 /* Make wake up HW */
4410 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4411 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4412
4413 wpalSleep(10);
4414
4415 dxeTXReSyncDesc(msgPtr);
4416}
4417/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004418 @ Function Name
4419 dxeTXISR
4420
4421 @ Description
4422 TX interrupt ISR
4423 Platform will call this function if INT is happen
4424 This function must be registered into platform interrupt module
4425
4426 @ Parameters
4427 void *hostCtxt
4428 DXE host driver control context,
4429 pre registerd during interrupt registration
4430
4431 @ Return
4432 PAL_STATUS_T
4433===========================================================================*/
4434static void dxeTXISR
4435(
4436 void *hostCtxt
4437)
4438{
4439 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
4440 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4441#ifdef FEATURE_R33D
4442 wpt_uint32 regValue;
4443#endif /* FEATURE_R33D */
4444
4445 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004446 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004447
4448 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004449 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004451 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004452 /* Disable interrupt at here,
4453 IMPS or IMPS Pending state should not access RIVA register */
4454 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4455 if(eWLAN_PAL_STATUS_SUCCESS != status)
4456 {
4457 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4458 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4459 return;
4460 }
4461 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004463 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 return;
4465 }
4466
4467#ifdef FEATURE_R33D
4468 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
4469 &regValue);
4470 if(eWLAN_PAL_STATUS_SUCCESS != status)
4471 {
4472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4473 "dxeTXCompISR Read INT_SRC_RAW fail");
4474 return;
4475 }
4476 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4477 "INT_SRC_RAW 0x%x", regValue);
4478 if(0 == regValue)
4479 {
4480 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4481 "This is not DXE Interrupt, Reject it");
4482 return;
4483 }
4484#endif /* FEATURE_R33D */
4485
4486 /* Disable TX Complete Interrupt at here */
4487 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4488 if(eWLAN_PAL_STATUS_SUCCESS != status)
4489 {
4490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4491 "dxeTXCompISR Disable TX complete interrupt fail");
4492 return;
4493 }
4494 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4495
4496
4497 if( dxeCtxt->ucTxMsgCnt )
4498 {
4499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4500 "Avoiding serializing TX Complete event");
4501 return;
4502 }
4503
4504 dxeCtxt->ucTxMsgCnt = 1;
4505
4506 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004507 if(NULL == dxeCtxt->txIsrMsg)
4508 {
4509 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4510 "Invalid message");
4511 HDXE_ASSERT(0);
4512 return;
4513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004514 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4515 dxeCtxt->txIsrMsg);
4516 if(eWLAN_PAL_STATUS_SUCCESS != status)
4517 {
4518 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4519 "dxeTXCompISR interrupt serialize fail status=%d", status);
4520 }
4521
4522 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004523 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 return;
4525}
4526
4527/*-------------------------------------------------------------------------
4528 * Global Function
4529 *-------------------------------------------------------------------------*/
4530/*==========================================================================
4531 @ Function Name
4532 WLANDXE_Open
4533
4534 @ Description
4535 Open host DXE driver, allocate DXE resources
4536 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4537
4538 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004539 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004540
4541 @ Return
4542 pVoid DXE local module control block pointer
4543===========================================================================*/
4544void *WLANDXE_Open
4545(
4546 void
4547)
4548{
4549 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4550 unsigned int idx;
4551 WLANDXE_ChannelCBType *currentChannel = NULL;
4552 int smsmInitState;
4553#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4554 wpt_uint32 sIdx;
4555 WLANDXE_ChannelCBType *channel = NULL;
4556 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4557 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4558#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4559
4560 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004561 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004562
4563 /* This is temporary allocation */
4564 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4565 if(NULL == tempDxeCtrlBlk)
4566 {
4567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4568 "WLANDXE_Open Control Block Alloc Fail");
4569 return NULL;
4570 }
4571 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4572
4573 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4574 if(eWLAN_PAL_STATUS_SUCCESS != status)
4575 {
4576 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4577 "WLANDXE_Open Common Configuration Fail");
4578 WLANDXE_Close(tempDxeCtrlBlk);
4579 return NULL;
4580 }
4581
4582 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4583 {
4584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4585 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4586 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
4587 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
4588 {
4589 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
4590 }
4591 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
4592 {
4593 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
4594 }
4595 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
4596 {
4597 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
4598 }
4599 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
4600 {
4601 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
4602 }
4603#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4604 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
4605 {
4606 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
4607 }
4608 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
4609 {
4610 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
4611 }
4612#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4613
4614 /* Config individual channels from channel default setup table */
4615 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4616 currentChannel);
4617 if(eWLAN_PAL_STATUS_SUCCESS != status)
4618 {
4619 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4620 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4621 WLANDXE_Close(tempDxeCtrlBlk);
4622 return NULL;
4623 }
4624
4625 /* Allocate DXE Control Block will be used by host DXE driver */
4626 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4627 if(eWLAN_PAL_STATUS_SUCCESS != status)
4628 {
4629 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4630 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4631
4632 WLANDXE_Close(tempDxeCtrlBlk);
4633 return NULL;
4634 }
4635 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4636 if(eWLAN_PAL_STATUS_SUCCESS != status)
4637 {
4638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4639 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4640 WLANDXE_Close(tempDxeCtrlBlk);
4641 return NULL;
4642 }
4643
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004644 status = wpalTimerInit(&currentChannel->healthMonitorTimer,
4645 dxeHealthMonitorTimeout,
4646 (void *)currentChannel);
4647 if(eWLAN_PAL_STATUS_SUCCESS != status)
4648 {
4649 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4650 "WLANDXE_Open Health Monitor timer init fail %d", idx);
4651 WLANDXE_Close(tempDxeCtrlBlk);
4652 return NULL;
4653 }
4654
4655 currentChannel->healthMonitorMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4656 if(NULL == currentChannel->healthMonitorMsg)
4657 {
4658 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4659 "WLANDXE_Open Health Monitor MSG Alloc fail %d", idx);
4660 WLANDXE_Close(tempDxeCtrlBlk);
4661 return NULL;
4662 }
4663 wpalMemoryZero(currentChannel->healthMonitorMsg, sizeof(wpt_msg));
4664 currentChannel->healthMonitorMsg->callback = dxeTXHealthMonitor;
4665 currentChannel->healthMonitorMsg->pContext = (void *)currentChannel;
4666
Jeff Johnson295189b2012-06-20 16:38:30 -07004667 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4668 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4669 }
4670
4671 /* Allocate and Init RX READY ISR Serialize Buffer */
4672 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4673 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4674 {
4675 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4676 "WLANDXE_Open Alloc RX ISR Fail");
4677 WLANDXE_Close(tempDxeCtrlBlk);
4678 return NULL;
4679 }
4680 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4681 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4682 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4683
4684 /* Allocate and Init TX COMP ISR Serialize Buffer */
4685 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4686 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4687 {
4688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4689 "WLANDXE_Open Alloc TX ISR Fail");
4690 WLANDXE_Close(tempDxeCtrlBlk);
4691 return NULL;
4692 }
4693 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4694 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4695 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4696
4697 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4698 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4699 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4700 {
4701 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4702 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4703 WLANDXE_Close(tempDxeCtrlBlk);
4704 return NULL;
4705 }
4706 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4707 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4708 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4709
4710 tempDxeCtrlBlk->freeRXPacket = NULL;
4711 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4712 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4713 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004714 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004715 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004716
4717 /* Initialize SMSM state
4718 * Init State is
4719 * Clear TX Enable
4720 * RING EMPTY STATE */
4721 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4722 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4723 if(0 != smsmInitState)
4724 {
4725 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4726 "SMSM Channel init fail %d", smsmInitState);
4727 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4728 {
4729 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4730 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004731 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4732 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004733 wpalMemoryFree(tempDxeCtrlBlk);
4734 return NULL;
4735 }
4736
Mihir Shete44547fb2014-03-10 14:15:42 +05304737#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004738 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4739 dxeRXResourceAvailableTimerExpHandler,
4740 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304741#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004742
Mihir Shetefdc9f532014-01-09 15:03:02 +05304743 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4744 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4745
Jeff Johnson295189b2012-06-20 16:38:30 -07004746 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4747 "WLANDXE_Open Success");
4748 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004749 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004750 return (void *)tempDxeCtrlBlk;
4751}
4752
4753/*==========================================================================
4754 @ Function Name
4755 WLANDXE_ClientRegistration
4756
4757 @ Description
4758 Make callback functions registration into DXE driver from DXE driver client
4759
4760 @ Parameters
4761 pVoid pDXEContext : DXE module control block
4762 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
4763 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
4764 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
4765 void *userContext : DXE Cliennt control block
4766
4767 @ Return
4768 wpt_status
4769===========================================================================*/
4770wpt_status WLANDXE_ClientRegistration
4771(
4772 void *pDXEContext,
4773 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
4774 WLANDXE_TxCompleteCbType txCompleteCB,
4775 WLANDXE_LowResourceCbType lowResourceCB,
4776 void *userContext
4777)
4778{
4779 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4780 WLANDXE_CtrlBlkType *dxeCtxt;
4781
4782 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004783 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004784
4785 /* Sanity */
4786 if(NULL == pDXEContext)
4787 {
4788 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4789 "WLANDXE_ClientRegistration Invalid DXE CB");
4790 return eWLAN_PAL_STATUS_E_INVAL;
4791 }
4792
4793 if(NULL == rxFrameReadyCB)
4794 {
4795 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4796 "WLANDXE_ClientRegistration Invalid RX READY CB");
4797 return eWLAN_PAL_STATUS_E_INVAL;
4798 }
4799
4800 if(NULL == txCompleteCB)
4801 {
4802 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4803 "WLANDXE_ClientRegistration Invalid txCompleteCB");
4804 return eWLAN_PAL_STATUS_E_INVAL;
4805 }
4806
4807 if(NULL == lowResourceCB)
4808 {
4809 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4810 "WLANDXE_ClientRegistration Invalid lowResourceCB");
4811 return eWLAN_PAL_STATUS_E_INVAL;
4812 }
4813
4814 if(NULL == userContext)
4815 {
4816 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4817 "WLANDXE_ClientRegistration Invalid userContext");
4818 return eWLAN_PAL_STATUS_E_INVAL;
4819 }
4820
4821 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4822
4823 /* Assign */
4824 dxeCtxt->rxReadyCB = rxFrameReadyCB;
4825 dxeCtxt->txCompCB = txCompleteCB;
4826 dxeCtxt->lowResourceCB = lowResourceCB;
4827 dxeCtxt->clientCtxt = userContext;
4828
4829 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004830 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 return status;
4832}
4833
4834/*==========================================================================
4835 @ Function Name
4836 WLANDXE_Start
4837
4838 @ Description
4839 Start Host DXE driver
4840 Initialize DXE channels and start channel
4841
4842 @ Parameters
4843 pVoid pDXEContext : DXE module control block
4844
4845 @ Return
4846 wpt_status
4847===========================================================================*/
4848wpt_status WLANDXE_Start
4849(
4850 void *pDXEContext
4851)
4852{
4853 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4854 wpt_uint32 idx;
4855 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4856
4857 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004858 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004859
4860 /* Sanity */
4861 if(NULL == pDXEContext)
4862 {
4863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4864 "WLANDXE_Start Invalid DXE CB");
4865 return eWLAN_PAL_STATUS_E_INVAL;
4866 }
4867 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4868
4869 /* WLANDXE_Start called means DXE engine already initiates
4870 * And DXE HW is reset and init finished
4871 * But here to make sure HW is initialized, reset again */
4872 status = dxeEngineCoreStart(dxeCtxt);
4873 if(eWLAN_PAL_STATUS_SUCCESS != status)
4874 {
4875 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4876 "WLANDXE_Start DXE HW init Fail");
4877 return status;
4878 }
4879
4880 /* Individual Channel Start */
4881 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4882 {
4883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4884 "WLANDXE_Start Channel %s Start", channelType[idx]);
4885
4886 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4887 /* Make connection between DXE descriptor and DXE control block */
4888 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4889 if(eWLAN_PAL_STATUS_SUCCESS != status)
4890 {
4891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4892 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4893 return status;
4894 }
4895
4896 /* Program each channel register with configuration arguments */
4897 status = dxeChannelInitProgram(dxeCtxt,
4898 &dxeCtxt->dxeChannel[idx]);
4899 if(eWLAN_PAL_STATUS_SUCCESS != status)
4900 {
4901 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4902 "WLANDXE_Start %d Program DMA channel Fail", idx);
4903 return status;
4904 }
4905
4906 /* ??? Trigger to start DMA channel
4907 * This must be seperated from ??? */
4908 status = dxeChannelStart(dxeCtxt,
4909 &dxeCtxt->dxeChannel[idx]);
4910 if(eWLAN_PAL_STATUS_SUCCESS != status)
4911 {
4912 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4913 "WLANDXE_Start %d Channel Start Fail", idx);
4914 return status;
4915 }
4916 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4917 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4918 }
4919
4920 /* Register ISR to OS */
4921 /* Register TX complete interrupt into platform */
4922 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4923 dxeTXISR,
4924 dxeCtxt);
4925 if(eWLAN_PAL_STATUS_SUCCESS != status)
4926 {
4927 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4928 "WLANDXE_Start TX comp interrupt registration Fail");
4929 return status;
4930 }
4931
4932 /* Register RX ready interrupt into platform */
4933 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4934 dxeRXISR,
4935 dxeCtxt);
4936 if(eWLAN_PAL_STATUS_SUCCESS != status)
4937 {
4938 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4939 "WLANDXE_Start RX Ready interrupt registration Fail");
4940 return status;
4941 }
4942
4943 /* Enable system level ISR */
4944 /* Enable RX ready Interrupt at here */
4945 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4946 if(eWLAN_PAL_STATUS_SUCCESS != status)
4947 {
4948 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4949 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4950 return status;
4951 }
4952
4953 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004954 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004955 return status;
4956}
4957
4958/*==========================================================================
4959 @ Function Name
4960 WLANDXE_TXFrame
4961
4962 @ Description
4963 Trigger frame transmit from host to RIVA
4964
4965 @ Parameters
4966 pVoid pDXEContext : DXE Control Block
4967 wpt_packet pPacket : transmit packet structure
4968 WDTS_ChannelType channel : TX channel
4969
4970 @ Return
4971 wpt_status
4972===========================================================================*/
4973wpt_status WLANDXE_TxFrame
4974(
4975 void *pDXEContext,
4976 wpt_packet *pPacket,
4977 WDTS_ChannelType channel
4978)
4979{
4980 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4981 WLANDXE_ChannelCBType *currentChannel = NULL;
4982 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4983 unsigned int *lowThreshold = NULL;
4984
4985 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004986 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004987
4988 /* Sanity */
4989 if(NULL == pDXEContext)
4990 {
4991 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4992 "WLANDXE_Start Invalid DXE CB");
4993 return eWLAN_PAL_STATUS_E_INVAL;
4994 }
4995
4996 if(NULL == pPacket)
4997 {
4998 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4999 "WLANDXE_Start Invalid pPacket");
5000 return eWLAN_PAL_STATUS_E_INVAL;
5001 }
5002
5003 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
5004 {
5005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5006 "WLANDXE_Start Invalid channel");
5007 return eWLAN_PAL_STATUS_E_INVAL;
5008 }
5009
5010 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
5011
5012 currentChannel = &dxeCtxt->dxeChannel[channel];
5013
5014
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005015 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
5016 if(eWLAN_PAL_STATUS_SUCCESS != status)
5017 {
5018 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5019 "WLANDXE_TxFrame Mutex Acquire fail");
5020 return status;
5021 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005022
5023 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
5024 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
5025 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
5026
5027 /* Decide have to activate TX complete event or not */
5028 switch(dxeCtxt->txCompInt.txIntEnable)
5029 {
5030 /* TX complete interrupt will be activated when low DXE resource */
5031 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
5032 if((currentChannel->numFreeDesc <= *lowThreshold) &&
5033 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
5034 {
5035 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
5036 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5037 channel,
5038 eWLAN_PAL_FALSE);
5039 }
5040 break;
5041
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08005042 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07005043 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
5044 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
5045 {
5046 currentChannel->numFrameBeforeInt++;
5047 }
5048 break;
5049
5050 /* TX complete interrupt will be activated periodically */
5051 case WLANDXE_TX_COMP_INT_TIMER:
5052 break;
5053 }
5054
5055 dxeCtxt->txCompletedFrames++;
5056
5057 /* Update DXE descriptor, this is frame based
5058 * if a frame consist of N fragments, N Descriptor will be programed */
5059 status = dxeTXPushFrame(currentChannel, pPacket);
5060 if(eWLAN_PAL_STATUS_SUCCESS != status)
5061 {
5062 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5063 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005064 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5065 if(eWLAN_PAL_STATUS_SUCCESS != status)
5066 {
5067 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5068 "WLANDXE_TxFrame Mutex Release fail");
5069 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 return status;
5071 }
5072
5073 /* If specific channel hit low resource condition, send notification to upper layer */
5074 if(currentChannel->numFreeDesc <= *lowThreshold)
5075 {
5076 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5077 channel,
5078 eWLAN_PAL_FALSE);
5079 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005080
5081 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5082 "%11s : Low Resource currentChannel->numRsvdDesc %d",
5083 channelType[currentChannel->channelType],
5084 currentChannel->numRsvdDesc);
Mihir Shete68ed77a2014-10-10 10:47:12 +05305085 if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5086 {
5087 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5088 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
5089 }
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005090 wpalTimerStart(&currentChannel->healthMonitorTimer,
5091 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005093 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5094 if(eWLAN_PAL_STATUS_SUCCESS != status)
5095 {
5096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5097 "WLANDXE_TxFrame Mutex Release fail");
5098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005099
5100 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005101 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005102 return status;
5103}
5104
5105/*==========================================================================
5106 @ Function Name
5107 WLANDXE_CompleteTX
5108
5109 @ Description
5110 Informs DXE that the current series of Tx packets is complete
5111
5112 @ Parameters
5113 pContext pDXEContext : DXE Control Block
5114 ucTxResReq TX resource number required by TL/WDI
5115
5116 @ Return
5117 wpt_status
5118===========================================================================*/
5119wpt_status
5120WLANDXE_CompleteTX
5121(
5122 void* pContext,
5123 wpt_uint32 ucTxResReq
5124)
5125{
5126 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5127 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
5128 WLANDXE_ChannelCBType *channelCb = NULL;
5129 wpt_boolean inLowRes;
5130
5131 /* Sanity Check */
5132 if( NULL == pContext )
5133 {
5134 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5135 "WLANDXE_CompleteTX invalid param");
5136 return eWLAN_PAL_STATUS_E_INVAL;
5137 }
5138
5139 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
5140 inLowRes = channelCb->hitLowResource;
5141
5142 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
5143 {
5144 /* Raise threshold temporarily if necessary */
5145 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
5146
5147 if(eWLAN_PAL_FALSE == inLowRes)
5148 {
5149 /* Put the channel to low resource condition */
5150 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5151 WDTS_CHANNEL_TX_LOW_PRI,
5152 eWLAN_PAL_FALSE);
5153 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005154 wpalTimerStart(&channelCb->healthMonitorTimer,
5155 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07005156 }
5157 }
5158
5159 /*Try to reclaim resources*/
5160 dxeTXCompleteProcessing(dxeCtxt);
5161
5162 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
5163 because its fragment size is larger than DXE free resource. */
5164 if(0 < ucTxResReq)
5165 {
5166 /* DXE successfully claimed enough free DXE resouces for next fetch. */
5167 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
5168 {
5169 /* DXE has not been in low resource condition. DXE forces to kick off
5170 TX tranmit */
5171 if((eWLAN_PAL_FALSE == inLowRes) &&
5172 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
5173 {
5174 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5175 WDTS_CHANNEL_TX_LOW_PRI,
5176 eWLAN_PAL_FALSE);
5177 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5178 WDTS_CHANNEL_TX_LOW_PRI,
5179 eWLAN_PAL_TRUE);
5180 channelCb->hitLowResource = eWLAN_PAL_FALSE;
5181 }
5182 }
5183 else
5184 {
5185 /* DXE doesn't have enough free DXE resources. Put the channel
5186 to low resource condition. */
5187 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
5188 {
5189 /* Put the channel to low resource condition */
5190 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5191 WDTS_CHANNEL_TX_LOW_PRI,
5192 eWLAN_PAL_FALSE);
5193 channelCb->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005194 wpalTimerStart(&channelCb->healthMonitorTimer,
5195 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Jeff Johnson295189b2012-06-20 16:38:30 -07005196 }
5197 }
5198 }
5199
5200 return status;
5201}
5202
5203/*==========================================================================
5204 @ Function Name
5205 WLANDXE_Stop
5206
5207 @ Description
5208 Stop DXE channels and DXE engine operations
5209 Disable all channel interrupt
5210 Stop all channel operation
5211
5212 @ Parameters
5213 pVoid pDXEContext : DXE Control Block
5214
5215 @ Return
5216 wpt_status
5217===========================================================================*/
5218wpt_status WLANDXE_Stop
5219(
5220 void *pDXEContext
5221)
5222{
5223 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5224 wpt_uint32 idx;
5225 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5226
5227 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005228 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005229
5230 /* Sanity */
5231 if(NULL == pDXEContext)
5232 {
5233 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5234 "WLANDXE_Stop Invalid DXE CB");
5235 return eWLAN_PAL_STATUS_E_INVAL;
5236 }
5237
5238 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
5239 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
5240 {
Yue Ma7faf58c2013-04-25 12:04:13 -07005241 if(VOS_TIMER_STATE_RUNNING == wpalTimerGetCurStatus(&dxeCtxt->dxeChannel[idx].healthMonitorTimer))
5242 {
5243 wpalTimerStop(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
5244 }
5245
Jeff Johnson295189b2012-06-20 16:38:30 -07005246 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5247 if(eWLAN_PAL_STATUS_SUCCESS != status)
5248 {
5249 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5250 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005251 }
5252 }
5253
5254 /* During Stop unregister interrupt */
5255 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
5256 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
5257
Mihir Shete44547fb2014-03-10 14:15:42 +05305258#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005259 if(VOS_TIMER_STATE_STOPPED !=
5260 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
5261 {
5262 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
5263 }
Mihir Shete44547fb2014-03-10 14:15:42 +05305264#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07005265
Jeff Johnson295189b2012-06-20 16:38:30 -07005266 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005267 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005268 return status;
5269}
5270
5271/*==========================================================================
5272 @ Function Name
5273 WLANDXE_Close
5274
5275 @ Description
5276 Close DXE channels
5277 Free DXE related resources
5278 DXE descriptor free
5279 Descriptor control block free
5280 Pre allocated RX buffer free
5281
5282 @ Parameters
5283 pVoid pDXEContext : DXE Control Block
5284
5285 @ Return
5286 wpt_status
5287===========================================================================*/
5288wpt_status WLANDXE_Close
5289(
5290 void *pDXEContext
5291)
5292{
5293 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5294 wpt_uint32 idx;
5295 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5296#ifdef WLANDXE_TEST_CHANNEL_ENABLE
5297 wpt_uint32 sIdx;
5298 WLANDXE_ChannelCBType *channel = NULL;
5299 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
5300 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
5301#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
5302
5303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005304 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005305
5306 /* Sanity */
5307 if(NULL == pDXEContext)
5308 {
5309 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5310 "WLANDXE_Stop Invalid DXE CB");
5311 return eWLAN_PAL_STATUS_E_INVAL;
5312 }
5313
5314 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05305315#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005316 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05305317#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05305318 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
5320 {
5321 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005322 wpalTimerDelete(&dxeCtxt->dxeChannel[idx].healthMonitorTimer);
5323 if(NULL != dxeCtxt->dxeChannel[idx].healthMonitorMsg)
5324 {
5325 wpalMemoryFree(dxeCtxt->dxeChannel[idx].healthMonitorMsg);
5326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5328#ifdef WLANDXE_TEST_CHANNEL_ENABLE
5329 channel = &dxeCtxt->dxeChannel[idx];
5330 crntDescCB = channel->headCtrlBlk;
5331 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
5332 {
5333 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
5334 wpalMemoryFree((void *)crntDescCB);
5335 crntDescCB = nextDescCB;
5336 if(NULL == crntDescCB)
5337 {
5338 break;
5339 }
5340 }
5341#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
5342 }
5343
5344 if(NULL != dxeCtxt->rxIsrMsg)
5345 {
5346 wpalMemoryFree(dxeCtxt->rxIsrMsg);
5347 }
5348 if(NULL != dxeCtxt->txIsrMsg)
5349 {
5350 wpalMemoryFree(dxeCtxt->txIsrMsg);
5351 }
5352 if(NULL != dxeCtxt->rxPktAvailMsg)
5353 {
5354 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
5355 }
5356
5357 wpalMemoryFree(pDXEContext);
5358
5359 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005360 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 return status;
5362}
5363
5364/*==========================================================================
5365 @ Function Name
5366 WLANDXE_TriggerTX
5367
5368 @ Description
5369 TBD
5370
5371 @ Parameters
5372 pVoid pDXEContext : DXE Control Block
5373
5374 @ Return
5375 wpt_status
5376===========================================================================*/
5377wpt_status WLANDXE_TriggerTX
5378(
5379 void *pDXEContext
5380)
5381{
5382 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5383
5384 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005385 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005386
5387 /* TBD */
5388
5389 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005390 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005391 return status;
5392}
5393
5394/*==========================================================================
5395 @ Function Name
5396 dxeTxThreadSetPowerStateEventHandler
5397
5398 @ Description
5399 If WDI sends set power state req, this event handler will be called in Tx
5400 thread context
5401
5402 @ Parameters
5403 void *msgPtr
5404 Event MSG
5405
5406 @ Return
5407 None
5408===========================================================================*/
5409void dxeTxThreadSetPowerStateEventHandler
5410(
5411 wpt_msg *msgPtr
5412)
5413{
5414 wpt_msg *msgContent = (wpt_msg *)msgPtr;
5415 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05305416 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05305418 wpt_int8 i;
5419 WLANDXE_ChannelCBType *channelEntry;
5420 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07005421
5422 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005423 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005424
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
5426 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
5427 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
5428
5429 switch(reqPowerState)
5430 {
5431 case WLANDXE_POWER_STATE_BMPS:
5432 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5433 {
5434 //don't block MC waiting for num_rsvd to become 0 since it may take a while
5435 //based on amount of TX and RX activity - during this time any received
5436 // management frames will remain un-processed consuming RX buffers
5437 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5438 dxeCtxt->hostPowerState = reqPowerState;
5439 }
5440 else
5441 {
5442 status = eWLAN_PAL_STATUS_E_INVAL;
5443 }
5444 break;
5445 case WLANDXE_POWER_STATE_IMPS:
5446 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5447 {
Mihir Shetea4306052014-03-25 00:02:54 +05305448
5449 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
5450 {
5451 channelEntry = &dxeCtxt->dxeChannel[i];
5452 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
5453 {
5454 status = eWLAN_PAL_STATUS_E_FAILURE;
5455 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
5456 "%11s : %s :TX Pending frame",
5457 channelType[channelEntry->channelType], __func__);
5458
5459 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
5460 dxeDescriptorDump(channelEntry,
5461 channelEntry->headCtrlBlk->linkedDesc, 0);
5462 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
5463 &channelLog);
5464 dxeChannelAllDescDump(channelEntry,
5465 channelEntry->channelType,
5466 &channelLog);
5467 }
5468 }
5469
5470 if (eWLAN_PAL_STATUS_SUCCESS == status)
5471 {
5472 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
5473 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 }
5476 else
5477 {
5478 status = eWLAN_PAL_STATUS_E_INVAL;
5479 }
5480 break;
5481 case WLANDXE_POWER_STATE_FULL:
5482 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5483 {
5484 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5485 }
5486 dxeCtxt->hostPowerState = reqPowerState;
5487 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5488 break;
5489 case WLANDXE_POWER_STATE_DOWN:
5490 WLANDXE_Stop((void *)dxeCtxt);
5491 break;
5492 default:
5493 //assert
5494 break;
5495 }
5496
5497 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
5498 {
5499 dxeCtxt->setPowerStateCb(status,
5500 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
5501 }
Ravali85acf6b2012-12-12 14:01:38 -08005502 else
5503 {
5504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5505 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
5506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 /* Free MSG buffer */
5508 wpalMemoryFree(msgPtr);
5509 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005510 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 return;
5512}
5513
5514
5515/*==========================================================================
5516 @ Function Name
5517 dxeRxThreadSetPowerStateEventHandler
5518
5519 @ Description
5520 If WDI sends set power state req, this event handler will be called in Rx
5521 thread context
5522
5523 @ Parameters
5524 void *msgPtr
5525 Event MSG
5526
5527 @ Return
5528 None
5529===========================================================================*/
5530void dxeRxThreadSetPowerStateEventHandler
5531(
5532 wpt_msg *msgPtr
5533)
5534{
5535 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5536
5537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005538 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005539
5540 /* Now serialise the message through Tx thread also to make sure
5541 * no register access when RIVA is in powersave */
5542 /*Use the same message pointer just change the call back function */
5543 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5544 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5545 msgPtr);
5546 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5547 {
5548 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5549 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005550 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 }
5552
5553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005554 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005555}
5556
5557/*==========================================================================
5558 @ Function Name
5559 WLANDXE_SetPowerState
5560
5561 @ Description
5562 From Client let DXE knows what is the WLAN HW(RIVA) power state
5563
5564 @ Parameters
5565 pVoid pDXEContext : DXE Control Block
5566 WLANDXE_PowerStateType powerState
5567
5568 @ Return
5569 wpt_status
5570===========================================================================*/
5571wpt_status WLANDXE_SetPowerState
5572(
5573 void *pDXEContext,
5574 WDTS_PowerStateType powerState,
5575 WDTS_SetPSCbType cBack
5576)
5577{
5578 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5579 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5580 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005581 wpt_msg *rxCompMsg;
5582 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005583
5584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005585 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 if(NULL == pDXEContext)
5587 {
5588 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005589 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 return eWLAN_PAL_STATUS_E_FAILURE;
5591 }
5592 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5593
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 switch(powerState)
5595 {
5596 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005597 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5598 {
5599 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5600 if(NULL == txDescReSyncMsg)
5601 {
5602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5603 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5604 }
5605 else
5606 {
5607 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5608 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5609 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5610 txDescReSyncMsg);
5611 if(eWLAN_PAL_STATUS_SUCCESS != status)
5612 {
5613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5614 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5615 }
5616 }
5617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 hostPowerState = WLANDXE_POWER_STATE_FULL;
5619 break;
5620 case WDTS_POWER_STATE_BMPS:
5621 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5622 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5623 break;
5624 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5626 break;
5627 case WDTS_POWER_STATE_DOWN:
5628 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5629 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5630 break;
5631 default:
5632 hostPowerState = WLANDXE_POWER_STATE_MAX;
5633 }
5634
5635 // A callback i.e. ACK back is needed only when we want to enable BMPS
5636 // and the data/management path is active because we want to ensure
5637 // DXE registers are not accessed when RIVA may be power-collapsed. So
5638 // we need a callback in enter_bmps_req (the request to RIVA is sent
5639 // only after ACK back from TX thread). A callback is not needed in
5640 // finish_scan_req during BMPS since data-path is resumed only in
5641 // finish_scan_rsp and no management frames are sent in between. No
5642 // callback is needed when going from BMPS enabled to BMPS suspended/
5643 // disabled when it is known that RIVA is awake and cannot enter power
5644 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5645 // init_scan_rsp
5646 if ( cBack )
5647 {
5648 //serialize through Rx thread
5649 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5650 if(NULL == rxCompMsg)
5651 {
5652 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5653 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5654 return eWLAN_PAL_STATUS_E_RESOURCES;
5655 }
5656
5657 /* Event type, where it must be defined???? */
5658 /* THIS MUST BE CLEARED ASAP
5659 txCompMsg->type = TX_COMPLETE; */
5660 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5661 rxCompMsg->pContext = pDxeCtrlBlk;
5662 rxCompMsg->val = hostPowerState;
5663 rxCompMsg->ptr = cBack;
5664 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5665 rxCompMsg);
5666 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5667 {
5668 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5669 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005670 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005671 }
5672 }
5673 else
5674 {
5675 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5676 {
5677 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5678 {
5679 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5680 }
5681 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5682 {
5683 /* Requested Full power from exit IMPS, reenable the interrupts*/
5684 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5685 {
5686 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5687 /* Enable RX interrupt at here, if new PS is not IMPS */
5688 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5689 if(eWLAN_PAL_STATUS_SUCCESS != status)
5690 {
5691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005692 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 return status;
5694 }
5695 }
5696 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5697 {
5698 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005699 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 /* Enable RX interrupt at here, if new PS is not IMPS */
5701 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5702 if(eWLAN_PAL_STATUS_SUCCESS != status)
5703 {
5704 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005705 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 return status;
5707 }
5708 }
5709 }
5710 pDxeCtrlBlk->hostPowerState = hostPowerState;
5711 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5712 }
5713 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5714 {
5715 pDxeCtrlBlk->hostPowerState = hostPowerState;
5716 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5717 }
Mihir Shetea4306052014-03-25 00:02:54 +05305718 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5719 {
5720 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 else
5723 {
5724 HDXE_ASSERT(0);
5725 }
5726 }
5727
5728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005729 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005730
5731 return status;
5732}
5733
5734/*==========================================================================
5735 @ Function Name
5736 WLANDXE_GetFreeTxDataResNumber
5737
5738 @ Description
5739 Returns free descriptor numbers for TX data channel (TX high priority)
5740
5741 @ Parameters
5742 pVoid pDXEContext : DXE Control Block
5743
5744 @ Return
5745 wpt_uint32 Free descriptor number of TX high pri ch
5746===========================================================================*/
5747wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5748(
5749 void *pDXEContext
5750)
5751{
5752 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005753 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005754
5755 if(NULL == pDXEContext)
5756 {
5757 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005758 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 return (0);
5760 }
5761
5762 return
5763 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
5764}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005765
5766/*==========================================================================
5767 @ Function Name
5768 WLANDXE_ChannelDebug
5769
5770 @ Description
5771 Display DXE Channel debugging information
5772 User may request to display DXE channel snapshot
5773 Or if host driver detects any abnormal stcuk may display
5774
5775 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005776 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305777 debugFlags : Enable stall detect features
5778 defined by WPAL_DeviceDebugFlags
5779 These features may effect
5780 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005781
5782 @ Return
5783 NONE
5784
5785===========================================================================*/
5786void WLANDXE_ChannelDebug
5787(
Mihir Shete40a55652014-03-02 14:14:47 +05305788 wpt_boolean displaySnapshot,
5789 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005790)
5791{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005792 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305793 wpt_msg *txDescReSyncMsg ;
Mihir Shete41c41bb2014-08-18 17:37:12 +05305794 wpt_uint32 regValue, regValueLocal = 0;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005795 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5796
5797 /* Debug Type 1, Display current snapshot */
5798 if(displaySnapshot)
5799 {
5800 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5801 * This will not simply wakeup RIVA
5802 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005803 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5804 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005805 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005806 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005807 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
Mihir Shete41c41bb2014-08-18 17:37:12 +05305808#ifdef WCN_PRONTO
5809 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
5810#endif
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005811 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305812 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====",
Leo Chang345ef992013-07-12 10:17:29 -07005813 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305814 tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005815
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005816 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5817 &regValue,
5818 NULL,
5819 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005820
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005821 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5822 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005823 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005824 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5825 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5826 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005827 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005828
5829 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5830 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5831 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005832 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005833 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5834 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005835 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005836 }
5837 }
5838
Mihir Shete40a55652014-03-02 14:14:47 +05305839 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005840 {
Mihir Shete40a55652014-03-02 14:14:47 +05305841 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5842 if(NULL == txDescReSyncMsg)
5843 {
5844 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5845 "%s: Resync MSG MEM alloc Fail",__func__);
5846 }
5847 else
5848 {
5849 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5850 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5851 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5852 txDescReSyncMsg);
5853 if(eWLAN_PAL_STATUS_SUCCESS != status)
5854 {
5855 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5856 "%s: Post TX re-sync MSG fail",__func__);
5857 }
5858 }
5859 }
5860
5861 if(debugFlags & WPAL_DEBUG_START_HEALTH_TIMER)
5862 {
5863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005864 "DXE TX Stall detect");
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005865 /* Start Stall detect timer and detect stall */
5866 wpalTimerStart(&tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].healthMonitorTimer,
5867 T_WLANDXE_PERIODIC_HEALTH_M_TIME);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005868 }
5869 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005870}