blob: 4e9f1b28bb9506fd711e0e93fd1d919ce5d83342 [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;
Mihir Shete5affadc2015-05-29 20:54:57 +05301888
1889 if (channelEntry->channelType == WDTS_CHANNEL_RX_FW_LOG)
1890 wpalPacketRawTrimHead(currentCtrlBlock->xfrFrame, WLANDXE_H2H_HEADER_OFFSET);
1891
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
Mihir Shetebc338242015-03-04 15:34:19 +05301893
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 if(eWLAN_PAL_STATUS_SUCCESS != status)
1895 {
1896 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1897 "dxeRXFrameBufferAlloc unable to lock packet");
1898 return status;
1899 }
1900
1901 /* Init iterator to get physical os buffer address */
1902 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1903 if(eWLAN_PAL_STATUS_SUCCESS != status)
1904 {
1905 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1906 "dxeRXFrameBufferAlloc iterator init fail");
1907 return status;
1908 }
1909 status = wpalIteratorNext(&iterator,
1910 currentPalPacketBuffer,
1911 &physAddress,
1912 &allocatedSize);
1913 if(eWLAN_PAL_STATUS_SUCCESS != status)
1914 {
1915 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1916 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1917 return status;
1918 }
1919 currentPalPacketBuffer->pBDPhys = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07001920
1921 /* DXE descriptor must have SWAPPED addres in it's structure
1922 * !!! SWAPPED !!! */
1923 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301924 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07001925
Jeff Johnson295189b2012-06-20 16:38:30 -07001926 return status;
1927}
1928
1929/*==========================================================================
1930 @ Function Name
1931 dxeRXFrameRefillRing
1932
1933 @ Description
1934 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1935
1936 @ Parameters
1937 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1938 DXE host driver main control block
1939 WLANDXE_ChannelCBType *channelEntry
1940 Channel specific control block
1941
1942 @ Return
1943 wpt_status
1944
1945===========================================================================*/
1946static wpt_status dxeRXFrameRefillRing
1947(
1948 WLANDXE_CtrlBlkType *dxeCtxt,
1949 WLANDXE_ChannelCBType *channelEntry
1950)
1951{
1952 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1953 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
1954 WLANDXE_DescType *currentDesc = NULL;
1955
1956 while(channelEntry->numFreeDesc > 0)
1957 {
1958 /* Current Control block is free
1959 * and associated frame buffer is not linked with control block anymore
1960 * allocate new frame buffer for current control block */
1961 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
1962 channelEntry,
1963 currentCtrlBlk);
1964
Leo Chang7e05f212013-07-01 19:54:15 -07001965 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
1966 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 {
1968 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1969 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
1970 break;
1971 }
1972
Leo Chang7e05f212013-07-01 19:54:15 -07001973 if(eWLAN_PAL_STATUS_E_EXISTS == status)
1974 {
1975 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1976 "dxeRXFrameRefillRing, Descriptor Non-Empry");
1977 }
1978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 currentDesc = currentCtrlBlk->linkedDesc;
1980 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1981
1982 /* Issue a dummy read from the DXE descriptor DDR location to ensure
1983 that any posted writes are reflected in memory before DXE looks at
1984 the descriptor. */
1985 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
1986 {
Karthick S3254c5d2015-04-28 15:06:17 +05301987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1988 "dxeRXFrameRefillRing, Descriptor write failed");
1989 ++channelEntry->desc_write_fail_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 //HDXE_ASSERT(0);
1991 }
1992
1993 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07001994 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 {
1996 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
1997 1 << channelEntry->assignedDMAChannel);
1998 }
1999 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07002000 if(eWLAN_PAL_STATUS_E_EXISTS != status)
2001 {
2002 --channelEntry->numFreeDesc;
2003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 }
2005
2006 channelEntry->tailCtrlBlk = currentCtrlBlk;
2007
2008 return status;
2009}
2010
Mihir Shete5affadc2015-05-29 20:54:57 +05302011static wpt_uint32 dxeRXLogRefillRing
2012(
2013 WLANDXE_CtrlBlkType *dxeCtxt,
2014 WLANDXE_ChannelCBType *channelEntry,
2015 wpt_uint64 bufferAddr,
2016 wpt_uint32 bufferLen
2017)
2018{
2019 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2020 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2021 WLANDXE_DescType *currentDesc = NULL;
2022 wpt_uint32 xfrSize, allocatedLen = 0;
2023
2024 while(bufferLen > 0)
2025 {
2026 /* Current Control block is free
2027 * and associated frame buffer is not linked with control block anymore
2028 * allocate new frame buffer for current control block */
2029 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2030 channelEntry,
2031 currentCtrlBlk);
2032
2033 if((eWLAN_PAL_STATUS_SUCCESS != status))
2034 {
2035 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2036 "%s, out of RX buffer pool, break here",__func__);
2037 break;
2038 }
2039
2040 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2041 {
2042 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2043 "%s, Descriptor Non-Empty",__func__);
2044 }
2045
2046 currentDesc = currentCtrlBlk->linkedDesc;
2047 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2048 xfrSize = WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE > bufferLen ?
2049 bufferLen : WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE;
2050 currentDesc->xfrSize = xfrSize;
2051 allocatedLen += xfrSize;
2052 bufferLen -= xfrSize;
2053 wpalPacketSetRxLength(currentCtrlBlk->xfrFrame,
2054 xfrSize);
2055
2056 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2057 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)bufferAddr);
2058
2059 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2060 that any posted writes are reflected in memory before DXE looks at
2061 the descriptor. */
2062 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2063 {
2064 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2065 "%s, Descriptor write failed",__func__);
2066 ++channelEntry->desc_write_fail_count;
2067 }
2068
2069 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2070 --channelEntry->numFreeDesc;
2071 bufferAddr += xfrSize;
2072 }
2073
2074 channelEntry->tailCtrlBlk = currentCtrlBlk;
2075
2076 return allocatedLen;
2077}
Jeff Johnson295189b2012-06-20 16:38:30 -07002078/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002079 @ Function Name
2080 dxeRXFrameRouteUpperLayer
2081
2082 @ Description
2083 Test DXE descriptors and if any RX frame pending within RING,
2084 Route to upper layer
2085
2086 @ Parameters
2087 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2088 DXE host driver main control block
2089 WLANDXE_ChannelCBType *channelEntry
2090 Channel specific control block
2091 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002092 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002093 0 No frame pulled from RX RING
2094 int number of RX frames pulled from RX ring
2095
2096===========================================================================*/
2097static wpt_int32 dxeRXFrameRouteUpperLayer
2098(
2099 WLANDXE_CtrlBlkType *dxeCtxt,
2100 WLANDXE_ChannelCBType *channelEntry
2101)
2102{
2103 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2104 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2105 WLANDXE_DescType *currentDesc = NULL;
2106 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002107 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002108
2109 currentCtrlBlk = channelEntry->headCtrlBlk;
2110 currentDesc = currentCtrlBlk->linkedDesc;
2111
2112 /* Descriptoe should be SWAPPED ???? */
2113 descCtrl = currentDesc->descCtrl.ctrl;
2114
2115 /* Get frames while VALID bit is not set (DMA complete) and a data
2116 * associated with it */
2117 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2118 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2119 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2120 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2121 {
2122 channelEntry->numTotalFrame++;
2123 channelEntry->numFreeDesc++;
Jeff Johnsone7245742012-09-05 17:12:55 -07002124 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
Mihir Shetebc338242015-03-04 15:34:19 +05302125
Jeff Johnsone7245742012-09-05 17:12:55 -07002126 if (eWLAN_PAL_STATUS_SUCCESS != status)
2127 {
2128 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2129 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002130 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002131 }
Mihir Shetebc338242015-03-04 15:34:19 +05302132
Jeff Johnsone7245742012-09-05 17:12:55 -07002133 /* This Descriptor is valid, so linked Control block is also valid
2134 * Linked Control block has pre allocated packet buffer
2135 * So, just let upper layer knows preallocated frame pointer will be OK */
2136 /* Reap Rx frames */
2137 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2138 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002139 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002140
2141 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Mihir Shete5affadc2015-05-29 20:54:57 +05302142 if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType)
2143 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002144
2145 /* Test next contorl block
2146 * if valid, this control block also has new RX frame must be handled */
2147 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2148 currentDesc = currentCtrlBlk->linkedDesc;
2149 descCtrl = currentDesc->descCtrl.ctrl;
2150 }
2151
2152 /* Update head control block
2153 * current control block's valid bit was 0
2154 * next trial first control block must be current control block */
2155 channelEntry->headCtrlBlk = currentCtrlBlk;
2156
2157 /* Deliver all the reaped RX frames to upper layers */
2158 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002159 while(i < frameCount)
2160 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002161 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2162 i++;
2163 }
2164
2165 return frameCount;
2166}
2167
2168/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002169 @ Function Name
2170 dxeRXFrameReady
2171
2172 @ Description
2173 Pop frame from descriptor and route frame to upper transport layer
2174 Assign new platform packet buffer into used descriptor
2175 Actual frame pop and resource realloc
2176
2177 @ Parameters
2178 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2179 DXE host driver main control block
2180 WLANDXE_ChannelCBType *channelEntry
2181 Channel specific control block
2182
2183 @ Return
2184 wpt_status
2185
2186===========================================================================*/
2187static wpt_status dxeRXFrameReady
2188(
2189 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002190 WLANDXE_ChannelCBType *channelEntry,
2191 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002192)
2193{
2194 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2195 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2196 WLANDXE_DescType *currentDesc = NULL;
2197 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002198 wpt_int32 frameCount = 0;
2199
2200 wpt_uint32 descLoop;
2201 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002202
2203 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002204 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002205
2206 /* Sanity Check */
2207 if((NULL == dxeCtxt) || (NULL == channelEntry))
2208 {
2209 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2210 "dxeRXFrameReady Channel Entry is not valid");
2211 return eWLAN_PAL_STATUS_E_INVAL;
2212 }
2213
Jeff Johnsone7245742012-09-05 17:12:55 -07002214 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002215
Jeff Johnsone7245742012-09-05 17:12:55 -07002216 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002217 {
2218 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002219 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002220 return eWLAN_PAL_STATUS_E_INVAL;
2221 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002222
Leo Changd6de1c22013-03-21 15:42:41 -07002223 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002224 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2225 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2226 {
Leo Changd6de1c22013-03-21 15:42:41 -07002227 /* None of the frame handled and CH is not enabled
2228 * RX CH wrap around happen and No RX free frame
2229 * RX side should wait till new free frame available in the pool
2230 * Do not try reload driver at here*/
2231 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2232 {
Leo Changbbf86b72013-06-19 16:13:00 -07002233 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002234 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2235 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002236 /* This is not empty interrupt case
2237 * If handle this as empty interrupt, false SSR might be issued
2238 * Frame count '1' is dummy frame count to avoid SSR */
2239 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002240 return eWLAN_PAL_STATUS_SUCCESS;
2241 }
2242
Jeff Johnsone7245742012-09-05 17:12:55 -07002243 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 currentDesc = currentCtrlBlk->linkedDesc;
2245 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002246
2247 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2248 {
2249 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2250 "RX ISR called but no frame handled PWS %d, channel %s",
2251 (int)dxeCtxt->hostPowerState,
2252 channelType[channelEntry->channelType]);
2253 }
2254
2255 /* Current interupt empty and previous interrupt also empty
2256 * detected successive empty interrupt
2257 * or first interrupt empty, this should not happen */
2258 if(0 == channelEntry->numFragmentCurrentChain)
2259 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002260 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2261 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2262 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2263 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002264 /* Abnormal interrupt detected, try to find not validated descriptor */
2265 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2266 {
2267 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2268 {
Leo Chang416afe02013-07-01 13:58:13 -07002269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002270 "Found Invalidated Descriptor %d", (int)descLoop);
2271 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2272 {
Leo Chang416afe02013-07-01 13:58:13 -07002273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002274 "Packet locked, Resync Host and HW");
2275 channelEntry->headCtrlBlk = currentCtrlBlk;
2276 invalidatedFound = 1;
2277 break;
2278 }
2279 else
2280 {
Leo Chang416afe02013-07-01 13:58:13 -07002281 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002282 "Packet Not Locked, cannot transfer frame");
2283 }
2284 }
2285 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2286 currentDesc = currentCtrlBlk->linkedDesc;
2287 descCtrl = currentDesc->descCtrl.ctrl;
2288 }
2289
Jeff Johnson32d95a32012-09-10 13:15:23 -07002290 /* Invalidated descriptor found, and that is not head descriptor
2291 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2292 * Try re-sync here */
2293 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002294 {
2295 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2296 "Found New Sync location with HW, handle frames from there");
2297 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2298 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2299 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002300 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002301 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002302 /* Successive Empty interrupt
2303 * But this case, first descriptor also invalidated, then it means head descriptor
2304 * is linked with already handled RX frame, then could not unlock RX frame
2305 * This is just Out of RX buffer pool, not need to anything here */
2306 else if((invalidatedFound) && (0 == descLoop))
2307 {
2308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2309 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2310 }
2311 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002312 else
2313 {
2314 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2315 "Could not found invalidated descriptor");
2316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2317 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2318 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2319 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302320 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002321 }
2322 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002323 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002324 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002326 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002327 return status;
2328}
2329
2330/*==========================================================================
2331 @ Function Name
2332 dxeNotifySmsm
2333
2334 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2335 buffer
2336
2337 @ Parameters
2338
2339 @ Return
2340 wpt_status
2341
2342===========================================================================*/
2343static wpt_status dxeNotifySmsm
2344(
2345 wpt_boolean kickDxe,
2346 wpt_boolean ringEmpty
2347)
2348{
2349 wpt_uint32 clrSt = 0;
2350 wpt_uint32 setSt = 0;
2351
2352 if(kickDxe)
2353 {
2354 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2355
2356 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2357 {
2358 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2359 tempDxeCtrlBlk->lastKickOffDxe = 1;
2360 }
2361 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2362 {
2363 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2364 tempDxeCtrlBlk->lastKickOffDxe = 0;
2365 }
2366 else
2367 {
2368 HDXE_ASSERT(0);
2369 }
2370 }
2371 else
2372 {
2373 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2374 }
2375
Mihir Shete68ed77a2014-10-10 10:47:12 +05302376 tempDxeCtrlBlk->txRingsEmpty = ringEmpty;
Jeff Johnson295189b2012-06-20 16:38:30 -07002377 if(ringEmpty)
2378 {
2379 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2380 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2381 }
2382 else
2383 {
2384 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2385 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2386 }
2387
2388 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2389
2390 wpalNotifySmsm(clrSt, setSt);
2391
2392 return eWLAN_PAL_STATUS_SUCCESS;
2393}
2394
2395/*==========================================================================
2396 @ Function Name
2397 dxePsComplete
2398
2399 @ Description: Utility function to check the resv desc to deside if we can
2400 get into Power Save mode now
2401
2402 @ Parameters
2403
2404 @ Return
2405 None
2406
2407===========================================================================*/
2408static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2409{
2410 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2411 {
2412 return;
2413 }
2414
2415 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2416 //must have been consumed by RIVA, OK to get into BMPS
2417 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2418 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2419 {
2420 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2421 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2422 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2423 {
2424 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2425 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2426 }
2427 }
2428 else //still more pkts to be served by RIVA
2429 {
2430 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2431
2432 switch(dxeCtxt->rivaPowerState)
2433 {
2434 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2435 //NOP
2436 break;
2437 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2438 if(intr_based)
2439 {
2440 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2441 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2442 }
2443 break;
2444 default:
2445 //assert
2446 break;
2447 }
2448 }
2449}
2450
2451/*==========================================================================
2452 @ Function Name
2453 dxeRXEventHandler
2454
2455 @ Description
2456 Handle serailized RX frame ready event
2457 First disable interrupt then pick up frame from pre allocated buffer
2458 Since frame handle is doen, clear interrupt bit to ready next interrupt
2459 Finally re enable interrupt
2460
2461 @ Parameters
2462 wpt_msg *rxReadyMsg
2463 RX frame ready MSG pointer
2464 include DXE control context
2465
2466 @ Return
2467 NONE
2468
2469===========================================================================*/
2470void dxeRXEventHandler
2471(
2472 wpt_msg *rxReadyMsg
2473)
2474{
2475 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2476 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2477 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2478 wpt_uint32 intSrc = 0;
2479 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002480 wpt_uint32 chHighStat = 0;
2481 wpt_uint32 chLowStat = 0;
Mihir Shetee6618162015-03-16 14:48:42 +05302482 wpt_uint32 chLogRxStat = 0;
Mihir Shetec4093f92015-05-28 15:21:11 +05302483 wpt_uint32 chLogRxFwStat = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302484 wpt_uint32 regValue, chanMask;
Jeff Johnson295189b2012-06-20 16:38:30 -07002485
Jeff Johnsone7245742012-09-05 17:12:55 -07002486 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002487
Jeff Johnsone7245742012-09-05 17:12:55 -07002488 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002489 {
2490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002491 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002492 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002493 }
2494
Jeff Johnsone7245742012-09-05 17:12:55 -07002495 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2496 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2497 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
Mihir Shetee6618162015-03-16 14:48:42 +05302498 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2499 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]);
Jeff Johnsone7245742012-09-05 17:12:55 -07002500
Jeff Johnson295189b2012-06-20 16:38:30 -07002501 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
2502
2503 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
Mihir Shetee6618162015-03-16 14:48:42 +05302504 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled) ||
2505 (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) &&
2506 !dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chEnabled))
Jeff Johnson295189b2012-06-20 16:38:30 -07002507 {
2508 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2509 "DXE already stopped in RX event handler. Just return");
2510 return;
2511 }
2512
2513 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2514 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2515 {
Mihir Shetec4093f92015-05-28 15:21:11 +05302516 if (WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
2517 {
2518 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2519 &intSrc);
2520 if(eWLAN_PAL_STATUS_SUCCESS != status || 0 == intSrc)
2521 {
2522 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2523 "%s: Read status: %d, regVal: %d",
2524 __func__, status, intSrc);
2525 }
2526 else
2527 {
2528 /* Register Read was succesful and we have a valid interrupt
2529 * source, so WCN is not power collapsed yet and it should
2530 * not power collapse till we set the synchronization bit
2531 * at the end of this function, safe to pull frames...
2532 */
2533 goto pull_frames;
2534 }
2535 }
2536
Jeff Johnson295189b2012-06-20 16:38:30 -07002537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2538 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002539 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002540
2541 /* Not to touch any register, just pull frame directly from chain ring
2542 * First high priority */
2543 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2544 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002545 channelCb,
2546 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002547 if(eWLAN_PAL_STATUS_SUCCESS != status)
2548 {
2549 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2550 "dxeRXEventHandler Pull from RX high channel fail");
2551 }
Leo Chang46f36162014-01-14 21:47:24 -08002552 /* In case FW could not power collapse in IMPS mode
2553 * Next power restore might have empty interrupt
2554 * If IMPS mode has empty interrupt since RX thread race,
2555 * Invalid re-load driver might happen
2556 * To prevent invalid re-load driver,
2557 * IMPS event handler set dummpy frame count */
2558 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002559
2560 /* Second low priority */
2561 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2562 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002563 channelCb,
2564 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002565 if(eWLAN_PAL_STATUS_SUCCESS != status)
2566 {
2567 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Mihir Shetee6618162015-03-16 14:48:42 +05302568 "dxeRXEventHandler Pull from RX low channel fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 }
Leo Chang46f36162014-01-14 21:47:24 -08002570 /* LOW Priority CH same above */
2571 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002572
Mihir Shetee6618162015-03-16 14:48:42 +05302573 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2574 {
2575 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2576 status = dxeRXFrameReady(dxeCtxt,
2577 channelCb,
2578 chLogRxStat);
2579 if(eWLAN_PAL_STATUS_SUCCESS != status)
2580 {
2581 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2582 "dxeRXEventHandler Pull from RX log channel fail");
2583 }
2584 channelCb->numFragmentCurrentChain = 1;
2585 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002586 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2587 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2588
2589 return;
2590 }
2591
2592 /* Disable device interrupt */
2593 /* Read whole interrupt mask register and exclusive only this channel int */
2594 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2595 &intSrc);
2596 if(eWLAN_PAL_STATUS_SUCCESS != status)
2597 {
2598 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2599 "dxeRXEventHandler Read INT_SRC register fail");
2600 return;
2601 }
2602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2603 "RX Event Handler INT Source 0x%x", intSrc);
2604
Mihir Shetec4093f92015-05-28 15:21:11 +05302605pull_frames:
Jeff Johnson295189b2012-06-20 16:38:30 -07002606 /* Test High Priority Channel interrupt is enabled or not */
2607 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2608 if(intSrc & (1 << channelCb->assignedDMAChannel))
2609 {
2610 status = dxeChannelCleanInt(channelCb, &chHighStat);
2611 if(eWLAN_PAL_STATUS_SUCCESS != status)
2612 {
2613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2614 "dxeRXEventHandler INT Clean up fail");
2615 return;
2616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002617 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2618 {
2619 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002620 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2621 "%11s : 0x%x Error Reported, Reload Driver",
2622 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302623
Mihir Shete79d6b582014-03-12 17:54:07 +05302624 dxeErrChannelDebug(channelCb, chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302625
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002626 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2627 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302628 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002630 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2631 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002632 {
2633 /* Handle RX Ready for high priority channel */
2634 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002635 channelCb,
2636 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002637 }
2638 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2639 {
2640 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002641 channelCb,
2642 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002643 }
2644 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2645 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002646 /* Update the Rx DONE histogram */
2647 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2648 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2649 {
2650 channelCb->rxDoneHistogram |= 1;
2651 }
2652 else
2653 {
2654 channelCb->rxDoneHistogram &= ~1;
2655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002657
2658 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002659 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002660 if(intSrc & (1 << channelCb->assignedDMAChannel))
2661 {
2662 status = dxeChannelCleanInt(channelCb, &chLowStat);
2663 if(eWLAN_PAL_STATUS_SUCCESS != status)
2664 {
2665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2666 "dxeRXEventHandler INT Clean up fail");
2667 return;
2668 }
2669
2670 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2671 {
2672 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2674 "%11s : 0x%x Error Reported, Reload Driver",
2675 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302676
Mihir Shete79d6b582014-03-12 17:54:07 +05302677 dxeErrChannelDebug(channelCb, chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302678
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002679 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2680 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302681 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 }
Mihir Shetef2000552014-05-12 16:21:34 +05302683 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) ||
2684 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 {
2686 /* Handle RX Ready for low priority channel */
2687 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002688 channelCb,
2689 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07002690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002691
2692 /* Update the Rx DONE histogram */
2693 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2694 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2695 {
2696 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002697 }
2698 else
2699 {
2700 channelCb->rxDoneHistogram &= ~1;
2701 }
2702 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2703 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2704 }
Mihir Shetee6618162015-03-16 14:48:42 +05302705
2706 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2707 {
2708 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2709
2710 if(intSrc & (1 << channelCb->assignedDMAChannel))
2711 {
2712 status = dxeChannelCleanInt(channelCb,&chLogRxStat);
2713 if(eWLAN_PAL_STATUS_SUCCESS != status)
2714 {
2715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2716 "dxeRXEventHandler INT Clean up fail");
2717 return;
2718 }
2719
2720 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxStat)
2721 {
2722 /* Error Happen during transaction, Handle it */
2723 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2724 "%11s : 0x%x Error Reported, Reload Driver",
2725 channelType[channelCb->channelType], chLogRxStat);
2726
2727 dxeErrChannelDebug(channelCb, chLogRxStat);
2728
2729 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2730 wpalWlanReload();
2731 dxeStartSSRTimer(dxeCtxt);
2732 }
2733 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxStat) ||
2734 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2735 {
2736 /* Handle RX Ready for low priority channel */
2737 status = dxeRXFrameReady(dxeCtxt,
2738 channelCb,
2739 chLogRxStat);
2740 }
2741
2742 /* Update the Rx DONE histogram */
2743 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2744 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)
2745 {
2746 channelCb->rxDoneHistogram |= 1;
2747 }
2748 else
2749 {
2750 channelCb->rxDoneHistogram &= ~1;
2751 }
2752 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2753 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxStat, channelCb->numFragmentCurrentChain);
2754 }
2755 }
2756
Mihir Shetec4093f92015-05-28 15:21:11 +05302757 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_FW_LOG))
2758 {
2759 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
2760
2761 if(intSrc & (1 << channelCb->assignedDMAChannel))
2762 {
2763 status = dxeChannelCleanInt(channelCb,&chLogRxFwStat);
2764 if(eWLAN_PAL_STATUS_SUCCESS != status)
2765 {
2766 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2767 "dxeRXEventHandler INT Clean up fail");
2768 return;
2769 }
2770
2771 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxFwStat)
2772 {
2773 /* Error Happen during transaction, Handle it */
2774 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2775 "%11s : 0x%x Error Reported, Reload Driver",
2776 channelType[channelCb->channelType], chLogRxFwStat);
2777
2778 dxeErrChannelDebug(channelCb, chLogRxFwStat);
2779
2780 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2781 wpalWlanReload();
2782 dxeStartSSRTimer(dxeCtxt);
2783 }
2784 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxFwStat) ||
2785 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat))
2786 {
2787 if (!dxeCtxt->hostInitiatedH2H)
2788 {
2789 dxeCtxt->receiveMbMsgCB(dxeCtxt->clientCtxt);
2790 }
2791 else
2792 {
2793 status = dxeRXFrameReady(dxeCtxt,
2794 channelCb,
2795 chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302796 if (channelCb->numFreeDesc == channelCb->numDesc)
2797 {
2798 dxeCtxt->hostInitiatedH2H = 0;
2799 dxeCtxt->receiveLogCompleteCB(dxeCtxt->clientCtxt);
2800 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302801 }
2802 }
2803
2804 /* Update the Rx DONE histogram */
2805 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2806 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat)
2807 {
2808 channelCb->rxDoneHistogram |= 1;
2809 }
2810 else
2811 {
2812 channelCb->rxDoneHistogram &= ~1;
2813 }
2814 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2815 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxFwStat, channelCb->numFragmentCurrentChain);
2816 }
2817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002818 if(eWLAN_PAL_STATUS_SUCCESS != status)
2819 {
2820 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2821 "dxeRXEventHandler Handle Frame Ready Fail");
2822 return;
2823 }
2824
Jeff Johnson295189b2012-06-20 16:38:30 -07002825 /* Prepare Control Register EN Channel */
2826 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2827 {
2828 HDXE_ASSERT(0);
2829 }
Mihir Shetef2000552014-05-12 16:21:34 +05302830
2831 if (dxeCtxt->rxPalPacketUnavailable &&
2832 (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat))
2833 {
2834 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask &
2835 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302836 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302837 }
2838 else
2839 {
2840 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302841 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302842 }
Leo Chang094ece82013-04-23 17:57:41 -07002843 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302844 chanMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002845
2846 /* Prepare Control Register EN Channel */
2847 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2848 {
2849 HDXE_ASSERT(0);
2850 }
Leo Chang094ece82013-04-23 17:57:41 -07002851
Mihir Shetef2000552014-05-12 16:21:34 +05302852 if (dxeCtxt->rxPalPacketUnavailable &&
2853 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
2854 {
2855 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask &
2856 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302857 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302858 }
2859 else
2860 {
2861 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302862 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302863 }
Leo Chang094ece82013-04-23 17:57:41 -07002864 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302865 chanMask);
2866
Mihir Shetee6618162015-03-16 14:48:42 +05302867 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2868 {
2869 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2870 {
2871 HDXE_ASSERT(0);
2872 }
2873
2874 if (dxeCtxt->rxPalPacketUnavailable &&
2875 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2876 {
2877 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask &
2878 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
2879 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 1;
2880 }
2881 else
2882 {
2883 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask;
2884 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 0;
2885 }
2886 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].channelRegister.chDXECtrlRegAddr,
2887 chanMask);
2888 }
Leo Chang094ece82013-04-23 17:57:41 -07002889
2890 /* Clear Interrupt handle processing bit
2891 * RIVA may power down */
Mihir Shete0670b402015-05-13 17:51:41 +05302892 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05302893 {
2894 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
2895 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
2896 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
2897 }
2898 else
2899 {
Karthick S09d5dd02015-05-27 16:58:32 +05302900 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
2901 regValue &= (~WLAN_PMU_POWER_DOWN_MASK);
2902 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05302903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002904
Leo Chang416afe02013-07-01 13:58:13 -07002905 /* Enable system level ISR */
2906 /* Enable RX ready Interrupt at here */
2907 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2908 if(eWLAN_PAL_STATUS_SUCCESS != status)
2909 {
2910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2911 "dxeRXEventHandler Enable RX Ready interrupt fail");
2912 return;
2913 }
2914
Jeff Johnson295189b2012-06-20 16:38:30 -07002915 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002916 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002917 return;
2918}
2919
2920/*==========================================================================
2921 @ Function Name
2922 dxeRXPacketAvailableEventHandler
2923
2924 @ Description
2925 Handle serialized RX Packet Available event when the corresponding callback
2926 is invoked by WPAL.
2927 Try to fill up any completed DXE descriptors with available Rx packet buffer
2928 pointers.
2929
2930 @ Parameters
2931 wpt_msg *rxPktAvailMsg
2932 RX frame ready MSG pointer
2933 include DXE control context
2934
2935 @ Return
2936 NONE
2937
2938===========================================================================*/
2939void dxeRXPacketAvailableEventHandler
2940(
2941 wpt_msg *rxPktAvailMsg
2942)
2943{
2944 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2945 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2946 WLANDXE_ChannelCBType *channelCb = NULL;
2947
2948 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002949 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002950
2951 /* Sanity Check */
2952 if(NULL == rxPktAvailMsg)
2953 {
2954 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2955 "dxeRXPacketAvailableEventHandler Context is not valid");
2956 return;
2957 }
2958
2959 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05302960
2961#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07002962 /* Available resource allocated
2963 * Stop timer not needed */
2964 if(VOS_TIMER_STATE_RUNNING ==
2965 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
2966 {
2967 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
2968 }
Mihir Shete44547fb2014-03-10 14:15:42 +05302969#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002970
2971 do
2972 {
2973 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2974 "dxeRXPacketAvailableEventHandler, start refilling ring");
2975
2976 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2977 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2978
2979 // Wait for another callback to indicate when Rx resources are available
2980 // again.
2981 if(eWLAN_PAL_STATUS_SUCCESS != status)
2982 {
2983 break;
2984 }
2985
2986 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2987 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2988 if(eWLAN_PAL_STATUS_SUCCESS != status)
2989 {
2990 break;
2991 }
Mihir Shetee6618162015-03-16 14:48:42 +05302992
2993 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2994 {
2995 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2996 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2997 if(eWLAN_PAL_STATUS_SUCCESS != status)
2998 {
2999 break;
3000 }
3001 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003002 } while(0);
3003
3004 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
3005 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
3006 {
3007 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
3008 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
3009 }
3010}
3011
3012/*==========================================================================
3013 @ Function Name
3014 dxeRXISR
3015
3016 @ Description
3017 RX frame ready interrupt service routine
3018 interrupt entry function, this function called based on ISR context
3019 Must be serialized
3020
3021 @ Parameters
3022 void *hostCtxt
3023 DXE host driver control context,
3024 pre registerd during interrupt registration
3025
3026 @ Return
3027 NONE
3028
3029===========================================================================*/
3030static void dxeRXISR
3031(
3032 void *hostCtxt
3033)
3034{
3035 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3036 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003037 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07003038
Leo Chang094ece82013-04-23 17:57:41 -07003039 /* Set Interrupt processing bit
3040 * During this bit set, WLAN HW may not power collapse */
Mihir Shete0670b402015-05-13 17:51:41 +05303041 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303042 {
3043 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3044 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
3045 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3046 }
3047 else
3048 {
Karthick S09d5dd02015-05-27 16:58:32 +05303049 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3050 regValue |= WLAN_PMU_POWER_DOWN_MASK;
3051 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303052 }
Leo Chang094ece82013-04-23 17:57:41 -07003053
Jeff Johnson295189b2012-06-20 16:38:30 -07003054 /* Disable interrupt at here
3055 * Disable RX Ready system level Interrupt at here
3056 * Otherwise infinite loop might happen */
3057 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
3058 if(eWLAN_PAL_STATUS_SUCCESS != status)
3059 {
3060 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3061 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3062 return;
3063 }
3064
3065 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003066 if(NULL == dxeCtxt->rxIsrMsg)
3067 {
3068 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3069 "dxeRXFrameReadyISR NULL message");
3070 HDXE_ASSERT(0);
3071 return;
3072 }
3073
Jeff Johnson295189b2012-06-20 16:38:30 -07003074 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
3075 dxeCtxt->rxIsrMsg);
3076 if(eWLAN_PAL_STATUS_SUCCESS != status)
3077 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003078 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3079 "dxeRXFrameReadyISR interrupt serialize fail");
3080 }
3081
Jeff Johnson295189b2012-06-20 16:38:30 -07003082 return;
3083}
3084
3085/*==========================================================================
3086 @ Function Name
3087 dxeTXPushFrame
3088
3089 @ Description
3090 Push TX frame into DXE descriptor and DXE register
3091 Send notification to DXE register that TX frame is ready to transfer
3092
3093 @ Parameters
3094 WLANDXE_ChannelCBType *channelEntry
3095 Channel specific control block
3096 wpt_packet *palPacket
3097 Packet pointer ready to transfer
3098
3099 @ Return
3100 PAL_STATUS_T
3101===========================================================================*/
3102static wpt_status dxeTXPushFrame
3103(
3104 WLANDXE_ChannelCBType *channelEntry,
3105 wpt_packet *palPacket
3106)
3107{
3108 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3109 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3110 WLANDXE_DescType *currentDesc = NULL;
3111 WLANDXE_DescType *firstDesc = NULL;
3112 WLANDXE_DescType *LastDesc = NULL;
3113 void *sourcePhysicalAddress = NULL;
3114 wpt_uint32 xferSize = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003115 wpt_iterator iterator;
Leo Changac1d3612013-07-01 15:15:51 -07003116 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003117
3118 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003119 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003120
Leo Changac1d3612013-07-01 15:15:51 -07003121 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3122 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3123 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003124 {
Leo Changac1d3612013-07-01 15:15:51 -07003125 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003126 }
3127
3128 channelEntry->numFragmentCurrentChain = 0;
3129 currentCtrlBlk = channelEntry->headCtrlBlk;
3130
3131 /* Initialize interator, TX is fragmented */
Jeff Johnson295189b2012-06-20 16:38:30 -07003132 status = wpalLockPacketForTransfer(palPacket);
3133 if(eWLAN_PAL_STATUS_SUCCESS != status)
3134 {
3135 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3136 "dxeTXPushFrame unable to lock packet");
3137 return status;
3138 }
3139
3140 status = wpalIteratorInit(&iterator, palPacket);
Jeff Johnson295189b2012-06-20 16:38:30 -07003141 if(eWLAN_PAL_STATUS_SUCCESS != status)
3142 {
3143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3144 "dxeTXPushFrame iterator init fail");
3145 return status;
3146 }
3147
3148 /* !!!! Revisit break condition !!!!!!! */
3149 while(1)
3150 {
3151 /* Get current descriptor pointer from current control block */
3152 currentDesc = currentCtrlBlk->linkedDesc;
3153 if(NULL == firstDesc)
3154 {
3155 firstDesc = currentCtrlBlk->linkedDesc;
3156 }
3157 /* All control block will have same palPacket Pointer
3158 * to make logic simpler */
3159 currentCtrlBlk->xfrFrame = palPacket;
3160
3161 /* Get next fragment physical address and fragment size
3162 * if this is the first trial, will get first physical address
3163 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
Jeff Johnson295189b2012-06-20 16:38:30 -07003164 status = wpalIteratorNext(&iterator,
3165 palPacket,
3166 &sourcePhysicalAddress,
3167 &xferSize);
3168 if((NULL == sourcePhysicalAddress) ||
3169 (0 == xferSize))
3170 {
3171 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3172 "dxeTXPushFrame end of current frame");
3173 break;
3174 }
3175 if(eWLAN_PAL_STATUS_SUCCESS != status)
3176 {
3177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3178 "dxeTXPushFrame Get next frame fail");
3179 return status;
3180 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003181
3182 /* This is the LAST descriptor valid for this transaction */
3183 LastDesc = currentCtrlBlk->linkedDesc;
3184
3185 /* Program DXE descriptor */
3186 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303187 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003188
3189 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3190 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3191 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3192 {
3193 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3194 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3195 }
3196 else
3197 {
3198 /* Test specific H2H transfer, destination address already set
3199 * Do Nothing */
3200 }
3201 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3202
3203 /* Program channel control register */
3204 /* First frame not set VAL bit, why ??? */
3205 if(0 == channelEntry->numFragmentCurrentChain)
3206 {
3207 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3208 }
3209 else
3210 {
3211 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3212 }
3213
3214 /* Update statistics */
3215 channelEntry->numFragmentCurrentChain++;
3216 channelEntry->numFreeDesc--;
3217 channelEntry->numRsvdDesc++;
3218
3219 /* Get next control block */
3220 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3221 }
3222 channelEntry->numTotalFrame++;
3223 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3224 "NUM TX FRAG %d, Total Frame %d",
3225 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3226
3227 /* Program Channel control register
3228 * Set as end of packet
3229 * Enable interrupt also for first code lock down
3230 * performace optimization, this will be revisited */
3231 if(NULL == LastDesc)
3232 {
3233 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3234 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3235 return eWLAN_PAL_STATUS_E_FAULT;
3236 }
3237 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3238 /* Now First one also Valid ????
3239 * this procedure will prevent over handle descriptor from previous
3240 * TX trigger */
3241 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3242
3243 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3244 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3245 {
3246 /* Update channel head as next avaliable linked slot */
3247 channelEntry->headCtrlBlk = currentCtrlBlk;
Leo Changac1d3612013-07-01 15:15:51 -07003248 if(isEmpty)
3249 {
3250 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3252 "SMSM_ret LO=%d HI=%d",
3253 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3254 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
3255 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3256 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
3257 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003258 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003259 }
3260
3261 /* If DXE use external descriptor, registers are not needed to be programmed
3262 * Just after finish to program descriptor, tirigger to send */
3263 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3264 {
3265 /* Issue a dummy read from the DXE descriptor DDR location to
3266 ensure that any previously posted write to the descriptor
3267 completes. */
3268 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3269 {
3270 //HDXE_ASSERT(0);
3271 }
3272
3273 /* Everything is ready
3274 * Trigger to start DMA */
3275 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3276 channelEntry->extraConfig.chan_mask);
3277 if(eWLAN_PAL_STATUS_SUCCESS != status)
3278 {
3279 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3280 "dxeTXPushFrame Write Channel Ctrl Register fail");
3281 return status;
3282 }
3283
3284 /* Update channel head as next avaliable linked slot */
3285 channelEntry->headCtrlBlk = currentCtrlBlk;
3286
3287 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003288 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003289 return status;
3290 }
3291
3292 /* If DXE not use external descriptor, program each registers */
3293 /* Circular buffer handle not need to program DESC register???
3294 * GEN5 code not programed RING buffer case
3295 * REVISIT THIS !!!!!! */
3296 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3297 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3298 {
3299 /* Destination address, assigned Work Q */
3300 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3301 channelEntry->channelConfig.refWQ);
3302 if(eWLAN_PAL_STATUS_SUCCESS != status)
3303 {
3304 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3305 "dxeTXPushFrame Program dest address register fail");
3306 return status;
3307 }
3308 /* If descriptor format is SHORT */
3309 if(channelEntry->channelConfig.useShortDescFmt)
3310 {
3311 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3312 0);
3313 if(eWLAN_PAL_STATUS_SUCCESS != status)
3314 {
3315 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3316 "dxeTXPushFrame Program dest address register fail");
3317 return status;
3318 }
3319 }
3320 else
3321 {
3322 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3323 "dxeTXPushFrame LONG Descriptor Format!!!");
3324 }
3325 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003326
3327 /* Program Source address register
3328 * This address is already programmed into DXE Descriptor
3329 * But register also upadte */
3330 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3331 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3332 if(eWLAN_PAL_STATUS_SUCCESS != status)
3333 {
3334 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3335 "dxeTXPushFrame Program src address register fail");
3336 return status;
3337 }
3338 /* If descriptor format is SHORT */
3339 if(channelEntry->channelConfig.useShortDescFmt)
3340 {
3341 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3342 0);
3343 if(eWLAN_PAL_STATUS_SUCCESS != status)
3344 {
3345 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3346 "dxeTXPushFrame Program dest address register fail");
3347 return status;
3348 }
3349 }
3350 else
3351 {
3352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3353 "dxeTXPushFrame LONG Descriptor Format!!!");
3354 }
3355
3356 /* Linked list Descriptor pointer */
3357 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3358 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3359 if(eWLAN_PAL_STATUS_SUCCESS != status)
3360 {
3361 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3362 "dxeTXPushFrame Write DESC Address register fail");
3363 return status;
3364 }
3365 /* If descriptor format is SHORT */
3366 if(channelEntry->channelConfig.useShortDescFmt)
3367 {
3368 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3369 0);
3370 if(eWLAN_PAL_STATUS_SUCCESS != status)
3371 {
3372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3373 "dxeTXPushFrame Program dest address register fail");
3374 return status;
3375 }
3376 }
3377 else
3378 {
3379 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3380 "dxeTXPushFrame LONG Descriptor Format!!!");
3381 }
3382
3383 /* Transfer Size */
3384 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3385 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3386 xferSize);
3387 if(eWLAN_PAL_STATUS_SUCCESS != status)
3388 {
3389 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3390 "dxeTXPushFrame Write DESC Address register fail");
3391 return status;
3392 }
3393
3394 /* Everything is ready
3395 * Trigger to start DMA */
3396 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3397 channelEntry->extraConfig.chan_mask);
3398 if(eWLAN_PAL_STATUS_SUCCESS != status)
3399 {
3400 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3401 "dxeTXPushFrame Write Channel Ctrl Register fail");
3402 return status;
3403 }
3404
3405 /* Update channel head as next avaliable linked slot */
3406 channelEntry->headCtrlBlk = currentCtrlBlk;
3407
3408 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003409 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003410 return status;
3411}
3412
3413/*==========================================================================
3414 @ Function Name
3415 dxeTXCompFrame
3416
3417 @ Description
3418 TX Frame transfer complete event handler
3419
3420 @ Parameters
3421 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3422 DXE host driver main control block
3423 WLANDXE_ChannelCBType *channelEntry
3424 Channel specific control block
3425
3426 @ Return
3427 PAL_STATUS_T
3428===========================================================================*/
3429static wpt_status dxeTXCompFrame
3430(
3431 WLANDXE_CtrlBlkType *hostCtxt,
3432 WLANDXE_ChannelCBType *channelEntry
3433)
3434{
3435 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3436 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3437 WLANDXE_DescType *currentDesc = NULL;
3438 wpt_uint32 descCtrlValue = 0;
3439 unsigned int *lowThreshold = NULL;
3440
3441 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003442 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003443
3444 /* Sanity */
3445 if((NULL == hostCtxt) || (NULL == channelEntry))
3446 {
3447 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3448 "dxeTXCompFrame Invalid ARG");
3449 return eWLAN_PAL_STATUS_E_INVAL;
3450 }
3451
3452 if(NULL == hostCtxt->txCompCB)
3453 {
3454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3455 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003456 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003457 }
3458
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003459 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3460 if(eWLAN_PAL_STATUS_SUCCESS != status)
3461 {
3462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3463 "dxeTXCompFrame Mutex Acquire fail");
3464 return status;
3465 }
3466
Jeff Johnson295189b2012-06-20 16:38:30 -07003467 currentCtrlBlk = channelEntry->tailCtrlBlk;
3468 currentDesc = currentCtrlBlk->linkedDesc;
3469
3470 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3471 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003472 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3473 if(eWLAN_PAL_STATUS_SUCCESS != status)
3474 {
3475 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3476 "dxeTXCompFrame Mutex Release fail");
3477 return status;
3478 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003479 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003480 }
3481
Kiet Lam842dad02014-02-18 18:44:02 -08003482
Jeff Johnson295189b2012-06-20 16:38:30 -07003483 while(1)
3484 {
3485// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3486 descCtrlValue = currentDesc->descCtrl.ctrl;
3487 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3488 {
3489 /* caught up with head, bail out */
3490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3491 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3492 break;
3493 }
3494
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003495 if(currentCtrlBlk->xfrFrame == NULL)
3496 {
3497 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3498 "Invalid transfer frame");
3499 HDXE_ASSERT(0);
3500 break;
3501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 channelEntry->numFreeDesc++;
3503 channelEntry->numRsvdDesc--;
3504
3505 /* Send Frame TX Complete notification with frame start fragment location */
3506 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3507 {
3508 hostCtxt->txCompletedFrames--;
Jeff Johnson295189b2012-06-20 16:38:30 -07003509 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3510 if (eWLAN_PAL_STATUS_SUCCESS != status)
3511 {
3512 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3513 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003514 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3515 if(eWLAN_PAL_STATUS_SUCCESS != status)
3516 {
3517 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3518 "dxeTXCompFrame Mutex Release fail");
3519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003520 return status;
3521 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003522 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3523 currentCtrlBlk->xfrFrame,
3524 eWLAN_PAL_STATUS_SUCCESS);
3525 channelEntry->numFragmentCurrentChain = 0;
3526 }
3527 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3528 currentDesc = currentCtrlBlk->linkedDesc;
3529
3530 /* Break condition
3531 * Head control block is the control block must be programed for the next TX
3532 * so, head control block is not programmed control block yet
3533 * if loop encounte head control block, stop to complete
3534 * in theory, COMP CB must be called already ??? */
3535 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3536 {
3537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3538 "dxeTXCompFrame caught up with head ptr");
3539 break;
3540 }
3541 /* VALID Bit check ???? */
3542 }
3543
3544 /* Tail and Head Control block must be same */
3545 channelEntry->tailCtrlBlk = currentCtrlBlk;
3546
3547 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3548 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3549 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3550
3551 /* If specific channel hit low resource condition send notification to upper layer */
3552 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3553 (channelEntry->numFreeDesc > *lowThreshold))
3554 {
3555 /* Change it back if we raised it for fetching a remaining packet from TL */
3556 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3557 {
3558 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3559 }
3560
3561 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3562 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3563 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3564 channelEntry->channelType,
3565 eWLAN_PAL_TRUE);
3566 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3567 }
3568
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003569 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3570 if(eWLAN_PAL_STATUS_SUCCESS != status)
3571 {
3572 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3573 "dxeTXCompFrame Mutex Release fail");
3574 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003575
3576 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003577 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003578 return status;
3579}
3580
3581/*==========================================================================
3582 @ Function Name
3583 dxeTXEventHandler
3584
3585 @ Description
3586 If DXE HW sends TX related interrupt, this event handler will be called
3587 Handle higher priority channel first
3588 Figureout why interrupt happen and call appropriate final even handler
3589 TX complete or error happen
3590
3591 @ Parameters
3592 void *msgPtr
3593 Even MSG
3594
3595 @ Return
3596 PAL_STATUS_T
3597===========================================================================*/
3598void dxeTXEventHandler
3599(
3600 wpt_msg *msgPtr
3601)
3602{
3603 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3604 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3605 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3606 wpt_uint32 intSrc = 0;
3607 wpt_uint32 chStat = 0;
3608 WLANDXE_ChannelCBType *channelCb = NULL;
3609
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003610 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003611 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003612
3613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003614 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003615
3616 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003617 dxeCtxt->ucTxMsgCnt = 0;
3618
3619 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3620 {
3621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3622 "wlan: TX COMP WLAN Driver re-loading in progress");
3623 return;
3624 }
3625
Jeff Johnson295189b2012-06-20 16:38:30 -07003626 /* Return from here if the RIVA is in IMPS, to avoid register access */
3627 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3628 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003629 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003631 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003632 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3633 if(eWLAN_PAL_STATUS_SUCCESS != status)
3634 {
3635 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003636 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003637 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003638
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003639 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3640 if(eWLAN_PAL_STATUS_SUCCESS != status)
3641 {
3642 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3643 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3644 }
3645
3646 if(((dxeCtxt->txCompletedFrames) &&
3647 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3648 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003649 {
3650 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3651 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3652 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003653 "TX COMP INT Enabled, remain TX frame count on ring %d",
3654 dxeCtxt->txCompletedFrames);
Jeff Johnsone7245742012-09-05 17:12:55 -07003655 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3656 the posibility of a race*/
3657 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3658 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003659 else
3660 {
3661 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3662 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3663 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
3664 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
3665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003666 return;
3667 }
3668
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003669 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003670 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
3671 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
3672 {
3673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3674 "DXE already stopped in TX event handler. Just return");
3675 return;
3676 }
3677
Jeff Johnson295189b2012-06-20 16:38:30 -07003678 /* Disable device interrupt */
3679 /* Read whole interrupt mask register and exclusive only this channel int */
3680 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3681 &intSrc);
3682 if(eWLAN_PAL_STATUS_SUCCESS != status)
3683 {
3684 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3685 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3686 return;
3687 }
3688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3689 "TX Event Handler INT Source 0x%x", intSrc);
3690
3691 /* Test High Priority Channel is the INT source or not */
3692 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3693 if(intSrc & (1 << channelCb->assignedDMAChannel))
3694 {
3695 status = dxeChannelCleanInt(channelCb, &chStat);
3696 if(eWLAN_PAL_STATUS_SUCCESS != status)
3697 {
3698 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3699 "dxeTXEventHandler INT Clean up fail");
3700 return;
3701 }
3702
3703 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3704 {
3705 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003706 "%11s : 0x%x Error Reported, Reload Driver",
3707 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303708
Mihir Shete79d6b582014-03-12 17:54:07 +05303709 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303710
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003711 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3712 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303713 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003714 }
3715 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3716 {
3717 /* Handle TX complete for high priority channel */
3718 status = dxeTXCompFrame(dxeCtxt,
3719 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003720 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003721 }
3722 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3723 {
3724 /* Handle TX complete for high priority channel */
3725 status = dxeTXCompFrame(dxeCtxt,
3726 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003727 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 }
3729 else
3730 {
3731 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3732 "dxeTXEventHandler TX HI status=%x", chStat);
3733 }
3734
3735 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3736 {
3737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3738 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3739 }
3740
3741 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3742 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3743 }
3744
3745 /* Test Low Priority Channel interrupt is enabled or not */
3746 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3747 if(intSrc & (1 << channelCb->assignedDMAChannel))
3748 {
3749 status = dxeChannelCleanInt(channelCb, &chStat);
3750 if(eWLAN_PAL_STATUS_SUCCESS != status)
3751 {
3752 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3753 "dxeTXEventHandler INT Clean up fail");
3754 return;
3755 }
3756
3757 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3758 {
3759 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003760 "%11s : 0x%x Error Reported, Reload Driver",
3761 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303762
Mihir Shete79d6b582014-03-12 17:54:07 +05303763 dxeErrChannelDebug(channelCb, chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303764
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003765 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
3766 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05303767 dxeStartSSRTimer(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07003768 }
3769 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3770 {
3771 /* Handle TX complete for low priority channel */
3772 status = dxeTXCompFrame(dxeCtxt,
3773 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003774 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003775 }
3776 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3777 {
3778 /* Handle TX complete for low priority channel */
3779 status = dxeTXCompFrame(dxeCtxt,
3780 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003781 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003782 }
3783 else
3784 {
3785 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3786 "dxeTXEventHandler TX LO status=%x", chStat);
3787 }
3788
3789 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3790 {
3791 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3792 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3793 }
3794 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3795 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3796 }
3797
3798
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3800 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3801 {
3802 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3803 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003804 if(0 != dxeCtxt->txCompletedFrames)
3805 {
3806 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3807 "TX COMP INT Enabled, remain TX frame count on ring %d",
3808 dxeCtxt->txCompletedFrames);
3809 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003810 }
3811
3812 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3813 the posibility of a race*/
3814 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3815
3816 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003817 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003818 return;
3819}
3820
3821
3822/*==========================================================================
3823 @ Function Name
3824 dxeTXCompleteProcessing
3825
3826 @ Description
3827 If DXE HW sends TX related interrupt, this event handler will be called
3828 Handle higher priority channel first
3829 Figureout why interrupt happen and call appropriate final even handler
3830 TX complete or error happen
3831
3832 @ Parameters
3833 dxeCtxt DXE context
3834
3835 @ Return
3836 PAL_STATUS_T
3837===========================================================================*/
3838void dxeTXCompleteProcessing
3839(
3840 WLANDXE_CtrlBlkType *dxeCtxt
3841)
3842{
3843 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3844 WLANDXE_ChannelCBType *channelCb = NULL;
3845
3846 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003847 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003848
3849 /* Test High Priority Channel is the INT source or not */
3850 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3851
3852 /* Handle TX complete for high priority channel */
3853 status = dxeTXCompFrame(dxeCtxt, channelCb);
3854
3855 /* Test Low Priority Channel interrupt is enabled or not */
3856 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3857
3858 /* Handle TX complete for low priority channel */
3859 status = dxeTXCompFrame(dxeCtxt, channelCb);
3860
3861 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3862 ((dxeCtxt->txCompletedFrames > 0) ||
3863 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3864 {
3865 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3866 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3867 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003868 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003869 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3870 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3871 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3872 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07003873
3874 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
3875 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
3876 {
3877 /* After TX Comp processing, still remaining frame on the DXE TX ring
3878 * And when push frame, RING was not empty marked
3879 * Then when push frame, no SMSM toggle happen
3880 * To avoid permanent TX stall, SMSM toggle is needed at here
3881 * With this toggle, host should gaurantee SMSM state should be changed */
Mihir Shete68ed77a2014-10-10 10:47:12 +05303882 dxeNotifySmsm(eWLAN_PAL_TRUE, dxeCtxt->txRingsEmpty);
Leo Changac1d3612013-07-01 15:15:51 -07003883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003884 }
3885
3886 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3887 the posibility of a race*/
3888 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3889
3890 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003891 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003892 return;
3893}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003894
3895/*==========================================================================
3896 @ Function Name
3897 dxeTXReSyncDesc
3898
3899 @ Description
3900 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
3901 And HW programmed descriptor.
3902 If any async happen between HW/SW TX stall will happen
3903
3904 @ Parameters
3905 void *msgPtr
3906 Message pointer to sync with TX thread
3907
3908 @ Return
3909 NONE
3910===========================================================================*/
3911void dxeTXReSyncDesc
3912(
3913 wpt_msg *msgPtr
3914)
3915{
3916 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3917 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
3918 wpt_uint32 nextDescReg;
3919 WLANDXE_ChannelCBType *channelEntry;
3920 WLANDXE_DescCtrlBlkType *validCtrlBlk;
3921 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003922 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003923
3924 if(NULL == msgContent)
3925 {
3926 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3927 "dxeTXReSyncDesc Invalid Control Block");
3928 return;
3929 }
3930
3931 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3932 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
3933 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
3934
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003935 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003936 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003937 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
3938 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3939 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
3940 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3941 &nextDescReg);
3942 /* Async detect without TX pending frame */
3943 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003944 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003945 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003946 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003947 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3948 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303949
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07003950 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
3951 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303952
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003953 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003954 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003955 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003956 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003957 /* Async detect with some TX pending frames
3958 * next descriptor register should sync with first valid descriptor */
3959 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003960 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003961 validCtrlBlk = channelEntry->tailCtrlBlk;
3962 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07003963 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003964 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
3965 {
3966 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
3967 {
3968 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3969 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303970
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07003971 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
3972 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303973
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003974 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3975 validCtrlBlk->linkedDescPhyAddr);
3976 }
3977 break;
3978 }
3979 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
3980 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
3981 {
3982 /* Finished to test till head control blcok, but could not find valid descriptor
3983 * from head to tail all descriptors are invalidated
3984 * host point of view head descriptor is next TX candidate
3985 * So, next descriptor control have to be programmed with head descriptor
3986 * check */
3987 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
3988 {
3989 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08003990 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303991
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07003992 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
3993 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05303994
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07003995 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3996 validCtrlBlk->linkedDescPhyAddr);
3997 }
3998 break;
3999 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004000 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004001 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004002 }
4003
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07004004 /* HW/SW descriptor resync is done.
4005 * Next if there are any valid descriptor in chain, Push to HW again */
4006 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
4007 {
4008 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4009 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
4010 {
4011 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4012 "%11s : No TX Pending frame",
4013 channelType[channelEntry->channelType]);
4014 /* No Pending frame, Do nothing */
4015 }
4016 else
4017 {
4018 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4019 "%11s : TX Pending frame, process it",
4020 channelType[channelEntry->channelType]);
4021 validCtrlBlk = channelEntry->tailCtrlBlk;
4022 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
4023 {
4024 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4025 {
4026 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4027 "%11s : when exit IMPS found valid descriptor",
4028 channelType[channelEntry->channelType]);
4029
4030 /* Found valid descriptor, kick DXE */
4031 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
4032 channelEntry->extraConfig.chan_mask);
4033 break;
4034 }
4035 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4036 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4037 {
4038 /* Finished to test till head control blcok, but could not find valid descriptor
4039 * from head to tail all descriptors are invalidated */
4040 break;
4041 }
4042 }
4043 }
4044 }
4045
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004046 wpalMemoryFree(msgPtr);
4047 return;
4048}
4049
Jeff Johnson295189b2012-06-20 16:38:30 -07004050/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05304051 @ Function Name
4052 dxeDebugTxDescReSync
4053
4054 @ Description
4055 Check DXE Tx channel state and correct it in
4056 case Tx Data stall is detected by calling
4057 %dxeTXReSyncDesc. Also ensure that WCN SS
4058 is not power collapsed before calling
4059 %dxeTXReSyncDesc
4060
4061 @ Parameters
4062 void *msgPtr
4063 Message pointer to sync with TX thread
4064
4065 @ Return
4066 NONE
4067===========================================================================*/
4068void dxeDebugTxDescReSync
4069(
4070 wpt_msg *msgPtr
4071)
4072{
4073 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4074 "%s: Check for DXE TX Async",__func__);
4075 /* Make wake up HW */
4076 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4077 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4078
4079 wpalSleep(10);
4080
4081 dxeTXReSyncDesc(msgPtr);
4082}
4083/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004084 @ Function Name
4085 dxeTXISR
4086
4087 @ Description
4088 TX interrupt ISR
4089 Platform will call this function if INT is happen
4090 This function must be registered into platform interrupt module
4091
4092 @ Parameters
4093 void *hostCtxt
4094 DXE host driver control context,
4095 pre registerd during interrupt registration
4096
4097 @ Return
4098 PAL_STATUS_T
4099===========================================================================*/
4100static void dxeTXISR
4101(
4102 void *hostCtxt
4103)
4104{
4105 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
4106 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004107
4108 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004109 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004110
4111 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004112 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004113 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004114 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004115 /* Disable interrupt at here,
4116 IMPS or IMPS Pending state should not access RIVA register */
4117 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4118 if(eWLAN_PAL_STATUS_SUCCESS != status)
4119 {
4120 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4121 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4122 return;
4123 }
4124 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4125 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004126 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004127 return;
4128 }
4129
Jeff Johnson295189b2012-06-20 16:38:30 -07004130 /* Disable TX Complete Interrupt at here */
4131 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4132 if(eWLAN_PAL_STATUS_SUCCESS != status)
4133 {
4134 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4135 "dxeTXCompISR Disable TX complete interrupt fail");
4136 return;
4137 }
4138 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4139
4140
4141 if( dxeCtxt->ucTxMsgCnt )
4142 {
4143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4144 "Avoiding serializing TX Complete event");
4145 return;
4146 }
4147
4148 dxeCtxt->ucTxMsgCnt = 1;
4149
4150 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004151 if(NULL == dxeCtxt->txIsrMsg)
4152 {
4153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4154 "Invalid message");
4155 HDXE_ASSERT(0);
4156 return;
4157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4159 dxeCtxt->txIsrMsg);
4160 if(eWLAN_PAL_STATUS_SUCCESS != status)
4161 {
4162 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4163 "dxeTXCompISR interrupt serialize fail status=%d", status);
4164 }
4165
4166 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004167 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004168 return;
4169}
4170
4171/*-------------------------------------------------------------------------
4172 * Global Function
4173 *-------------------------------------------------------------------------*/
4174/*==========================================================================
4175 @ Function Name
4176 WLANDXE_Open
4177
4178 @ Description
4179 Open host DXE driver, allocate DXE resources
4180 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4181
4182 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004183 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004184
4185 @ Return
4186 pVoid DXE local module control block pointer
4187===========================================================================*/
4188void *WLANDXE_Open
4189(
4190 void
4191)
4192{
4193 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4194 unsigned int idx;
4195 WLANDXE_ChannelCBType *currentChannel = NULL;
4196 int smsmInitState;
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304197 wpt_uint8 chanMask = WDTS_TRANSPORT_CHANNELS_MASK;
Jeff Johnson295189b2012-06-20 16:38:30 -07004198
4199 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004200 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004201
Mihir Shetee6618162015-03-16 14:48:42 +05304202 if (wpalIsFwLoggingEnabled())
4203 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304204 chanMask |= WDTS_RX_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304205 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304206
4207 if (wpalIsFwEvLoggingEnabled())
Mihir Shetee6618162015-03-16 14:48:42 +05304208 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304209 chanMask |= WDTS_RX_FW_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304210 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304211 dxeSetEnabledChannels(chanMask);
Mihir Shetee6618162015-03-16 14:48:42 +05304212
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 /* This is temporary allocation */
4214 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4215 if(NULL == tempDxeCtrlBlk)
4216 {
4217 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4218 "WLANDXE_Open Control Block Alloc Fail");
4219 return NULL;
4220 }
4221 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4222
4223 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
4224 if(eWLAN_PAL_STATUS_SUCCESS != status)
4225 {
4226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4227 "WLANDXE_Open Common Configuration Fail");
4228 WLANDXE_Close(tempDxeCtrlBlk);
4229 return NULL;
4230 }
4231
Mihir Shetee6618162015-03-16 14:48:42 +05304232 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 {
4234 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4235 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4236 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304237 currentChannel->channelType = idx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004238
4239 /* Config individual channels from channel default setup table */
4240 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4241 currentChannel);
4242 if(eWLAN_PAL_STATUS_SUCCESS != status)
4243 {
4244 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4245 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4246 WLANDXE_Close(tempDxeCtrlBlk);
4247 return NULL;
4248 }
4249
4250 /* Allocate DXE Control Block will be used by host DXE driver */
4251 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4252 if(eWLAN_PAL_STATUS_SUCCESS != status)
4253 {
4254 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4255 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4256
4257 WLANDXE_Close(tempDxeCtrlBlk);
4258 return NULL;
4259 }
4260 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4261 if(eWLAN_PAL_STATUS_SUCCESS != status)
4262 {
4263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4264 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4265 WLANDXE_Close(tempDxeCtrlBlk);
4266 return NULL;
4267 }
4268
4269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4270 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4271 }
4272
4273 /* Allocate and Init RX READY ISR Serialize Buffer */
4274 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4275 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4276 {
4277 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4278 "WLANDXE_Open Alloc RX ISR Fail");
4279 WLANDXE_Close(tempDxeCtrlBlk);
4280 return NULL;
4281 }
4282 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4283 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4284 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4285
4286 /* Allocate and Init TX COMP ISR Serialize Buffer */
4287 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4288 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4289 {
4290 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4291 "WLANDXE_Open Alloc TX ISR Fail");
4292 WLANDXE_Close(tempDxeCtrlBlk);
4293 return NULL;
4294 }
4295 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4296 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4297 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4298
4299 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4300 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4301 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4302 {
4303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4304 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4305 WLANDXE_Close(tempDxeCtrlBlk);
4306 return NULL;
4307 }
4308 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4309 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4310 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4311
4312 tempDxeCtrlBlk->freeRXPacket = NULL;
4313 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4314 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4315 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004316 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004317 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004318
4319 /* Initialize SMSM state
4320 * Init State is
4321 * Clear TX Enable
4322 * RING EMPTY STATE */
4323 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4324 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4325 if(0 != smsmInitState)
4326 {
4327 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4328 "SMSM Channel init fail %d", smsmInitState);
Mihir Shetee6618162015-03-16 14:48:42 +05304329 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004330 {
4331 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4332 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004333 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4334 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004335 wpalMemoryFree(tempDxeCtrlBlk);
4336 return NULL;
4337 }
4338
Mihir Shete44547fb2014-03-10 14:15:42 +05304339#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004340 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4341 dxeRXResourceAvailableTimerExpHandler,
4342 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304343#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004344
Mihir Shetefdc9f532014-01-09 15:03:02 +05304345 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4346 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4347
Jeff Johnson295189b2012-06-20 16:38:30 -07004348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4349 "WLANDXE_Open Success");
4350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004351 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004352 return (void *)tempDxeCtrlBlk;
4353}
4354
4355/*==========================================================================
4356 @ Function Name
4357 WLANDXE_ClientRegistration
4358
4359 @ Description
4360 Make callback functions registration into DXE driver from DXE driver client
4361
4362 @ Parameters
4363 pVoid pDXEContext : DXE module control block
Mihir Shetec4093f92015-05-28 15:21:11 +05304364 WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events
Jeff Johnson295189b2012-06-20 16:38:30 -07004365 void *userContext : DXE Cliennt control block
4366
4367 @ Return
4368 wpt_status
4369===========================================================================*/
4370wpt_status WLANDXE_ClientRegistration
4371(
4372 void *pDXEContext,
Mihir Shetec4093f92015-05-28 15:21:11 +05304373 WDTS_ClientCallbacks WDTSCb,
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 void *userContext
4375)
4376{
4377 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4378 WLANDXE_CtrlBlkType *dxeCtxt;
4379
4380 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004381 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004382
4383 /* Sanity */
4384 if(NULL == pDXEContext)
4385 {
4386 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4387 "WLANDXE_ClientRegistration Invalid DXE CB");
4388 return eWLAN_PAL_STATUS_E_INVAL;
4389 }
4390
Jeff Johnson295189b2012-06-20 16:38:30 -07004391 if(NULL == userContext)
4392 {
4393 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4394 "WLANDXE_ClientRegistration Invalid userContext");
4395 return eWLAN_PAL_STATUS_E_INVAL;
4396 }
4397
4398 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4399
4400 /* Assign */
Mihir Shetec4093f92015-05-28 15:21:11 +05304401 dxeCtxt->rxReadyCB = WDTSCb.rxFrameReadyCB;
4402 dxeCtxt->txCompCB = WDTSCb.txCompleteCB;
4403 dxeCtxt->lowResourceCB = WDTSCb.lowResourceCB;
4404 dxeCtxt->receiveMbMsgCB = WDTSCb.receiveMbMsgCB;
Mihir Shete5affadc2015-05-29 20:54:57 +05304405 dxeCtxt->receiveLogCompleteCB = WDTSCb.receiveLogCompleteCB;
Jeff Johnson295189b2012-06-20 16:38:30 -07004406 dxeCtxt->clientCtxt = userContext;
4407
4408 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004409 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004410 return status;
4411}
4412
4413/*==========================================================================
4414 @ Function Name
4415 WLANDXE_Start
4416
4417 @ Description
4418 Start Host DXE driver
4419 Initialize DXE channels and start channel
4420
4421 @ Parameters
4422 pVoid pDXEContext : DXE module control block
4423
4424 @ Return
4425 wpt_status
4426===========================================================================*/
4427wpt_status WLANDXE_Start
4428(
4429 void *pDXEContext
4430)
4431{
4432 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4433 wpt_uint32 idx;
4434 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4435
4436 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004437 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004438
4439 /* Sanity */
4440 if(NULL == pDXEContext)
4441 {
4442 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4443 "WLANDXE_Start Invalid DXE CB");
4444 return eWLAN_PAL_STATUS_E_INVAL;
4445 }
4446 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4447
4448 /* WLANDXE_Start called means DXE engine already initiates
4449 * And DXE HW is reset and init finished
4450 * But here to make sure HW is initialized, reset again */
4451 status = dxeEngineCoreStart(dxeCtxt);
4452 if(eWLAN_PAL_STATUS_SUCCESS != status)
4453 {
4454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4455 "WLANDXE_Start DXE HW init Fail");
4456 return status;
4457 }
4458
4459 /* Individual Channel Start */
Mihir Shetee6618162015-03-16 14:48:42 +05304460 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 {
4462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4463 "WLANDXE_Start Channel %s Start", channelType[idx]);
4464
4465 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4466 /* Make connection between DXE descriptor and DXE control block */
4467 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4468 if(eWLAN_PAL_STATUS_SUCCESS != status)
4469 {
4470 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4471 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4472 return status;
4473 }
4474
4475 /* Program each channel register with configuration arguments */
4476 status = dxeChannelInitProgram(dxeCtxt,
4477 &dxeCtxt->dxeChannel[idx]);
4478 if(eWLAN_PAL_STATUS_SUCCESS != status)
4479 {
4480 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4481 "WLANDXE_Start %d Program DMA channel Fail", idx);
4482 return status;
4483 }
4484
4485 /* ??? Trigger to start DMA channel
4486 * This must be seperated from ??? */
4487 status = dxeChannelStart(dxeCtxt,
4488 &dxeCtxt->dxeChannel[idx]);
4489 if(eWLAN_PAL_STATUS_SUCCESS != status)
4490 {
4491 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4492 "WLANDXE_Start %d Channel Start Fail", idx);
4493 return status;
4494 }
4495 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4496 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4497 }
4498
4499 /* Register ISR to OS */
4500 /* Register TX complete interrupt into platform */
4501 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4502 dxeTXISR,
4503 dxeCtxt);
4504 if(eWLAN_PAL_STATUS_SUCCESS != status)
4505 {
4506 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4507 "WLANDXE_Start TX comp interrupt registration Fail");
4508 return status;
4509 }
4510
4511 /* Register RX ready interrupt into platform */
4512 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4513 dxeRXISR,
4514 dxeCtxt);
4515 if(eWLAN_PAL_STATUS_SUCCESS != status)
4516 {
4517 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4518 "WLANDXE_Start RX Ready interrupt registration Fail");
4519 return status;
4520 }
4521
4522 /* Enable system level ISR */
4523 /* Enable RX ready Interrupt at here */
4524 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4525 if(eWLAN_PAL_STATUS_SUCCESS != status)
4526 {
4527 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4528 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4529 return status;
4530 }
4531
4532 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004533 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004534 return status;
4535}
4536
4537/*==========================================================================
4538 @ Function Name
4539 WLANDXE_TXFrame
4540
4541 @ Description
4542 Trigger frame transmit from host to RIVA
4543
4544 @ Parameters
4545 pVoid pDXEContext : DXE Control Block
4546 wpt_packet pPacket : transmit packet structure
4547 WDTS_ChannelType channel : TX channel
4548
4549 @ Return
4550 wpt_status
4551===========================================================================*/
4552wpt_status WLANDXE_TxFrame
4553(
4554 void *pDXEContext,
4555 wpt_packet *pPacket,
4556 WDTS_ChannelType channel
4557)
4558{
4559 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4560 WLANDXE_ChannelCBType *currentChannel = NULL;
4561 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4562 unsigned int *lowThreshold = NULL;
4563
4564 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004565 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004566
4567 /* Sanity */
4568 if(NULL == pDXEContext)
4569 {
4570 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4571 "WLANDXE_Start Invalid DXE CB");
4572 return eWLAN_PAL_STATUS_E_INVAL;
4573 }
4574
4575 if(NULL == pPacket)
4576 {
4577 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4578 "WLANDXE_Start Invalid pPacket");
4579 return eWLAN_PAL_STATUS_E_INVAL;
4580 }
4581
Mihir Shetee6618162015-03-16 14:48:42 +05304582 if(WDTS_CHANNEL_MAX <= channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 {
4584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4585 "WLANDXE_Start Invalid channel");
4586 return eWLAN_PAL_STATUS_E_INVAL;
4587 }
4588
4589 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4590
4591 currentChannel = &dxeCtxt->dxeChannel[channel];
4592
4593
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004594 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4595 if(eWLAN_PAL_STATUS_SUCCESS != status)
4596 {
4597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4598 "WLANDXE_TxFrame Mutex Acquire fail");
4599 return status;
4600 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004601
4602 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4603 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4604 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4605
4606 /* Decide have to activate TX complete event or not */
4607 switch(dxeCtxt->txCompInt.txIntEnable)
4608 {
4609 /* TX complete interrupt will be activated when low DXE resource */
4610 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4611 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4612 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4613 {
4614 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4615 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4616 channel,
4617 eWLAN_PAL_FALSE);
4618 }
4619 break;
4620
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004621 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004622 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4623 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4624 {
4625 currentChannel->numFrameBeforeInt++;
4626 }
4627 break;
4628
4629 /* TX complete interrupt will be activated periodically */
4630 case WLANDXE_TX_COMP_INT_TIMER:
4631 break;
4632 }
4633
4634 dxeCtxt->txCompletedFrames++;
4635
4636 /* Update DXE descriptor, this is frame based
4637 * if a frame consist of N fragments, N Descriptor will be programed */
4638 status = dxeTXPushFrame(currentChannel, pPacket);
4639 if(eWLAN_PAL_STATUS_SUCCESS != status)
4640 {
4641 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4642 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004643 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4644 if(eWLAN_PAL_STATUS_SUCCESS != status)
4645 {
4646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4647 "WLANDXE_TxFrame Mutex Release fail");
4648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004649 return status;
4650 }
4651
4652 /* If specific channel hit low resource condition, send notification to upper layer */
4653 if(currentChannel->numFreeDesc <= *lowThreshold)
4654 {
4655 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4656 channel,
4657 eWLAN_PAL_FALSE);
4658 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004659
4660 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4661 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4662 channelType[currentChannel->channelType],
4663 currentChannel->numRsvdDesc);
Mihir Shete68ed77a2014-10-10 10:47:12 +05304664 if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4665 {
4666 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4667 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004669 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004670 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4671 if(eWLAN_PAL_STATUS_SUCCESS != status)
4672 {
4673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4674 "WLANDXE_TxFrame Mutex Release fail");
4675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004676
4677 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004678 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 return status;
4680}
4681
4682/*==========================================================================
4683 @ Function Name
4684 WLANDXE_CompleteTX
4685
4686 @ Description
4687 Informs DXE that the current series of Tx packets is complete
4688
4689 @ Parameters
4690 pContext pDXEContext : DXE Control Block
4691 ucTxResReq TX resource number required by TL/WDI
4692
4693 @ Return
4694 wpt_status
4695===========================================================================*/
4696wpt_status
4697WLANDXE_CompleteTX
4698(
4699 void* pContext,
4700 wpt_uint32 ucTxResReq
4701)
4702{
4703 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4704 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
4705 WLANDXE_ChannelCBType *channelCb = NULL;
4706 wpt_boolean inLowRes;
4707
4708 /* Sanity Check */
4709 if( NULL == pContext )
4710 {
4711 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4712 "WLANDXE_CompleteTX invalid param");
4713 return eWLAN_PAL_STATUS_E_INVAL;
4714 }
4715
4716 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4717 inLowRes = channelCb->hitLowResource;
4718
4719 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
4720 {
4721 /* Raise threshold temporarily if necessary */
4722 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
4723
4724 if(eWLAN_PAL_FALSE == inLowRes)
4725 {
4726 /* Put the channel to low resource condition */
4727 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4728 WDTS_CHANNEL_TX_LOW_PRI,
4729 eWLAN_PAL_FALSE);
4730 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
4731 }
4732 }
4733
4734 /*Try to reclaim resources*/
4735 dxeTXCompleteProcessing(dxeCtxt);
4736
4737 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
4738 because its fragment size is larger than DXE free resource. */
4739 if(0 < ucTxResReq)
4740 {
4741 /* DXE successfully claimed enough free DXE resouces for next fetch. */
4742 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
4743 {
4744 /* DXE has not been in low resource condition. DXE forces to kick off
4745 TX tranmit */
4746 if((eWLAN_PAL_FALSE == inLowRes) &&
4747 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
4748 {
4749 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4750 WDTS_CHANNEL_TX_LOW_PRI,
4751 eWLAN_PAL_FALSE);
4752 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4753 WDTS_CHANNEL_TX_LOW_PRI,
4754 eWLAN_PAL_TRUE);
4755 channelCb->hitLowResource = eWLAN_PAL_FALSE;
4756 }
4757 }
4758 else
4759 {
4760 /* DXE doesn't have enough free DXE resources. Put the channel
4761 to low resource condition. */
4762 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
4763 {
4764 /* Put the channel to low resource condition */
4765 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4766 WDTS_CHANNEL_TX_LOW_PRI,
4767 eWLAN_PAL_FALSE);
4768 channelCb->hitLowResource = eWLAN_PAL_TRUE;
4769 }
4770 }
4771 }
4772
4773 return status;
4774}
4775
4776/*==========================================================================
4777 @ Function Name
4778 WLANDXE_Stop
4779
4780 @ Description
4781 Stop DXE channels and DXE engine operations
4782 Disable all channel interrupt
4783 Stop all channel operation
4784
4785 @ Parameters
4786 pVoid pDXEContext : DXE Control Block
4787
4788 @ Return
4789 wpt_status
4790===========================================================================*/
4791wpt_status WLANDXE_Stop
4792(
4793 void *pDXEContext
4794)
4795{
4796 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4797 wpt_uint32 idx;
4798 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4799
4800 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004801 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004802
4803 /* Sanity */
4804 if(NULL == pDXEContext)
4805 {
4806 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4807 "WLANDXE_Stop Invalid DXE CB");
4808 return eWLAN_PAL_STATUS_E_INVAL;
4809 }
4810
4811 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shetee6618162015-03-16 14:48:42 +05304812 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004813 {
4814 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4815 if(eWLAN_PAL_STATUS_SUCCESS != status)
4816 {
4817 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4818 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07004819 }
4820 }
4821
4822 /* During Stop unregister interrupt */
4823 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
4824 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
4825
Mihir Shete44547fb2014-03-10 14:15:42 +05304826#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004827 if(VOS_TIMER_STATE_STOPPED !=
4828 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
4829 {
4830 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
4831 }
Mihir Shete44547fb2014-03-10 14:15:42 +05304832#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004833
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004835 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004836 return status;
4837}
4838
4839/*==========================================================================
4840 @ Function Name
4841 WLANDXE_Close
4842
4843 @ Description
4844 Close DXE channels
4845 Free DXE related resources
4846 DXE descriptor free
4847 Descriptor control block free
4848 Pre allocated RX buffer free
4849
4850 @ Parameters
4851 pVoid pDXEContext : DXE Control Block
4852
4853 @ Return
4854 wpt_status
4855===========================================================================*/
4856wpt_status WLANDXE_Close
4857(
4858 void *pDXEContext
4859)
4860{
4861 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4862 wpt_uint32 idx;
4863 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004864
4865 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004866 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004867
4868 /* Sanity */
4869 if(NULL == pDXEContext)
4870 {
4871 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4872 "WLANDXE_Stop Invalid DXE CB");
4873 return eWLAN_PAL_STATUS_E_INVAL;
4874 }
4875
4876 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05304877#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004878 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05304879#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05304880 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Mihir Shetee6618162015-03-16 14:48:42 +05304881 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004882 {
4883 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
4884 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
Jeff Johnson295189b2012-06-20 16:38:30 -07004885 }
4886
4887 if(NULL != dxeCtxt->rxIsrMsg)
4888 {
4889 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4890 }
4891 if(NULL != dxeCtxt->txIsrMsg)
4892 {
4893 wpalMemoryFree(dxeCtxt->txIsrMsg);
4894 }
4895 if(NULL != dxeCtxt->rxPktAvailMsg)
4896 {
4897 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4898 }
4899
4900 wpalMemoryFree(pDXEContext);
4901
4902 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004903 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004904 return status;
4905}
4906
4907/*==========================================================================
4908 @ Function Name
4909 WLANDXE_TriggerTX
4910
4911 @ Description
4912 TBD
4913
4914 @ Parameters
4915 pVoid pDXEContext : DXE Control Block
4916
4917 @ Return
4918 wpt_status
4919===========================================================================*/
4920wpt_status WLANDXE_TriggerTX
4921(
4922 void *pDXEContext
4923)
4924{
4925 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4926
4927 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004928 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004929
4930 /* TBD */
4931
4932 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004933 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 return status;
4935}
4936
4937/*==========================================================================
4938 @ Function Name
4939 dxeTxThreadSetPowerStateEventHandler
4940
4941 @ Description
4942 If WDI sends set power state req, this event handler will be called in Tx
4943 thread context
4944
4945 @ Parameters
4946 void *msgPtr
4947 Event MSG
4948
4949 @ Return
4950 None
4951===========================================================================*/
4952void dxeTxThreadSetPowerStateEventHandler
4953(
4954 wpt_msg *msgPtr
4955)
4956{
4957 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4958 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05304959 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004960 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05304961 wpt_int8 i;
4962 WLANDXE_ChannelCBType *channelEntry;
4963 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07004964
4965 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004966 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004967
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4969 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4970 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4971
4972 switch(reqPowerState)
4973 {
4974 case WLANDXE_POWER_STATE_BMPS:
4975 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4976 {
4977 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4978 //based on amount of TX and RX activity - during this time any received
4979 // management frames will remain un-processed consuming RX buffers
4980 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4981 dxeCtxt->hostPowerState = reqPowerState;
4982 }
4983 else
4984 {
4985 status = eWLAN_PAL_STATUS_E_INVAL;
4986 }
4987 break;
4988 case WLANDXE_POWER_STATE_IMPS:
4989 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4990 {
Mihir Shetea4306052014-03-25 00:02:54 +05304991
4992 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
4993 {
4994 channelEntry = &dxeCtxt->dxeChannel[i];
4995 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
4996 {
4997 status = eWLAN_PAL_STATUS_E_FAILURE;
4998 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4999 "%11s : %s :TX Pending frame",
5000 channelType[channelEntry->channelType], __func__);
5001
5002 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
5003 dxeDescriptorDump(channelEntry,
5004 channelEntry->headCtrlBlk->linkedDesc, 0);
5005 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
5006 &channelLog);
5007 dxeChannelAllDescDump(channelEntry,
5008 channelEntry->channelType,
5009 &channelLog);
5010 }
5011 }
5012
5013 if (eWLAN_PAL_STATUS_SUCCESS == status)
5014 {
5015 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
5016 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5017 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 }
5019 else
5020 {
5021 status = eWLAN_PAL_STATUS_E_INVAL;
5022 }
5023 break;
5024 case WLANDXE_POWER_STATE_FULL:
5025 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5026 {
5027 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5028 }
5029 dxeCtxt->hostPowerState = reqPowerState;
5030 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5031 break;
5032 case WLANDXE_POWER_STATE_DOWN:
5033 WLANDXE_Stop((void *)dxeCtxt);
5034 break;
5035 default:
5036 //assert
5037 break;
5038 }
5039
5040 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
5041 {
5042 dxeCtxt->setPowerStateCb(status,
5043 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
5044 }
Ravali85acf6b2012-12-12 14:01:38 -08005045 else
5046 {
5047 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5048 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
5049 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005050 /* Free MSG buffer */
5051 wpalMemoryFree(msgPtr);
5052 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005053 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 return;
5055}
5056
5057
5058/*==========================================================================
5059 @ Function Name
5060 dxeRxThreadSetPowerStateEventHandler
5061
5062 @ Description
5063 If WDI sends set power state req, this event handler will be called in Rx
5064 thread context
5065
5066 @ Parameters
5067 void *msgPtr
5068 Event MSG
5069
5070 @ Return
5071 None
5072===========================================================================*/
5073void dxeRxThreadSetPowerStateEventHandler
5074(
5075 wpt_msg *msgPtr
5076)
5077{
5078 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5079
5080 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005081 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005082
5083 /* Now serialise the message through Tx thread also to make sure
5084 * no register access when RIVA is in powersave */
5085 /*Use the same message pointer just change the call back function */
5086 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5087 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5088 msgPtr);
5089 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5090 {
5091 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5092 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005093 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005094 }
5095
5096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005097 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005098}
5099
5100/*==========================================================================
5101 @ Function Name
5102 WLANDXE_SetPowerState
5103
5104 @ Description
5105 From Client let DXE knows what is the WLAN HW(RIVA) power state
5106
5107 @ Parameters
5108 pVoid pDXEContext : DXE Control Block
5109 WLANDXE_PowerStateType powerState
5110
5111 @ Return
5112 wpt_status
5113===========================================================================*/
5114wpt_status WLANDXE_SetPowerState
5115(
5116 void *pDXEContext,
5117 WDTS_PowerStateType powerState,
5118 WDTS_SetPSCbType cBack
5119)
5120{
5121 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5122 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5123 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005124 wpt_msg *rxCompMsg;
5125 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005126
5127 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005128 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 if(NULL == pDXEContext)
5130 {
5131 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005132 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005133 return eWLAN_PAL_STATUS_E_FAILURE;
5134 }
5135 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5136
Jeff Johnson295189b2012-06-20 16:38:30 -07005137 switch(powerState)
5138 {
5139 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005140 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5141 {
5142 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5143 if(NULL == txDescReSyncMsg)
5144 {
5145 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5146 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5147 }
5148 else
5149 {
5150 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5151 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5152 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5153 txDescReSyncMsg);
5154 if(eWLAN_PAL_STATUS_SUCCESS != status)
5155 {
5156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5157 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5158 }
5159 }
5160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005161 hostPowerState = WLANDXE_POWER_STATE_FULL;
5162 break;
5163 case WDTS_POWER_STATE_BMPS:
5164 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5165 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5166 break;
5167 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005168 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5169 break;
5170 case WDTS_POWER_STATE_DOWN:
5171 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5172 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5173 break;
5174 default:
5175 hostPowerState = WLANDXE_POWER_STATE_MAX;
5176 }
5177
5178 // A callback i.e. ACK back is needed only when we want to enable BMPS
5179 // and the data/management path is active because we want to ensure
5180 // DXE registers are not accessed when RIVA may be power-collapsed. So
5181 // we need a callback in enter_bmps_req (the request to RIVA is sent
5182 // only after ACK back from TX thread). A callback is not needed in
5183 // finish_scan_req during BMPS since data-path is resumed only in
5184 // finish_scan_rsp and no management frames are sent in between. No
5185 // callback is needed when going from BMPS enabled to BMPS suspended/
5186 // disabled when it is known that RIVA is awake and cannot enter power
5187 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5188 // init_scan_rsp
5189 if ( cBack )
5190 {
5191 //serialize through Rx thread
5192 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5193 if(NULL == rxCompMsg)
5194 {
5195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5196 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5197 return eWLAN_PAL_STATUS_E_RESOURCES;
5198 }
5199
5200 /* Event type, where it must be defined???? */
5201 /* THIS MUST BE CLEARED ASAP
5202 txCompMsg->type = TX_COMPLETE; */
5203 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5204 rxCompMsg->pContext = pDxeCtrlBlk;
5205 rxCompMsg->val = hostPowerState;
5206 rxCompMsg->ptr = cBack;
5207 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5208 rxCompMsg);
5209 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5210 {
5211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5212 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005213 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 }
5215 }
5216 else
5217 {
5218 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5219 {
5220 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5221 {
5222 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5223 }
5224 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5225 {
5226 /* Requested Full power from exit IMPS, reenable the interrupts*/
5227 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5228 {
5229 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5230 /* Enable RX interrupt at here, if new PS is not IMPS */
5231 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5232 if(eWLAN_PAL_STATUS_SUCCESS != status)
5233 {
5234 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005235 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 return status;
5237 }
5238 }
5239 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5240 {
5241 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005242 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 /* Enable RX interrupt at here, if new PS is not IMPS */
5244 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5245 if(eWLAN_PAL_STATUS_SUCCESS != status)
5246 {
5247 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005248 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 return status;
5250 }
5251 }
5252 }
5253 pDxeCtrlBlk->hostPowerState = hostPowerState;
5254 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5255 }
5256 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5257 {
5258 pDxeCtrlBlk->hostPowerState = hostPowerState;
5259 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5260 }
Mihir Shetea4306052014-03-25 00:02:54 +05305261 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5262 {
5263 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005265 else
5266 {
5267 HDXE_ASSERT(0);
5268 }
5269 }
5270
5271 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005272 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005273
5274 return status;
5275}
5276
5277/*==========================================================================
5278 @ Function Name
5279 WLANDXE_GetFreeTxDataResNumber
5280
5281 @ Description
5282 Returns free descriptor numbers for TX data channel (TX high priority)
5283
5284 @ Parameters
5285 pVoid pDXEContext : DXE Control Block
5286
5287 @ Return
5288 wpt_uint32 Free descriptor number of TX high pri ch
5289===========================================================================*/
5290wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5291(
5292 void *pDXEContext
5293)
5294{
5295 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005296 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005297
5298 if(NULL == pDXEContext)
5299 {
5300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005301 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005302 return (0);
5303 }
5304
Mihir Shetee6618162015-03-16 14:48:42 +05305305 return ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005306}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005307
5308/*==========================================================================
5309 @ Function Name
5310 WLANDXE_ChannelDebug
5311
5312 @ Description
5313 Display DXE Channel debugging information
5314 User may request to display DXE channel snapshot
5315 Or if host driver detects any abnormal stcuk may display
5316
5317 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005318 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305319 debugFlags : Enable stall detect features
5320 defined by WPAL_DeviceDebugFlags
5321 These features may effect
5322 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005323
5324 @ Return
5325 NONE
5326
5327===========================================================================*/
5328void WLANDXE_ChannelDebug
5329(
Mihir Shete40a55652014-03-02 14:14:47 +05305330 wpt_boolean displaySnapshot,
5331 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005332)
5333{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005334 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305335 wpt_msg *txDescReSyncMsg ;
Mihir Shete41c41bb2014-08-18 17:37:12 +05305336 wpt_uint32 regValue, regValueLocal = 0;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005337 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5338
5339 /* Debug Type 1, Display current snapshot */
5340 if(displaySnapshot)
5341 {
5342 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5343 * This will not simply wakeup RIVA
5344 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005345 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5346 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005347 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005348 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005349 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
Mihir Shete41c41bb2014-08-18 17:37:12 +05305350#ifdef WCN_PRONTO
5351 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
5352#endif
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005353 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305354 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====",
Leo Chang345ef992013-07-12 10:17:29 -07005355 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305356 tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005357
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005358 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5359 &regValue,
5360 NULL,
5361 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005362
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005363 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5364 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005365 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005366 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5367 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5368 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005369 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005370
5371 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5372 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5373 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005374 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005375 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5376 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005377 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005378 }
5379 }
5380
Mihir Shete40a55652014-03-02 14:14:47 +05305381 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005382 {
Mihir Shete40a55652014-03-02 14:14:47 +05305383 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5384 if(NULL == txDescReSyncMsg)
5385 {
5386 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5387 "%s: Resync MSG MEM alloc Fail",__func__);
5388 }
5389 else
5390 {
5391 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5392 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5393 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5394 txDescReSyncMsg);
5395 if(eWLAN_PAL_STATUS_SUCCESS != status)
5396 {
5397 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5398 "%s: Post TX re-sync MSG fail",__func__);
5399 }
5400 }
5401 }
5402
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005403 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005404}
Mihir Shete5affadc2015-05-29 20:54:57 +05305405
5406wpt_uint32 WLANDXE_SetupLogTransfer(wpt_uint64 bufferAddr, wpt_uint32 bufferLen)
5407{
5408 WLANDXE_ChannelCBType *channelEntry;
5409
5410 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5411
5412
5413 return dxeRXLogRefillRing(tempDxeCtrlBlk, channelEntry, bufferAddr,
5414 bufferLen);
5415}
5416
5417wpt_status WLANDXE_StartLogTransfer(void)
5418{
5419 WLANDXE_ChannelCBType *channelEntry;
5420 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5421
5422 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5423
5424 tempDxeCtrlBlk->hostInitiatedH2H = 1;
5425 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
5426 channelEntry->headCtrlBlk->linkedDescPhyAddr);
5427 if(eWLAN_PAL_STATUS_SUCCESS != status)
5428 {
5429 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5430 "%s Write DESC Address register fail", __func__);
5431 return status;
5432 }
5433
5434 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
5435 channelEntry->extraConfig.chan_mask);
5436 if(eWLAN_PAL_STATUS_SUCCESS != status)
5437 {
5438 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5439 "dxeChannelInitProgram Write RX Control register fail");
5440 return status;
5441 }
5442 return status;
5443}