blob: e9cbbe0756c154622304526707c444e631d0f8a3 [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"
Jeff Johnson295189b2012-06-20 16:38:30 -070067
68/*----------------------------------------------------------------------------
69 * Local Definitions
70 * -------------------------------------------------------------------------*/
71//#define WLANDXE_DEBUG_CH_INFO_DUMP
72
73/* Temporary configuration defines
74 * Have to find out permanent solution */
75#define T_WLANDXE_MAX_DESCRIPTOR_COUNT 40
76#define T_WLANDXE_MAX_FRAME_SIZE 2000
77#define T_WLANDXE_TX_INT_ENABLE_FCOUNT 1
78#define T_WLANDXE_MEMDUMP_BYTE_PER_LINE 16
79#define T_WLANDXE_MAX_RX_PACKET_WAIT 6000
Mihir Shetefdc9f532014-01-09 15:03:02 +053080#define T_WLANDXE_SSR_TIMEOUT 5000
Leo Chang5edb2d32013-04-03 13:32:58 -070081#define T_WLANDXE_PERIODIC_HEALTH_M_TIME 2500
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -070082#define T_WLANDXE_MAX_HW_ACCESS_WAIT 2000
Jeff Johnsone7245742012-09-05 17:12:55 -070083#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -070084
Leo Chang094ece82013-04-23 17:57:41 -070085#define WLANPAL_RX_INTERRUPT_PRO_MASK 0x20
86#define WLANDXE_RX_INTERRUPT_PRO_UNMASK 0x5F
Leo Chang00708f62013-12-03 20:21:51 -080087
88/* 1msec busy wait in case CSR is not valid */
89#define WLANDXE_CSR_NEXT_READ_WAIT 1000
90/* CSR max retry count */
91#define WLANDXE_CSR_MAX_READ_COUNT 30
92
93
Jeff Johnson295189b2012-06-20 16:38:30 -070094/* This is temporary fot the compile
95 * WDI will release official version
96 * This must be removed */
97#define WDI_GET_PAL_CTX() NULL
98
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -070099
Jeff Johnson295189b2012-06-20 16:38:30 -0700100/*-------------------------------------------------------------------------
101 * Local Varables
102 *-------------------------------------------------------------------------*/
103/* This is temp, someone have to allocate for me, and must be part of global context */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700104static WLANDXE_CtrlBlkType *tempDxeCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -0700105static char *channelType[WDTS_CHANNEL_MAX] =
106 {
107 "TX_LOW_PRI",
108 "TX_HIGH_PRI",
109 "RX_LOW_PRI",
Jeff Johnson295189b2012-06-20 16:38:30 -0700110 "RX_HIGH_PRI",
Mihir Shetebe94ebb2015-05-26 12:07:14 +0530111 "RX_LOGS",
Mihir Shetee6618162015-03-16 14:48:42 +0530112 "RX_FW_LOGS",
Jeff Johnson295189b2012-06-20 16:38:30 -0700113 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700114static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700115
116/*-------------------------------------------------------------------------
117 * External Function Proto Type
118 *-------------------------------------------------------------------------*/
119
120/*-------------------------------------------------------------------------
121 * Local Function Proto Type
122 *-------------------------------------------------------------------------*/
123static wpt_status dxeRXFrameSingleBufferAlloc
124(
125 WLANDXE_CtrlBlkType *dxeCtxt,
126 WLANDXE_ChannelCBType *channelEntry,
127 WLANDXE_DescCtrlBlkType *currentCtrlBlock
128);
129
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700130static wpt_status dxeNotifySmsm
131(
132 wpt_boolean kickDxe,
133 wpt_boolean ringEmpty
134);
135
Mihir Shetefdc9f532014-01-09 15:03:02 +0530136static void dxeStartSSRTimer
137(
138 WLANDXE_CtrlBlkType *dxeCtxt
139);
140
Jeff Johnson295189b2012-06-20 16:38:30 -0700141/*-------------------------------------------------------------------------
142 * Local Function
143 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/*==========================================================================
145 @ Function Name
146 dxeChannelMonitor
147
148 @ Description
149
150 @ Parameters
151 WLANDXE_ChannelCBType *channelEntry
152 Channel specific control block
153
154 @ Return
155 wpt_status
156
157===========================================================================*/
158static wpt_status dxeChannelMonitor
159(
160 char *monitorDescription,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530161 WLANDXE_ChannelCBType *channelEntry,
162 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700163)
164{
165 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
166
Jeff Johnsone7245742012-09-05 17:12:55 -0700167 if((NULL == monitorDescription) || (NULL == channelEntry))
168 {
169 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
170 "INVALID Input ARG");
171 return eWLAN_PAL_STATUS_E_INVAL;
172 }
173
Mihir Shetee6618162015-03-16 14:48:42 +0530174 if(channelEntry->channelType >= WDTS_CHANNEL_MAX)
Jeff Johnsone7245742012-09-05 17:12:55 -0700175 {
176 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
177 "INVALID Channel type");
178 return eWLAN_PAL_STATUS_E_INVAL;
179 }
180
Leo Chang345ef992013-07-12 10:17:29 -0700181 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
182 "%11s : HCBO %d, HCBDP 0x%x, HCBDC 0x%x,",
183 channelType[channelEntry->channelType],
184 channelEntry->headCtrlBlk->ctrlBlkOrder,
185 channelEntry->headCtrlBlk->linkedDescPhyAddr,
186 channelEntry->headCtrlBlk->linkedDesc->descCtrl.ctrl);
187 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
188 "%11s : TCBO %d, TCBDP 0x%x, TCBDC 0x%x",
189 channelType[channelEntry->channelType],
190 channelEntry->tailCtrlBlk->ctrlBlkOrder,
191 channelEntry->tailCtrlBlk->linkedDescPhyAddr,
192 channelEntry->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
193 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
194 "%11s : FDC %d, RDC %d, TFC %d",
195 channelType[channelEntry->channelType],
196 channelEntry->numFreeDesc,
197 channelEntry->numRsvdDesc,
198 channelEntry->numTotalFrame);
Jeff Johnson295189b2012-06-20 16:38:30 -0700199
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700200 if(channelLog)
201 {
202 channelLog->numDesc = channelEntry->numDesc;
203 channelLog->numFreeDesc = channelEntry->numFreeDesc;
204 channelLog->numRsvdDesc = channelEntry->numRsvdDesc;
205 channelLog->headDescOrder = channelEntry->headCtrlBlk->ctrlBlkOrder;
206 channelLog->tailDescOrder = channelEntry->tailCtrlBlk->ctrlBlkOrder;
207 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 return status;
210}
211
Jeff Johnsone7245742012-09-05 17:12:55 -0700212#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700213/*==========================================================================
214 @ Function Name
215 dxeMemoryDump
216
217 @ Description
218
219 @ Parameters
220 WLANDXE_ChannelCBType *channelEntry
221 Channel specific control block
222
223 @ Return
224 wpt_status
225
226===========================================================================*/
227static wpt_status dxeMemoryDump
228(
229 wpt_uint8 *dumpPointer,
230 wpt_uint32 dumpSize,
231 char *dumpTarget
232)
233{
234 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
235 wpt_uint32 numBytes = 0;
236 wpt_uint32 idx;
237
Jeff Johnsone7245742012-09-05 17:12:55 -0700238 if((NULL == dumpPointer) ||
239 (NULL == dumpTarget))
240 {
241 return status;
242 }
243
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
245 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
246 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
247 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
248
249 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
250 for(idx = 0; idx < dumpSize; idx++)
251 {
252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
253 "0x%2x ", dumpPointer[idx]);
254 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
255 {
256 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
257 }
258 }
259 if(0 != numBytes)
260 {
261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
262 }
263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
264 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
265
266 return status;
267}
Jeff Johnsone7245742012-09-05 17:12:55 -0700268#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700269
270/*==========================================================================
271 @ Function Name
272 dxeDescriptorDump
273
274 @ Description
275
276 @ Parameters
277 WLANDXE_ChannelCBType *channelEntry
278 Channel specific control block
279
280 @ Return
281 wpt_status
282
283===========================================================================*/
284wpt_status dxeDescriptorDump
285(
286 WLANDXE_ChannelCBType *channelEntry,
287 WLANDXE_DescType *targetDesc,
288 wpt_uint32 fragmentOrder
289)
290{
291 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
292
293
Jeff Johnsone7245742012-09-05 17:12:55 -0700294 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700295 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700296 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700297 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700299 fragmentOrder + 1,
300 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700301
Jeff Johnsone7245742012-09-05 17:12:55 -0700302 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700303 "CTRL WORD 0x%x, TransferSize %d",
304 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
305 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
308 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
309 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
310 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700311 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
313
314 return status;
315}
316
317/*==========================================================================
318 @ Function Name
319 dxeChannelRegisterDump
320
321 @ Description
322
323 @ Parameters
324 WLANDXE_ChannelCBType *channelEntry
325 Channel specific control block
326
327 @ Return
328 wpt_status
329
330===========================================================================*/
331wpt_status dxeChannelRegisterDump
332(
333 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530334 char *dumpTarget,
335 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700336)
337{
Leo Chang345ef992013-07-12 10:17:29 -0700338 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
339 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
340
341 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
342 * This will not simply wakeup RIVA
343 * Just incase TX not wanted stuck, Trigger TX again */
344 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
345 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
346 wpalSleep(10);
Jeff Johnson295189b2012-06-20 16:38:30 -0700347
Mihir Shetee6618162015-03-16 14:48:42 +0530348 if(channelEntry->channelType >= WDTS_CHANNEL_MAX)
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700349 {
350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
351 "INVALID Channel type");
352 return eWLAN_PAL_STATUS_E_INVAL;
353 }
354
Leo Chang345ef992013-07-12 10:17:29 -0700355 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &chDescReg);
356 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
357 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &chControlReg);
358 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &chStatusReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700359
Leo Chang345ef992013-07-12 10:17:29 -0700360 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
361 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x",
362 channelType[channelEntry->channelType],
363 chControlReg, chStatusReg, chDescReg, chLDescReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700364
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700365 if(channelLog)
366 {
367 channelLog->ctrlRegVal = chControlReg;
368 channelLog->statRegVal = chStatusReg;
369 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700370
Jeff Johnson295189b2012-06-20 16:38:30 -0700371 return status;
372}
Jeff Johnsone7245742012-09-05 17:12:55 -0700373
374/*==========================================================================
375 @ Function Name
376 dxeChannelAllDescDump
377
378 @ Description
379 Dump all DXE descriptors within assigned channe;
380
381 @ Parameters
382 WLANDXE_ChannelCBType *channelEntry
383
384 @ Return
385 NONE
386
387===========================================================================*/
388void dxeChannelAllDescDump
389(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700390 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530391 WDTS_ChannelType channel,
392 wpt_log_data_stall_channel_type *channelLog
Jeff Johnsone7245742012-09-05 17:12:55 -0700393)
394{
395 wpt_uint32 channelLoop;
396 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700397 wpt_uint32 previousCtrlValue = 0;
Leo Chang345ef992013-07-12 10:17:29 -0700398 wpt_uint32 previousCtrlValid = 0;
399 wpt_uint32 currentCtrlValid = 0;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700400 wpt_uint32 valDescCount = 0;
401 wpt_uint32 invalDescCount = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700402
403 targetCtrlBlk = channelEntry->headCtrlBlk;
404
405 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Leo Chang345ef992013-07-12 10:17:29 -0700406 "%11s : %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700407 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700408 channelEntry->numDesc,
409 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700410 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
411
412 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530413 (WDTS_CHANNEL_RX_HIGH_PRI == channel)||
414 (WDTS_CHANNEL_RX_LOG == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700415 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700416 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700417 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700418 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
419 {
420 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
421 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
422 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
423 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700424 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
425 {
426 valDescCount++;
427 }
428 else
429 {
430 invalDescCount++;
431 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700432 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
433 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700434 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700435 }
436 else
437 {
Leo Chang345ef992013-07-12 10:17:29 -0700438 /* Head Descriptor is valid or not */
439 previousCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
440 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700441 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
442 {
Leo Chang345ef992013-07-12 10:17:29 -0700443 currentCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700444 if(currentCtrlValid)
445 {
446 valDescCount++;
447 }
448 else
449 {
450 invalDescCount++;
451 }
Leo Chang345ef992013-07-12 10:17:29 -0700452 if(currentCtrlValid != previousCtrlValid)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700453 {
454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
455 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
456 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
457 }
Leo Chang345ef992013-07-12 10:17:29 -0700458 previousCtrlValid = currentCtrlValid;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700459 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
460 }
461 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530462
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700463 if(channelLog)
464 {
465 channelLog->numValDesc = valDescCount;
466 channelLog->numInvalDesc = invalDescCount;
467 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530468
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700469 return;
470}
471
472/*==========================================================================
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530473 @ Function Name
474 dxeErrChannelDebug
475
476 @ Description
477 Dump channel information for which Error interrupt has occured
478
479 @ Parameters
480 WLANDXE_ChannelCBType *channelCb
481
482 @ Return
483 NONE
484
485===========================================================================*/
486void dxeErrChannelDebug
487(
Mihir Shete79d6b582014-03-12 17:54:07 +0530488 WLANDXE_ChannelCBType *channelCb,
489 wpt_uint32 chStatusReg
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530490)
491{
492 wpt_log_data_stall_channel_type channelLog;
Mihir Shete79d6b582014-03-12 17:54:07 +0530493 wpt_uint32 chLDescReg, channelLoop;
494 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530495
496 dxeChannelMonitor("INT_ERR", channelCb, &channelLog);
497 dxeDescriptorDump(channelCb, channelCb->headCtrlBlk->linkedDesc, 0);
498 dxeChannelRegisterDump(channelCb, "INT_ERR", &channelLog);
499 dxeChannelAllDescDump(channelCb, channelCb->channelType, &channelLog);
500 wpalMemoryCopy(channelLog.channelName,
501 "INT_ERR",
502 WPT_TRPT_CHANNEL_NAME);
503 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelCb->channelType);
504#ifdef FEATURE_WLAN_DIAG_SUPPORT
505 wpalPacketStallDumpLog();
506#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Mihir Shete79d6b582014-03-12 17:54:07 +0530507 switch ((chStatusReg & WLANDXE_CH_STAT_ERR_CODE_MASK) >>
508 WLANDXE_CH_STAT_ERR_CODE_OFFSET)
509 {
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530510
Mihir Shete79d6b582014-03-12 17:54:07 +0530511 case WLANDXE_ERROR_PRG_INV_B2H_SRC_QID:
512 case WLANDXE_ERROR_PRG_INV_B2H_DST_QID:
513 case WLANDXE_ERROR_PRG_INV_B2H_SRC_IDX:
514 case WLANDXE_ERROR_PRG_INV_H2B_SRC_QID:
515 case WLANDXE_ERROR_PRG_INV_H2B_DST_QID:
516 case WLANDXE_ERROR_PRG_INV_H2B_DST_IDX:
517 {
518 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
519 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
520 wpalSleep(10);
521
522 if(channelCb->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
523 {
524 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
525 "%s: Invalid Channel", __func__);
526 break;
527 }
528
529 wpalReadRegister(channelCb->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
530
531 targetCtrlBlk = channelCb->headCtrlBlk;
532
533 for(channelLoop = 0; channelLoop < channelCb->numDesc; channelLoop++)
534 {
535 if (targetCtrlBlk->linkedDescPhyAddr == chLDescReg)
536 {
537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
538 "%11s :CHx_DESCL: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
539 channelType[channelCb->channelType],
540 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
541 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
542 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
543 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
544
545 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
546
547 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
548 "%11s :Next Desc: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
549 channelType[channelCb->channelType],
550 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
551 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
552 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
553 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
554 break;
555 }
556 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
557 }
558 break;
559 }
560 default:
561 {
562 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
563 "%s: No Debug Inormation", __func__);
564 break;
565 }
566
567 }
Siddharth Bhal68115602015-01-18 20:44:55 +0530568 wpalFwDumpReq(17, 0, 0, 0, 0, 0);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530569}
570/*==========================================================================
571 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700572 dxeTxThreadChannelDebugHandler
573
574 @ Description
575 Dump TX channel information
576
577 @ Parameters
578 Wwpt_msg *msgPtr
579
580 @ Return
581 NONE
582
583===========================================================================*/
584void dxeTxThreadChannelDebugHandler
585(
586 wpt_msg *msgPtr
587)
588{
589 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700590 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700591
592 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700593 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700594
595 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
596 * This will not simply wakeup RIVA
597 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700598 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
599 {
600 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530601 &tempDxeCtrlBlk->dxeChannel[channelLoop],
602 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700603 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530604 "Abnormal successive empty interrupt",
605 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700606 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530607 channelLoop,
608 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700609
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700610 wpalMemoryCopy(channelLog.channelName,
611 channelType[channelLoop],
612 WPT_TRPT_CHANNEL_NAME);
613 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700614 }
615
Leo Chang345ef992013-07-12 10:17:29 -0700616 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700617 "================== DXE Dump End ======================");
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700618 wpalMemoryFree(msgPtr);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700619
620#ifdef FEATURE_WLAN_DIAG_SUPPORT
621 wpalPacketStallDumpLog();
622#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700623 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700624 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700625 return;
626}
627
628/*==========================================================================
629 @ Function Name
630 dxeRxThreadChannelDebugHandler
631
632 @ Description
633 Dump RX channel information
634
635 @ Parameters
636 Wwpt_msg *msgPtr
637
638 @ Return
639 NONE
640
641===========================================================================*/
642void dxeRxThreadChannelDebugHandler
643(
644 wpt_msg *msgPtr
645)
646{
647 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
648 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700649 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700650
651 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700652 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700653
654 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
655 * This will not simply wakeup RIVA
656 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700657 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
658 {
Mihir Shetee6618162015-03-16 14:48:42 +0530659 if (!WLANDXE_IS_VALID_CHANNEL(channelLoop))
660 continue;
661
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700662 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530663 &tempDxeCtrlBlk->dxeChannel[channelLoop],
664 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700665 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530666 "Abnormal successive empty interrupt",
667 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700668 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530669 channelLoop, &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700670
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700671 wpalMemoryCopy(channelLog.channelName,
672 channelType[channelLoop],
673 WPT_TRPT_CHANNEL_NAME);
674 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530675
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700676 }
677
678 /* Now serialise the message through Tx thread also to make sure
679 * no register access when RIVA is in powersave */
680 /*Use the same message pointer just change the call back function */
681 msgPtr->callback = dxeTxThreadChannelDebugHandler;
682 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
683 msgPtr);
684 if ( eWLAN_PAL_STATUS_SUCCESS != status )
685 {
686 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700687 "Tx thread state dump req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700688 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700689 }
690
691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700692 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700693 return;
694}
Jeff Johnson295189b2012-06-20 16:38:30 -0700695
696/*==========================================================================
697 @ Function Name
698 dxeCtrlBlkAlloc
699
700 @ Description
701 Allocate DXE Control block
702 DXE control block will used by Host DXE driver only, internal structure
703 Will make ring linked list
704
705 @ Parameters
706 WLANDXE_CtrlBlkType *dxeCtrlBlk,
707 DXE host driver main control block
708 WLANDXE_ChannelCBType *channelEntry
709 Channel specific control block
710
711 @ Return
712 wpt_status
713
714===========================================================================*/
715static wpt_status dxeCtrlBlkAlloc
716(
717 WLANDXE_CtrlBlkType *dxeCtrlBlk,
718 WLANDXE_ChannelCBType *channelEntry
719)
720{
721 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
722 unsigned int idx, fIdx;
723 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
724 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
725 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
726 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
727
728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700729 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700730
731 /* Sanity check */
732 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
733 {
734 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
735 "dxeCtrlBlkAlloc Channel Entry is not valid");
736 return eWLAN_PAL_STATUS_E_INVAL;
737 }
738
739 /* Allocate pre asigned number of control blocks */
740 for(idx = 0; idx < channelEntry->numDesc; idx++)
741 {
742 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
743 if(NULL == currentCtrlBlk)
744 {
745 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
746 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
747 channelEntry->channelType);
748 freeCtrlBlk = channelEntry->headCtrlBlk;
749 for(fIdx = 0; fIdx < idx; fIdx++)
750 {
751 if(NULL == freeCtrlBlk)
752 {
753 break;
754 }
755
756 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
757 wpalMemoryFree((void *)freeCtrlBlk);
758 freeCtrlBlk = nextCtrlBlk;
759 }
760 return eWLAN_PAL_STATUS_E_FAULT;
761 }
762
763 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
764 /* Initialize common elements first */
765 currentCtrlBlk->xfrFrame = NULL;
766 currentCtrlBlk->linkedDesc = NULL;
767 currentCtrlBlk->linkedDescPhyAddr = 0;
768 currentCtrlBlk->ctrlBlkOrder = idx;
769
770 /* This is the first control block allocated
771 * Next Control block is not allocated yet
772 * head and tail must be first control block */
773 if(0 == idx)
774 {
775 currentCtrlBlk->nextCtrlBlk = NULL;
776 channelEntry->headCtrlBlk = currentCtrlBlk;
777 channelEntry->tailCtrlBlk = currentCtrlBlk;
778 }
779 /* This is not first, not last control block
780 * previous control block may has next linked block */
781 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
782 {
783 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
784 }
785 /* This is last control blocl
786 * next control block for the last control block is head, first control block
787 * then whole linked list made RING */
788 else if((channelEntry->numDesc - 1) == idx)
789 {
790 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
791 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
792 }
793 else
794 {
795 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
796 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
797 channelEntry->channelType);
798 wpalMemoryFree(currentCtrlBlk);
799 return eWLAN_PAL_STATUS_E_FAULT;
800 }
801
802 prevCtrlBlk = currentCtrlBlk;
803 channelEntry->numFreeDesc++;
804 }
805
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700806 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700807 return status;
808}
809
810/*==========================================================================
811 @ Function Name
812 dxeDescLinkAlloc
813
814 @ Description
815 Allocate DXE descriptor
816 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
817 Will make RING linked list
818 Will be linked with Descriptor control block one by one
819
820 @ Parameters
821 WLANDXE_CtrlBlkType *dxeCtrlBlk,
822 DXE host driver main control block
823 WLANDXE_ChannelCBType *channelEntry
824 Channel specific control block
825 @ Return
826 wpt_status
827
828===========================================================================*/
829static wpt_status dxeDescAllocAndLink
830(
831 WLANDXE_CtrlBlkType *dxeCtrlBlk,
832 WLANDXE_ChannelCBType *channelEntry
833)
834{
835 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
836 WLANDXE_DescType *currentDesc = NULL;
837 WLANDXE_DescType *prevDesc = NULL;
838 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
839 unsigned int idx;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530840 void *physAddressAlloc = NULL;
841 wpt_uint32 physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700842
843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700844 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700845
846 /* Sanity Check */
847 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
848 {
849 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
850 "dxeDescLinkAlloc Channel Entry is not valid");
851 return eWLAN_PAL_STATUS_E_INVAL;
852 }
853
854 currentCtrlBlk = channelEntry->headCtrlBlk;
855
Jeff Johnson295189b2012-06-20 16:38:30 -0700856 /* allocate all DXE descriptors for this channel in one chunk */
857 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
858 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530859 &physAddressAlloc);
860 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 if(NULL == channelEntry->descriptorAllocation)
862 {
863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
864 "dxeDescLinkAlloc Descriptor Alloc Fail");
865 return eWLAN_PAL_STATUS_E_RESOURCES;
866 }
867 currentDesc = channelEntry->descriptorAllocation;
Jeff Johnson295189b2012-06-20 16:38:30 -0700868
869 /* Allocate pre asigned number of descriptor */
870 for(idx = 0; idx < channelEntry->numDesc; idx++)
871 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700872 // descriptors were allocated in a chunk -- use the current one
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 if(NULL == currentDesc)
874 {
875 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
876 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
877 channelEntry->channelType);
878 return eWLAN_PAL_STATUS_E_FAULT;
879 }
Mihir Shete96cd1902015-03-04 15:47:31 +0530880 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
881 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
882 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700883
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 currentCtrlBlk->linkedDesc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530885 currentCtrlBlk->linkedDescPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700886 /* First descriptor, next none
887 * descriptor bottom location is first descriptor address */
888 if(0 == idx)
889 {
890 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
891 channelEntry->DescBottomLoc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530892 channelEntry->descBottomLocPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700893 }
894 /* Not first, not last descriptor
895 * may make link for previous descriptor with current descriptor
896 * ENDIAN SWAP needed ????? */
897 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
898 {
899 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530900 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 }
902 /* Last descriptor
903 * make a ring by asign next pointer as first descriptor
904 * ENDIAN SWAP NEEDED ??? */
905 else if((channelEntry->numDesc - 1) == idx)
906 {
907 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530908 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700909 currentDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530910 WLANDXE_U32_SWAP_ENDIAN(channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700911 }
912
913 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
914 * Pre allocated and physical address must be assigned into
915 * Corresponding DXE Descriptor */
Jeff Johnson295189b2012-06-20 16:38:30 -0700916 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530917 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
918 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -0700919 {
920 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
921 channelEntry,
922 currentCtrlBlk);
923 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
924 {
925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
926 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
927 channelEntry->channelType);
928 return status;
929 }
930 --channelEntry->numFreeDesc;
931 }
932
Leo Chang7e05f212013-07-01 19:54:15 -0700933 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
934 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
935 {
936 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
937 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
938 }
939 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530940 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
941 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Leo Chang7e05f212013-07-01 19:54:15 -0700942 {
943 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
944 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
945 }
946 else
947 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +0530948 /* Just in case. H2H RX channel, do nothing
Leo Chang7e05f212013-07-01 19:54:15 -0700949 * By Definition this must not happen */
950 }
951
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
953 prevDesc = currentDesc;
954
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 // advance to the next pre-allocated descriptor in the chunk
956 currentDesc++;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530957 physAddress = (physAddress + sizeof(WLANDXE_DescType));
Jeff Johnson295189b2012-06-20 16:38:30 -0700958 }
959
960 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700961 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 return status;
963}
964
965/*==========================================================================
966 @ Function Name
967
968 @ Description
969
970 @ Parameters
971
972 @ Return
973 wpt_status
974
975===========================================================================*/
976static wpt_status dxeSetInterruptPath
977(
978 WLANDXE_CtrlBlkType *dxeCtrlBlk
979)
980{
981 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
982 wpt_uint32 interruptPath = 0;
983 wpt_uint32 idx;
984 WLANDXE_ChannelCBType *channelEntry = NULL;
985
986 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700987 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700988
Mihir Shetee6618162015-03-16 14:48:42 +0530989 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -0700990 {
991 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
993 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 {
995 interruptPath |= (1 << channelEntry->assignedDMAChannel);
996 }
997 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530998 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
Mihir Shetec4093f92015-05-28 15:21:11 +0530999 (WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301000 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001001 {
1002 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1003 }
1004 else
1005 {
1006 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1007 "H2H TEST RX???? %d", channelEntry->channelType);
1008 }
1009 }
1010 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1011 "Interrupt Path Must be 0x%x", interruptPath);
1012 dxeCtrlBlk->interruptPath = interruptPath;
1013 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1014
1015 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001016 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001017 return status;
1018}
1019
1020/*==========================================================================
1021 @ Function Name
1022 dxeEngineCoreStart
1023
1024 @ Description
1025 Trigger to start RIVA DXE Hardware
1026
1027 @ Parameters
1028 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1029 DXE host driver main control block
1030
1031 @ Return
1032 wpt_status
1033
1034===========================================================================*/
1035static wpt_status dxeEngineCoreStart
1036(
1037 WLANDXE_CtrlBlkType *dxeCtrlBlk
1038)
1039{
1040 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1041 wpt_uint32 registerData = 0;
Leo Chang00708f62013-12-03 20:21:51 -08001042 wpt_uint8 readRetry;
Jeff Johnson295189b2012-06-20 16:38:30 -07001043
1044 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001045 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001046
Leo Chang00708f62013-12-03 20:21:51 -08001047#ifdef WCN_PRONTO
1048 /* Read default */
1049 wpalReadRegister(WLANDXE_CCU_SOFT_RESET, &registerData);
1050 registerData |= WLANDXE_DMA_CCU_DXE_RESET_MASK;
1051
1052 /* Make reset */
1053 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1054
1055 /* Clear reset */
1056 registerData &= ~WLANDXE_DMA_CCU_DXE_RESET_MASK;
1057 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1058#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001059 /* START This core init is not needed for the integrated system */
1060 /* Reset First */
1061 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1062 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1063 registerData);
Leo Chang00708f62013-12-03 20:21:51 -08001064#endif /* WCN_PRONTO */
Jeff Johnson295189b2012-06-20 16:38:30 -07001065
Leo Chang00708f62013-12-03 20:21:51 -08001066 for(readRetry = 0; readRetry < WLANDXE_CSR_MAX_READ_COUNT; readRetry++)
1067 {
1068 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1069 WLANDXE_CSR_DEFAULT_ENABLE);
1070 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &registerData);
1071 if(!(registerData & WLANDXE_DMA_CSR_EN_MASK))
1072 {
1073 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1074 "%s CSR 0x%x, count %d",
1075 __func__, registerData, readRetry);
1076 /* CSR is not valid value, re-try to write */
1077 wpalBusyWait(WLANDXE_CSR_NEXT_READ_WAIT);
1078 }
1079 else
1080 {
1081 break;
1082 }
1083 }
1084 if(WLANDXE_CSR_MAX_READ_COUNT == readRetry)
1085 {
1086 /* MAX wait, still cannot write correct value
1087 * Panic device */
1088 wpalDevicePanic();
1089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001090
1091 /* Is This needed?
1092 * Not sure, revisit with integrated system */
1093 /* END This core init is not needed for the integrated system */
1094
1095 dxeSetInterruptPath(dxeCtrlBlk);
1096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001097 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001098 return status;
1099}
1100
1101/*==========================================================================
1102 @ Function Name
1103 dxeChannelInitProgram
1104
1105 @ Description
1106 Program RIVA DXE engine register with initial value
1107 What must be programmed
1108 - Source Address (SADRL, chDXESadrlRegAddr)
1109 - Destination address (DADRL, chDXEDadrlRegAddr)
1110 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1111 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1112
1113 Not need to program now
1114 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1115 TX : Have to program to trigger send out frame
1116 RX : programmed by DXE engine
1117
1118 @ Parameters
1119 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1120 DXE host driver main control block
1121 WLANDXE_ChannelCBType *channelEntry
1122 Channel specific control block
1123 @ Return
1124 wpt_status
1125
1126===========================================================================*/
1127static wpt_status dxeChannelInitProgram
1128(
1129 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1130 WLANDXE_ChannelCBType *channelEntry
1131)
1132{
1133 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1134 wpt_uint32 idx;
1135 WLANDXE_DescType *currentDesc = NULL;
1136 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1137
1138 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001139 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001140
1141 /* Sanity Check */
1142 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1143 {
1144 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1145 "dxeChannelInitProgram Channel Entry is not valid");
1146 return eWLAN_PAL_STATUS_E_INVAL;
1147 }
1148
1149 /* Program Source address and destination adderss */
1150 if(!channelEntry->channelConfig.useShortDescFmt)
1151 {
1152 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1153 "dxeChannelInitProgram Long Descriptor not support yet");
1154 return eWLAN_PAL_STATUS_E_FAILURE;
1155 }
1156
1157 /* Common register area */
1158 /* Next linked list Descriptor pointer */
1159 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1160 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1161 if(eWLAN_PAL_STATUS_SUCCESS != status)
1162 {
1163 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1164 "dxeChannelInitProgram Write DESC Address register fail");
1165 return status;
1166 }
1167
1168 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1169 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1170 {
1171 /* Program default registers */
1172 /* TX DMA channel, DMA destination address is work Q */
1173 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1174 channelEntry->channelConfig.refWQ);
1175 if(eWLAN_PAL_STATUS_SUCCESS != status)
1176 {
1177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1178 "dxeChannelInitProgram Write TX DAddress register fail");
1179 return status;
1180 }
1181 }
1182 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301183 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1184 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001185 {
1186 /* Initialize Descriptor control Word First */
1187 currentCtrlBlk = channelEntry->headCtrlBlk;
1188 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1189 {
1190 currentDesc = currentCtrlBlk->linkedDesc;
1191 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1192 }
1193
1194 /* RX DMA channel, DMA source address is work Q */
1195 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1196 channelEntry->channelConfig.refWQ);
1197 if(eWLAN_PAL_STATUS_SUCCESS != status)
1198 {
1199 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1200 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1201 return status;
1202 }
1203
1204 /* RX DMA channel, Program pre allocated destination Address */
1205 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1206 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1207 if(eWLAN_PAL_STATUS_SUCCESS != status)
1208 {
1209 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1210 "dxeChannelInitProgram Write RX DAddress register fail");
1211 return status;
1212 }
1213
1214 /* RX Channels, default Control registers MUST BE ENABLED */
1215 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1216 channelEntry->extraConfig.chan_mask);
1217 if(eWLAN_PAL_STATUS_SUCCESS != status)
1218 {
1219 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1220 "dxeChannelInitProgram Write RX Control register fail");
1221 return status;
1222 }
1223 }
1224 else
1225 {
1226 /* H2H test channel, not use work Q */
Jeff Johnson295189b2012-06-20 16:38:30 -07001227 }
1228
1229 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001230 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001231 return status;
1232}
1233
1234
1235/*==========================================================================
1236 @ Function Name
1237 dxeChannelStart
1238
1239 @ Description
1240 Start Specific Channel
1241
1242 @ Parameters
1243 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1244 DXE host driver main control block
1245 WLANDXE_ChannelCBType *channelEntry
1246 Channel specific control block
1247
1248 @ Return
1249 wpt_status
1250
1251===========================================================================*/
1252static wpt_status dxeChannelStart
1253(
1254 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1255 WLANDXE_ChannelCBType *channelEntry
1256)
1257{
1258 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1259 wpt_uint32 regValue = 0;
1260 wpt_uint32 intMaskVal = 0;
1261
1262 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001263 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001264
1265 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1266 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1267
1268 /* Enable individual channel
1269 * not to break current channel setup, first read register */
1270 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1271 &regValue);
1272 if(eWLAN_PAL_STATUS_SUCCESS != status)
1273 {
1274 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1275 "dxeChannelStart Read Channel Enable register fail");
1276 return status;
1277 }
1278
1279 /* Enable Channel specific Interrupt */
1280 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1281 &intMaskVal);
1282 if(eWLAN_PAL_STATUS_SUCCESS != status)
1283 {
1284 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1285 "dxeChannelStart Read INT_MASK register fail");
1286 return status;
1287 }
1288 intMaskVal |= channelEntry->extraConfig.intMask;
1289 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1290 intMaskVal);
1291 if(eWLAN_PAL_STATUS_SUCCESS != status)
1292 {
1293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1294 "dxeChannelStart Write INT_MASK register fail");
1295 return status;
1296 }
1297
1298 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001299 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 return status;
1301}
1302
1303/*==========================================================================
1304 @ Function Name
1305 dxeChannelStop
1306
1307 @ Description
1308 Stop Specific Channel
1309
1310 @ Parameters
1311 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1312 DXE host driver main control block
1313 WLANDXE_ChannelCBType *channelEntry
1314 Channel specific control block
1315
1316 @ Return
1317 wpt_status
1318
1319===========================================================================*/
1320static wpt_status dxeChannelStop
1321(
1322 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1323 WLANDXE_ChannelCBType *channelEntry
1324)
1325{
1326 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1327 wpt_uint32 intMaskVal = 0;
1328
1329 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001330 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001331
1332 /* Sanity */
1333 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1334 {
1335 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1336 "dxeChannelStop Invalid arg input");
1337 return eWLAN_PAL_STATUS_E_INVAL;
1338 }
1339
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001340 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1341 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1342 {
1343 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1344 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001345 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001346 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001347 /* Maskout interrupt */
1348 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1349 &intMaskVal);
1350 if(eWLAN_PAL_STATUS_SUCCESS != status)
1351 {
1352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1353 "dxeChannelStop Read INT_MASK register fail");
1354 return status;
1355 }
1356 intMaskVal ^= channelEntry->extraConfig.intMask;
1357 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1358 intMaskVal);
1359 if(eWLAN_PAL_STATUS_SUCCESS != status)
1360 {
1361 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1362 "dxeChannelStop Write INT_MASK register fail");
1363 return status;
1364 }
1365
1366 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1367
1368 /* Stop Channel ??? */
1369 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001370 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001371 return status;
1372}
1373
1374/*==========================================================================
1375 @ Function Name
1376 dxeChannelClose
1377
1378 @ Description
1379 Close Specific Channel
1380 Free pre allocated RX frame buffer if RX channel
1381 Free DXE descriptor for each channel
1382 Free Descriptor control block for each channel
1383
1384 @ Parameters
1385 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1386 DXE host driver main control block
1387 WLANDXE_ChannelCBType *channelEntry
1388 Channel specific control block
1389
1390 @ Return
1391 wpt_status
1392
1393===========================================================================*/
1394static wpt_status dxeChannelClose
1395(
1396 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1397 WLANDXE_ChannelCBType *channelEntry
1398)
1399{
1400 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1401 wpt_uint32 idx;
1402 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1403 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1404 WLANDXE_DescType *currentDescriptor = NULL;
1405 WLANDXE_DescType *nextDescriptor = NULL;
1406
1407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001408 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001409
1410 /* Sanity */
1411 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1412 {
1413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1414 "dxeChannelStop Invalid arg input");
1415 return eWLAN_PAL_STATUS_E_INVAL;
1416 }
1417
1418 currentCtrlBlk = channelEntry->headCtrlBlk;
1419 if(NULL != currentCtrlBlk)
1420 {
1421 currentDescriptor = currentCtrlBlk->linkedDesc;
1422 for(idx = 0; idx < channelEntry->numDesc; idx++)
1423 {
1424 if (idx + 1 != channelEntry->numDesc)
1425 {
1426 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1427 nextDescriptor = nextCtrlBlk->linkedDesc;
1428 }
1429 else
1430 {
1431 nextCtrlBlk = NULL;
1432 nextDescriptor = NULL;
1433 }
1434 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301435 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1436 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 {
1438 if (NULL != currentCtrlBlk->xfrFrame)
1439 {
1440 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1441 wpalPacketFree(currentCtrlBlk->xfrFrame);
1442 }
1443 }
1444 /*
1445 * It is the responsibility of DXE to walk through the
1446 * descriptor chain and unlock any pending packets (if
1447 * locked).
1448 */
1449 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1450 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1451 {
1452 if((NULL != currentCtrlBlk->xfrFrame) &&
1453 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1454 {
1455 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1456 wpalPacketFree(currentCtrlBlk->xfrFrame);
1457 }
1458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001459 wpalMemoryFree(currentCtrlBlk);
1460
1461 currentCtrlBlk = nextCtrlBlk;
1462 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001463 if(NULL == currentCtrlBlk)
1464 {
1465 /* Already reach last of the control block
1466 * Not need to process anymore, break */
1467 break;
1468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001469 }
1470 }
1471
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 // descriptors were allocated as a single chunk so free the chunk
1473 if(NULL != channelEntry->descriptorAllocation)
1474 {
1475 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001477
1478 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001479 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001480 return status;
1481}
1482
1483/*==========================================================================
1484 @ Function Name
1485 dxeChannelCleanInt
1486
1487 @ Description
1488 Clean up interrupt from RIVA HW
1489 After Host finish to handle interrupt, interrupt signal must be cleaned up
1490 Otherwise next interrupt will not be generated
1491
1492 @ Parameters
1493 WLANDXE_ChannelCBType *channelEntry
1494 Channel specific control block
1495 wpt_uint32 *chStat
1496 Channel Status register value
1497
1498 @ Return
1499 wpt_status
1500
1501===========================================================================*/
1502static wpt_status dxeChannelCleanInt
1503(
1504 WLANDXE_ChannelCBType *channelEntry,
1505 wpt_uint32 *chStat
1506)
1507{
1508 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1509
1510 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001511 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001512
1513 /* Read Channel Status Register to know why INT Happen */
1514 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1515 chStat);
1516 if(eWLAN_PAL_STATUS_SUCCESS != status)
1517 {
1518 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1519 "dxeChannelCleanInt Read CH STAT register fail");
1520 return eWLAN_PAL_STATUS_E_FAULT;
1521 }
1522 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1523 "%s Channel INT Clean, Status 0x%x",
1524 channelType[channelEntry->channelType], *chStat);
1525
1526 /* Clean up all the INT within this channel */
1527 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1528 (1 << channelEntry->assignedDMAChannel));
1529 if(eWLAN_PAL_STATUS_SUCCESS != status)
1530 {
1531 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1532 "dxeChannelCleanInt Write CH Clean register fail");
1533 return eWLAN_PAL_STATUS_E_FAULT;
1534 }
1535
Jeff Johnsone7245742012-09-05 17:12:55 -07001536 /* Clean up Error INT Bit */
1537 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1538 {
1539 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1540 (1 << channelEntry->assignedDMAChannel));
1541 if(eWLAN_PAL_STATUS_SUCCESS != status)
1542 {
1543 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1544 "dxeChannelCleanInt Read CH STAT register fail");
1545 return eWLAN_PAL_STATUS_E_FAULT;
1546 }
1547 }
1548
1549 /* Clean up DONE INT Bit */
1550 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1551 {
1552 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1553 (1 << channelEntry->assignedDMAChannel));
1554 if(eWLAN_PAL_STATUS_SUCCESS != status)
1555 {
1556 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1557 "dxeChannelCleanInt Read CH STAT register fail");
1558 return eWLAN_PAL_STATUS_E_FAULT;
1559 }
1560 }
1561
1562 /* Clean up ED INT Bit */
1563 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1564 {
1565 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1566 (1 << channelEntry->assignedDMAChannel));
1567 if(eWLAN_PAL_STATUS_SUCCESS != status)
1568 {
1569 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1570 "dxeChannelCleanInt Read CH STAT register fail");
1571 return eWLAN_PAL_STATUS_E_FAULT;
1572 }
1573 }
1574
Jeff Johnson295189b2012-06-20 16:38:30 -07001575 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001576 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001577 return status;
1578}
1579
Mihir Shete44547fb2014-03-10 14:15:42 +05301580#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Jeff Johnson295189b2012-06-20 16:38:30 -07001581/*==========================================================================
Leo Chang72cdfd32013-10-17 20:36:30 -07001582 @ Function Name
1583 dxeRXResourceAvailableTimerExpHandler
1584
1585 @ Description
1586 During pre-set timeperiod, if free available RX buffer is not allocated
1587 Trigger Driver re-loading to recover RX dead end
1588
1589 @ Parameters
1590 v_VOID_t *usrData
1591 DXE context
1592
1593 @ Return
1594 NONE
1595
1596===========================================================================*/
1597void dxeRXResourceAvailableTimerExpHandler
1598(
1599 void *usrData
1600)
1601{
Katya Nigam93888ff2014-02-10 17:58:11 +05301602 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Mihir Shete058fcff2014-06-26 18:54:06 +05301603 wpt_uint32 numRxFreePackets;
Mihir Sheted183cef2014-09-26 19:17:56 +05301604 wpt_uint32 numAllocFailures;
Katya Nigam93888ff2014-02-10 17:58:11 +05301605
1606 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1607
Leo Chang72cdfd32013-10-17 20:36:30 -07001608 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1609 "RX Low resource, Durign wait time period %d, RX resource not allocated",
Katya Nigama6fbf662015-03-17 18:35:47 +05301610 wpalGetDxeReplenishRXTimerVal());
Katya Nigam93888ff2014-02-10 17:58:11 +05301611
Mihir Shete058fcff2014-06-26 18:54:06 +05301612 //This API wil also try to replenish packets
1613 wpalGetNumRxFreePacket(&numRxFreePackets);
Mihir Sheted183cef2014-09-26 19:17:56 +05301614 wpalGetNumRxPacketAllocFailures(&numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301615
Mihir Sheted183cef2014-09-26 19:17:56 +05301616 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1617 "Free Packets: %u, Alloc Failures: %u",
1618 numRxFreePackets, numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301619 if (numRxFreePackets > 0)
1620 {
1621 /* If no. of free packets is greater than 0, it means
1622 * that some packets were replenished and can be used
1623 * by DXE to receive frames. So try to restart the
1624 * resourceAvailable timer here, it will be stopped
1625 * by the DXE's low resource callback if atleast one
1626 * free packet reaches DXE.
1627 */
1628 if (NULL != dxeCtxt)
1629 {
1630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1631 "%s: Replenish successful. Restart the Rx Low resource timer",
1632 __func__);
1633 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301634 wpalGetDxeReplenishRXTimerVal());
Mihir Shete058fcff2014-06-26 18:54:06 +05301635 return;
1636 }
1637 }
Katya Nigama6fbf662015-03-17 18:35:47 +05301638 if(wpalIsDxeSSREnable())
1639 {
1640 if (NULL != dxeCtxt)
1641 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
Mihir Shete058fcff2014-06-26 18:54:06 +05301642
Katya Nigama6fbf662015-03-17 18:35:47 +05301643 wpalWlanReload();
Katya Nigam93888ff2014-02-10 17:58:11 +05301644
Katya Nigama6fbf662015-03-17 18:35:47 +05301645 if (NULL != usrData)
1646 dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
1647 }
1648 else
1649 {
1650 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
1651 wpalGetDxeReplenishRXTimerVal());
1652 }
Mihir Shetefdc9f532014-01-09 15:03:02 +05301653 return;
1654}
Mihir Shete44547fb2014-03-10 14:15:42 +05301655#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05301656
1657/*==========================================================================
1658 @ Function Name
1659 dxeStartSSRTimer
1660
1661 @ Description
1662 Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip,
1663 this makes sure that if the chip does not respond to the FIQ within
1664 the timeout period the dxeSSRTimer expiration handler will take the
1665 appropriate action.
1666
1667 @ Parameters
1668 NONE
1669
1670 @ Return
1671 NONE
1672
1673===========================================================================*/
1674static void dxeStartSSRTimer
1675(
1676 WLANDXE_CtrlBlkType *dxeCtxt
1677)
1678{
1679 if(VOS_TIMER_STATE_RUNNING !=
1680 wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer))
1681 {
1682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1683 "%s: Starting SSR Timer",__func__);
1684 wpalTimerStart(&dxeCtxt->dxeSSRTimer,
1685 T_WLANDXE_SSR_TIMEOUT);
1686 }
1687}
1688
1689/*==========================================================================
1690 @ Function Name
1691 dxeSSRTimerExpHandler
1692
1693 @ Description
1694 Issue an explicit subsystem restart of the wcnss subsystem if the
1695 WCN chip does not respond to the FIQ within the timeout period
1696
1697 @ Parameters
1698 v_VOID_t *usrData
1699
1700 @ Return
1701 NONE
1702
1703===========================================================================*/
1704void dxeSSRTimerExpHandler
1705(
1706 void *usrData
1707)
1708{
1709 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1710 "DXE not shutdown %d ms after FIQ!! Issue SSR",
1711 T_WLANDXE_SSR_TIMEOUT);
1712 wpalRivaSubystemRestart();
1713
Leo Chang72cdfd32013-10-17 20:36:30 -07001714 return;
1715}
1716
1717/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001718 @ Function Name
1719 dxeRXPacketAvailableCB
1720
1721 @ Description
1722 If RX frame handler encounts RX buffer pool empty condition,
1723 DXE RX handle loop will be blocked till get available RX buffer pool.
1724 When new RX buffer pool available, Packet available CB function will
1725 be called.
1726
1727 @ Parameters
1728 wpt_packet *freePacket
1729 Newly allocated RX buffer
1730 v_VOID_t *usrData
1731 DXE context
1732
1733 @ Return
1734 NONE
1735
1736===========================================================================*/
1737void dxeRXPacketAvailableCB
1738(
1739 wpt_packet *freePacket,
1740 v_VOID_t *usrData
1741)
1742{
1743 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1744 wpt_status status;
1745
1746 /* Simple Sanity */
1747 if((NULL == freePacket) || (NULL == usrData))
1748 {
1749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1750 "Get Free RX Buffer fail, Critical Error");
1751 HDXE_ASSERT(0);
1752 return;
1753 }
1754
1755 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1756
1757 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1758 {
1759 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1760 "DXE Context data corrupted, Critical Error");
1761 HDXE_ASSERT(0);
1762 return;
1763 }
1764
1765 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1766 "DXE RX packet available, post MSG to RX Thread");
1767
1768 dxeCtxt->freeRXPacket = freePacket;
1769
1770 /* Serialize RX Packet Available message upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08001771 if (NULL == dxeCtxt->rxPktAvailMsg)
1772 {
1773 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1774 "DXE NULL pkt");
1775 HDXE_ASSERT(0);
1776 return;
1777 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001778
1779 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1780 dxeCtxt->rxPktAvailMsg);
1781 if(eWLAN_PAL_STATUS_SUCCESS != status)
1782 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001783 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1784 "dxeRXPacketAvailableCB serialize fail");
1785 }
1786
1787 return;
1788}
1789
1790/*==========================================================================
1791 @ Function Name
1792 dxeRXFrameSingleBufferAlloc
1793
1794 @ Description
1795 Allocate Platform packet buffer to prepare RX frame
1796 RX frame memory space must be pre allocted and must be asigned to
1797 descriptor
1798 then whenever DMA engine want to tranfer frame from BMU,
1799 buffer must be ready
1800
1801 @ Parameters
1802 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1803 DXE host driver main control block
1804 WLANDXE_ChannelCBType *channelEntry
1805 Channel specific control block
1806 WLANDXE_DescCtrlBlkType currentCtrlBlock
1807 current control block which have to be asigned
1808 frame buffer
1809
1810 @ Return
1811 wpt_status
1812
1813===========================================================================*/
1814static wpt_status dxeRXFrameSingleBufferAlloc
1815(
1816 WLANDXE_CtrlBlkType *dxeCtxt,
1817 WLANDXE_ChannelCBType *channelEntry,
1818 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1819)
1820{
1821 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1822 wpt_packet *currentPalPacketBuffer = NULL;
1823 WLANDXE_DescType *currentDesc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001824 wpt_iterator iterator;
1825 wpt_uint32 allocatedSize = 0;
1826 void *physAddress = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001827
1828 currentDesc = currentCtrlBlock->linkedDesc;
1829
Leo Chang7e05f212013-07-01 19:54:15 -07001830 if(currentDesc->descCtrl.valid)
1831 {
1832 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1833 "This Descriptor is valid, Do not refill");
1834 return eWLAN_PAL_STATUS_E_EXISTS;
1835 }
1836
Jeff Johnson295189b2012-06-20 16:38:30 -07001837 /* First check if a packet pointer has already been provided by a previously
1838 invoked Rx packet available callback. If so use that packet. */
1839 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1840 {
1841 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1842 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1843 dxeCtxt->freeRXPacket = NULL;
Mihir Sheted183cef2014-09-26 19:17:56 +05301844
1845 if (channelEntry->doneIntDisabled)
1846 {
1847 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1848 channelEntry->extraConfig.chan_mask);
1849 channelEntry->doneIntDisabled = 0;
1850 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001851 }
1852 else if(!dxeCtxt->rxPalPacketUnavailable)
1853 {
Leo Chang72cdfd32013-10-17 20:36:30 -07001854 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1855 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
Jeff Johnson295189b2012-06-20 16:38:30 -07001856 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1857 dxeRXPacketAvailableCB,
1858 (void *)dxeCtxt);
1859
1860 if(NULL == currentPalPacketBuffer)
1861 {
1862 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
Mihir Shete44547fb2014-03-10 14:15:42 +05301863#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07001864 /* Out of RX free buffer,
1865 * Start timer to recover from RX dead end */
1866 if(VOS_TIMER_STATE_RUNNING !=
1867 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
1868 {
1869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1870 "RX Low resource, wait available resource");
1871 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301872 wpalGetDxeReplenishRXTimerVal());
Leo Chang72cdfd32013-10-17 20:36:30 -07001873 }
Mihir Shete44547fb2014-03-10 14:15:42 +05301874#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 }
1876 }
1877
1878 if(NULL == currentPalPacketBuffer)
1879 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001880 return eWLAN_PAL_STATUS_E_RESOURCES;
1881 }
1882
1883 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1884 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1885 currentPalPacketBuffer->pBD = NULL;
1886 currentPalPacketBuffer->pBDPhys = NULL;
1887 currentPalPacketBuffer->BDLength = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
Mihir Shetebc338242015-03-04 15:34:19 +05301889
Jeff Johnson295189b2012-06-20 16:38:30 -07001890 if(eWLAN_PAL_STATUS_SUCCESS != status)
1891 {
1892 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1893 "dxeRXFrameBufferAlloc unable to lock packet");
1894 return status;
1895 }
1896
1897 /* Init iterator to get physical os buffer address */
1898 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1899 if(eWLAN_PAL_STATUS_SUCCESS != status)
1900 {
1901 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1902 "dxeRXFrameBufferAlloc iterator init fail");
1903 return status;
1904 }
1905 status = wpalIteratorNext(&iterator,
1906 currentPalPacketBuffer,
1907 &physAddress,
1908 &allocatedSize);
1909 if(eWLAN_PAL_STATUS_SUCCESS != status)
1910 {
1911 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1912 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1913 return status;
1914 }
1915 currentPalPacketBuffer->pBDPhys = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07001916
1917 /* DXE descriptor must have SWAPPED addres in it's structure
1918 * !!! SWAPPED !!! */
1919 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301920 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07001921
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 return status;
1923}
1924
1925/*==========================================================================
1926 @ Function Name
1927 dxeRXFrameRefillRing
1928
1929 @ Description
1930 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1931
1932 @ Parameters
1933 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1934 DXE host driver main control block
1935 WLANDXE_ChannelCBType *channelEntry
1936 Channel specific control block
1937
1938 @ Return
1939 wpt_status
1940
1941===========================================================================*/
1942static wpt_status dxeRXFrameRefillRing
1943(
1944 WLANDXE_CtrlBlkType *dxeCtxt,
1945 WLANDXE_ChannelCBType *channelEntry
1946)
1947{
1948 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1949 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
1950 WLANDXE_DescType *currentDesc = NULL;
1951
1952 while(channelEntry->numFreeDesc > 0)
1953 {
1954 /* Current Control block is free
1955 * and associated frame buffer is not linked with control block anymore
1956 * allocate new frame buffer for current control block */
1957 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
1958 channelEntry,
1959 currentCtrlBlk);
1960
Leo Chang7e05f212013-07-01 19:54:15 -07001961 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
1962 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 {
1964 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1965 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
1966 break;
1967 }
1968
Leo Chang7e05f212013-07-01 19:54:15 -07001969 if(eWLAN_PAL_STATUS_E_EXISTS == status)
1970 {
1971 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1972 "dxeRXFrameRefillRing, Descriptor Non-Empry");
1973 }
1974
Jeff Johnson295189b2012-06-20 16:38:30 -07001975 currentDesc = currentCtrlBlk->linkedDesc;
1976 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1977
1978 /* Issue a dummy read from the DXE descriptor DDR location to ensure
1979 that any posted writes are reflected in memory before DXE looks at
1980 the descriptor. */
1981 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
1982 {
Karthick S3254c5d2015-04-28 15:06:17 +05301983 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1984 "dxeRXFrameRefillRing, Descriptor write failed");
1985 ++channelEntry->desc_write_fail_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001986 //HDXE_ASSERT(0);
1987 }
1988
1989 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07001990 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 {
1992 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
1993 1 << channelEntry->assignedDMAChannel);
1994 }
1995 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07001996 if(eWLAN_PAL_STATUS_E_EXISTS != status)
1997 {
1998 --channelEntry->numFreeDesc;
1999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 }
2001
2002 channelEntry->tailCtrlBlk = currentCtrlBlk;
2003
2004 return status;
2005}
2006
2007/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002008 @ Function Name
2009 dxeRXFrameRouteUpperLayer
2010
2011 @ Description
2012 Test DXE descriptors and if any RX frame pending within RING,
2013 Route to upper layer
2014
2015 @ Parameters
2016 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2017 DXE host driver main control block
2018 WLANDXE_ChannelCBType *channelEntry
2019 Channel specific control block
2020 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002021 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002022 0 No frame pulled from RX RING
2023 int number of RX frames pulled from RX ring
2024
2025===========================================================================*/
2026static wpt_int32 dxeRXFrameRouteUpperLayer
2027(
2028 WLANDXE_CtrlBlkType *dxeCtxt,
2029 WLANDXE_ChannelCBType *channelEntry
2030)
2031{
2032 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2033 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2034 WLANDXE_DescType *currentDesc = NULL;
2035 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002036 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002037
2038 currentCtrlBlk = channelEntry->headCtrlBlk;
2039 currentDesc = currentCtrlBlk->linkedDesc;
2040
2041 /* Descriptoe should be SWAPPED ???? */
2042 descCtrl = currentDesc->descCtrl.ctrl;
2043
2044 /* Get frames while VALID bit is not set (DMA complete) and a data
2045 * associated with it */
2046 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2047 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2048 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2049 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2050 {
2051 channelEntry->numTotalFrame++;
2052 channelEntry->numFreeDesc++;
Jeff Johnsone7245742012-09-05 17:12:55 -07002053 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
Mihir Shetebc338242015-03-04 15:34:19 +05302054
Jeff Johnsone7245742012-09-05 17:12:55 -07002055 if (eWLAN_PAL_STATUS_SUCCESS != status)
2056 {
2057 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2058 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002059 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002060 }
Mihir Shetebc338242015-03-04 15:34:19 +05302061
Jeff Johnsone7245742012-09-05 17:12:55 -07002062 /* This Descriptor is valid, so linked Control block is also valid
2063 * Linked Control block has pre allocated packet buffer
2064 * So, just let upper layer knows preallocated frame pointer will be OK */
2065 /* Reap Rx frames */
2066 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2067 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002068 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002069
2070 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Leo Changd6de1c22013-03-21 15:42:41 -07002071 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002072
2073 /* Test next contorl block
2074 * if valid, this control block also has new RX frame must be handled */
2075 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2076 currentDesc = currentCtrlBlk->linkedDesc;
2077 descCtrl = currentDesc->descCtrl.ctrl;
2078 }
2079
2080 /* Update head control block
2081 * current control block's valid bit was 0
2082 * next trial first control block must be current control block */
2083 channelEntry->headCtrlBlk = currentCtrlBlk;
2084
2085 /* Deliver all the reaped RX frames to upper layers */
2086 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002087 while(i < frameCount)
2088 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002089 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2090 i++;
2091 }
2092
2093 return frameCount;
2094}
2095
2096/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002097 @ Function Name
2098 dxeRXFrameReady
2099
2100 @ Description
2101 Pop frame from descriptor and route frame to upper transport layer
2102 Assign new platform packet buffer into used descriptor
2103 Actual frame pop and resource realloc
2104
2105 @ Parameters
2106 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2107 DXE host driver main control block
2108 WLANDXE_ChannelCBType *channelEntry
2109 Channel specific control block
2110
2111 @ Return
2112 wpt_status
2113
2114===========================================================================*/
2115static wpt_status dxeRXFrameReady
2116(
2117 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002118 WLANDXE_ChannelCBType *channelEntry,
2119 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002120)
2121{
2122 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2123 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2124 WLANDXE_DescType *currentDesc = NULL;
2125 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002126 wpt_int32 frameCount = 0;
2127
2128 wpt_uint32 descLoop;
2129 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002130
2131 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002132 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002133
2134 /* Sanity Check */
2135 if((NULL == dxeCtxt) || (NULL == channelEntry))
2136 {
2137 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2138 "dxeRXFrameReady Channel Entry is not valid");
2139 return eWLAN_PAL_STATUS_E_INVAL;
2140 }
2141
Jeff Johnsone7245742012-09-05 17:12:55 -07002142 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002143
Jeff Johnsone7245742012-09-05 17:12:55 -07002144 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002145 {
2146 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002147 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002148 return eWLAN_PAL_STATUS_E_INVAL;
2149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002150
Leo Changd6de1c22013-03-21 15:42:41 -07002151 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002152 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2153 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2154 {
Leo Changd6de1c22013-03-21 15:42:41 -07002155 /* None of the frame handled and CH is not enabled
2156 * RX CH wrap around happen and No RX free frame
2157 * RX side should wait till new free frame available in the pool
2158 * Do not try reload driver at here*/
2159 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2160 {
Leo Changbbf86b72013-06-19 16:13:00 -07002161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002162 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2163 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002164 /* This is not empty interrupt case
2165 * If handle this as empty interrupt, false SSR might be issued
2166 * Frame count '1' is dummy frame count to avoid SSR */
2167 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002168 return eWLAN_PAL_STATUS_SUCCESS;
2169 }
2170
Jeff Johnsone7245742012-09-05 17:12:55 -07002171 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002172 currentDesc = currentCtrlBlk->linkedDesc;
2173 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002174
2175 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2176 {
2177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2178 "RX ISR called but no frame handled PWS %d, channel %s",
2179 (int)dxeCtxt->hostPowerState,
2180 channelType[channelEntry->channelType]);
2181 }
2182
2183 /* Current interupt empty and previous interrupt also empty
2184 * detected successive empty interrupt
2185 * or first interrupt empty, this should not happen */
2186 if(0 == channelEntry->numFragmentCurrentChain)
2187 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002188 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2189 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2190 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2191 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002192 /* Abnormal interrupt detected, try to find not validated descriptor */
2193 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2194 {
2195 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2196 {
Leo Chang416afe02013-07-01 13:58:13 -07002197 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002198 "Found Invalidated Descriptor %d", (int)descLoop);
2199 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2200 {
Leo Chang416afe02013-07-01 13:58:13 -07002201 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002202 "Packet locked, Resync Host and HW");
2203 channelEntry->headCtrlBlk = currentCtrlBlk;
2204 invalidatedFound = 1;
2205 break;
2206 }
2207 else
2208 {
Leo Chang416afe02013-07-01 13:58:13 -07002209 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002210 "Packet Not Locked, cannot transfer frame");
2211 }
2212 }
2213 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2214 currentDesc = currentCtrlBlk->linkedDesc;
2215 descCtrl = currentDesc->descCtrl.ctrl;
2216 }
2217
Jeff Johnson32d95a32012-09-10 13:15:23 -07002218 /* Invalidated descriptor found, and that is not head descriptor
2219 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2220 * Try re-sync here */
2221 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002222 {
2223 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2224 "Found New Sync location with HW, handle frames from there");
2225 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2227 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002228 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002229 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002230 /* Successive Empty interrupt
2231 * But this case, first descriptor also invalidated, then it means head descriptor
2232 * is linked with already handled RX frame, then could not unlock RX frame
2233 * This is just Out of RX buffer pool, not need to anything here */
2234 else if((invalidatedFound) && (0 == descLoop))
2235 {
2236 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2237 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2238 }
2239 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002240 else
2241 {
2242 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2243 "Could not found invalidated descriptor");
2244 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2245 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2246 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2247 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302248 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002249 }
2250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002252 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002254 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 return status;
2256}
2257
2258/*==========================================================================
2259 @ Function Name
2260 dxeNotifySmsm
2261
2262 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2263 buffer
2264
2265 @ Parameters
2266
2267 @ Return
2268 wpt_status
2269
2270===========================================================================*/
2271static wpt_status dxeNotifySmsm
2272(
2273 wpt_boolean kickDxe,
2274 wpt_boolean ringEmpty
2275)
2276{
2277 wpt_uint32 clrSt = 0;
2278 wpt_uint32 setSt = 0;
2279
2280 if(kickDxe)
2281 {
2282 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2283
2284 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2285 {
2286 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2287 tempDxeCtrlBlk->lastKickOffDxe = 1;
2288 }
2289 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2290 {
2291 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2292 tempDxeCtrlBlk->lastKickOffDxe = 0;
2293 }
2294 else
2295 {
2296 HDXE_ASSERT(0);
2297 }
2298 }
2299 else
2300 {
2301 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2302 }
2303
Mihir Shete68ed77a2014-10-10 10:47:12 +05302304 tempDxeCtrlBlk->txRingsEmpty = ringEmpty;
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 if(ringEmpty)
2306 {
2307 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2308 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2309 }
2310 else
2311 {
2312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2313 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2314 }
2315
2316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2317
2318 wpalNotifySmsm(clrSt, setSt);
2319
2320 return eWLAN_PAL_STATUS_SUCCESS;
2321}
2322
2323/*==========================================================================
2324 @ Function Name
2325 dxePsComplete
2326
2327 @ Description: Utility function to check the resv desc to deside if we can
2328 get into Power Save mode now
2329
2330 @ Parameters
2331
2332 @ Return
2333 None
2334
2335===========================================================================*/
2336static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2337{
2338 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2339 {
2340 return;
2341 }
2342
2343 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2344 //must have been consumed by RIVA, OK to get into BMPS
2345 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2346 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2347 {
2348 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2349 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2350 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2351 {
2352 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2353 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2354 }
2355 }
2356 else //still more pkts to be served by RIVA
2357 {
2358 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2359
2360 switch(dxeCtxt->rivaPowerState)
2361 {
2362 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2363 //NOP
2364 break;
2365 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2366 if(intr_based)
2367 {
2368 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2369 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2370 }
2371 break;
2372 default:
2373 //assert
2374 break;
2375 }
2376 }
2377}
2378
2379/*==========================================================================
2380 @ Function Name
2381 dxeRXEventHandler
2382
2383 @ Description
2384 Handle serailized RX frame ready event
2385 First disable interrupt then pick up frame from pre allocated buffer
2386 Since frame handle is doen, clear interrupt bit to ready next interrupt
2387 Finally re enable interrupt
2388
2389 @ Parameters
2390 wpt_msg *rxReadyMsg
2391 RX frame ready MSG pointer
2392 include DXE control context
2393
2394 @ Return
2395 NONE
2396
2397===========================================================================*/
2398void dxeRXEventHandler
2399(
2400 wpt_msg *rxReadyMsg
2401)
2402{
2403 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2404 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2405 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2406 wpt_uint32 intSrc = 0;
2407 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002408 wpt_uint32 chHighStat = 0;
2409 wpt_uint32 chLowStat = 0;
Mihir Shetee6618162015-03-16 14:48:42 +05302410 wpt_uint32 chLogRxStat = 0;
Mihir Shetec4093f92015-05-28 15:21:11 +05302411 wpt_uint32 chLogRxFwStat = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302412 wpt_uint32 regValue, chanMask;
Jeff Johnson295189b2012-06-20 16:38:30 -07002413
Jeff Johnsone7245742012-09-05 17:12:55 -07002414 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002415
Jeff Johnsone7245742012-09-05 17:12:55 -07002416 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002417 {
2418 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002419 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002420 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 }
2422
Jeff Johnsone7245742012-09-05 17:12:55 -07002423 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2424 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2425 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
Mihir Shetee6618162015-03-16 14:48:42 +05302426 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2427 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]);
Jeff Johnsone7245742012-09-05 17:12:55 -07002428
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2430
2431 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
Mihir Shetee6618162015-03-16 14:48:42 +05302432 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled) ||
2433 (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) &&
2434 !dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chEnabled))
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 {
2436 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2437 "DXE already stopped in RX event handler. Just return");
2438 return;
2439 }
2440
2441 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2442 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2443 {
Mihir Shetec4093f92015-05-28 15:21:11 +05302444 if (WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
2445 {
2446 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2447 &intSrc);
2448 if(eWLAN_PAL_STATUS_SUCCESS != status || 0 == intSrc)
2449 {
2450 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2451 "%s: Read status: %d, regVal: %d",
2452 __func__, status, intSrc);
2453 }
2454 else
2455 {
2456 /* Register Read was succesful and we have a valid interrupt
2457 * source, so WCN is not power collapsed yet and it should
2458 * not power collapse till we set the synchronization bit
2459 * at the end of this function, safe to pull frames...
2460 */
2461 goto pull_frames;
2462 }
2463 }
2464
Jeff Johnson295189b2012-06-20 16:38:30 -07002465 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2466 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002467 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002468
2469 /* Not to touch any register, just pull frame directly from chain ring
2470 * First high priority */
2471 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2472 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002473 channelCb,
2474 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002475 if(eWLAN_PAL_STATUS_SUCCESS != status)
2476 {
2477 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2478 "dxeRXEventHandler Pull from RX high channel fail");
2479 }
Leo Chang46f36162014-01-14 21:47:24 -08002480 /* In case FW could not power collapse in IMPS mode
2481 * Next power restore might have empty interrupt
2482 * If IMPS mode has empty interrupt since RX thread race,
2483 * Invalid re-load driver might happen
2484 * To prevent invalid re-load driver,
2485 * IMPS event handler set dummpy frame count */
2486 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002487
2488 /* Second low priority */
2489 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2490 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002491 channelCb,
2492 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002493 if(eWLAN_PAL_STATUS_SUCCESS != status)
2494 {
2495 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Mihir Shetee6618162015-03-16 14:48:42 +05302496 "dxeRXEventHandler Pull from RX low channel fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 }
Leo Chang46f36162014-01-14 21:47:24 -08002498 /* LOW Priority CH same above */
2499 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002500
Mihir Shetee6618162015-03-16 14:48:42 +05302501 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2502 {
2503 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2504 status = dxeRXFrameReady(dxeCtxt,
2505 channelCb,
2506 chLogRxStat);
2507 if(eWLAN_PAL_STATUS_SUCCESS != status)
2508 {
2509 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2510 "dxeRXEventHandler Pull from RX log channel fail");
2511 }
2512 channelCb->numFragmentCurrentChain = 1;
2513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002514 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2515 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2516
2517 return;
2518 }
2519
2520 /* Disable device interrupt */
2521 /* Read whole interrupt mask register and exclusive only this channel int */
2522 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2523 &intSrc);
2524 if(eWLAN_PAL_STATUS_SUCCESS != status)
2525 {
2526 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2527 "dxeRXEventHandler Read INT_SRC register fail");
2528 return;
2529 }
2530 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2531 "RX Event Handler INT Source 0x%x", intSrc);
2532
Mihir Shetec4093f92015-05-28 15:21:11 +05302533pull_frames:
Jeff Johnson295189b2012-06-20 16:38:30 -07002534 /* Test High Priority Channel interrupt is enabled or not */
2535 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2536 if(intSrc & (1 << channelCb->assignedDMAChannel))
2537 {
2538 status = dxeChannelCleanInt(channelCb, &chHighStat);
2539 if(eWLAN_PAL_STATUS_SUCCESS != status)
2540 {
2541 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2542 "dxeRXEventHandler INT Clean up fail");
2543 return;
2544 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2546 {
2547 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002548 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2549 "%11s : 0x%x Error Reported, Reload Driver",
2550 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302551
Mihir Shete79d6b582014-03-12 17:54:07 +05302552 dxeErrChannelDebug(channelCb, chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302553
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002554 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2555 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302556 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002557 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002558 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2559 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002560 {
2561 /* Handle RX Ready for high priority channel */
2562 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002563 channelCb,
2564 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002565 }
2566 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2567 {
2568 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002569 channelCb,
2570 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002571 }
2572 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2573 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002574 /* Update the Rx DONE histogram */
2575 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2576 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2577 {
2578 channelCb->rxDoneHistogram |= 1;
2579 }
2580 else
2581 {
2582 channelCb->rxDoneHistogram &= ~1;
2583 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002585
2586 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002587 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 if(intSrc & (1 << channelCb->assignedDMAChannel))
2589 {
2590 status = dxeChannelCleanInt(channelCb, &chLowStat);
2591 if(eWLAN_PAL_STATUS_SUCCESS != status)
2592 {
2593 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2594 "dxeRXEventHandler INT Clean up fail");
2595 return;
2596 }
2597
2598 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2599 {
2600 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002601 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2602 "%11s : 0x%x Error Reported, Reload Driver",
2603 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302604
Mihir Shete79d6b582014-03-12 17:54:07 +05302605 dxeErrChannelDebug(channelCb, chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302606
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002607 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2608 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302609 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002610 }
Mihir Shetef2000552014-05-12 16:21:34 +05302611 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) ||
2612 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002613 {
2614 /* Handle RX Ready for low priority channel */
2615 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002616 channelCb,
2617 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07002618 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002619
2620 /* Update the Rx DONE histogram */
2621 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2622 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2623 {
2624 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 }
2626 else
2627 {
2628 channelCb->rxDoneHistogram &= ~1;
2629 }
2630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2631 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2632 }
Mihir Shetee6618162015-03-16 14:48:42 +05302633
2634 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2635 {
2636 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2637
2638 if(intSrc & (1 << channelCb->assignedDMAChannel))
2639 {
2640 status = dxeChannelCleanInt(channelCb,&chLogRxStat);
2641 if(eWLAN_PAL_STATUS_SUCCESS != status)
2642 {
2643 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2644 "dxeRXEventHandler INT Clean up fail");
2645 return;
2646 }
2647
2648 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxStat)
2649 {
2650 /* Error Happen during transaction, Handle it */
2651 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2652 "%11s : 0x%x Error Reported, Reload Driver",
2653 channelType[channelCb->channelType], chLogRxStat);
2654
2655 dxeErrChannelDebug(channelCb, chLogRxStat);
2656
2657 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2658 wpalWlanReload();
2659 dxeStartSSRTimer(dxeCtxt);
2660 }
2661 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxStat) ||
2662 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2663 {
2664 /* Handle RX Ready for low priority channel */
2665 status = dxeRXFrameReady(dxeCtxt,
2666 channelCb,
2667 chLogRxStat);
2668 }
2669
2670 /* Update the Rx DONE histogram */
2671 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2672 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)
2673 {
2674 channelCb->rxDoneHistogram |= 1;
2675 }
2676 else
2677 {
2678 channelCb->rxDoneHistogram &= ~1;
2679 }
2680 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2681 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxStat, channelCb->numFragmentCurrentChain);
2682 }
2683 }
2684
Mihir Shetec4093f92015-05-28 15:21:11 +05302685 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_FW_LOG))
2686 {
2687 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
2688
2689 if(intSrc & (1 << channelCb->assignedDMAChannel))
2690 {
2691 status = dxeChannelCleanInt(channelCb,&chLogRxFwStat);
2692 if(eWLAN_PAL_STATUS_SUCCESS != status)
2693 {
2694 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2695 "dxeRXEventHandler INT Clean up fail");
2696 return;
2697 }
2698
2699 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxFwStat)
2700 {
2701 /* Error Happen during transaction, Handle it */
2702 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2703 "%11s : 0x%x Error Reported, Reload Driver",
2704 channelType[channelCb->channelType], chLogRxFwStat);
2705
2706 dxeErrChannelDebug(channelCb, chLogRxFwStat);
2707
2708 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2709 wpalWlanReload();
2710 dxeStartSSRTimer(dxeCtxt);
2711 }
2712 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxFwStat) ||
2713 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat))
2714 {
2715 if (!dxeCtxt->hostInitiatedH2H)
2716 {
2717 dxeCtxt->receiveMbMsgCB(dxeCtxt->clientCtxt);
2718 }
2719 else
2720 {
2721 status = dxeRXFrameReady(dxeCtxt,
2722 channelCb,
2723 chLogRxFwStat);
2724 }
2725 }
2726
2727 /* Update the Rx DONE histogram */
2728 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2729 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat)
2730 {
2731 channelCb->rxDoneHistogram |= 1;
2732 }
2733 else
2734 {
2735 channelCb->rxDoneHistogram &= ~1;
2736 }
2737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2738 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxFwStat, channelCb->numFragmentCurrentChain);
2739 }
2740 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002741 if(eWLAN_PAL_STATUS_SUCCESS != status)
2742 {
2743 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2744 "dxeRXEventHandler Handle Frame Ready Fail");
2745 return;
2746 }
2747
Jeff Johnson295189b2012-06-20 16:38:30 -07002748 /* Prepare Control Register EN Channel */
2749 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2750 {
2751 HDXE_ASSERT(0);
2752 }
Mihir Shetef2000552014-05-12 16:21:34 +05302753
2754 if (dxeCtxt->rxPalPacketUnavailable &&
2755 (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat))
2756 {
2757 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask &
2758 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302759 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302760 }
2761 else
2762 {
2763 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302764 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302765 }
Leo Chang094ece82013-04-23 17:57:41 -07002766 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302767 chanMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002768
2769 /* Prepare Control Register EN Channel */
2770 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2771 {
2772 HDXE_ASSERT(0);
2773 }
Leo Chang094ece82013-04-23 17:57:41 -07002774
Mihir Shetef2000552014-05-12 16:21:34 +05302775 if (dxeCtxt->rxPalPacketUnavailable &&
2776 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
2777 {
2778 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask &
2779 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302780 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302781 }
2782 else
2783 {
2784 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302785 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302786 }
Leo Chang094ece82013-04-23 17:57:41 -07002787 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302788 chanMask);
2789
Mihir Shetee6618162015-03-16 14:48:42 +05302790 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2791 {
2792 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2793 {
2794 HDXE_ASSERT(0);
2795 }
2796
2797 if (dxeCtxt->rxPalPacketUnavailable &&
2798 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2799 {
2800 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask &
2801 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
2802 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 1;
2803 }
2804 else
2805 {
2806 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask;
2807 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 0;
2808 }
2809 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].channelRegister.chDXECtrlRegAddr,
2810 chanMask);
2811 }
Leo Chang094ece82013-04-23 17:57:41 -07002812
2813 /* Clear Interrupt handle processing bit
2814 * RIVA may power down */
Mihir Shete0670b402015-05-13 17:51:41 +05302815 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05302816 {
2817 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
2818 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
2819 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
2820 }
2821 else
2822 {
Karthick S09d5dd02015-05-27 16:58:32 +05302823 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
2824 regValue &= (~WLAN_PMU_POWER_DOWN_MASK);
2825 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05302826 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002827
Leo Chang416afe02013-07-01 13:58:13 -07002828 /* Enable system level ISR */
2829 /* Enable RX ready Interrupt at here */
2830 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2831 if(eWLAN_PAL_STATUS_SUCCESS != status)
2832 {
2833 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2834 "dxeRXEventHandler Enable RX Ready interrupt fail");
2835 return;
2836 }
2837
Jeff Johnson295189b2012-06-20 16:38:30 -07002838 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002839 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002840 return;
2841}
2842
2843/*==========================================================================
2844 @ Function Name
2845 dxeRXPacketAvailableEventHandler
2846
2847 @ Description
2848 Handle serialized RX Packet Available event when the corresponding callback
2849 is invoked by WPAL.
2850 Try to fill up any completed DXE descriptors with available Rx packet buffer
2851 pointers.
2852
2853 @ Parameters
2854 wpt_msg *rxPktAvailMsg
2855 RX frame ready MSG pointer
2856 include DXE control context
2857
2858 @ Return
2859 NONE
2860
2861===========================================================================*/
2862void dxeRXPacketAvailableEventHandler
2863(
2864 wpt_msg *rxPktAvailMsg
2865)
2866{
2867 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2868 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2869 WLANDXE_ChannelCBType *channelCb = NULL;
2870
2871 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002872 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002873
2874 /* Sanity Check */
2875 if(NULL == rxPktAvailMsg)
2876 {
2877 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2878 "dxeRXPacketAvailableEventHandler Context is not valid");
2879 return;
2880 }
2881
2882 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05302883
2884#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07002885 /* Available resource allocated
2886 * Stop timer not needed */
2887 if(VOS_TIMER_STATE_RUNNING ==
2888 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
2889 {
2890 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
2891 }
Mihir Shete44547fb2014-03-10 14:15:42 +05302892#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002893
2894 do
2895 {
2896 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2897 "dxeRXPacketAvailableEventHandler, start refilling ring");
2898
2899 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2900 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2901
2902 // Wait for another callback to indicate when Rx resources are available
2903 // again.
2904 if(eWLAN_PAL_STATUS_SUCCESS != status)
2905 {
2906 break;
2907 }
2908
2909 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2910 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2911 if(eWLAN_PAL_STATUS_SUCCESS != status)
2912 {
2913 break;
2914 }
Mihir Shetee6618162015-03-16 14:48:42 +05302915
2916 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2917 {
2918 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2919 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2920 if(eWLAN_PAL_STATUS_SUCCESS != status)
2921 {
2922 break;
2923 }
2924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002925 } while(0);
2926
2927 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2928 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2929 {
2930 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2931 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2932 }
2933}
2934
2935/*==========================================================================
2936 @ Function Name
2937 dxeRXISR
2938
2939 @ Description
2940 RX frame ready interrupt service routine
2941 interrupt entry function, this function called based on ISR context
2942 Must be serialized
2943
2944 @ Parameters
2945 void *hostCtxt
2946 DXE host driver control context,
2947 pre registerd during interrupt registration
2948
2949 @ Return
2950 NONE
2951
2952===========================================================================*/
2953static void dxeRXISR
2954(
2955 void *hostCtxt
2956)
2957{
2958 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2959 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07002961
Leo Chang094ece82013-04-23 17:57:41 -07002962 /* Set Interrupt processing bit
2963 * During this bit set, WLAN HW may not power collapse */
Mihir Shete0670b402015-05-13 17:51:41 +05302964 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05302965 {
2966 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
2967 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
2968 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
2969 }
2970 else
2971 {
Karthick S09d5dd02015-05-27 16:58:32 +05302972 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
2973 regValue |= WLAN_PMU_POWER_DOWN_MASK;
2974 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05302975 }
Leo Chang094ece82013-04-23 17:57:41 -07002976
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 /* Disable interrupt at here
2978 * Disable RX Ready system level Interrupt at here
2979 * Otherwise infinite loop might happen */
2980 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2981 if(eWLAN_PAL_STATUS_SUCCESS != status)
2982 {
2983 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2984 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2985 return;
2986 }
2987
2988 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08002989 if(NULL == dxeCtxt->rxIsrMsg)
2990 {
2991 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2992 "dxeRXFrameReadyISR NULL message");
2993 HDXE_ASSERT(0);
2994 return;
2995 }
2996
Jeff Johnson295189b2012-06-20 16:38:30 -07002997 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2998 dxeCtxt->rxIsrMsg);
2999 if(eWLAN_PAL_STATUS_SUCCESS != status)
3000 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003001 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3002 "dxeRXFrameReadyISR interrupt serialize fail");
3003 }
3004
Jeff Johnson295189b2012-06-20 16:38:30 -07003005 return;
3006}
3007
3008/*==========================================================================
3009 @ Function Name
3010 dxeTXPushFrame
3011
3012 @ Description
3013 Push TX frame into DXE descriptor and DXE register
3014 Send notification to DXE register that TX frame is ready to transfer
3015
3016 @ Parameters
3017 WLANDXE_ChannelCBType *channelEntry
3018 Channel specific control block
3019 wpt_packet *palPacket
3020 Packet pointer ready to transfer
3021
3022 @ Return
3023 PAL_STATUS_T
3024===========================================================================*/
3025static wpt_status dxeTXPushFrame
3026(
3027 WLANDXE_ChannelCBType *channelEntry,
3028 wpt_packet *palPacket
3029)
3030{
3031 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3032 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3033 WLANDXE_DescType *currentDesc = NULL;
3034 WLANDXE_DescType *firstDesc = NULL;
3035 WLANDXE_DescType *LastDesc = NULL;
3036 void *sourcePhysicalAddress = NULL;
3037 wpt_uint32 xferSize = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003038 wpt_iterator iterator;
Leo Changac1d3612013-07-01 15:15:51 -07003039 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003040
3041 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003042 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003043
Leo Changac1d3612013-07-01 15:15:51 -07003044 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3045 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3046 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003047 {
Leo Changac1d3612013-07-01 15:15:51 -07003048 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003049 }
3050
3051 channelEntry->numFragmentCurrentChain = 0;
3052 currentCtrlBlk = channelEntry->headCtrlBlk;
3053
3054 /* Initialize interator, TX is fragmented */
Jeff Johnson295189b2012-06-20 16:38:30 -07003055 status = wpalLockPacketForTransfer(palPacket);
3056 if(eWLAN_PAL_STATUS_SUCCESS != status)
3057 {
3058 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3059 "dxeTXPushFrame unable to lock packet");
3060 return status;
3061 }
3062
3063 status = wpalIteratorInit(&iterator, palPacket);
Jeff Johnson295189b2012-06-20 16:38:30 -07003064 if(eWLAN_PAL_STATUS_SUCCESS != status)
3065 {
3066 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3067 "dxeTXPushFrame iterator init fail");
3068 return status;
3069 }
3070
3071 /* !!!! Revisit break condition !!!!!!! */
3072 while(1)
3073 {
3074 /* Get current descriptor pointer from current control block */
3075 currentDesc = currentCtrlBlk->linkedDesc;
3076 if(NULL == firstDesc)
3077 {
3078 firstDesc = currentCtrlBlk->linkedDesc;
3079 }
3080 /* All control block will have same palPacket Pointer
3081 * to make logic simpler */
3082 currentCtrlBlk->xfrFrame = palPacket;
3083
3084 /* Get next fragment physical address and fragment size
3085 * if this is the first trial, will get first physical address
3086 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
Jeff Johnson295189b2012-06-20 16:38:30 -07003087 status = wpalIteratorNext(&iterator,
3088 palPacket,
3089 &sourcePhysicalAddress,
3090 &xferSize);
3091 if((NULL == sourcePhysicalAddress) ||
3092 (0 == xferSize))
3093 {
3094 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3095 "dxeTXPushFrame end of current frame");
3096 break;
3097 }
3098 if(eWLAN_PAL_STATUS_SUCCESS != status)
3099 {
3100 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3101 "dxeTXPushFrame Get next frame fail");
3102 return status;
3103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003104
3105 /* This is the LAST descriptor valid for this transaction */
3106 LastDesc = currentCtrlBlk->linkedDesc;
3107
3108 /* Program DXE descriptor */
3109 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303110 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003111
3112 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3113 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3114 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3115 {
3116 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3117 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3118 }
3119 else
3120 {
3121 /* Test specific H2H transfer, destination address already set
3122 * Do Nothing */
3123 }
3124 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3125
3126 /* Program channel control register */
3127 /* First frame not set VAL bit, why ??? */
3128 if(0 == channelEntry->numFragmentCurrentChain)
3129 {
3130 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3131 }
3132 else
3133 {
3134 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3135 }
3136
3137 /* Update statistics */
3138 channelEntry->numFragmentCurrentChain++;
3139 channelEntry->numFreeDesc--;
3140 channelEntry->numRsvdDesc++;
3141
3142 /* Get next control block */
3143 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3144 }
3145 channelEntry->numTotalFrame++;
3146 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3147 "NUM TX FRAG %d, Total Frame %d",
3148 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3149
3150 /* Program Channel control register
3151 * Set as end of packet
3152 * Enable interrupt also for first code lock down
3153 * performace optimization, this will be revisited */
3154 if(NULL == LastDesc)
3155 {
3156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3157 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3158 return eWLAN_PAL_STATUS_E_FAULT;
3159 }
3160 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3161 /* Now First one also Valid ????
3162 * this procedure will prevent over handle descriptor from previous
3163 * TX trigger */
3164 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3165
3166 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3167 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3168 {
3169 /* Update channel head as next avaliable linked slot */
3170 channelEntry->headCtrlBlk = currentCtrlBlk;
Leo Changac1d3612013-07-01 15:15:51 -07003171 if(isEmpty)
3172 {
3173 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3174 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3175 "SMSM_ret LO=%d HI=%d",
3176 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3177 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3178 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3179 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
3180 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003181 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003182 }
3183
3184 /* If DXE use external descriptor, registers are not needed to be programmed
3185 * Just after finish to program descriptor, tirigger to send */
3186 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3187 {
3188 /* Issue a dummy read from the DXE descriptor DDR location to
3189 ensure that any previously posted write to the descriptor
3190 completes. */
3191 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3192 {
3193 //HDXE_ASSERT(0);
3194 }
3195
3196 /* Everything is ready
3197 * Trigger to start DMA */
3198 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3199 channelEntry->extraConfig.chan_mask);
3200 if(eWLAN_PAL_STATUS_SUCCESS != status)
3201 {
3202 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3203 "dxeTXPushFrame Write Channel Ctrl Register fail");
3204 return status;
3205 }
3206
3207 /* Update channel head as next avaliable linked slot */
3208 channelEntry->headCtrlBlk = currentCtrlBlk;
3209
3210 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003211 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003212 return status;
3213 }
3214
3215 /* If DXE not use external descriptor, program each registers */
3216 /* Circular buffer handle not need to program DESC register???
3217 * GEN5 code not programed RING buffer case
3218 * REVISIT THIS !!!!!! */
3219 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3220 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3221 {
3222 /* Destination address, assigned Work Q */
3223 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3224 channelEntry->channelConfig.refWQ);
3225 if(eWLAN_PAL_STATUS_SUCCESS != status)
3226 {
3227 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3228 "dxeTXPushFrame Program dest address register fail");
3229 return status;
3230 }
3231 /* If descriptor format is SHORT */
3232 if(channelEntry->channelConfig.useShortDescFmt)
3233 {
3234 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3235 0);
3236 if(eWLAN_PAL_STATUS_SUCCESS != status)
3237 {
3238 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3239 "dxeTXPushFrame Program dest address register fail");
3240 return status;
3241 }
3242 }
3243 else
3244 {
3245 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3246 "dxeTXPushFrame LONG Descriptor Format!!!");
3247 }
3248 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003249
3250 /* Program Source address register
3251 * This address is already programmed into DXE Descriptor
3252 * But register also upadte */
3253 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3254 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3255 if(eWLAN_PAL_STATUS_SUCCESS != status)
3256 {
3257 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3258 "dxeTXPushFrame Program src address register fail");
3259 return status;
3260 }
3261 /* If descriptor format is SHORT */
3262 if(channelEntry->channelConfig.useShortDescFmt)
3263 {
3264 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3265 0);
3266 if(eWLAN_PAL_STATUS_SUCCESS != status)
3267 {
3268 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3269 "dxeTXPushFrame Program dest address register fail");
3270 return status;
3271 }
3272 }
3273 else
3274 {
3275 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3276 "dxeTXPushFrame LONG Descriptor Format!!!");
3277 }
3278
3279 /* Linked list Descriptor pointer */
3280 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3281 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3282 if(eWLAN_PAL_STATUS_SUCCESS != status)
3283 {
3284 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3285 "dxeTXPushFrame Write DESC Address register fail");
3286 return status;
3287 }
3288 /* If descriptor format is SHORT */
3289 if(channelEntry->channelConfig.useShortDescFmt)
3290 {
3291 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3292 0);
3293 if(eWLAN_PAL_STATUS_SUCCESS != status)
3294 {
3295 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3296 "dxeTXPushFrame Program dest address register fail");
3297 return status;
3298 }
3299 }
3300 else
3301 {
3302 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3303 "dxeTXPushFrame LONG Descriptor Format!!!");
3304 }
3305
3306 /* Transfer Size */
3307 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3308 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3309 xferSize);
3310 if(eWLAN_PAL_STATUS_SUCCESS != status)
3311 {
3312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3313 "dxeTXPushFrame Write DESC Address register fail");
3314 return status;
3315 }
3316
3317 /* Everything is ready
3318 * Trigger to start DMA */
3319 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3320 channelEntry->extraConfig.chan_mask);
3321 if(eWLAN_PAL_STATUS_SUCCESS != status)
3322 {
3323 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3324 "dxeTXPushFrame Write Channel Ctrl Register fail");
3325 return status;
3326 }
3327
3328 /* Update channel head as next avaliable linked slot */
3329 channelEntry->headCtrlBlk = currentCtrlBlk;
3330
3331 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003332 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003333 return status;
3334}
3335
3336/*==========================================================================
3337 @ Function Name
3338 dxeTXCompFrame
3339
3340 @ Description
3341 TX Frame transfer complete event handler
3342
3343 @ Parameters
3344 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3345 DXE host driver main control block
3346 WLANDXE_ChannelCBType *channelEntry
3347 Channel specific control block
3348
3349 @ Return
3350 PAL_STATUS_T
3351===========================================================================*/
3352static wpt_status dxeTXCompFrame
3353(
3354 WLANDXE_CtrlBlkType *hostCtxt,
3355 WLANDXE_ChannelCBType *channelEntry
3356)
3357{
3358 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3359 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3360 WLANDXE_DescType *currentDesc = NULL;
3361 wpt_uint32 descCtrlValue = 0;
3362 unsigned int *lowThreshold = NULL;
3363
3364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003365 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003366
3367 /* Sanity */
3368 if((NULL == hostCtxt) || (NULL == channelEntry))
3369 {
3370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3371 "dxeTXCompFrame Invalid ARG");
3372 return eWLAN_PAL_STATUS_E_INVAL;
3373 }
3374
3375 if(NULL == hostCtxt->txCompCB)
3376 {
3377 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3378 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003379 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003380 }
3381
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003382 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3383 if(eWLAN_PAL_STATUS_SUCCESS != status)
3384 {
3385 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3386 "dxeTXCompFrame Mutex Acquire fail");
3387 return status;
3388 }
3389
Jeff Johnson295189b2012-06-20 16:38:30 -07003390 currentCtrlBlk = channelEntry->tailCtrlBlk;
3391 currentDesc = currentCtrlBlk->linkedDesc;
3392
3393 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3394 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003395 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3396 if(eWLAN_PAL_STATUS_SUCCESS != status)
3397 {
3398 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3399 "dxeTXCompFrame Mutex Release fail");
3400 return status;
3401 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003402 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003403 }
3404
Kiet Lam842dad02014-02-18 18:44:02 -08003405
Jeff Johnson295189b2012-06-20 16:38:30 -07003406 while(1)
3407 {
3408// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3409 descCtrlValue = currentDesc->descCtrl.ctrl;
3410 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3411 {
3412 /* caught up with head, bail out */
3413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3414 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3415 break;
3416 }
3417
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003418 if(currentCtrlBlk->xfrFrame == NULL)
3419 {
3420 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3421 "Invalid transfer frame");
3422 HDXE_ASSERT(0);
3423 break;
3424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003425 channelEntry->numFreeDesc++;
3426 channelEntry->numRsvdDesc--;
3427
3428 /* Send Frame TX Complete notification with frame start fragment location */
3429 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3430 {
3431 hostCtxt->txCompletedFrames--;
Jeff Johnson295189b2012-06-20 16:38:30 -07003432 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3433 if (eWLAN_PAL_STATUS_SUCCESS != status)
3434 {
3435 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3436 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003437 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3438 if(eWLAN_PAL_STATUS_SUCCESS != status)
3439 {
3440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3441 "dxeTXCompFrame Mutex Release fail");
3442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003443 return status;
3444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003445 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3446 currentCtrlBlk->xfrFrame,
3447 eWLAN_PAL_STATUS_SUCCESS);
3448 channelEntry->numFragmentCurrentChain = 0;
3449 }
3450 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3451 currentDesc = currentCtrlBlk->linkedDesc;
3452
3453 /* Break condition
3454 * Head control block is the control block must be programed for the next TX
3455 * so, head control block is not programmed control block yet
3456 * if loop encounte head control block, stop to complete
3457 * in theory, COMP CB must be called already ??? */
3458 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3459 {
3460 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3461 "dxeTXCompFrame caught up with head ptr");
3462 break;
3463 }
3464 /* VALID Bit check ???? */
3465 }
3466
3467 /* Tail and Head Control block must be same */
3468 channelEntry->tailCtrlBlk = currentCtrlBlk;
3469
3470 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3471 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3472 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3473
3474 /* If specific channel hit low resource condition send notification to upper layer */
3475 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3476 (channelEntry->numFreeDesc > *lowThreshold))
3477 {
3478 /* Change it back if we raised it for fetching a remaining packet from TL */
3479 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3480 {
3481 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3482 }
3483
3484 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3485 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3486 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3487 channelEntry->channelType,
3488 eWLAN_PAL_TRUE);
3489 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3490 }
3491
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003492 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3493 if(eWLAN_PAL_STATUS_SUCCESS != status)
3494 {
3495 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3496 "dxeTXCompFrame Mutex Release fail");
3497 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003498
3499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003500 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003501 return status;
3502}
3503
3504/*==========================================================================
3505 @ Function Name
3506 dxeTXEventHandler
3507
3508 @ Description
3509 If DXE HW sends TX related interrupt, this event handler will be called
3510 Handle higher priority channel first
3511 Figureout why interrupt happen and call appropriate final even handler
3512 TX complete or error happen
3513
3514 @ Parameters
3515 void *msgPtr
3516 Even MSG
3517
3518 @ Return
3519 PAL_STATUS_T
3520===========================================================================*/
3521void dxeTXEventHandler
3522(
3523 wpt_msg *msgPtr
3524)
3525{
3526 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3527 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3528 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3529 wpt_uint32 intSrc = 0;
3530 wpt_uint32 chStat = 0;
3531 WLANDXE_ChannelCBType *channelCb = NULL;
3532
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003533 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003534 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003535
3536 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003537 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003538
3539 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003540 dxeCtxt->ucTxMsgCnt = 0;
3541
3542 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3543 {
3544 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3545 "wlan: TX COMP WLAN Driver re-loading in progress");
3546 return;
3547 }
3548
Jeff Johnson295189b2012-06-20 16:38:30 -07003549 /* Return from here if the RIVA is in IMPS, to avoid register access */
3550 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3551 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003552 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003554 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003555 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3556 if(eWLAN_PAL_STATUS_SUCCESS != status)
3557 {
3558 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003559 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003560 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003561
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003562 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3563 if(eWLAN_PAL_STATUS_SUCCESS != status)
3564 {
3565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3566 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3567 }
3568
3569 if(((dxeCtxt->txCompletedFrames) &&
3570 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3571 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003572 {
3573 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3574 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3575 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003576 "TX COMP INT Enabled, remain TX frame count on ring %d",
3577 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003578 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3579 the posibility of a race*/
3580 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3581 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003582 else
3583 {
3584 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3585 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3586 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3587 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003589 return;
3590 }
3591
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003592 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003593 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3594 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3595 {
3596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3597 "DXE already stopped in TX event handler. Just return");
3598 return;
3599 }
3600
Jeff Johnson295189b2012-06-20 16:38:30 -07003601 /* Disable device interrupt */
3602 /* Read whole interrupt mask register and exclusive only this channel int */
3603 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3604 &intSrc);
3605 if(eWLAN_PAL_STATUS_SUCCESS != status)
3606 {
3607 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3608 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3609 return;
3610 }
3611 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3612 "TX Event Handler INT Source 0x%x", intSrc);
3613
3614 /* Test High Priority Channel is the INT source or not */
3615 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3616 if(intSrc & (1 << channelCb->assignedDMAChannel))
3617 {
3618 status = dxeChannelCleanInt(channelCb, &chStat);
3619 if(eWLAN_PAL_STATUS_SUCCESS != status)
3620 {
3621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3622 "dxeTXEventHandler INT Clean up fail");
3623 return;
3624 }
3625
3626 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3627 {
3628 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003629 "%11s : 0x%x Error Reported, Reload Driver",
3630 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303631
Mihir Shete79d6b582014-03-12 17:54:07 +05303632 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303633
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003634 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3635 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303636 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 }
3638 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3639 {
3640 /* Handle TX complete for high priority channel */
3641 status = dxeTXCompFrame(dxeCtxt,
3642 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003643 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003644 }
3645 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3646 {
3647 /* Handle TX complete for high priority channel */
3648 status = dxeTXCompFrame(dxeCtxt,
3649 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003650 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 }
3652 else
3653 {
3654 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3655 "dxeTXEventHandler TX HI status=%x", chStat);
3656 }
3657
3658 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3659 {
3660 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3661 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3662 }
3663
3664 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3665 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3666 }
3667
3668 /* Test Low Priority Channel interrupt is enabled or not */
3669 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3670 if(intSrc & (1 << channelCb->assignedDMAChannel))
3671 {
3672 status = dxeChannelCleanInt(channelCb, &chStat);
3673 if(eWLAN_PAL_STATUS_SUCCESS != status)
3674 {
3675 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3676 "dxeTXEventHandler INT Clean up fail");
3677 return;
3678 }
3679
3680 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3681 {
3682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003683 "%11s : 0x%x Error Reported, Reload Driver",
3684 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303685
Mihir Shete79d6b582014-03-12 17:54:07 +05303686 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303687
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003688 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3689 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303690 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003691 }
3692 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3693 {
3694 /* Handle TX complete for low priority channel */
3695 status = dxeTXCompFrame(dxeCtxt,
3696 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003697 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 }
3699 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3700 {
3701 /* Handle TX complete for low priority channel */
3702 status = dxeTXCompFrame(dxeCtxt,
3703 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003704 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003705 }
3706 else
3707 {
3708 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3709 "dxeTXEventHandler TX LO status=%x", chStat);
3710 }
3711
3712 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3713 {
3714 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3715 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3716 }
3717 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3718 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3719 }
3720
3721
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3723 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3724 {
3725 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3726 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003727 if(0 != dxeCtxt->txCompletedFrames)
3728 {
3729 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3730 "TX COMP INT Enabled, remain TX frame count on ring %d",
3731 dxeCtxt->txCompletedFrames);
3732 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003733 }
3734
3735 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3736 the posibility of a race*/
3737 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3738
3739 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003740 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 return;
3742}
3743
3744
3745/*==========================================================================
3746 @ Function Name
3747 dxeTXCompleteProcessing
3748
3749 @ Description
3750 If DXE HW sends TX related interrupt, this event handler will be called
3751 Handle higher priority channel first
3752 Figureout why interrupt happen and call appropriate final even handler
3753 TX complete or error happen
3754
3755 @ Parameters
3756 dxeCtxt DXE context
3757
3758 @ Return
3759 PAL_STATUS_T
3760===========================================================================*/
3761void dxeTXCompleteProcessing
3762(
3763 WLANDXE_CtrlBlkType *dxeCtxt
3764)
3765{
3766 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3767 WLANDXE_ChannelCBType *channelCb = NULL;
3768
3769 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003770 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003771
3772 /* Test High Priority Channel is the INT source or not */
3773 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3774
3775 /* Handle TX complete for high priority channel */
3776 status = dxeTXCompFrame(dxeCtxt, channelCb);
3777
3778 /* Test Low Priority Channel interrupt is enabled or not */
3779 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3780
3781 /* Handle TX complete for low priority channel */
3782 status = dxeTXCompFrame(dxeCtxt, channelCb);
3783
3784 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3785 ((dxeCtxt->txCompletedFrames > 0) ||
3786 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3787 {
3788 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3789 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003791 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003792 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3793 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3794 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3795 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07003796
3797 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
3798 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
3799 {
3800 /* After TX Comp processing, still remaining frame on the DXE TX ring
3801 * And when push frame, RING was not empty marked
3802 * Then when push frame, no SMSM toggle happen
3803 * To avoid permanent TX stall, SMSM toggle is needed at here
3804 * With this toggle, host should gaurantee SMSM state should be changed */
Mihir Shete68ed77a2014-10-10 10:47:12 +05303805 dxeNotifySmsm(eWLAN_PAL_TRUE, dxeCtxt->txRingsEmpty);
Leo Changac1d3612013-07-01 15:15:51 -07003806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003807 }
3808
3809 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3810 the posibility of a race*/
3811 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3812
3813 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003814 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003815 return;
3816}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003817
3818/*==========================================================================
3819 @ Function Name
3820 dxeTXReSyncDesc
3821
3822 @ Description
3823 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3824 And HW programmed descriptor.
3825 If any async happen between HW/SW TX stall will happen
3826
3827 @ Parameters
3828 void *msgPtr
3829 Message pointer to sync with TX thread
3830
3831 @ Return
3832 NONE
3833===========================================================================*/
3834void dxeTXReSyncDesc
3835(
3836 wpt_msg *msgPtr
3837)
3838{
3839 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3840 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3841 wpt_uint32 nextDescReg;
3842 WLANDXE_ChannelCBType *channelEntry;
3843 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3844 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003845 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003846
3847 if(NULL == msgContent)
3848 {
3849 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3850 "dxeTXReSyncDesc Invalid Control Block");
3851 return;
3852 }
3853
3854 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3855 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3856 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3857
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003858 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003859 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003860 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3861 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3862 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3863 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3864 &nextDescReg);
3865 /* Async detect without TX pending frame */
3866 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003867 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003868 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003869 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003870 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3871 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303872
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07003873 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
3874 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303875
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003876 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003877 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003878 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003879 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003880 /* Async detect with some TX pending frames
3881 * next descriptor register should sync with first valid descriptor */
3882 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003883 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003884 validCtrlBlk = channelEntry->tailCtrlBlk;
3885 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003886 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003887 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3888 {
3889 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3890 {
3891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3892 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303893
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07003894 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
3895 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303896
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003897 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3898 validCtrlBlk->linkedDescPhyAddr);
3899 }
3900 break;
3901 }
3902 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3903 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3904 {
3905 /* Finished to test till head control blcok, but could not find valid descriptor
3906 * from head to tail all descriptors are invalidated
3907 * host point of view head descriptor is next TX candidate
3908 * So, next descriptor control have to be programmed with head descriptor
3909 * check */
3910 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3911 {
3912 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08003913 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303914
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07003915 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
3916 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303917
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003918 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3919 validCtrlBlk->linkedDescPhyAddr);
3920 }
3921 break;
3922 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003923 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003924 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003925 }
3926
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07003927 /* HW/SW descriptor resync is done.
3928 * Next if there are any valid descriptor in chain, Push to HW again */
3929 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
3930 {
3931 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3932 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
3933 {
3934 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3935 "%11s : No TX Pending frame",
3936 channelType[channelEntry->channelType]);
3937 /* No Pending frame, Do nothing */
3938 }
3939 else
3940 {
3941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3942 "%11s : TX Pending frame, process it",
3943 channelType[channelEntry->channelType]);
3944 validCtrlBlk = channelEntry->tailCtrlBlk;
3945 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
3946 {
3947 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3948 {
3949 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3950 "%11s : when exit IMPS found valid descriptor",
3951 channelType[channelEntry->channelType]);
3952
3953 /* Found valid descriptor, kick DXE */
3954 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3955 channelEntry->extraConfig.chan_mask);
3956 break;
3957 }
3958 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3959 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3960 {
3961 /* Finished to test till head control blcok, but could not find valid descriptor
3962 * from head to tail all descriptors are invalidated */
3963 break;
3964 }
3965 }
3966 }
3967 }
3968
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003969 wpalMemoryFree(msgPtr);
3970 return;
3971}
3972
Jeff Johnson295189b2012-06-20 16:38:30 -07003973/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05303974 @ Function Name
3975 dxeDebugTxDescReSync
3976
3977 @ Description
3978 Check DXE Tx channel state and correct it in
3979 case Tx Data stall is detected by calling
3980 %dxeTXReSyncDesc. Also ensure that WCN SS
3981 is not power collapsed before calling
3982 %dxeTXReSyncDesc
3983
3984 @ Parameters
3985 void *msgPtr
3986 Message pointer to sync with TX thread
3987
3988 @ Return
3989 NONE
3990===========================================================================*/
3991void dxeDebugTxDescReSync
3992(
3993 wpt_msg *msgPtr
3994)
3995{
3996 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3997 "%s: Check for DXE TX Async",__func__);
3998 /* Make wake up HW */
3999 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4000 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4001
4002 wpalSleep(10);
4003
4004 dxeTXReSyncDesc(msgPtr);
4005}
4006/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004007 @ Function Name
4008 dxeTXISR
4009
4010 @ Description
4011 TX interrupt ISR
4012 Platform will call this function if INT is happen
4013 This function must be registered into platform interrupt module
4014
4015 @ Parameters
4016 void *hostCtxt
4017 DXE host driver control context,
4018 pre registerd during interrupt registration
4019
4020 @ Return
4021 PAL_STATUS_T
4022===========================================================================*/
4023static void dxeTXISR
4024(
4025 void *hostCtxt
4026)
4027{
4028 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
4029 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004030
4031 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004032 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004033
4034 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004035 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004036 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004037 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004038 /* Disable interrupt at here,
4039 IMPS or IMPS Pending state should not access RIVA register */
4040 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4041 if(eWLAN_PAL_STATUS_SUCCESS != status)
4042 {
4043 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4044 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4045 return;
4046 }
4047 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4048 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004049 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004050 return;
4051 }
4052
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 /* Disable TX Complete Interrupt at here */
4054 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4055 if(eWLAN_PAL_STATUS_SUCCESS != status)
4056 {
4057 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4058 "dxeTXCompISR Disable TX complete interrupt fail");
4059 return;
4060 }
4061 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4062
4063
4064 if( dxeCtxt->ucTxMsgCnt )
4065 {
4066 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4067 "Avoiding serializing TX Complete event");
4068 return;
4069 }
4070
4071 dxeCtxt->ucTxMsgCnt = 1;
4072
4073 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004074 if(NULL == dxeCtxt->txIsrMsg)
4075 {
4076 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4077 "Invalid message");
4078 HDXE_ASSERT(0);
4079 return;
4080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4082 dxeCtxt->txIsrMsg);
4083 if(eWLAN_PAL_STATUS_SUCCESS != status)
4084 {
4085 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4086 "dxeTXCompISR interrupt serialize fail status=%d", status);
4087 }
4088
4089 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004090 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004091 return;
4092}
4093
4094/*-------------------------------------------------------------------------
4095 * Global Function
4096 *-------------------------------------------------------------------------*/
4097/*==========================================================================
4098 @ Function Name
4099 WLANDXE_Open
4100
4101 @ Description
4102 Open host DXE driver, allocate DXE resources
4103 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4104
4105 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004106 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004107
4108 @ Return
4109 pVoid DXE local module control block pointer
4110===========================================================================*/
4111void *WLANDXE_Open
4112(
4113 void
4114)
4115{
4116 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4117 unsigned int idx;
4118 WLANDXE_ChannelCBType *currentChannel = NULL;
4119 int smsmInitState;
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304120 wpt_uint8 chanMask = WDTS_TRANSPORT_CHANNELS_MASK;
Jeff Johnson295189b2012-06-20 16:38:30 -07004121
4122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004123 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004124
Mihir Shetee6618162015-03-16 14:48:42 +05304125 if (wpalIsFwLoggingEnabled())
4126 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304127 chanMask |= WDTS_RX_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304128 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304129
4130 if (wpalIsFwEvLoggingEnabled())
Mihir Shetee6618162015-03-16 14:48:42 +05304131 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304132 chanMask |= WDTS_RX_FW_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304133 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304134 dxeSetEnabledChannels(chanMask);
Mihir Shetee6618162015-03-16 14:48:42 +05304135
Jeff Johnson295189b2012-06-20 16:38:30 -07004136 /* This is temporary allocation */
4137 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4138 if(NULL == tempDxeCtrlBlk)
4139 {
4140 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4141 "WLANDXE_Open Control Block Alloc Fail");
4142 return NULL;
4143 }
4144 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4145
4146 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4147 if(eWLAN_PAL_STATUS_SUCCESS != status)
4148 {
4149 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4150 "WLANDXE_Open Common Configuration Fail");
4151 WLANDXE_Close(tempDxeCtrlBlk);
4152 return NULL;
4153 }
4154
Mihir Shetee6618162015-03-16 14:48:42 +05304155 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 {
4157 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4158 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4159 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304160 currentChannel->channelType = idx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004161
4162 /* Config individual channels from channel default setup table */
4163 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4164 currentChannel);
4165 if(eWLAN_PAL_STATUS_SUCCESS != status)
4166 {
4167 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4168 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4169 WLANDXE_Close(tempDxeCtrlBlk);
4170 return NULL;
4171 }
4172
4173 /* Allocate DXE Control Block will be used by host DXE driver */
4174 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4175 if(eWLAN_PAL_STATUS_SUCCESS != status)
4176 {
4177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4178 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4179
4180 WLANDXE_Close(tempDxeCtrlBlk);
4181 return NULL;
4182 }
4183 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4184 if(eWLAN_PAL_STATUS_SUCCESS != status)
4185 {
4186 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4187 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4188 WLANDXE_Close(tempDxeCtrlBlk);
4189 return NULL;
4190 }
4191
4192 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4193 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4194 }
4195
4196 /* Allocate and Init RX READY ISR Serialize Buffer */
4197 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4198 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4199 {
4200 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4201 "WLANDXE_Open Alloc RX ISR Fail");
4202 WLANDXE_Close(tempDxeCtrlBlk);
4203 return NULL;
4204 }
4205 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4206 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4207 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4208
4209 /* Allocate and Init TX COMP ISR Serialize Buffer */
4210 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4211 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4212 {
4213 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4214 "WLANDXE_Open Alloc TX ISR Fail");
4215 WLANDXE_Close(tempDxeCtrlBlk);
4216 return NULL;
4217 }
4218 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4219 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4220 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4221
4222 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4223 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4224 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4225 {
4226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4227 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4228 WLANDXE_Close(tempDxeCtrlBlk);
4229 return NULL;
4230 }
4231 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4232 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4233 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4234
4235 tempDxeCtrlBlk->freeRXPacket = NULL;
4236 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4237 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4238 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004239 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004240 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004241
4242 /* Initialize SMSM state
4243 * Init State is
4244 * Clear TX Enable
4245 * RING EMPTY STATE */
4246 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4247 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4248 if(0 != smsmInitState)
4249 {
4250 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4251 "SMSM Channel init fail %d", smsmInitState);
Mihir Shetee6618162015-03-16 14:48:42 +05304252 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004253 {
4254 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4255 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004256 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4257 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 wpalMemoryFree(tempDxeCtrlBlk);
4259 return NULL;
4260 }
4261
Mihir Shete44547fb2014-03-10 14:15:42 +05304262#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004263 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4264 dxeRXResourceAvailableTimerExpHandler,
4265 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304266#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004267
Mihir Shetefdc9f532014-01-09 15:03:02 +05304268 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4269 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4270
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4272 "WLANDXE_Open Success");
4273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004274 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004275 return (void *)tempDxeCtrlBlk;
4276}
4277
4278/*==========================================================================
4279 @ Function Name
4280 WLANDXE_ClientRegistration
4281
4282 @ Description
4283 Make callback functions registration into DXE driver from DXE driver client
4284
4285 @ Parameters
4286 pVoid pDXEContext : DXE module control block
Mihir Shetec4093f92015-05-28 15:21:11 +05304287 WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events
Jeff Johnson295189b2012-06-20 16:38:30 -07004288 void *userContext : DXE Cliennt control block
4289
4290 @ Return
4291 wpt_status
4292===========================================================================*/
4293wpt_status WLANDXE_ClientRegistration
4294(
4295 void *pDXEContext,
Mihir Shetec4093f92015-05-28 15:21:11 +05304296 WDTS_ClientCallbacks WDTSCb,
Jeff Johnson295189b2012-06-20 16:38:30 -07004297 void *userContext
4298)
4299{
4300 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4301 WLANDXE_CtrlBlkType *dxeCtxt;
4302
4303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004304 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004305
4306 /* Sanity */
4307 if(NULL == pDXEContext)
4308 {
4309 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4310 "WLANDXE_ClientRegistration Invalid DXE CB");
4311 return eWLAN_PAL_STATUS_E_INVAL;
4312 }
4313
Jeff Johnson295189b2012-06-20 16:38:30 -07004314 if(NULL == userContext)
4315 {
4316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4317 "WLANDXE_ClientRegistration Invalid userContext");
4318 return eWLAN_PAL_STATUS_E_INVAL;
4319 }
4320
4321 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4322
4323 /* Assign */
Mihir Shetec4093f92015-05-28 15:21:11 +05304324 dxeCtxt->rxReadyCB = WDTSCb.rxFrameReadyCB;
4325 dxeCtxt->txCompCB = WDTSCb.txCompleteCB;
4326 dxeCtxt->lowResourceCB = WDTSCb.lowResourceCB;
4327 dxeCtxt->receiveMbMsgCB = WDTSCb.receiveMbMsgCB;
Jeff Johnson295189b2012-06-20 16:38:30 -07004328 dxeCtxt->clientCtxt = userContext;
4329
4330 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004331 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004332 return status;
4333}
4334
4335/*==========================================================================
4336 @ Function Name
4337 WLANDXE_Start
4338
4339 @ Description
4340 Start Host DXE driver
4341 Initialize DXE channels and start channel
4342
4343 @ Parameters
4344 pVoid pDXEContext : DXE module control block
4345
4346 @ Return
4347 wpt_status
4348===========================================================================*/
4349wpt_status WLANDXE_Start
4350(
4351 void *pDXEContext
4352)
4353{
4354 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4355 wpt_uint32 idx;
4356 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4357
4358 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004359 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004360
4361 /* Sanity */
4362 if(NULL == pDXEContext)
4363 {
4364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4365 "WLANDXE_Start Invalid DXE CB");
4366 return eWLAN_PAL_STATUS_E_INVAL;
4367 }
4368 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4369
4370 /* WLANDXE_Start called means DXE engine already initiates
4371 * And DXE HW is reset and init finished
4372 * But here to make sure HW is initialized, reset again */
4373 status = dxeEngineCoreStart(dxeCtxt);
4374 if(eWLAN_PAL_STATUS_SUCCESS != status)
4375 {
4376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4377 "WLANDXE_Start DXE HW init Fail");
4378 return status;
4379 }
4380
4381 /* Individual Channel Start */
Mihir Shetee6618162015-03-16 14:48:42 +05304382 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 {
4384 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4385 "WLANDXE_Start Channel %s Start", channelType[idx]);
4386
4387 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4388 /* Make connection between DXE descriptor and DXE control block */
4389 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4390 if(eWLAN_PAL_STATUS_SUCCESS != status)
4391 {
4392 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4393 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4394 return status;
4395 }
4396
4397 /* Program each channel register with configuration arguments */
4398 status = dxeChannelInitProgram(dxeCtxt,
4399 &dxeCtxt->dxeChannel[idx]);
4400 if(eWLAN_PAL_STATUS_SUCCESS != status)
4401 {
4402 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4403 "WLANDXE_Start %d Program DMA channel Fail", idx);
4404 return status;
4405 }
4406
4407 /* ??? Trigger to start DMA channel
4408 * This must be seperated from ??? */
4409 status = dxeChannelStart(dxeCtxt,
4410 &dxeCtxt->dxeChannel[idx]);
4411 if(eWLAN_PAL_STATUS_SUCCESS != status)
4412 {
4413 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4414 "WLANDXE_Start %d Channel Start Fail", idx);
4415 return status;
4416 }
4417 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4418 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4419 }
4420
4421 /* Register ISR to OS */
4422 /* Register TX complete interrupt into platform */
4423 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4424 dxeTXISR,
4425 dxeCtxt);
4426 if(eWLAN_PAL_STATUS_SUCCESS != status)
4427 {
4428 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4429 "WLANDXE_Start TX comp interrupt registration Fail");
4430 return status;
4431 }
4432
4433 /* Register RX ready interrupt into platform */
4434 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4435 dxeRXISR,
4436 dxeCtxt);
4437 if(eWLAN_PAL_STATUS_SUCCESS != status)
4438 {
4439 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4440 "WLANDXE_Start RX Ready interrupt registration Fail");
4441 return status;
4442 }
4443
4444 /* Enable system level ISR */
4445 /* Enable RX ready Interrupt at here */
4446 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4447 if(eWLAN_PAL_STATUS_SUCCESS != status)
4448 {
4449 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4450 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4451 return status;
4452 }
4453
4454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004455 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004456 return status;
4457}
4458
4459/*==========================================================================
4460 @ Function Name
4461 WLANDXE_TXFrame
4462
4463 @ Description
4464 Trigger frame transmit from host to RIVA
4465
4466 @ Parameters
4467 pVoid pDXEContext : DXE Control Block
4468 wpt_packet pPacket : transmit packet structure
4469 WDTS_ChannelType channel : TX channel
4470
4471 @ Return
4472 wpt_status
4473===========================================================================*/
4474wpt_status WLANDXE_TxFrame
4475(
4476 void *pDXEContext,
4477 wpt_packet *pPacket,
4478 WDTS_ChannelType channel
4479)
4480{
4481 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4482 WLANDXE_ChannelCBType *currentChannel = NULL;
4483 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4484 unsigned int *lowThreshold = NULL;
4485
4486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004487 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004488
4489 /* Sanity */
4490 if(NULL == pDXEContext)
4491 {
4492 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4493 "WLANDXE_Start Invalid DXE CB");
4494 return eWLAN_PAL_STATUS_E_INVAL;
4495 }
4496
4497 if(NULL == pPacket)
4498 {
4499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4500 "WLANDXE_Start Invalid pPacket");
4501 return eWLAN_PAL_STATUS_E_INVAL;
4502 }
4503
Mihir Shetee6618162015-03-16 14:48:42 +05304504 if(WDTS_CHANNEL_MAX <= channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004505 {
4506 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4507 "WLANDXE_Start Invalid channel");
4508 return eWLAN_PAL_STATUS_E_INVAL;
4509 }
4510
4511 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4512
4513 currentChannel = &dxeCtxt->dxeChannel[channel];
4514
4515
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004516 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4517 if(eWLAN_PAL_STATUS_SUCCESS != status)
4518 {
4519 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4520 "WLANDXE_TxFrame Mutex Acquire fail");
4521 return status;
4522 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004523
4524 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4525 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4526 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4527
4528 /* Decide have to activate TX complete event or not */
4529 switch(dxeCtxt->txCompInt.txIntEnable)
4530 {
4531 /* TX complete interrupt will be activated when low DXE resource */
4532 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4533 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4534 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4535 {
4536 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4537 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4538 channel,
4539 eWLAN_PAL_FALSE);
4540 }
4541 break;
4542
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004543 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4545 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4546 {
4547 currentChannel->numFrameBeforeInt++;
4548 }
4549 break;
4550
4551 /* TX complete interrupt will be activated periodically */
4552 case WLANDXE_TX_COMP_INT_TIMER:
4553 break;
4554 }
4555
4556 dxeCtxt->txCompletedFrames++;
4557
4558 /* Update DXE descriptor, this is frame based
4559 * if a frame consist of N fragments, N Descriptor will be programed */
4560 status = dxeTXPushFrame(currentChannel, pPacket);
4561 if(eWLAN_PAL_STATUS_SUCCESS != status)
4562 {
4563 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4564 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004565 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4566 if(eWLAN_PAL_STATUS_SUCCESS != status)
4567 {
4568 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4569 "WLANDXE_TxFrame Mutex Release fail");
4570 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004571 return status;
4572 }
4573
4574 /* If specific channel hit low resource condition, send notification to upper layer */
4575 if(currentChannel->numFreeDesc <= *lowThreshold)
4576 {
4577 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4578 channel,
4579 eWLAN_PAL_FALSE);
4580 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004581
4582 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4583 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4584 channelType[currentChannel->channelType],
4585 currentChannel->numRsvdDesc);
Mihir Shete68ed77a2014-10-10 10:47:12 +05304586 if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4587 {
4588 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4589 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004591 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004592 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4593 if(eWLAN_PAL_STATUS_SUCCESS != status)
4594 {
4595 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4596 "WLANDXE_TxFrame Mutex Release fail");
4597 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004598
4599 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004600 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004601 return status;
4602}
4603
4604/*==========================================================================
4605 @ Function Name
4606 WLANDXE_CompleteTX
4607
4608 @ Description
4609 Informs DXE that the current series of Tx packets is complete
4610
4611 @ Parameters
4612 pContext pDXEContext : DXE Control Block
4613 ucTxResReq TX resource number required by TL/WDI
4614
4615 @ Return
4616 wpt_status
4617===========================================================================*/
4618wpt_status
4619WLANDXE_CompleteTX
4620(
4621 void* pContext,
4622 wpt_uint32 ucTxResReq
4623)
4624{
4625 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4626 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4627 WLANDXE_ChannelCBType *channelCb = NULL;
4628 wpt_boolean inLowRes;
4629
4630 /* Sanity Check */
4631 if( NULL == pContext )
4632 {
4633 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4634 "WLANDXE_CompleteTX invalid param");
4635 return eWLAN_PAL_STATUS_E_INVAL;
4636 }
4637
4638 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4639 inLowRes = channelCb->hitLowResource;
4640
4641 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4642 {
4643 /* Raise threshold temporarily if necessary */
4644 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4645
4646 if(eWLAN_PAL_FALSE == inLowRes)
4647 {
4648 /* Put the channel to low resource condition */
4649 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4650 WDTS_CHANNEL_TX_LOW_PRI,
4651 eWLAN_PAL_FALSE);
4652 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
4653 }
4654 }
4655
4656 /*Try to reclaim resources*/
4657 dxeTXCompleteProcessing(dxeCtxt);
4658
4659 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4660 because its fragment size is larger than DXE free resource. */
4661 if(0 < ucTxResReq)
4662 {
4663 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4664 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4665 {
4666 /* DXE has not been in low resource condition. DXE forces to kick off
4667 TX tranmit */
4668 if((eWLAN_PAL_FALSE == inLowRes) &&
4669 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4670 {
4671 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4672 WDTS_CHANNEL_TX_LOW_PRI,
4673 eWLAN_PAL_FALSE);
4674 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4675 WDTS_CHANNEL_TX_LOW_PRI,
4676 eWLAN_PAL_TRUE);
4677 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4678 }
4679 }
4680 else
4681 {
4682 /* DXE doesn't have enough free DXE resources. Put the channel
4683 to low resource condition. */
4684 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4685 {
4686 /* Put the channel to low resource condition */
4687 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4688 WDTS_CHANNEL_TX_LOW_PRI,
4689 eWLAN_PAL_FALSE);
4690 channelCb->hitLowResource = eWLAN_PAL_TRUE;
4691 }
4692 }
4693 }
4694
4695 return status;
4696}
4697
4698/*==========================================================================
4699 @ Function Name
4700 WLANDXE_Stop
4701
4702 @ Description
4703 Stop DXE channels and DXE engine operations
4704 Disable all channel interrupt
4705 Stop all channel operation
4706
4707 @ Parameters
4708 pVoid pDXEContext : DXE Control Block
4709
4710 @ Return
4711 wpt_status
4712===========================================================================*/
4713wpt_status WLANDXE_Stop
4714(
4715 void *pDXEContext
4716)
4717{
4718 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4719 wpt_uint32 idx;
4720 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4721
4722 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004723 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004724
4725 /* Sanity */
4726 if(NULL == pDXEContext)
4727 {
4728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4729 "WLANDXE_Stop Invalid DXE CB");
4730 return eWLAN_PAL_STATUS_E_INVAL;
4731 }
4732
4733 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shetee6618162015-03-16 14:48:42 +05304734 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004735 {
4736 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4737 if(eWLAN_PAL_STATUS_SUCCESS != status)
4738 {
4739 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4740 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07004741 }
4742 }
4743
4744 /* During Stop unregister interrupt */
4745 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4746 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4747
Mihir Shete44547fb2014-03-10 14:15:42 +05304748#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004749 if(VOS_TIMER_STATE_STOPPED !=
4750 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
4751 {
4752 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
4753 }
Mihir Shete44547fb2014-03-10 14:15:42 +05304754#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004755
Jeff Johnson295189b2012-06-20 16:38:30 -07004756 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004757 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004758 return status;
4759}
4760
4761/*==========================================================================
4762 @ Function Name
4763 WLANDXE_Close
4764
4765 @ Description
4766 Close DXE channels
4767 Free DXE related resources
4768 DXE descriptor free
4769 Descriptor control block free
4770 Pre allocated RX buffer free
4771
4772 @ Parameters
4773 pVoid pDXEContext : DXE Control Block
4774
4775 @ Return
4776 wpt_status
4777===========================================================================*/
4778wpt_status WLANDXE_Close
4779(
4780 void *pDXEContext
4781)
4782{
4783 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4784 wpt_uint32 idx;
4785 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004786
4787 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004788 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004789
4790 /* Sanity */
4791 if(NULL == pDXEContext)
4792 {
4793 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4794 "WLANDXE_Stop Invalid DXE CB");
4795 return eWLAN_PAL_STATUS_E_INVAL;
4796 }
4797
4798 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05304799#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004800 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05304801#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05304802 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Mihir Shetee6618162015-03-16 14:48:42 +05304803 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004804 {
4805 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
4806 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 }
4808
4809 if(NULL != dxeCtxt->rxIsrMsg)
4810 {
4811 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4812 }
4813 if(NULL != dxeCtxt->txIsrMsg)
4814 {
4815 wpalMemoryFree(dxeCtxt->txIsrMsg);
4816 }
4817 if(NULL != dxeCtxt->rxPktAvailMsg)
4818 {
4819 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4820 }
4821
4822 wpalMemoryFree(pDXEContext);
4823
4824 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004825 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004826 return status;
4827}
4828
4829/*==========================================================================
4830 @ Function Name
4831 WLANDXE_TriggerTX
4832
4833 @ Description
4834 TBD
4835
4836 @ Parameters
4837 pVoid pDXEContext : DXE Control Block
4838
4839 @ Return
4840 wpt_status
4841===========================================================================*/
4842wpt_status WLANDXE_TriggerTX
4843(
4844 void *pDXEContext
4845)
4846{
4847 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4848
4849 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004850 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004851
4852 /* TBD */
4853
4854 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004855 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 return status;
4857}
4858
4859/*==========================================================================
4860 @ Function Name
4861 dxeTxThreadSetPowerStateEventHandler
4862
4863 @ Description
4864 If WDI sends set power state req, this event handler will be called in Tx
4865 thread context
4866
4867 @ Parameters
4868 void *msgPtr
4869 Event MSG
4870
4871 @ Return
4872 None
4873===========================================================================*/
4874void dxeTxThreadSetPowerStateEventHandler
4875(
4876 wpt_msg *msgPtr
4877)
4878{
4879 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4880 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05304881 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004882 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05304883 wpt_int8 i;
4884 WLANDXE_ChannelCBType *channelEntry;
4885 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07004886
4887 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004888 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004889
Jeff Johnson295189b2012-06-20 16:38:30 -07004890 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4891 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4892 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4893
4894 switch(reqPowerState)
4895 {
4896 case WLANDXE_POWER_STATE_BMPS:
4897 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4898 {
4899 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4900 //based on amount of TX and RX activity - during this time any received
4901 // management frames will remain un-processed consuming RX buffers
4902 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4903 dxeCtxt->hostPowerState = reqPowerState;
4904 }
4905 else
4906 {
4907 status = eWLAN_PAL_STATUS_E_INVAL;
4908 }
4909 break;
4910 case WLANDXE_POWER_STATE_IMPS:
4911 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4912 {
Mihir Shetea4306052014-03-25 00:02:54 +05304913
4914 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
4915 {
4916 channelEntry = &dxeCtxt->dxeChannel[i];
4917 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
4918 {
4919 status = eWLAN_PAL_STATUS_E_FAILURE;
4920 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4921 "%11s : %s :TX Pending frame",
4922 channelType[channelEntry->channelType], __func__);
4923
4924 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
4925 dxeDescriptorDump(channelEntry,
4926 channelEntry->headCtrlBlk->linkedDesc, 0);
4927 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
4928 &channelLog);
4929 dxeChannelAllDescDump(channelEntry,
4930 channelEntry->channelType,
4931 &channelLog);
4932 }
4933 }
4934
4935 if (eWLAN_PAL_STATUS_SUCCESS == status)
4936 {
4937 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4938 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
4939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 }
4941 else
4942 {
4943 status = eWLAN_PAL_STATUS_E_INVAL;
4944 }
4945 break;
4946 case WLANDXE_POWER_STATE_FULL:
4947 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4948 {
4949 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4950 }
4951 dxeCtxt->hostPowerState = reqPowerState;
4952 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4953 break;
4954 case WLANDXE_POWER_STATE_DOWN:
4955 WLANDXE_Stop((void *)dxeCtxt);
4956 break;
4957 default:
4958 //assert
4959 break;
4960 }
4961
4962 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4963 {
4964 dxeCtxt->setPowerStateCb(status,
4965 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4966 }
Ravali85acf6b2012-12-12 14:01:38 -08004967 else
4968 {
4969 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4970 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
4971 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004972 /* Free MSG buffer */
4973 wpalMemoryFree(msgPtr);
4974 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004975 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 return;
4977}
4978
4979
4980/*==========================================================================
4981 @ Function Name
4982 dxeRxThreadSetPowerStateEventHandler
4983
4984 @ Description
4985 If WDI sends set power state req, this event handler will be called in Rx
4986 thread context
4987
4988 @ Parameters
4989 void *msgPtr
4990 Event MSG
4991
4992 @ Return
4993 None
4994===========================================================================*/
4995void dxeRxThreadSetPowerStateEventHandler
4996(
4997 wpt_msg *msgPtr
4998)
4999{
5000 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5001
5002 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005003 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005004
5005 /* Now serialise the message through Tx thread also to make sure
5006 * no register access when RIVA is in powersave */
5007 /*Use the same message pointer just change the call back function */
5008 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5009 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5010 msgPtr);
5011 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5012 {
5013 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5014 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005015 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 }
5017
5018 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005019 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005020}
5021
5022/*==========================================================================
5023 @ Function Name
5024 WLANDXE_SetPowerState
5025
5026 @ Description
5027 From Client let DXE knows what is the WLAN HW(RIVA) power state
5028
5029 @ Parameters
5030 pVoid pDXEContext : DXE Control Block
5031 WLANDXE_PowerStateType powerState
5032
5033 @ Return
5034 wpt_status
5035===========================================================================*/
5036wpt_status WLANDXE_SetPowerState
5037(
5038 void *pDXEContext,
5039 WDTS_PowerStateType powerState,
5040 WDTS_SetPSCbType cBack
5041)
5042{
5043 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5044 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5045 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005046 wpt_msg *rxCompMsg;
5047 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005048
5049 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005050 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 if(NULL == pDXEContext)
5052 {
5053 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005054 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 return eWLAN_PAL_STATUS_E_FAILURE;
5056 }
5057 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5058
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 switch(powerState)
5060 {
5061 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005062 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5063 {
5064 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5065 if(NULL == txDescReSyncMsg)
5066 {
5067 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5068 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5069 }
5070 else
5071 {
5072 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5073 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5074 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5075 txDescReSyncMsg);
5076 if(eWLAN_PAL_STATUS_SUCCESS != status)
5077 {
5078 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5079 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5080 }
5081 }
5082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005083 hostPowerState = WLANDXE_POWER_STATE_FULL;
5084 break;
5085 case WDTS_POWER_STATE_BMPS:
5086 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5087 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5088 break;
5089 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5091 break;
5092 case WDTS_POWER_STATE_DOWN:
5093 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5094 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5095 break;
5096 default:
5097 hostPowerState = WLANDXE_POWER_STATE_MAX;
5098 }
5099
5100 // A callback i.e. ACK back is needed only when we want to enable BMPS
5101 // and the data/management path is active because we want to ensure
5102 // DXE registers are not accessed when RIVA may be power-collapsed. So
5103 // we need a callback in enter_bmps_req (the request to RIVA is sent
5104 // only after ACK back from TX thread). A callback is not needed in
5105 // finish_scan_req during BMPS since data-path is resumed only in
5106 // finish_scan_rsp and no management frames are sent in between. No
5107 // callback is needed when going from BMPS enabled to BMPS suspended/
5108 // disabled when it is known that RIVA is awake and cannot enter power
5109 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5110 // init_scan_rsp
5111 if ( cBack )
5112 {
5113 //serialize through Rx thread
5114 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5115 if(NULL == rxCompMsg)
5116 {
5117 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5118 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5119 return eWLAN_PAL_STATUS_E_RESOURCES;
5120 }
5121
5122 /* Event type, where it must be defined???? */
5123 /* THIS MUST BE CLEARED ASAP
5124 txCompMsg->type = TX_COMPLETE; */
5125 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5126 rxCompMsg->pContext = pDxeCtrlBlk;
5127 rxCompMsg->val = hostPowerState;
5128 rxCompMsg->ptr = cBack;
5129 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5130 rxCompMsg);
5131 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5132 {
5133 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5134 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005135 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005136 }
5137 }
5138 else
5139 {
5140 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5141 {
5142 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5143 {
5144 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5145 }
5146 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5147 {
5148 /* Requested Full power from exit IMPS, reenable the interrupts*/
5149 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5150 {
5151 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5152 /* Enable RX interrupt at here, if new PS is not IMPS */
5153 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5154 if(eWLAN_PAL_STATUS_SUCCESS != status)
5155 {
5156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005157 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 return status;
5159 }
5160 }
5161 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5162 {
5163 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005164 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005165 /* Enable RX interrupt at here, if new PS is not IMPS */
5166 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5167 if(eWLAN_PAL_STATUS_SUCCESS != status)
5168 {
5169 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005170 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005171 return status;
5172 }
5173 }
5174 }
5175 pDxeCtrlBlk->hostPowerState = hostPowerState;
5176 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5177 }
5178 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5179 {
5180 pDxeCtrlBlk->hostPowerState = hostPowerState;
5181 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5182 }
Mihir Shetea4306052014-03-25 00:02:54 +05305183 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5184 {
5185 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005187 else
5188 {
5189 HDXE_ASSERT(0);
5190 }
5191 }
5192
5193 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005194 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005195
5196 return status;
5197}
5198
5199/*==========================================================================
5200 @ Function Name
5201 WLANDXE_GetFreeTxDataResNumber
5202
5203 @ Description
5204 Returns free descriptor numbers for TX data channel (TX high priority)
5205
5206 @ Parameters
5207 pVoid pDXEContext : DXE Control Block
5208
5209 @ Return
5210 wpt_uint32 Free descriptor number of TX high pri ch
5211===========================================================================*/
5212wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5213(
5214 void *pDXEContext
5215)
5216{
5217 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005218 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005219
5220 if(NULL == pDXEContext)
5221 {
5222 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005223 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 return (0);
5225 }
5226
Mihir Shetee6618162015-03-16 14:48:42 +05305227 return ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005228}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005229
5230/*==========================================================================
5231 @ Function Name
5232 WLANDXE_ChannelDebug
5233
5234 @ Description
5235 Display DXE Channel debugging information
5236 User may request to display DXE channel snapshot
5237 Or if host driver detects any abnormal stcuk may display
5238
5239 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005240 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305241 debugFlags : Enable stall detect features
5242 defined by WPAL_DeviceDebugFlags
5243 These features may effect
5244 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005245
5246 @ Return
5247 NONE
5248
5249===========================================================================*/
5250void WLANDXE_ChannelDebug
5251(
Mihir Shete40a55652014-03-02 14:14:47 +05305252 wpt_boolean displaySnapshot,
5253 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005254)
5255{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005256 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305257 wpt_msg *txDescReSyncMsg ;
Mihir Shete41c41bb2014-08-18 17:37:12 +05305258 wpt_uint32 regValue, regValueLocal = 0;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005259 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5260
5261 /* Debug Type 1, Display current snapshot */
5262 if(displaySnapshot)
5263 {
5264 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5265 * This will not simply wakeup RIVA
5266 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005267 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5268 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005269 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005270 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005271 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
Mihir Shete41c41bb2014-08-18 17:37:12 +05305272#ifdef WCN_PRONTO
5273 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
5274#endif
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005275 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305276 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====",
Leo Chang345ef992013-07-12 10:17:29 -07005277 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305278 tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005279
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005280 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5281 &regValue,
5282 NULL,
5283 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005284
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005285 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5286 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005287 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005288 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5289 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5290 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005291 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005292
5293 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5294 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5295 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005296 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005297 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5298 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005299 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005300 }
5301 }
5302
Mihir Shete40a55652014-03-02 14:14:47 +05305303 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005304 {
Mihir Shete40a55652014-03-02 14:14:47 +05305305 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5306 if(NULL == txDescReSyncMsg)
5307 {
5308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5309 "%s: Resync MSG MEM alloc Fail",__func__);
5310 }
5311 else
5312 {
5313 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5314 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5315 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5316 txDescReSyncMsg);
5317 if(eWLAN_PAL_STATUS_SUCCESS != status)
5318 {
5319 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5320 "%s: Post TX re-sync MSG fail",__func__);
5321 }
5322 }
5323 }
5324
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005325 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005326}