blob: 253203bb2ceb55e37b4171ef425a504f95f052a2 [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];
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +0530115static WLANDXE_EnvInformation dxeEnvBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -0700116
117/*-------------------------------------------------------------------------
118 * External Function Proto Type
119 *-------------------------------------------------------------------------*/
120
121/*-------------------------------------------------------------------------
122 * Local Function Proto Type
123 *-------------------------------------------------------------------------*/
124static wpt_status dxeRXFrameSingleBufferAlloc
125(
126 WLANDXE_CtrlBlkType *dxeCtxt,
127 WLANDXE_ChannelCBType *channelEntry,
128 WLANDXE_DescCtrlBlkType *currentCtrlBlock
129);
130
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700131static wpt_status dxeNotifySmsm
132(
133 wpt_boolean kickDxe,
134 wpt_boolean ringEmpty
135);
136
Mihir Shetefdc9f532014-01-09 15:03:02 +0530137static void dxeStartSSRTimer
138(
139 WLANDXE_CtrlBlkType *dxeCtxt
140);
141
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530142static wpt_status dxeTXCleanup
143(
144 WLANDXE_CtrlBlkType *hostCtxt
145);
146
Jeff Johnson295189b2012-06-20 16:38:30 -0700147/*-------------------------------------------------------------------------
148 * Local Function
149 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700150/*==========================================================================
151 @ Function Name
152 dxeChannelMonitor
153
154 @ Description
155
156 @ Parameters
157 WLANDXE_ChannelCBType *channelEntry
158 Channel specific control block
159
160 @ Return
161 wpt_status
162
163===========================================================================*/
164static wpt_status dxeChannelMonitor
165(
166 char *monitorDescription,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530167 WLANDXE_ChannelCBType *channelEntry,
168 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700169)
170{
171 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
172
Jeff Johnsone7245742012-09-05 17:12:55 -0700173 if((NULL == monitorDescription) || (NULL == channelEntry))
174 {
175 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
176 "INVALID Input ARG");
177 return eWLAN_PAL_STATUS_E_INVAL;
178 }
179
Mihir Shetee6618162015-03-16 14:48:42 +0530180 if(channelEntry->channelType >= WDTS_CHANNEL_MAX)
Jeff Johnsone7245742012-09-05 17:12:55 -0700181 {
182 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
183 "INVALID Channel type");
184 return eWLAN_PAL_STATUS_E_INVAL;
185 }
186
Leo Chang345ef992013-07-12 10:17:29 -0700187 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
188 "%11s : HCBO %d, HCBDP 0x%x, HCBDC 0x%x,",
189 channelType[channelEntry->channelType],
190 channelEntry->headCtrlBlk->ctrlBlkOrder,
191 channelEntry->headCtrlBlk->linkedDescPhyAddr,
192 channelEntry->headCtrlBlk->linkedDesc->descCtrl.ctrl);
193 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
194 "%11s : TCBO %d, TCBDP 0x%x, TCBDC 0x%x",
195 channelType[channelEntry->channelType],
196 channelEntry->tailCtrlBlk->ctrlBlkOrder,
197 channelEntry->tailCtrlBlk->linkedDescPhyAddr,
198 channelEntry->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
199 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
200 "%11s : FDC %d, RDC %d, TFC %d",
201 channelType[channelEntry->channelType],
202 channelEntry->numFreeDesc,
203 channelEntry->numRsvdDesc,
204 channelEntry->numTotalFrame);
Jeff Johnson295189b2012-06-20 16:38:30 -0700205
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700206 if(channelLog)
207 {
208 channelLog->numDesc = channelEntry->numDesc;
209 channelLog->numFreeDesc = channelEntry->numFreeDesc;
210 channelLog->numRsvdDesc = channelEntry->numRsvdDesc;
211 channelLog->headDescOrder = channelEntry->headCtrlBlk->ctrlBlkOrder;
212 channelLog->tailDescOrder = channelEntry->tailCtrlBlk->ctrlBlkOrder;
213 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530214
Jeff Johnson295189b2012-06-20 16:38:30 -0700215 return status;
216}
217
Jeff Johnsone7245742012-09-05 17:12:55 -0700218#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700219/*==========================================================================
220 @ Function Name
221 dxeMemoryDump
222
223 @ Description
224
225 @ Parameters
226 WLANDXE_ChannelCBType *channelEntry
227 Channel specific control block
228
229 @ Return
230 wpt_status
231
232===========================================================================*/
233static wpt_status dxeMemoryDump
234(
235 wpt_uint8 *dumpPointer,
236 wpt_uint32 dumpSize,
237 char *dumpTarget
238)
239{
240 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
241 wpt_uint32 numBytes = 0;
242 wpt_uint32 idx;
243
Jeff Johnsone7245742012-09-05 17:12:55 -0700244 if((NULL == dumpPointer) ||
245 (NULL == dumpTarget))
246 {
247 return status;
248 }
249
Jeff Johnson295189b2012-06-20 16:38:30 -0700250 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
251 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
253 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
254
255 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
256 for(idx = 0; idx < dumpSize; idx++)
257 {
258 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
259 "0x%2x ", dumpPointer[idx]);
260 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
261 {
262 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
263 }
264 }
265 if(0 != numBytes)
266 {
267 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
268 }
269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
270 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
271
272 return status;
273}
Jeff Johnsone7245742012-09-05 17:12:55 -0700274#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700275
276/*==========================================================================
277 @ Function Name
278 dxeDescriptorDump
279
280 @ Description
281
282 @ Parameters
283 WLANDXE_ChannelCBType *channelEntry
284 Channel specific control block
285
286 @ Return
287 wpt_status
288
289===========================================================================*/
290wpt_status dxeDescriptorDump
291(
292 WLANDXE_ChannelCBType *channelEntry,
293 WLANDXE_DescType *targetDesc,
294 wpt_uint32 fragmentOrder
295)
296{
297 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
298
299
Jeff Johnsone7245742012-09-05 17:12:55 -0700300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700302 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700303 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700305 fragmentOrder + 1,
306 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700307
Jeff Johnsone7245742012-09-05 17:12:55 -0700308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 "CTRL WORD 0x%x, TransferSize %d",
310 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
311 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700313 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
314 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
315 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
316 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700317 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
319
320 return status;
321}
322
323/*==========================================================================
324 @ Function Name
325 dxeChannelRegisterDump
326
327 @ Description
328
329 @ Parameters
330 WLANDXE_ChannelCBType *channelEntry
331 Channel specific control block
332
333 @ Return
334 wpt_status
335
336===========================================================================*/
337wpt_status dxeChannelRegisterDump
338(
339 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530340 char *dumpTarget,
341 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700342)
343{
Leo Chang345ef992013-07-12 10:17:29 -0700344 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
345 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
346
347 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
348 * This will not simply wakeup RIVA
349 * Just incase TX not wanted stuck, Trigger TX again */
350 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
351 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
352 wpalSleep(10);
Jeff Johnson295189b2012-06-20 16:38:30 -0700353
Mihir Shetee6618162015-03-16 14:48:42 +0530354 if(channelEntry->channelType >= WDTS_CHANNEL_MAX)
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700355 {
356 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
357 "INVALID Channel type");
358 return eWLAN_PAL_STATUS_E_INVAL;
359 }
360
Leo Chang345ef992013-07-12 10:17:29 -0700361 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &chDescReg);
362 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
363 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &chControlReg);
364 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &chStatusReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365
Leo Chang345ef992013-07-12 10:17:29 -0700366 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
367 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x",
368 channelType[channelEntry->channelType],
369 chControlReg, chStatusReg, chDescReg, chLDescReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700371 if(channelLog)
372 {
373 channelLog->ctrlRegVal = chControlReg;
374 channelLog->statRegVal = chStatusReg;
375 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700376
Jeff Johnson295189b2012-06-20 16:38:30 -0700377 return status;
378}
Jeff Johnsone7245742012-09-05 17:12:55 -0700379
380/*==========================================================================
381 @ Function Name
382 dxeChannelAllDescDump
383
384 @ Description
385 Dump all DXE descriptors within assigned channe;
386
387 @ Parameters
388 WLANDXE_ChannelCBType *channelEntry
389
390 @ Return
391 NONE
392
393===========================================================================*/
394void dxeChannelAllDescDump
395(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700396 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530397 WDTS_ChannelType channel,
398 wpt_log_data_stall_channel_type *channelLog
Jeff Johnsone7245742012-09-05 17:12:55 -0700399)
400{
401 wpt_uint32 channelLoop;
402 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700403 wpt_uint32 previousCtrlValue = 0;
Leo Chang345ef992013-07-12 10:17:29 -0700404 wpt_uint32 previousCtrlValid = 0;
405 wpt_uint32 currentCtrlValid = 0;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700406 wpt_uint32 valDescCount = 0;
407 wpt_uint32 invalDescCount = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700408
409 targetCtrlBlk = channelEntry->headCtrlBlk;
410
411 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Leo Chang345ef992013-07-12 10:17:29 -0700412 "%11s : %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700413 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700414 channelEntry->numDesc,
415 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700416 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
417
418 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530419 (WDTS_CHANNEL_RX_HIGH_PRI == channel)||
420 (WDTS_CHANNEL_RX_LOG == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700421 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700422 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700423 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700424 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
425 {
426 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
427 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
428 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
429 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700430 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
431 {
432 valDescCount++;
433 }
434 else
435 {
436 invalDescCount++;
437 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700438 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
439 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700440 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700441 }
442 else
443 {
Leo Chang345ef992013-07-12 10:17:29 -0700444 /* Head Descriptor is valid or not */
445 previousCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
446 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700447 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
448 {
Leo Chang345ef992013-07-12 10:17:29 -0700449 currentCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700450 if(currentCtrlValid)
451 {
452 valDescCount++;
453 }
454 else
455 {
456 invalDescCount++;
457 }
Leo Chang345ef992013-07-12 10:17:29 -0700458 if(currentCtrlValid != previousCtrlValid)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700459 {
460 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
461 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
462 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
463 }
Leo Chang345ef992013-07-12 10:17:29 -0700464 previousCtrlValid = currentCtrlValid;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700465 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
466 }
467 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530468
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700469 if(channelLog)
470 {
471 channelLog->numValDesc = valDescCount;
472 channelLog->numInvalDesc = invalDescCount;
473 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530474
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700475 return;
476}
477
478/*==========================================================================
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530479 @ Function Name
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530480 dxeErrHandler
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530481
482 @ Description
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530483 Dump channel information for which Error interrupt has occured and
484 try to recover from the Error
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530485
486 @ Parameters
487 WLANDXE_ChannelCBType *channelCb
488
489 @ Return
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530490 wpt_status: eWLAN_PAL_STATUS_SUCCESS if recovery is possible and
491 successful
492 eWLAN_PAL_STATUS_E_FAILURE if recovery is not possible
493 or recovery fails
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530494===========================================================================*/
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530495wpt_status dxeErrHandler
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530496(
Mihir Shete79d6b582014-03-12 17:54:07 +0530497 WLANDXE_ChannelCBType *channelCb,
498 wpt_uint32 chStatusReg
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530499)
500{
501 wpt_log_data_stall_channel_type channelLog;
Mihir Shete79d6b582014-03-12 17:54:07 +0530502 wpt_uint32 chLDescReg, channelLoop;
503 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530504
505 dxeChannelMonitor("INT_ERR", channelCb, &channelLog);
506 dxeDescriptorDump(channelCb, channelCb->headCtrlBlk->linkedDesc, 0);
507 dxeChannelRegisterDump(channelCb, "INT_ERR", &channelLog);
508 dxeChannelAllDescDump(channelCb, channelCb->channelType, &channelLog);
509 wpalMemoryCopy(channelLog.channelName,
510 "INT_ERR",
511 WPT_TRPT_CHANNEL_NAME);
512 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelCb->channelType);
513#ifdef FEATURE_WLAN_DIAG_SUPPORT
514 wpalPacketStallDumpLog();
515#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Mihir Shete79d6b582014-03-12 17:54:07 +0530516 switch ((chStatusReg & WLANDXE_CH_STAT_ERR_CODE_MASK) >>
517 WLANDXE_CH_STAT_ERR_CODE_OFFSET)
518 {
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530519
Mihir Shete79d6b582014-03-12 17:54:07 +0530520 case WLANDXE_ERROR_PRG_INV_B2H_SRC_QID:
521 case WLANDXE_ERROR_PRG_INV_B2H_DST_QID:
522 case WLANDXE_ERROR_PRG_INV_B2H_SRC_IDX:
523 case WLANDXE_ERROR_PRG_INV_H2B_SRC_QID:
524 case WLANDXE_ERROR_PRG_INV_H2B_DST_QID:
525 case WLANDXE_ERROR_PRG_INV_H2B_DST_IDX:
526 {
527 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
528 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
529 wpalSleep(10);
530
531 if(channelCb->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
532 {
533 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
534 "%s: Invalid Channel", __func__);
535 break;
536 }
537
538 wpalReadRegister(channelCb->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
539
540 targetCtrlBlk = channelCb->headCtrlBlk;
541
542 for(channelLoop = 0; channelLoop < channelCb->numDesc; channelLoop++)
543 {
544 if (targetCtrlBlk->linkedDescPhyAddr == chLDescReg)
545 {
546 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
547 "%11s :CHx_DESCL: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
548 channelType[channelCb->channelType],
549 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
550 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
551 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
552 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
553
554 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
555
556 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
557 "%11s :Next Desc: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
558 channelType[channelCb->channelType],
559 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
560 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
561 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
562 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
563 break;
564 }
565 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
566 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530567 wpalFwDumpReq(17, 0, 0, 0, 0, 1);
Mihir Shete79d6b582014-03-12 17:54:07 +0530568 break;
569 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530570 case WLANDXE_ERROR_ABORT:
571 {
572 wpt_uint32 regValue, regValueLocal;
573 wpt_uint32 count = 0;
574 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
575 "%s: DXE Abort Error from S/W", __func__);
576
577 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &regValue);
578 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
579 "%s: DXE CSR Value: %08x", __func__,regValue);
580
581 //Execute the BMU recovery only if firmware triggered the ABORT
582 if (regValue & WLANDXE_DMA_CSR_FW_BMU_RECOVERY)
583 {
584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
585 "%s: Firmware BMU recovery On %08x", __func__,regValue);
586
587 // Clean up the descriptors
588 if (eWLAN_PAL_STATUS_SUCCESS !=
589 dxeTXCleanup(tempDxeCtrlBlk))
590 {
591 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
592 "%s: Host DXE Cleanup Failed!!!!", __func__);
593 }
594
595 // Debug DXE channel after cleanup
596 dxeChannelMonitor("INT_ERR", channelCb, &channelLog);
597 dxeDescriptorDump(channelCb, channelCb->headCtrlBlk->linkedDesc, 0);
598 dxeChannelRegisterDump(channelCb, "INT_ERR", &channelLog);
599 dxeChannelAllDescDump(channelCb, channelCb->channelType, &channelLog);
600
601 // Unblock the firmware
602 regValue |= WLANDXE_DMA_CSR_HOST_RECOVERY_DONE;
603 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
604 "%s: Host DXE Cleanup done %08x", __func__,regValue);
605 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS, regValue);
606
607 // Wait for firmware to complete the cleanup
608 do
609 {
610 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &regValue);
611 wpalBusyWait(5000);
612 count++;
613 //count is 60 because wait is for 5 ms and 60*5=300ms
614 //which is the time WD bark happens in firmware
615 } while(count < 60 && !(regValue & WLANDXE_DMA_CSR_RECOVERY_DONE));
616 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
617 "%s: FW Cleanup done %08x", __func__,regValue);
618
619 //clear all spare bits in CSR
620 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,regValue &
621 ~(WLANDXE_DMA_CSR_RECOVERY_DONE |
622 WLANDXE_DMA_CSR_FW_BMU_RECOVERY |
623 WLANDXE_DMA_CSR_HOST_RECOVERY_DONE));
624
625 //check if the h/w resources have recovered
626 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
627 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
628 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
629 "===== count %d ABD %d, ABD LOCAL %d =====", count,
630 regValue, regValueLocal);
631 if(regValue == 0 || regValueLocal == 0)
632 {
633 return eWLAN_PAL_STATUS_E_FAILURE;
634 }
635
636 return eWLAN_PAL_STATUS_SUCCESS;
637 }
638 break;
639 }
Mihir Shete79d6b582014-03-12 17:54:07 +0530640 default:
641 {
642 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
643 "%s: No Debug Inormation", __func__);
644 break;
645 }
646
647 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530648 return eWLAN_PAL_STATUS_E_FAILURE;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530649}
650/*==========================================================================
651 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700652 dxeTxThreadChannelDebugHandler
653
654 @ Description
655 Dump TX channel information
656
657 @ Parameters
658 Wwpt_msg *msgPtr
659
660 @ Return
661 NONE
662
663===========================================================================*/
664void dxeTxThreadChannelDebugHandler
665(
666 wpt_msg *msgPtr
667)
668{
669 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700670 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700671
672 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700673 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700674
675 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
676 * This will not simply wakeup RIVA
677 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700678 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
679 {
680 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530681 &tempDxeCtrlBlk->dxeChannel[channelLoop],
682 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700683 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530684 "Abnormal successive empty interrupt",
685 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700686 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530687 channelLoop,
688 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700689
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700690 wpalMemoryCopy(channelLog.channelName,
691 channelType[channelLoop],
692 WPT_TRPT_CHANNEL_NAME);
693 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700694 }
695
Leo Chang345ef992013-07-12 10:17:29 -0700696 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700697 "================== DXE Dump End ======================");
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700698 wpalMemoryFree(msgPtr);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700699
700#ifdef FEATURE_WLAN_DIAG_SUPPORT
701 wpalPacketStallDumpLog();
702#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700704 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700705 return;
706}
707
708/*==========================================================================
709 @ Function Name
710 dxeRxThreadChannelDebugHandler
711
712 @ Description
713 Dump RX channel information
714
715 @ Parameters
716 Wwpt_msg *msgPtr
717
718 @ Return
719 NONE
720
721===========================================================================*/
722void dxeRxThreadChannelDebugHandler
723(
724 wpt_msg *msgPtr
725)
726{
727 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
728 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700729 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700730
731 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700732 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700733
734 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
735 * This will not simply wakeup RIVA
736 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700737 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
738 {
Mihir Shetee6618162015-03-16 14:48:42 +0530739 if (!WLANDXE_IS_VALID_CHANNEL(channelLoop))
740 continue;
741
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700742 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530743 &tempDxeCtrlBlk->dxeChannel[channelLoop],
744 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700745 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530746 "Abnormal successive empty interrupt",
747 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700748 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530749 channelLoop, &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700750
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700751 wpalMemoryCopy(channelLog.channelName,
752 channelType[channelLoop],
753 WPT_TRPT_CHANNEL_NAME);
754 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530755
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700756 }
757
758 /* Now serialise the message through Tx thread also to make sure
759 * no register access when RIVA is in powersave */
760 /*Use the same message pointer just change the call back function */
761 msgPtr->callback = dxeTxThreadChannelDebugHandler;
762 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
763 msgPtr);
764 if ( eWLAN_PAL_STATUS_SUCCESS != status )
765 {
766 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700767 "Tx thread state dump req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700768 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700769 }
770
771 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700772 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700773 return;
774}
Jeff Johnson295189b2012-06-20 16:38:30 -0700775
776/*==========================================================================
777 @ Function Name
778 dxeCtrlBlkAlloc
779
780 @ Description
781 Allocate DXE Control block
782 DXE control block will used by Host DXE driver only, internal structure
783 Will make ring linked list
784
785 @ Parameters
786 WLANDXE_CtrlBlkType *dxeCtrlBlk,
787 DXE host driver main control block
788 WLANDXE_ChannelCBType *channelEntry
789 Channel specific control block
790
791 @ Return
792 wpt_status
793
794===========================================================================*/
795static wpt_status dxeCtrlBlkAlloc
796(
797 WLANDXE_CtrlBlkType *dxeCtrlBlk,
798 WLANDXE_ChannelCBType *channelEntry
799)
800{
801 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
802 unsigned int idx, fIdx;
803 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
804 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
805 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
806 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
807
808 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700809 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700810
811 /* Sanity check */
812 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
813 {
814 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
815 "dxeCtrlBlkAlloc Channel Entry is not valid");
816 return eWLAN_PAL_STATUS_E_INVAL;
817 }
818
819 /* Allocate pre asigned number of control blocks */
820 for(idx = 0; idx < channelEntry->numDesc; idx++)
821 {
822 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
823 if(NULL == currentCtrlBlk)
824 {
825 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
826 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
827 channelEntry->channelType);
828 freeCtrlBlk = channelEntry->headCtrlBlk;
829 for(fIdx = 0; fIdx < idx; fIdx++)
830 {
831 if(NULL == freeCtrlBlk)
832 {
833 break;
834 }
835
836 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
837 wpalMemoryFree((void *)freeCtrlBlk);
838 freeCtrlBlk = nextCtrlBlk;
839 }
840 return eWLAN_PAL_STATUS_E_FAULT;
841 }
842
843 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
844 /* Initialize common elements first */
845 currentCtrlBlk->xfrFrame = NULL;
846 currentCtrlBlk->linkedDesc = NULL;
847 currentCtrlBlk->linkedDescPhyAddr = 0;
848 currentCtrlBlk->ctrlBlkOrder = idx;
849
850 /* This is the first control block allocated
851 * Next Control block is not allocated yet
852 * head and tail must be first control block */
853 if(0 == idx)
854 {
855 currentCtrlBlk->nextCtrlBlk = NULL;
856 channelEntry->headCtrlBlk = currentCtrlBlk;
857 channelEntry->tailCtrlBlk = currentCtrlBlk;
858 }
859 /* This is not first, not last control block
860 * previous control block may has next linked block */
861 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
862 {
863 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
864 }
865 /* This is last control blocl
866 * next control block for the last control block is head, first control block
867 * then whole linked list made RING */
868 else if((channelEntry->numDesc - 1) == idx)
869 {
870 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
871 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
872 }
873 else
874 {
875 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
876 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
877 channelEntry->channelType);
878 wpalMemoryFree(currentCtrlBlk);
879 return eWLAN_PAL_STATUS_E_FAULT;
880 }
881
882 prevCtrlBlk = currentCtrlBlk;
883 channelEntry->numFreeDesc++;
884 }
885
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700886 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 return status;
888}
889
890/*==========================================================================
891 @ Function Name
892 dxeDescLinkAlloc
893
894 @ Description
895 Allocate DXE descriptor
896 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
897 Will make RING linked list
898 Will be linked with Descriptor control block one by one
899
900 @ Parameters
901 WLANDXE_CtrlBlkType *dxeCtrlBlk,
902 DXE host driver main control block
903 WLANDXE_ChannelCBType *channelEntry
904 Channel specific control block
905 @ Return
906 wpt_status
907
908===========================================================================*/
909static wpt_status dxeDescAllocAndLink
910(
911 WLANDXE_CtrlBlkType *dxeCtrlBlk,
912 WLANDXE_ChannelCBType *channelEntry
913)
914{
915 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
916 WLANDXE_DescType *currentDesc = NULL;
917 WLANDXE_DescType *prevDesc = NULL;
918 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
919 unsigned int idx;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530920 void *physAddressAlloc = NULL;
921 wpt_uint32 physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700922
923 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700924 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700925
926 /* Sanity Check */
927 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
928 {
929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
930 "dxeDescLinkAlloc Channel Entry is not valid");
931 return eWLAN_PAL_STATUS_E_INVAL;
932 }
933
934 currentCtrlBlk = channelEntry->headCtrlBlk;
935
Jeff Johnson295189b2012-06-20 16:38:30 -0700936 /* allocate all DXE descriptors for this channel in one chunk */
937 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
938 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530939 &physAddressAlloc);
940 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700941 if(NULL == channelEntry->descriptorAllocation)
942 {
943 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
944 "dxeDescLinkAlloc Descriptor Alloc Fail");
945 return eWLAN_PAL_STATUS_E_RESOURCES;
946 }
947 currentDesc = channelEntry->descriptorAllocation;
Jeff Johnson295189b2012-06-20 16:38:30 -0700948
949 /* Allocate pre asigned number of descriptor */
950 for(idx = 0; idx < channelEntry->numDesc; idx++)
951 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 // descriptors were allocated in a chunk -- use the current one
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 if(NULL == currentDesc)
954 {
955 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
956 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
957 channelEntry->channelType);
958 return eWLAN_PAL_STATUS_E_FAULT;
959 }
Mihir Shete96cd1902015-03-04 15:47:31 +0530960 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
962 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700963
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 currentCtrlBlk->linkedDesc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530965 currentCtrlBlk->linkedDescPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700966 /* First descriptor, next none
967 * descriptor bottom location is first descriptor address */
968 if(0 == idx)
969 {
970 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
971 channelEntry->DescBottomLoc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530972 channelEntry->descBottomLocPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700973 }
974 /* Not first, not last descriptor
975 * may make link for previous descriptor with current descriptor
976 * ENDIAN SWAP needed ????? */
977 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
978 {
979 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530980 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700981 }
982 /* Last descriptor
983 * make a ring by asign next pointer as first descriptor
984 * ENDIAN SWAP NEEDED ??? */
985 else if((channelEntry->numDesc - 1) == idx)
986 {
987 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530988 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 currentDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530990 WLANDXE_U32_SWAP_ENDIAN(channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700991 }
992
993 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
994 * Pre allocated and physical address must be assigned into
995 * Corresponding DXE Descriptor */
Jeff Johnson295189b2012-06-20 16:38:30 -0700996 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530997 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
998 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -0700999 {
1000 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
1001 channelEntry,
1002 currentCtrlBlk);
1003 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1004 {
1005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1006 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1007 channelEntry->channelType);
1008 return status;
1009 }
1010 --channelEntry->numFreeDesc;
1011 }
1012
Leo Chang7e05f212013-07-01 19:54:15 -07001013 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1014 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1015 {
1016 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1017 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1018 }
1019 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301020 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
1021 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Leo Chang7e05f212013-07-01 19:54:15 -07001022 {
1023 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1024 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1025 }
1026 else
1027 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05301028 /* Just in case. H2H RX channel, do nothing
Leo Chang7e05f212013-07-01 19:54:15 -07001029 * By Definition this must not happen */
1030 }
1031
Jeff Johnson295189b2012-06-20 16:38:30 -07001032 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1033 prevDesc = currentDesc;
1034
Jeff Johnson295189b2012-06-20 16:38:30 -07001035 // advance to the next pre-allocated descriptor in the chunk
1036 currentDesc++;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301037 physAddress = (physAddress + sizeof(WLANDXE_DescType));
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 }
1039
1040 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001041 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 return status;
1043}
1044
1045/*==========================================================================
1046 @ Function Name
1047
1048 @ Description
1049
1050 @ Parameters
1051
1052 @ Return
1053 wpt_status
1054
1055===========================================================================*/
1056static wpt_status dxeSetInterruptPath
1057(
1058 WLANDXE_CtrlBlkType *dxeCtrlBlk
1059)
1060{
1061 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1062 wpt_uint32 interruptPath = 0;
1063 wpt_uint32 idx;
1064 WLANDXE_ChannelCBType *channelEntry = NULL;
1065
1066 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001067 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001068
Mihir Shetee6618162015-03-16 14:48:42 +05301069 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07001070 {
1071 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1073 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001074 {
1075 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1076 }
1077 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301078 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
Mihir Shetec4093f92015-05-28 15:21:11 +05301079 (WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301080 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 {
1082 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1083 }
1084 else
1085 {
1086 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1087 "H2H TEST RX???? %d", channelEntry->channelType);
1088 }
1089 }
1090 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1091 "Interrupt Path Must be 0x%x", interruptPath);
1092 dxeCtrlBlk->interruptPath = interruptPath;
1093 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1094
1095 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001096 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 return status;
1098}
1099
1100/*==========================================================================
1101 @ Function Name
1102 dxeEngineCoreStart
1103
1104 @ Description
1105 Trigger to start RIVA DXE Hardware
1106
1107 @ Parameters
1108 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1109 DXE host driver main control block
1110
1111 @ Return
jagadeeshf869bba2015-04-07 20:06:21 +05301112 void
Jeff Johnson295189b2012-06-20 16:38:30 -07001113
1114===========================================================================*/
jagadeeshf869bba2015-04-07 20:06:21 +05301115static void dxeEngineCoreStart
Jeff Johnson295189b2012-06-20 16:38:30 -07001116(
1117 WLANDXE_CtrlBlkType *dxeCtrlBlk
1118)
1119{
Jeff Johnson295189b2012-06-20 16:38:30 -07001120 wpt_uint32 registerData = 0;
Leo Chang00708f62013-12-03 20:21:51 -08001121 wpt_uint8 readRetry;
Jeff Johnson295189b2012-06-20 16:38:30 -07001122
1123 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001124 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001125
Leo Chang00708f62013-12-03 20:21:51 -08001126#ifdef WCN_PRONTO
1127 /* Read default */
1128 wpalReadRegister(WLANDXE_CCU_SOFT_RESET, &registerData);
1129 registerData |= WLANDXE_DMA_CCU_DXE_RESET_MASK;
1130
1131 /* Make reset */
1132 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1133
1134 /* Clear reset */
1135 registerData &= ~WLANDXE_DMA_CCU_DXE_RESET_MASK;
1136 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1137#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001138 /* START This core init is not needed for the integrated system */
1139 /* Reset First */
1140 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1141 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1142 registerData);
Leo Chang00708f62013-12-03 20:21:51 -08001143#endif /* WCN_PRONTO */
Jeff Johnson295189b2012-06-20 16:38:30 -07001144
Leo Chang00708f62013-12-03 20:21:51 -08001145 for(readRetry = 0; readRetry < WLANDXE_CSR_MAX_READ_COUNT; readRetry++)
1146 {
1147 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1148 WLANDXE_CSR_DEFAULT_ENABLE);
1149 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &registerData);
1150 if(!(registerData & WLANDXE_DMA_CSR_EN_MASK))
1151 {
1152 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1153 "%s CSR 0x%x, count %d",
1154 __func__, registerData, readRetry);
1155 /* CSR is not valid value, re-try to write */
1156 wpalBusyWait(WLANDXE_CSR_NEXT_READ_WAIT);
1157 }
1158 else
1159 {
1160 break;
1161 }
1162 }
1163 if(WLANDXE_CSR_MAX_READ_COUNT == readRetry)
1164 {
1165 /* MAX wait, still cannot write correct value
1166 * Panic device */
1167 wpalDevicePanic();
1168 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001169
1170 /* Is This needed?
1171 * Not sure, revisit with integrated system */
1172 /* END This core init is not needed for the integrated system */
1173
1174 dxeSetInterruptPath(dxeCtrlBlk);
1175 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001176 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001177}
1178
1179/*==========================================================================
1180 @ Function Name
1181 dxeChannelInitProgram
1182
1183 @ Description
1184 Program RIVA DXE engine register with initial value
1185 What must be programmed
1186 - Source Address (SADRL, chDXESadrlRegAddr)
1187 - Destination address (DADRL, chDXEDadrlRegAddr)
1188 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1189 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1190
1191 Not need to program now
1192 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1193 TX : Have to program to trigger send out frame
1194 RX : programmed by DXE engine
1195
1196 @ Parameters
1197 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1198 DXE host driver main control block
1199 WLANDXE_ChannelCBType *channelEntry
1200 Channel specific control block
1201 @ Return
1202 wpt_status
1203
1204===========================================================================*/
1205static wpt_status dxeChannelInitProgram
1206(
1207 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1208 WLANDXE_ChannelCBType *channelEntry
1209)
1210{
1211 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1212 wpt_uint32 idx;
1213 WLANDXE_DescType *currentDesc = NULL;
1214 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1215
1216 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001217 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001218
1219 /* Sanity Check */
1220 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1221 {
1222 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1223 "dxeChannelInitProgram Channel Entry is not valid");
1224 return eWLAN_PAL_STATUS_E_INVAL;
1225 }
1226
1227 /* Program Source address and destination adderss */
1228 if(!channelEntry->channelConfig.useShortDescFmt)
1229 {
1230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1231 "dxeChannelInitProgram Long Descriptor not support yet");
1232 return eWLAN_PAL_STATUS_E_FAILURE;
1233 }
1234
1235 /* Common register area */
1236 /* Next linked list Descriptor pointer */
1237 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1238 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1239 if(eWLAN_PAL_STATUS_SUCCESS != status)
1240 {
1241 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1242 "dxeChannelInitProgram Write DESC Address register fail");
1243 return status;
1244 }
1245
1246 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1247 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1248 {
1249 /* Program default registers */
1250 /* TX DMA channel, DMA destination address is work Q */
1251 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1252 channelEntry->channelConfig.refWQ);
1253 if(eWLAN_PAL_STATUS_SUCCESS != status)
1254 {
1255 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1256 "dxeChannelInitProgram Write TX DAddress register fail");
1257 return status;
1258 }
1259 }
1260 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301261 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1262 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001263 {
1264 /* Initialize Descriptor control Word First */
1265 currentCtrlBlk = channelEntry->headCtrlBlk;
1266 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1267 {
1268 currentDesc = currentCtrlBlk->linkedDesc;
1269 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1270 }
1271
1272 /* RX DMA channel, DMA source address is work Q */
1273 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1274 channelEntry->channelConfig.refWQ);
1275 if(eWLAN_PAL_STATUS_SUCCESS != status)
1276 {
1277 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1278 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1279 return status;
1280 }
1281
1282 /* RX DMA channel, Program pre allocated destination Address */
1283 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1284 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1285 if(eWLAN_PAL_STATUS_SUCCESS != status)
1286 {
1287 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1288 "dxeChannelInitProgram Write RX DAddress register fail");
1289 return status;
1290 }
1291
1292 /* RX Channels, default Control registers MUST BE ENABLED */
jagadeeshf869bba2015-04-07 20:06:21 +05301293 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07001294 channelEntry->extraConfig.chan_mask);
1295 if(eWLAN_PAL_STATUS_SUCCESS != status)
1296 {
1297 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1298 "dxeChannelInitProgram Write RX Control register fail");
1299 return status;
1300 }
1301 }
1302 else
1303 {
1304 /* H2H test channel, not use work Q */
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 }
1306
1307 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001308 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001309 return status;
1310}
1311
1312
1313/*==========================================================================
1314 @ Function Name
1315 dxeChannelStart
1316
1317 @ Description
1318 Start Specific Channel
1319
1320 @ Parameters
1321 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1322 DXE host driver main control block
1323 WLANDXE_ChannelCBType *channelEntry
1324 Channel specific control block
1325
1326 @ Return
1327 wpt_status
1328
1329===========================================================================*/
1330static wpt_status dxeChannelStart
1331(
1332 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1333 WLANDXE_ChannelCBType *channelEntry
1334)
1335{
1336 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1337 wpt_uint32 regValue = 0;
1338 wpt_uint32 intMaskVal = 0;
1339
1340 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001341 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001342
1343 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1344 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1345
1346 /* Enable individual channel
1347 * not to break current channel setup, first read register */
1348 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1349 &regValue);
1350 if(eWLAN_PAL_STATUS_SUCCESS != status)
1351 {
1352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1353 "dxeChannelStart Read Channel Enable register fail");
1354 return status;
1355 }
1356
1357 /* Enable Channel specific Interrupt */
1358 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1359 &intMaskVal);
1360 if(eWLAN_PAL_STATUS_SUCCESS != status)
1361 {
1362 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1363 "dxeChannelStart Read INT_MASK register fail");
1364 return status;
1365 }
1366 intMaskVal |= channelEntry->extraConfig.intMask;
1367 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1368 intMaskVal);
1369 if(eWLAN_PAL_STATUS_SUCCESS != status)
1370 {
1371 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1372 "dxeChannelStart Write INT_MASK register fail");
1373 return status;
1374 }
1375
1376 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001377 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001378 return status;
1379}
1380
1381/*==========================================================================
1382 @ Function Name
1383 dxeChannelStop
1384
1385 @ Description
1386 Stop Specific Channel
1387
1388 @ Parameters
1389 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1390 DXE host driver main control block
1391 WLANDXE_ChannelCBType *channelEntry
1392 Channel specific control block
1393
1394 @ Return
1395 wpt_status
1396
1397===========================================================================*/
1398static wpt_status dxeChannelStop
1399(
1400 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1401 WLANDXE_ChannelCBType *channelEntry
1402)
1403{
1404 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1405 wpt_uint32 intMaskVal = 0;
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
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001418 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1419 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1420 {
1421 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1422 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001423 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 /* Maskout interrupt */
1426 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1427 &intMaskVal);
1428 if(eWLAN_PAL_STATUS_SUCCESS != status)
1429 {
1430 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1431 "dxeChannelStop Read INT_MASK register fail");
1432 return status;
1433 }
1434 intMaskVal ^= channelEntry->extraConfig.intMask;
1435 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1436 intMaskVal);
1437 if(eWLAN_PAL_STATUS_SUCCESS != status)
1438 {
1439 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1440 "dxeChannelStop Write INT_MASK register fail");
1441 return status;
1442 }
1443
1444 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1445
1446 /* Stop Channel ??? */
1447 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001448 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 return status;
1450}
1451
1452/*==========================================================================
1453 @ Function Name
1454 dxeChannelClose
1455
1456 @ Description
1457 Close Specific Channel
1458 Free pre allocated RX frame buffer if RX channel
1459 Free DXE descriptor for each channel
1460 Free Descriptor control block for each channel
1461
1462 @ Parameters
1463 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1464 DXE host driver main control block
1465 WLANDXE_ChannelCBType *channelEntry
1466 Channel specific control block
1467
1468 @ Return
1469 wpt_status
1470
1471===========================================================================*/
1472static wpt_status dxeChannelClose
1473(
1474 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1475 WLANDXE_ChannelCBType *channelEntry
1476)
1477{
1478 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1479 wpt_uint32 idx;
1480 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1481 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1482 WLANDXE_DescType *currentDescriptor = NULL;
1483 WLANDXE_DescType *nextDescriptor = NULL;
1484
1485 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001486 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001487
1488 /* Sanity */
1489 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1490 {
1491 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1492 "dxeChannelStop Invalid arg input");
1493 return eWLAN_PAL_STATUS_E_INVAL;
1494 }
1495
1496 currentCtrlBlk = channelEntry->headCtrlBlk;
1497 if(NULL != currentCtrlBlk)
1498 {
1499 currentDescriptor = currentCtrlBlk->linkedDesc;
1500 for(idx = 0; idx < channelEntry->numDesc; idx++)
1501 {
1502 if (idx + 1 != channelEntry->numDesc)
1503 {
1504 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1505 nextDescriptor = nextCtrlBlk->linkedDesc;
1506 }
1507 else
1508 {
1509 nextCtrlBlk = NULL;
1510 nextDescriptor = NULL;
1511 }
1512 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301513 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1514 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 {
1516 if (NULL != currentCtrlBlk->xfrFrame)
1517 {
1518 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1519 wpalPacketFree(currentCtrlBlk->xfrFrame);
1520 }
1521 }
1522 /*
1523 * It is the responsibility of DXE to walk through the
1524 * descriptor chain and unlock any pending packets (if
1525 * locked).
1526 */
1527 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1528 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1529 {
1530 if((NULL != currentCtrlBlk->xfrFrame) &&
1531 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1532 {
1533 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1534 wpalPacketFree(currentCtrlBlk->xfrFrame);
1535 }
1536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001537 wpalMemoryFree(currentCtrlBlk);
1538
1539 currentCtrlBlk = nextCtrlBlk;
1540 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001541 if(NULL == currentCtrlBlk)
1542 {
1543 /* Already reach last of the control block
1544 * Not need to process anymore, break */
1545 break;
1546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001547 }
1548 }
1549
Jeff Johnson295189b2012-06-20 16:38:30 -07001550 // descriptors were allocated as a single chunk so free the chunk
1551 if(NULL != channelEntry->descriptorAllocation)
1552 {
1553 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1554 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001555
1556 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001557 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 return status;
1559}
1560
1561/*==========================================================================
1562 @ Function Name
1563 dxeChannelCleanInt
1564
1565 @ Description
1566 Clean up interrupt from RIVA HW
1567 After Host finish to handle interrupt, interrupt signal must be cleaned up
1568 Otherwise next interrupt will not be generated
1569
1570 @ Parameters
1571 WLANDXE_ChannelCBType *channelEntry
1572 Channel specific control block
1573 wpt_uint32 *chStat
1574 Channel Status register value
1575
1576 @ Return
1577 wpt_status
1578
1579===========================================================================*/
1580static wpt_status dxeChannelCleanInt
1581(
1582 WLANDXE_ChannelCBType *channelEntry,
1583 wpt_uint32 *chStat
1584)
1585{
1586 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1587
1588 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001589 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001590
1591 /* Read Channel Status Register to know why INT Happen */
1592 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1593 chStat);
1594 if(eWLAN_PAL_STATUS_SUCCESS != status)
1595 {
1596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1597 "dxeChannelCleanInt Read CH STAT register fail");
1598 return eWLAN_PAL_STATUS_E_FAULT;
1599 }
1600 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1601 "%s Channel INT Clean, Status 0x%x",
1602 channelType[channelEntry->channelType], *chStat);
1603
1604 /* Clean up all the INT within this channel */
1605 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1606 (1 << channelEntry->assignedDMAChannel));
1607 if(eWLAN_PAL_STATUS_SUCCESS != status)
1608 {
1609 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1610 "dxeChannelCleanInt Write CH Clean register fail");
1611 return eWLAN_PAL_STATUS_E_FAULT;
1612 }
1613
Jeff Johnsone7245742012-09-05 17:12:55 -07001614 /* Clean up Error INT Bit */
1615 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1616 {
1617 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1618 (1 << channelEntry->assignedDMAChannel));
1619 if(eWLAN_PAL_STATUS_SUCCESS != status)
1620 {
1621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1622 "dxeChannelCleanInt Read CH STAT register fail");
1623 return eWLAN_PAL_STATUS_E_FAULT;
1624 }
1625 }
1626
1627 /* Clean up DONE INT Bit */
1628 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1629 {
1630 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1631 (1 << channelEntry->assignedDMAChannel));
1632 if(eWLAN_PAL_STATUS_SUCCESS != status)
1633 {
1634 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1635 "dxeChannelCleanInt Read CH STAT register fail");
1636 return eWLAN_PAL_STATUS_E_FAULT;
1637 }
1638 }
1639
1640 /* Clean up ED INT Bit */
1641 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1642 {
1643 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1644 (1 << channelEntry->assignedDMAChannel));
1645 if(eWLAN_PAL_STATUS_SUCCESS != status)
1646 {
1647 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1648 "dxeChannelCleanInt Read CH STAT register fail");
1649 return eWLAN_PAL_STATUS_E_FAULT;
1650 }
1651 }
1652
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001654 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001655 return status;
1656}
1657
Mihir Shete44547fb2014-03-10 14:15:42 +05301658#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Jeff Johnson295189b2012-06-20 16:38:30 -07001659/*==========================================================================
Leo Chang72cdfd32013-10-17 20:36:30 -07001660 @ Function Name
1661 dxeRXResourceAvailableTimerExpHandler
1662
1663 @ Description
1664 During pre-set timeperiod, if free available RX buffer is not allocated
1665 Trigger Driver re-loading to recover RX dead end
1666
1667 @ Parameters
1668 v_VOID_t *usrData
1669 DXE context
1670
1671 @ Return
1672 NONE
1673
1674===========================================================================*/
1675void dxeRXResourceAvailableTimerExpHandler
1676(
1677 void *usrData
1678)
1679{
Katya Nigam93888ff2014-02-10 17:58:11 +05301680 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Mihir Shete058fcff2014-06-26 18:54:06 +05301681 wpt_uint32 numRxFreePackets;
Mihir Sheted183cef2014-09-26 19:17:56 +05301682 wpt_uint32 numAllocFailures;
Katya Nigam93888ff2014-02-10 17:58:11 +05301683
1684 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1685
Leo Chang72cdfd32013-10-17 20:36:30 -07001686 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1687 "RX Low resource, Durign wait time period %d, RX resource not allocated",
Katya Nigama6fbf662015-03-17 18:35:47 +05301688 wpalGetDxeReplenishRXTimerVal());
Katya Nigam93888ff2014-02-10 17:58:11 +05301689
Mihir Shete058fcff2014-06-26 18:54:06 +05301690 //This API wil also try to replenish packets
1691 wpalGetNumRxFreePacket(&numRxFreePackets);
Mihir Sheted183cef2014-09-26 19:17:56 +05301692 wpalGetNumRxPacketAllocFailures(&numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301693
Mihir Sheted183cef2014-09-26 19:17:56 +05301694 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1695 "Free Packets: %u, Alloc Failures: %u",
1696 numRxFreePackets, numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301697 if (numRxFreePackets > 0)
1698 {
1699 /* If no. of free packets is greater than 0, it means
1700 * that some packets were replenished and can be used
1701 * by DXE to receive frames. So try to restart the
1702 * resourceAvailable timer here, it will be stopped
1703 * by the DXE's low resource callback if atleast one
1704 * free packet reaches DXE.
1705 */
1706 if (NULL != dxeCtxt)
1707 {
1708 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1709 "%s: Replenish successful. Restart the Rx Low resource timer",
1710 __func__);
1711 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301712 wpalGetDxeReplenishRXTimerVal());
Mihir Shete058fcff2014-06-26 18:54:06 +05301713 return;
1714 }
1715 }
Katya Nigama6fbf662015-03-17 18:35:47 +05301716 if(wpalIsDxeSSREnable())
1717 {
1718 if (NULL != dxeCtxt)
1719 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
Mihir Shete058fcff2014-06-26 18:54:06 +05301720
Katya Nigama6fbf662015-03-17 18:35:47 +05301721 wpalWlanReload();
Katya Nigam93888ff2014-02-10 17:58:11 +05301722
Katya Nigama6fbf662015-03-17 18:35:47 +05301723 if (NULL != usrData)
1724 dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
1725 }
1726 else
1727 {
1728 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
1729 wpalGetDxeReplenishRXTimerVal());
1730 }
Mihir Shetefdc9f532014-01-09 15:03:02 +05301731 return;
1732}
Mihir Shete44547fb2014-03-10 14:15:42 +05301733#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05301734
1735/*==========================================================================
1736 @ Function Name
1737 dxeStartSSRTimer
1738
1739 @ Description
1740 Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip,
1741 this makes sure that if the chip does not respond to the FIQ within
1742 the timeout period the dxeSSRTimer expiration handler will take the
1743 appropriate action.
1744
1745 @ Parameters
1746 NONE
1747
1748 @ Return
1749 NONE
1750
1751===========================================================================*/
1752static void dxeStartSSRTimer
1753(
1754 WLANDXE_CtrlBlkType *dxeCtxt
1755)
1756{
1757 if(VOS_TIMER_STATE_RUNNING !=
1758 wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer))
1759 {
1760 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1761 "%s: Starting SSR Timer",__func__);
1762 wpalTimerStart(&dxeCtxt->dxeSSRTimer,
1763 T_WLANDXE_SSR_TIMEOUT);
1764 }
1765}
1766
1767/*==========================================================================
1768 @ Function Name
1769 dxeSSRTimerExpHandler
1770
1771 @ Description
1772 Issue an explicit subsystem restart of the wcnss subsystem if the
1773 WCN chip does not respond to the FIQ within the timeout period
1774
1775 @ Parameters
1776 v_VOID_t *usrData
1777
1778 @ Return
1779 NONE
1780
1781===========================================================================*/
1782void dxeSSRTimerExpHandler
1783(
1784 void *usrData
1785)
1786{
1787 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1788 "DXE not shutdown %d ms after FIQ!! Issue SSR",
1789 T_WLANDXE_SSR_TIMEOUT);
1790 wpalRivaSubystemRestart();
1791
Leo Chang72cdfd32013-10-17 20:36:30 -07001792 return;
1793}
1794
1795/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 @ Function Name
1797 dxeRXPacketAvailableCB
1798
1799 @ Description
1800 If RX frame handler encounts RX buffer pool empty condition,
1801 DXE RX handle loop will be blocked till get available RX buffer pool.
1802 When new RX buffer pool available, Packet available CB function will
1803 be called.
1804
1805 @ Parameters
1806 wpt_packet *freePacket
1807 Newly allocated RX buffer
1808 v_VOID_t *usrData
1809 DXE context
1810
1811 @ Return
1812 NONE
1813
1814===========================================================================*/
1815void dxeRXPacketAvailableCB
1816(
1817 wpt_packet *freePacket,
1818 v_VOID_t *usrData
1819)
1820{
1821 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1822 wpt_status status;
1823
1824 /* Simple Sanity */
1825 if((NULL == freePacket) || (NULL == usrData))
1826 {
1827 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1828 "Get Free RX Buffer fail, Critical Error");
1829 HDXE_ASSERT(0);
1830 return;
1831 }
1832
1833 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1834
1835 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1836 {
1837 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1838 "DXE Context data corrupted, Critical Error");
1839 HDXE_ASSERT(0);
1840 return;
1841 }
1842
1843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1844 "DXE RX packet available, post MSG to RX Thread");
1845
1846 dxeCtxt->freeRXPacket = freePacket;
1847
1848 /* Serialize RX Packet Available message upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08001849 if (NULL == dxeCtxt->rxPktAvailMsg)
1850 {
1851 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1852 "DXE NULL pkt");
1853 HDXE_ASSERT(0);
1854 return;
1855 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001856
1857 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1858 dxeCtxt->rxPktAvailMsg);
1859 if(eWLAN_PAL_STATUS_SUCCESS != status)
1860 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1862 "dxeRXPacketAvailableCB serialize fail");
1863 }
1864
1865 return;
1866}
1867
1868/*==========================================================================
1869 @ Function Name
1870 dxeRXFrameSingleBufferAlloc
1871
1872 @ Description
1873 Allocate Platform packet buffer to prepare RX frame
1874 RX frame memory space must be pre allocted and must be asigned to
1875 descriptor
1876 then whenever DMA engine want to tranfer frame from BMU,
1877 buffer must be ready
1878
1879 @ Parameters
1880 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1881 DXE host driver main control block
1882 WLANDXE_ChannelCBType *channelEntry
1883 Channel specific control block
1884 WLANDXE_DescCtrlBlkType currentCtrlBlock
1885 current control block which have to be asigned
1886 frame buffer
1887
1888 @ Return
1889 wpt_status
1890
1891===========================================================================*/
1892static wpt_status dxeRXFrameSingleBufferAlloc
1893(
1894 WLANDXE_CtrlBlkType *dxeCtxt,
1895 WLANDXE_ChannelCBType *channelEntry,
1896 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1897)
1898{
1899 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1900 wpt_packet *currentPalPacketBuffer = NULL;
1901 WLANDXE_DescType *currentDesc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001902 wpt_iterator iterator;
1903 wpt_uint32 allocatedSize = 0;
1904 void *physAddress = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001905
1906 currentDesc = currentCtrlBlock->linkedDesc;
1907
Leo Chang7e05f212013-07-01 19:54:15 -07001908 if(currentDesc->descCtrl.valid)
1909 {
1910 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1911 "This Descriptor is valid, Do not refill");
1912 return eWLAN_PAL_STATUS_E_EXISTS;
1913 }
1914
Jeff Johnson295189b2012-06-20 16:38:30 -07001915 /* First check if a packet pointer has already been provided by a previously
1916 invoked Rx packet available callback. If so use that packet. */
1917 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1918 {
1919 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1920 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1921 dxeCtxt->freeRXPacket = NULL;
Mihir Sheted183cef2014-09-26 19:17:56 +05301922
1923 if (channelEntry->doneIntDisabled)
1924 {
1925 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1926 channelEntry->extraConfig.chan_mask);
1927 channelEntry->doneIntDisabled = 0;
1928 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001929 }
1930 else if(!dxeCtxt->rxPalPacketUnavailable)
1931 {
Leo Chang72cdfd32013-10-17 20:36:30 -07001932 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1933 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
Jeff Johnson295189b2012-06-20 16:38:30 -07001934 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1935 dxeRXPacketAvailableCB,
1936 (void *)dxeCtxt);
1937
1938 if(NULL == currentPalPacketBuffer)
1939 {
1940 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
Mihir Shete44547fb2014-03-10 14:15:42 +05301941#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07001942 /* Out of RX free buffer,
1943 * Start timer to recover from RX dead end */
1944 if(VOS_TIMER_STATE_RUNNING !=
1945 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
1946 {
1947 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1948 "RX Low resource, wait available resource");
1949 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301950 wpalGetDxeReplenishRXTimerVal());
Leo Chang72cdfd32013-10-17 20:36:30 -07001951 }
Mihir Shete44547fb2014-03-10 14:15:42 +05301952#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 }
1954 }
1955
1956 if(NULL == currentPalPacketBuffer)
1957 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 return eWLAN_PAL_STATUS_E_RESOURCES;
1959 }
1960
1961 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1962 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1963 currentPalPacketBuffer->pBD = NULL;
1964 currentPalPacketBuffer->pBDPhys = NULL;
1965 currentPalPacketBuffer->BDLength = 0;
Mihir Shete5affadc2015-05-29 20:54:57 +05301966
1967 if (channelEntry->channelType == WDTS_CHANNEL_RX_FW_LOG)
Hanumantha Reddy Pothulabd3303c2015-07-15 17:22:00 +05301968 wpalPacketRawTrimHead(currentCtrlBlock->xfrFrame, WLANDXE_NL_HEADER_SZ);
Mihir Shete5affadc2015-05-29 20:54:57 +05301969
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
Mihir Shetebc338242015-03-04 15:34:19 +05301971
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 if(eWLAN_PAL_STATUS_SUCCESS != status)
1973 {
1974 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1975 "dxeRXFrameBufferAlloc unable to lock packet");
1976 return status;
1977 }
1978
1979 /* Init iterator to get physical os buffer address */
1980 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1981 if(eWLAN_PAL_STATUS_SUCCESS != status)
1982 {
1983 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1984 "dxeRXFrameBufferAlloc iterator init fail");
1985 return status;
1986 }
1987 status = wpalIteratorNext(&iterator,
1988 currentPalPacketBuffer,
1989 &physAddress,
1990 &allocatedSize);
1991 if(eWLAN_PAL_STATUS_SUCCESS != status)
1992 {
1993 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1994 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1995 return status;
1996 }
1997 currentPalPacketBuffer->pBDPhys = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07001998
1999 /* DXE descriptor must have SWAPPED addres in it's structure
2000 * !!! SWAPPED !!! */
2001 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05302002 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07002003
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 return status;
2005}
2006
2007/*==========================================================================
2008 @ Function Name
2009 dxeRXFrameRefillRing
2010
2011 @ Description
2012 Allocate Platform packet buffers to try to fill up the DXE Rx ring
2013
2014 @ Parameters
2015 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2016 DXE host driver main control block
2017 WLANDXE_ChannelCBType *channelEntry
2018 Channel specific control block
2019
2020 @ Return
2021 wpt_status
2022
2023===========================================================================*/
2024static wpt_status dxeRXFrameRefillRing
2025(
2026 WLANDXE_CtrlBlkType *dxeCtxt,
2027 WLANDXE_ChannelCBType *channelEntry
2028)
2029{
2030 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2031 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2032 WLANDXE_DescType *currentDesc = NULL;
2033
2034 while(channelEntry->numFreeDesc > 0)
2035 {
2036 /* Current Control block is free
2037 * and associated frame buffer is not linked with control block anymore
2038 * allocate new frame buffer for current control block */
2039 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2040 channelEntry,
2041 currentCtrlBlk);
2042
Leo Chang7e05f212013-07-01 19:54:15 -07002043 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2044 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 {
2046 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2047 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2048 break;
2049 }
2050
Leo Chang7e05f212013-07-01 19:54:15 -07002051 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2052 {
2053 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2054 "dxeRXFrameRefillRing, Descriptor Non-Empry");
2055 }
2056
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 currentDesc = currentCtrlBlk->linkedDesc;
2058 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2059
2060 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2061 that any posted writes are reflected in memory before DXE looks at
2062 the descriptor. */
2063 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2064 {
Karthick S3254c5d2015-04-28 15:06:17 +05302065 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2066 "dxeRXFrameRefillRing, Descriptor write failed");
2067 ++channelEntry->desc_write_fail_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07002068 //HDXE_ASSERT(0);
2069 }
2070
2071 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07002072 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002073 {
2074 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2075 1 << channelEntry->assignedDMAChannel);
2076 }
2077 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07002078 if(eWLAN_PAL_STATUS_E_EXISTS != status)
2079 {
2080 --channelEntry->numFreeDesc;
2081 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 }
2083
2084 channelEntry->tailCtrlBlk = currentCtrlBlk;
2085
2086 return status;
2087}
2088
Mihir Shete5affadc2015-05-29 20:54:57 +05302089static wpt_uint32 dxeRXLogRefillRing
2090(
2091 WLANDXE_CtrlBlkType *dxeCtxt,
2092 WLANDXE_ChannelCBType *channelEntry,
2093 wpt_uint64 bufferAddr,
2094 wpt_uint32 bufferLen
2095)
2096{
2097 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2098 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2099 WLANDXE_DescType *currentDesc = NULL;
2100 wpt_uint32 xfrSize, allocatedLen = 0;
2101
Karthick Sed59a282015-08-10 14:52:16 +05302102 while(bufferLen > 0 && channelEntry->numFreeDesc > 0)
Mihir Shete5affadc2015-05-29 20:54:57 +05302103 {
2104 /* Current Control block is free
2105 * and associated frame buffer is not linked with control block anymore
2106 * allocate new frame buffer for current control block */
2107 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2108 channelEntry,
2109 currentCtrlBlk);
2110
Karthick S122fa9e2015-07-24 17:20:03 +05302111 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2112 (eWLAN_PAL_STATUS_E_EXISTS != status))
Mihir Shete5affadc2015-05-29 20:54:57 +05302113 {
2114 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Karthick S122fa9e2015-07-24 17:20:03 +05302115 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
Mihir Shete5affadc2015-05-29 20:54:57 +05302116 break;
2117 }
2118
2119 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2120 {
2121 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2122 "%s, Descriptor Non-Empty",__func__);
2123 }
2124
2125 currentDesc = currentCtrlBlk->linkedDesc;
2126 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
Hanumantha Reddy Pothulabd3303c2015-07-15 17:22:00 +05302127 xfrSize = WLANDXE_FW_LOGGING_XFSIZE > bufferLen ?
2128 bufferLen : WLANDXE_FW_LOGGING_XFSIZE;
Mihir Shete5affadc2015-05-29 20:54:57 +05302129 currentDesc->xfrSize = xfrSize;
2130 allocatedLen += xfrSize;
2131 bufferLen -= xfrSize;
2132 wpalPacketSetRxLength(currentCtrlBlk->xfrFrame,
2133 xfrSize);
2134
2135 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2136 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)bufferAddr);
2137
2138 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2139 that any posted writes are reflected in memory before DXE looks at
2140 the descriptor. */
2141 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2142 {
2143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2144 "%s, Descriptor write failed",__func__);
2145 ++channelEntry->desc_write_fail_count;
2146 }
2147
2148 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2149 --channelEntry->numFreeDesc;
2150 bufferAddr += xfrSize;
2151 }
2152
2153 channelEntry->tailCtrlBlk = currentCtrlBlk;
2154
2155 return allocatedLen;
2156}
Jeff Johnson295189b2012-06-20 16:38:30 -07002157/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002158 @ Function Name
2159 dxeRXFrameRouteUpperLayer
2160
2161 @ Description
2162 Test DXE descriptors and if any RX frame pending within RING,
2163 Route to upper layer
2164
2165 @ Parameters
2166 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2167 DXE host driver main control block
2168 WLANDXE_ChannelCBType *channelEntry
2169 Channel specific control block
2170 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002171 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002172 0 No frame pulled from RX RING
2173 int number of RX frames pulled from RX ring
2174
2175===========================================================================*/
2176static wpt_int32 dxeRXFrameRouteUpperLayer
2177(
2178 WLANDXE_CtrlBlkType *dxeCtxt,
2179 WLANDXE_ChannelCBType *channelEntry
2180)
2181{
2182 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2183 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2184 WLANDXE_DescType *currentDesc = NULL;
2185 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002186 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002187
2188 currentCtrlBlk = channelEntry->headCtrlBlk;
2189 currentDesc = currentCtrlBlk->linkedDesc;
2190
2191 /* Descriptoe should be SWAPPED ???? */
2192 descCtrl = currentDesc->descCtrl.ctrl;
2193
2194 /* Get frames while VALID bit is not set (DMA complete) and a data
2195 * associated with it */
2196 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2197 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2198 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2199 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2200 {
2201 channelEntry->numTotalFrame++;
2202 channelEntry->numFreeDesc++;
Jeff Johnsone7245742012-09-05 17:12:55 -07002203 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
Mihir Shetebc338242015-03-04 15:34:19 +05302204
Jeff Johnsone7245742012-09-05 17:12:55 -07002205 if (eWLAN_PAL_STATUS_SUCCESS != status)
2206 {
2207 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2208 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002209 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002210 }
Mihir Shetebc338242015-03-04 15:34:19 +05302211
Jeff Johnsone7245742012-09-05 17:12:55 -07002212 /* This Descriptor is valid, so linked Control block is also valid
2213 * Linked Control block has pre allocated packet buffer
2214 * So, just let upper layer knows preallocated frame pointer will be OK */
2215 /* Reap Rx frames */
2216 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2217 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002218 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002219
2220 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Mihir Shete5affadc2015-05-29 20:54:57 +05302221 if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType)
2222 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002223
2224 /* Test next contorl block
2225 * if valid, this control block also has new RX frame must be handled */
2226 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2227 currentDesc = currentCtrlBlk->linkedDesc;
2228 descCtrl = currentDesc->descCtrl.ctrl;
2229 }
2230
2231 /* Update head control block
2232 * current control block's valid bit was 0
2233 * next trial first control block must be current control block */
2234 channelEntry->headCtrlBlk = currentCtrlBlk;
2235
2236 /* Deliver all the reaped RX frames to upper layers */
2237 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002238 while(i < frameCount)
2239 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002240 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2241 i++;
2242 }
2243
2244 return frameCount;
2245}
2246
2247/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 @ Function Name
2249 dxeRXFrameReady
2250
2251 @ Description
2252 Pop frame from descriptor and route frame to upper transport layer
2253 Assign new platform packet buffer into used descriptor
2254 Actual frame pop and resource realloc
2255
2256 @ Parameters
2257 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2258 DXE host driver main control block
2259 WLANDXE_ChannelCBType *channelEntry
2260 Channel specific control block
2261
2262 @ Return
2263 wpt_status
2264
2265===========================================================================*/
2266static wpt_status dxeRXFrameReady
2267(
2268 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002269 WLANDXE_ChannelCBType *channelEntry,
2270 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002271)
2272{
2273 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2274 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2275 WLANDXE_DescType *currentDesc = NULL;
2276 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002277 wpt_int32 frameCount = 0;
2278
2279 wpt_uint32 descLoop;
2280 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002281
2282 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002283 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002284
2285 /* Sanity Check */
2286 if((NULL == dxeCtxt) || (NULL == channelEntry))
2287 {
2288 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2289 "dxeRXFrameReady Channel Entry is not valid");
2290 return eWLAN_PAL_STATUS_E_INVAL;
2291 }
2292
Jeff Johnsone7245742012-09-05 17:12:55 -07002293 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002294
Jeff Johnsone7245742012-09-05 17:12:55 -07002295 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002296 {
2297 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002298 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002299 return eWLAN_PAL_STATUS_E_INVAL;
2300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002301
Leo Changd6de1c22013-03-21 15:42:41 -07002302 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002303 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2304 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2305 {
Leo Changd6de1c22013-03-21 15:42:41 -07002306 /* None of the frame handled and CH is not enabled
2307 * RX CH wrap around happen and No RX free frame
2308 * RX side should wait till new free frame available in the pool
2309 * Do not try reload driver at here*/
2310 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2311 {
Leo Changbbf86b72013-06-19 16:13:00 -07002312 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002313 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2314 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002315 /* This is not empty interrupt case
2316 * If handle this as empty interrupt, false SSR might be issued
2317 * Frame count '1' is dummy frame count to avoid SSR */
2318 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002319 return eWLAN_PAL_STATUS_SUCCESS;
2320 }
2321
Jeff Johnsone7245742012-09-05 17:12:55 -07002322 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002323 currentDesc = currentCtrlBlk->linkedDesc;
2324 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002325
2326 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2327 {
2328 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2329 "RX ISR called but no frame handled PWS %d, channel %s",
2330 (int)dxeCtxt->hostPowerState,
2331 channelType[channelEntry->channelType]);
2332 }
2333
2334 /* Current interupt empty and previous interrupt also empty
2335 * detected successive empty interrupt
2336 * or first interrupt empty, this should not happen */
2337 if(0 == channelEntry->numFragmentCurrentChain)
2338 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002339 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2340 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2341 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2342 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002343 /* Abnormal interrupt detected, try to find not validated descriptor */
2344 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2345 {
2346 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2347 {
Leo Chang416afe02013-07-01 13:58:13 -07002348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002349 "Found Invalidated Descriptor %d", (int)descLoop);
2350 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2351 {
Leo Chang416afe02013-07-01 13:58:13 -07002352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002353 "Packet locked, Resync Host and HW");
2354 channelEntry->headCtrlBlk = currentCtrlBlk;
2355 invalidatedFound = 1;
2356 break;
2357 }
2358 else
2359 {
Leo Chang416afe02013-07-01 13:58:13 -07002360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002361 "Packet Not Locked, cannot transfer frame");
2362 }
2363 }
2364 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2365 currentDesc = currentCtrlBlk->linkedDesc;
2366 descCtrl = currentDesc->descCtrl.ctrl;
2367 }
2368
Jeff Johnson32d95a32012-09-10 13:15:23 -07002369 /* Invalidated descriptor found, and that is not head descriptor
2370 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2371 * Try re-sync here */
2372 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002373 {
2374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2375 "Found New Sync location with HW, handle frames from there");
2376 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2377 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2378 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002379 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002380 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002381 /* Successive Empty interrupt
2382 * But this case, first descriptor also invalidated, then it means head descriptor
2383 * is linked with already handled RX frame, then could not unlock RX frame
2384 * This is just Out of RX buffer pool, not need to anything here */
2385 else if((invalidatedFound) && (0 == descLoop))
2386 {
2387 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2388 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2389 }
2390 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002391 else
2392 {
2393 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2394 "Could not found invalidated descriptor");
2395 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2396 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2397 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2398 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302399 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002400 }
2401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002403 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002404 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002405 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002406 return status;
2407}
2408
2409/*==========================================================================
2410 @ Function Name
2411 dxeNotifySmsm
2412
2413 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2414 buffer
2415
2416 @ Parameters
2417
2418 @ Return
2419 wpt_status
2420
2421===========================================================================*/
2422static wpt_status dxeNotifySmsm
2423(
2424 wpt_boolean kickDxe,
2425 wpt_boolean ringEmpty
2426)
2427{
2428 wpt_uint32 clrSt = 0;
2429 wpt_uint32 setSt = 0;
2430
2431 if(kickDxe)
2432 {
2433 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2434
2435 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2436 {
2437 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2438 tempDxeCtrlBlk->lastKickOffDxe = 1;
2439 }
2440 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2441 {
2442 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2443 tempDxeCtrlBlk->lastKickOffDxe = 0;
2444 }
2445 else
2446 {
2447 HDXE_ASSERT(0);
2448 }
2449 }
2450 else
2451 {
2452 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2453 }
2454
Mihir Shete68ed77a2014-10-10 10:47:12 +05302455 tempDxeCtrlBlk->txRingsEmpty = ringEmpty;
Jeff Johnson295189b2012-06-20 16:38:30 -07002456 if(ringEmpty)
2457 {
2458 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2459 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2460 }
2461 else
2462 {
2463 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2464 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2465 }
2466
2467 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2468
Karthick Sc6ec8362015-08-12 18:18:47 +05302469 /* Store the smsm notification sent to firmware */
2470 tempDxeCtrlBlk->smsmDxeHistogram = (tempDxeCtrlBlk->smsmDxeHistogram << 1);
2471 if(setSt & WPAL_SMSM_WLAN_TX_ENABLE)
2472 {
2473 tempDxeCtrlBlk->smsmDxeHistogram |= 1;
2474 }
2475 else
2476 {
2477 tempDxeCtrlBlk->smsmDxeHistogram &= ~((wpt_uint32)1);
2478 }
2479 tempDxeCtrlBlk->smsmRingsEmptyHistogram = (tempDxeCtrlBlk->smsmRingsEmptyHistogram << 1);
2480 if(setSt & WPAL_SMSM_WLAN_TX_RINGS_EMPTY)
2481 {
2482 tempDxeCtrlBlk->smsmRingsEmptyHistogram |= 1;
2483 }
2484 else
2485 {
2486 tempDxeCtrlBlk->smsmRingsEmptyHistogram &= ~((wpt_uint32)1);
2487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002488 wpalNotifySmsm(clrSt, setSt);
2489
2490 return eWLAN_PAL_STATUS_SUCCESS;
2491}
2492
2493/*==========================================================================
2494 @ Function Name
2495 dxePsComplete
2496
2497 @ Description: Utility function to check the resv desc to deside if we can
2498 get into Power Save mode now
2499
2500 @ Parameters
2501
2502 @ Return
2503 None
2504
2505===========================================================================*/
2506static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2507{
2508 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2509 {
2510 return;
2511 }
2512
2513 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2514 //must have been consumed by RIVA, OK to get into BMPS
2515 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2516 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2517 {
2518 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2519 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2520 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2521 {
2522 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2523 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2524 }
2525 }
2526 else //still more pkts to be served by RIVA
2527 {
2528 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2529
2530 switch(dxeCtxt->rivaPowerState)
2531 {
2532 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2533 //NOP
2534 break;
2535 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2536 if(intr_based)
2537 {
2538 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2539 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2540 }
2541 break;
2542 default:
2543 //assert
2544 break;
2545 }
2546 }
2547}
2548
2549/*==========================================================================
2550 @ Function Name
2551 dxeRXEventHandler
2552
2553 @ Description
2554 Handle serailized RX frame ready event
2555 First disable interrupt then pick up frame from pre allocated buffer
2556 Since frame handle is doen, clear interrupt bit to ready next interrupt
2557 Finally re enable interrupt
2558
2559 @ Parameters
2560 wpt_msg *rxReadyMsg
2561 RX frame ready MSG pointer
2562 include DXE control context
2563
2564 @ Return
2565 NONE
2566
2567===========================================================================*/
2568void dxeRXEventHandler
2569(
2570 wpt_msg *rxReadyMsg
2571)
2572{
2573 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2574 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2575 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2576 wpt_uint32 intSrc = 0;
2577 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002578 wpt_uint32 chHighStat = 0;
2579 wpt_uint32 chLowStat = 0;
Mihir Shetee6618162015-03-16 14:48:42 +05302580 wpt_uint32 chLogRxStat = 0;
Mihir Shetec4093f92015-05-28 15:21:11 +05302581 wpt_uint32 chLogRxFwStat = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302582 wpt_uint32 regValue, chanMask;
Jeff Johnson295189b2012-06-20 16:38:30 -07002583
Jeff Johnsone7245742012-09-05 17:12:55 -07002584 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002585
Jeff Johnsone7245742012-09-05 17:12:55 -07002586 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 {
2588 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002589 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002590 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002591 }
2592
Jeff Johnsone7245742012-09-05 17:12:55 -07002593 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2594 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2595 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
Mihir Shetee6618162015-03-16 14:48:42 +05302596 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2597 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002598
2599 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
Mihir Shetee6618162015-03-16 14:48:42 +05302600 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled) ||
2601 (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) &&
2602 !dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chEnabled))
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 {
2604 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2605 "DXE already stopped in RX event handler. Just return");
2606 return;
2607 }
2608
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302609 /* Disable device interrupt */
2610 /* Read whole interrupt mask register and exclusive only this channel int */
2611 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2612 &intSrc);
2613 if(eWLAN_PAL_STATUS_SUCCESS != status)
2614 {
2615 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2616 "dxeRXEventHandler Read INT_SRC register fail");
2617 return;
2618 }
2619 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2620 "RX Event Handler INT Source 0x%x", intSrc);
2621
2622 dxeEnvBlk.rxIntChanlSrc = intSrc&0xFF;
2623
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2625 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2626 {
Mihir Shetec4093f92015-05-28 15:21:11 +05302627 if (WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
2628 {
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302629 if(0 == intSrc)
Mihir Shetec4093f92015-05-28 15:21:11 +05302630 {
2631 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2632 "%s: Read status: %d, regVal: %d",
2633 __func__, status, intSrc);
2634 }
2635 else
2636 {
2637 /* Register Read was succesful and we have a valid interrupt
2638 * source, so WCN is not power collapsed yet and it should
2639 * not power collapse till we set the synchronization bit
2640 * at the end of this function, safe to pull frames...
2641 */
2642 goto pull_frames;
2643 }
2644 }
2645
Jeff Johnson295189b2012-06-20 16:38:30 -07002646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2647 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002648 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002649
2650 /* Not to touch any register, just pull frame directly from chain ring
2651 * First high priority */
2652 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2653 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002654 channelCb,
2655 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002656 if(eWLAN_PAL_STATUS_SUCCESS != status)
2657 {
2658 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2659 "dxeRXEventHandler Pull from RX high channel fail");
2660 }
Leo Chang46f36162014-01-14 21:47:24 -08002661 /* In case FW could not power collapse in IMPS mode
2662 * Next power restore might have empty interrupt
2663 * If IMPS mode has empty interrupt since RX thread race,
2664 * Invalid re-load driver might happen
2665 * To prevent invalid re-load driver,
2666 * IMPS event handler set dummpy frame count */
2667 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002668
2669 /* Second low priority */
2670 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2671 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002672 channelCb,
2673 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002674 if(eWLAN_PAL_STATUS_SUCCESS != status)
2675 {
2676 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Mihir Shetee6618162015-03-16 14:48:42 +05302677 "dxeRXEventHandler Pull from RX low channel fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002678 }
Leo Chang46f36162014-01-14 21:47:24 -08002679 /* LOW Priority CH same above */
2680 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002681
Mihir Shetee6618162015-03-16 14:48:42 +05302682 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2683 {
2684 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2685 status = dxeRXFrameReady(dxeCtxt,
2686 channelCb,
2687 chLogRxStat);
2688 if(eWLAN_PAL_STATUS_SUCCESS != status)
2689 {
2690 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2691 "dxeRXEventHandler Pull from RX log channel fail");
2692 }
2693 channelCb->numFragmentCurrentChain = 1;
2694 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2696 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302697 dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002698
2699 return;
2700 }
2701
Mihir Shetec4093f92015-05-28 15:21:11 +05302702pull_frames:
Jeff Johnson295189b2012-06-20 16:38:30 -07002703 /* Test High Priority Channel interrupt is enabled or not */
2704 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2705 if(intSrc & (1 << channelCb->assignedDMAChannel))
2706 {
2707 status = dxeChannelCleanInt(channelCb, &chHighStat);
2708 if(eWLAN_PAL_STATUS_SUCCESS != status)
2709 {
2710 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2711 "dxeRXEventHandler INT Clean up fail");
2712 return;
2713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002714 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2715 {
2716 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002717 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2718 "%11s : 0x%x Error Reported, Reload Driver",
2719 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302720
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302721 if (eWLAN_PAL_STATUS_SUCCESS != dxeErrHandler(channelCb, chHighStat))
2722 {
2723 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2724 wpalWlanReload();
2725 dxeStartSSRTimer(dxeCtxt);
2726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002727 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002728 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2729 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002730 {
2731 /* Handle RX Ready for high priority channel */
2732 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002733 channelCb,
2734 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002735 }
2736 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2737 {
2738 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002739 channelCb,
2740 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002741 }
2742 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2743 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002744 /* Update the Rx DONE histogram */
2745 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2746 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2747 {
2748 channelCb->rxDoneHistogram |= 1;
2749 }
2750 else
2751 {
jagadeeshf869bba2015-04-07 20:06:21 +05302752 channelCb->rxDoneHistogram &= ~((wpt_uint64)1);
Jeff Johnsone7245742012-09-05 17:12:55 -07002753 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002755
2756 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002757 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002758 if(intSrc & (1 << channelCb->assignedDMAChannel))
2759 {
2760 status = dxeChannelCleanInt(channelCb, &chLowStat);
2761 if(eWLAN_PAL_STATUS_SUCCESS != status)
2762 {
2763 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2764 "dxeRXEventHandler INT Clean up fail");
2765 return;
2766 }
2767
2768 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2769 {
2770 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002771 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2772 "%11s : 0x%x Error Reported, Reload Driver",
2773 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302774
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302775 if (eWLAN_PAL_STATUS_SUCCESS !=
2776 dxeErrHandler(channelCb, chLowStat))
2777 {
2778 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2779 wpalWlanReload();
2780 dxeStartSSRTimer(dxeCtxt);
2781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002782 }
Mihir Shetef2000552014-05-12 16:21:34 +05302783 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) ||
2784 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002785 {
2786 /* Handle RX Ready for low priority channel */
2787 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002788 channelCb,
2789 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07002790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002791
2792 /* Update the Rx DONE histogram */
2793 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2794 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2795 {
2796 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 }
2798 else
2799 {
jagadeeshf869bba2015-04-07 20:06:21 +05302800 channelCb->rxDoneHistogram &= ~((wpt_uint64)1);
Jeff Johnson295189b2012-06-20 16:38:30 -07002801 }
2802 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2803 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2804 }
Mihir Shetee6618162015-03-16 14:48:42 +05302805
2806 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2807 {
2808 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2809
2810 if(intSrc & (1 << channelCb->assignedDMAChannel))
2811 {
2812 status = dxeChannelCleanInt(channelCb,&chLogRxStat);
2813 if(eWLAN_PAL_STATUS_SUCCESS != status)
2814 {
2815 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2816 "dxeRXEventHandler INT Clean up fail");
2817 return;
2818 }
2819
2820 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxStat)
2821 {
2822 /* Error Happen during transaction, Handle it */
2823 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2824 "%11s : 0x%x Error Reported, Reload Driver",
2825 channelType[channelCb->channelType], chLogRxStat);
2826
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302827 if (eWLAN_PAL_STATUS_SUCCESS !=
2828 dxeErrHandler(channelCb, chLogRxStat))
2829 {
2830 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2831 wpalWlanReload();
2832 dxeStartSSRTimer(dxeCtxt);
2833 }
Mihir Shetee6618162015-03-16 14:48:42 +05302834
Mihir Shetee6618162015-03-16 14:48:42 +05302835 }
2836 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxStat) ||
2837 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2838 {
2839 /* Handle RX Ready for low priority channel */
2840 status = dxeRXFrameReady(dxeCtxt,
2841 channelCb,
2842 chLogRxStat);
2843 }
2844
2845 /* Update the Rx DONE histogram */
2846 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2847 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)
2848 {
2849 channelCb->rxDoneHistogram |= 1;
2850 }
2851 else
2852 {
2853 channelCb->rxDoneHistogram &= ~1;
2854 }
2855 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2856 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxStat, channelCb->numFragmentCurrentChain);
2857 }
2858 }
2859
Mihir Shetec4093f92015-05-28 15:21:11 +05302860 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_FW_LOG))
2861 {
2862 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
2863
2864 if(intSrc & (1 << channelCb->assignedDMAChannel))
2865 {
2866 status = dxeChannelCleanInt(channelCb,&chLogRxFwStat);
2867 if(eWLAN_PAL_STATUS_SUCCESS != status)
2868 {
2869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2870 "dxeRXEventHandler INT Clean up fail");
2871 return;
2872 }
2873
2874 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxFwStat)
2875 {
2876 /* Error Happen during transaction, Handle it */
2877 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2878 "%11s : 0x%x Error Reported, Reload Driver",
2879 channelType[channelCb->channelType], chLogRxFwStat);
2880
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302881 if (eWLAN_PAL_STATUS_SUCCESS !=
2882 dxeErrHandler(channelCb, chLogRxFwStat))
2883 {
2884 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2885 wpalWlanReload();
2886 dxeStartSSRTimer(dxeCtxt);
2887 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302888
Mihir Shetec4093f92015-05-28 15:21:11 +05302889 }
2890 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxFwStat) ||
2891 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat))
2892 {
2893 if (!dxeCtxt->hostInitiatedH2H)
2894 {
2895 dxeCtxt->receiveMbMsgCB(dxeCtxt->clientCtxt);
2896 }
2897 else
2898 {
2899 status = dxeRXFrameReady(dxeCtxt,
2900 channelCb,
2901 chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302902 if (channelCb->numFreeDesc == channelCb->numDesc)
2903 {
Mihir Shete0b090bf2015-06-09 14:00:44 +05302904 /*
2905 * We have already cleared the interrupts before coming here,
2906 * but it can happen that DXE will copy some new packets after
2907 * that and raise interrupts for those. The packets will be
2908 * processed above but the interrupts will still be pending.
2909 * Its safe to clear those interrupts here because we have
2910 * pulled data from all the allocated descriptors.
2911 */
2912 dxeChannelCleanInt(channelCb,&chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302913 dxeCtxt->hostInitiatedH2H = 0;
2914 dxeCtxt->receiveLogCompleteCB(dxeCtxt->clientCtxt);
2915 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302916 }
2917 }
2918
2919 /* Update the Rx DONE histogram */
2920 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2921 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat)
2922 {
2923 channelCb->rxDoneHistogram |= 1;
2924 }
2925 else
2926 {
2927 channelCb->rxDoneHistogram &= ~1;
2928 }
2929 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2930 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxFwStat, channelCb->numFragmentCurrentChain);
2931 }
2932 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 if(eWLAN_PAL_STATUS_SUCCESS != status)
2934 {
2935 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2936 "dxeRXEventHandler Handle Frame Ready Fail");
2937 return;
2938 }
2939
Jeff Johnson295189b2012-06-20 16:38:30 -07002940 /* Prepare Control Register EN Channel */
2941 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2942 {
2943 HDXE_ASSERT(0);
2944 }
Mihir Shetef2000552014-05-12 16:21:34 +05302945
2946 if (dxeCtxt->rxPalPacketUnavailable &&
2947 (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat))
2948 {
2949 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask &
2950 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302951 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302952 }
2953 else
2954 {
2955 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302956 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302957 }
Leo Chang094ece82013-04-23 17:57:41 -07002958 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302959 chanMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002960
2961 /* Prepare Control Register EN Channel */
2962 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2963 {
2964 HDXE_ASSERT(0);
2965 }
Leo Chang094ece82013-04-23 17:57:41 -07002966
Mihir Shetef2000552014-05-12 16:21:34 +05302967 if (dxeCtxt->rxPalPacketUnavailable &&
2968 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
2969 {
2970 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask &
2971 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302972 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302973 }
2974 else
2975 {
2976 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302977 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302978 }
Leo Chang094ece82013-04-23 17:57:41 -07002979 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302980 chanMask);
2981
Mihir Shetec01157f2015-06-18 14:13:34 +05302982 /* We do not have knowledge of firmare capabilities when the
2983 * RX_LOG channel is enabled. But when we get the first interrupt
2984 * we have all the required information. So if MGMT Logging is not
2985 * supported by the firmware, do not re-enable RX_LOG channel
2986 */
2987 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) && wpalIsFwLoggingSupported())
Mihir Shetee6618162015-03-16 14:48:42 +05302988 {
2989 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2990 {
2991 HDXE_ASSERT(0);
2992 }
2993
2994 if (dxeCtxt->rxPalPacketUnavailable &&
2995 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2996 {
2997 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask &
2998 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
2999 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 1;
3000 }
3001 else
3002 {
3003 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask;
3004 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 0;
3005 }
3006 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].channelRegister.chDXECtrlRegAddr,
3007 chanMask);
3008 }
Leo Chang094ece82013-04-23 17:57:41 -07003009
3010 /* Clear Interrupt handle processing bit
3011 * RIVA may power down */
Mihir Shete0670b402015-05-13 17:51:41 +05303012 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303013 {
3014 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3015 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
3016 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3017 }
3018 else
3019 {
Karthick S09d5dd02015-05-27 16:58:32 +05303020 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3021 regValue &= (~WLAN_PMU_POWER_DOWN_MASK);
3022 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003024
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303025 dxeEnvBlk.rxIntChanlSrc = 0;
3026
Leo Chang416afe02013-07-01 13:58:13 -07003027 /* Enable system level ISR */
3028 /* Enable RX ready Interrupt at here */
3029 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
3030 if(eWLAN_PAL_STATUS_SUCCESS != status)
3031 {
3032 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3033 "dxeRXEventHandler Enable RX Ready interrupt fail");
3034 return;
3035 }
3036
Jeff Johnson295189b2012-06-20 16:38:30 -07003037 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003038 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003039 return;
3040}
3041
3042/*==========================================================================
3043 @ Function Name
3044 dxeRXPacketAvailableEventHandler
3045
3046 @ Description
3047 Handle serialized RX Packet Available event when the corresponding callback
3048 is invoked by WPAL.
3049 Try to fill up any completed DXE descriptors with available Rx packet buffer
3050 pointers.
3051
3052 @ Parameters
3053 wpt_msg *rxPktAvailMsg
3054 RX frame ready MSG pointer
3055 include DXE control context
3056
3057 @ Return
3058 NONE
3059
3060===========================================================================*/
3061void dxeRXPacketAvailableEventHandler
3062(
3063 wpt_msg *rxPktAvailMsg
3064)
3065{
3066 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3067 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3068 WLANDXE_ChannelCBType *channelCb = NULL;
3069
3070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003071 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003072
3073 /* Sanity Check */
3074 if(NULL == rxPktAvailMsg)
3075 {
3076 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3077 "dxeRXPacketAvailableEventHandler Context is not valid");
3078 return;
3079 }
3080
3081 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05303082
3083#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07003084 /* Available resource allocated
3085 * Stop timer not needed */
3086 if(VOS_TIMER_STATE_RUNNING ==
3087 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
3088 {
3089 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
3090 }
Mihir Shete44547fb2014-03-10 14:15:42 +05303091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003092
3093 do
3094 {
3095 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3096 "dxeRXPacketAvailableEventHandler, start refilling ring");
3097
3098 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
3099 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3100
3101 // Wait for another callback to indicate when Rx resources are available
3102 // again.
3103 if(eWLAN_PAL_STATUS_SUCCESS != status)
3104 {
3105 break;
3106 }
3107
3108 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
3109 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3110 if(eWLAN_PAL_STATUS_SUCCESS != status)
3111 {
3112 break;
3113 }
Mihir Shetee6618162015-03-16 14:48:42 +05303114
3115 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
3116 {
3117 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
3118 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3119 if(eWLAN_PAL_STATUS_SUCCESS != status)
3120 {
3121 break;
3122 }
3123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003124 } while(0);
3125
3126 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
3127 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
3128 {
3129 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
3130 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303131 dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003132 }
3133}
3134
3135/*==========================================================================
3136 @ Function Name
3137 dxeRXISR
3138
3139 @ Description
3140 RX frame ready interrupt service routine
3141 interrupt entry function, this function called based on ISR context
3142 Must be serialized
3143
3144 @ Parameters
3145 void *hostCtxt
3146 DXE host driver control context,
3147 pre registerd during interrupt registration
3148
3149 @ Return
3150 NONE
3151
3152===========================================================================*/
3153static void dxeRXISR
3154(
3155 void *hostCtxt
3156)
3157{
3158 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3159 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003160 wpt_uint32 regValue;
Jeff Johnson295189b2012-06-20 16:38:30 -07003161
Leo Chang094ece82013-04-23 17:57:41 -07003162 /* Set Interrupt processing bit
3163 * During this bit set, WLAN HW may not power collapse */
Mihir Shete0670b402015-05-13 17:51:41 +05303164 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303165 {
3166 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3167 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
3168 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3169 }
3170 else
3171 {
Karthick S09d5dd02015-05-27 16:58:32 +05303172 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3173 regValue |= WLAN_PMU_POWER_DOWN_MASK;
3174 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303175 }
Leo Chang094ece82013-04-23 17:57:41 -07003176
Jeff Johnson295189b2012-06-20 16:38:30 -07003177 /* Disable interrupt at here
3178 * Disable RX Ready system level Interrupt at here
3179 * Otherwise infinite loop might happen */
3180 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
3181 if(eWLAN_PAL_STATUS_SUCCESS != status)
3182 {
3183 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3184 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3185 return;
3186 }
3187
3188 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003189 if(NULL == dxeCtxt->rxIsrMsg)
3190 {
3191 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3192 "dxeRXFrameReadyISR NULL message");
3193 HDXE_ASSERT(0);
3194 return;
3195 }
3196
Jeff Johnson295189b2012-06-20 16:38:30 -07003197 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
3198 dxeCtxt->rxIsrMsg);
3199 if(eWLAN_PAL_STATUS_SUCCESS != status)
3200 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003201 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3202 "dxeRXFrameReadyISR interrupt serialize fail");
3203 }
3204
Jeff Johnson295189b2012-06-20 16:38:30 -07003205 return;
3206}
3207
3208/*==========================================================================
3209 @ Function Name
3210 dxeTXPushFrame
3211
3212 @ Description
3213 Push TX frame into DXE descriptor and DXE register
3214 Send notification to DXE register that TX frame is ready to transfer
3215
3216 @ Parameters
3217 WLANDXE_ChannelCBType *channelEntry
3218 Channel specific control block
3219 wpt_packet *palPacket
3220 Packet pointer ready to transfer
3221
3222 @ Return
3223 PAL_STATUS_T
3224===========================================================================*/
3225static wpt_status dxeTXPushFrame
3226(
3227 WLANDXE_ChannelCBType *channelEntry,
3228 wpt_packet *palPacket
3229)
3230{
3231 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3232 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3233 WLANDXE_DescType *currentDesc = NULL;
3234 WLANDXE_DescType *firstDesc = NULL;
3235 WLANDXE_DescType *LastDesc = NULL;
3236 void *sourcePhysicalAddress = NULL;
3237 wpt_uint32 xferSize = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003238 wpt_iterator iterator;
Karthick S8a7e2862015-09-14 09:13:37 +05303239 wpt_uint32 KickDxe = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003240
3241 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003242 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003243
Leo Changac1d3612013-07-01 15:15:51 -07003244 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3245 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3246 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003247 {
Karthick S8a7e2862015-09-14 09:13:37 +05303248 KickDxe = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003249 }
3250
Karthick S8a7e2862015-09-14 09:13:37 +05303251 /* Kick DXE when the ring is about to fill */
3252 if (WLANDXE_TX_LOW_RES_THRESHOLD >= channelEntry->numFreeDesc)
3253 KickDxe = 1;
3254
Jeff Johnson295189b2012-06-20 16:38:30 -07003255 channelEntry->numFragmentCurrentChain = 0;
3256 currentCtrlBlk = channelEntry->headCtrlBlk;
3257
3258 /* Initialize interator, TX is fragmented */
Jeff Johnson295189b2012-06-20 16:38:30 -07003259 status = wpalLockPacketForTransfer(palPacket);
3260 if(eWLAN_PAL_STATUS_SUCCESS != status)
3261 {
3262 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3263 "dxeTXPushFrame unable to lock packet");
3264 return status;
3265 }
3266
3267 status = wpalIteratorInit(&iterator, palPacket);
Jeff Johnson295189b2012-06-20 16:38:30 -07003268 if(eWLAN_PAL_STATUS_SUCCESS != status)
3269 {
3270 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3271 "dxeTXPushFrame iterator init fail");
3272 return status;
3273 }
3274
3275 /* !!!! Revisit break condition !!!!!!! */
3276 while(1)
3277 {
3278 /* Get current descriptor pointer from current control block */
3279 currentDesc = currentCtrlBlk->linkedDesc;
3280 if(NULL == firstDesc)
3281 {
3282 firstDesc = currentCtrlBlk->linkedDesc;
3283 }
3284 /* All control block will have same palPacket Pointer
3285 * to make logic simpler */
3286 currentCtrlBlk->xfrFrame = palPacket;
3287
3288 /* Get next fragment physical address and fragment size
3289 * if this is the first trial, will get first physical address
3290 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
Jeff Johnson295189b2012-06-20 16:38:30 -07003291 status = wpalIteratorNext(&iterator,
3292 palPacket,
3293 &sourcePhysicalAddress,
3294 &xferSize);
jagadeeshf869bba2015-04-07 20:06:21 +05303295 if(eWLAN_PAL_STATUS_SUCCESS != status)
3296 {
3297 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3298 "dxeTXPushFrame Get next frame fail");
3299 return status;
3300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 if((NULL == sourcePhysicalAddress) ||
3302 (0 == xferSize))
3303 {
3304 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3305 "dxeTXPushFrame end of current frame");
3306 break;
3307 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003308
3309 /* This is the LAST descriptor valid for this transaction */
3310 LastDesc = currentCtrlBlk->linkedDesc;
3311
3312 /* Program DXE descriptor */
3313 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303314 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003315
3316 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3317 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3318 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3319 {
3320 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3321 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3322 }
3323 else
3324 {
3325 /* Test specific H2H transfer, destination address already set
3326 * Do Nothing */
3327 }
3328 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3329
3330 /* Program channel control register */
3331 /* First frame not set VAL bit, why ??? */
3332 if(0 == channelEntry->numFragmentCurrentChain)
3333 {
3334 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3335 }
3336 else
3337 {
3338 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3339 }
3340
3341 /* Update statistics */
3342 channelEntry->numFragmentCurrentChain++;
3343 channelEntry->numFreeDesc--;
3344 channelEntry->numRsvdDesc++;
3345
3346 /* Get next control block */
3347 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3348 }
3349 channelEntry->numTotalFrame++;
3350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3351 "NUM TX FRAG %d, Total Frame %d",
3352 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3353
3354 /* Program Channel control register
3355 * Set as end of packet
3356 * Enable interrupt also for first code lock down
3357 * performace optimization, this will be revisited */
3358 if(NULL == LastDesc)
3359 {
3360 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3361 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3362 return eWLAN_PAL_STATUS_E_FAULT;
3363 }
3364 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3365 /* Now First one also Valid ????
3366 * this procedure will prevent over handle descriptor from previous
3367 * TX trigger */
3368 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3369
3370 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3371 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3372 {
3373 /* Update channel head as next avaliable linked slot */
3374 channelEntry->headCtrlBlk = currentCtrlBlk;
Karthick S8a7e2862015-09-14 09:13:37 +05303375 if(KickDxe)
Leo Changac1d3612013-07-01 15:15:51 -07003376 {
3377 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3378 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3379 "SMSM_ret LO=%d HI=%d",
3380 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3381 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
Karthick S39823072015-07-08 18:16:41 +05303382 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Leo Changac1d3612013-07-01 15:15:51 -07003383 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3384 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
3385 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003386 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003387 }
3388
3389 /* If DXE use external descriptor, registers are not needed to be programmed
3390 * Just after finish to program descriptor, tirigger to send */
3391 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3392 {
3393 /* Issue a dummy read from the DXE descriptor DDR location to
3394 ensure that any previously posted write to the descriptor
3395 completes. */
3396 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3397 {
3398 //HDXE_ASSERT(0);
3399 }
3400
3401 /* Everything is ready
3402 * Trigger to start DMA */
3403 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3404 channelEntry->extraConfig.chan_mask);
3405 if(eWLAN_PAL_STATUS_SUCCESS != status)
3406 {
3407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3408 "dxeTXPushFrame Write Channel Ctrl Register fail");
3409 return status;
3410 }
3411
3412 /* Update channel head as next avaliable linked slot */
3413 channelEntry->headCtrlBlk = currentCtrlBlk;
3414
3415 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003416 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003417 return status;
3418 }
3419
3420 /* If DXE not use external descriptor, program each registers */
3421 /* Circular buffer handle not need to program DESC register???
3422 * GEN5 code not programed RING buffer case
3423 * REVISIT THIS !!!!!! */
3424 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3425 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3426 {
3427 /* Destination address, assigned Work Q */
3428 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3429 channelEntry->channelConfig.refWQ);
3430 if(eWLAN_PAL_STATUS_SUCCESS != status)
3431 {
3432 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3433 "dxeTXPushFrame Program dest address register fail");
3434 return status;
3435 }
3436 /* If descriptor format is SHORT */
3437 if(channelEntry->channelConfig.useShortDescFmt)
3438 {
3439 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3440 0);
3441 if(eWLAN_PAL_STATUS_SUCCESS != status)
3442 {
3443 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3444 "dxeTXPushFrame Program dest address register fail");
3445 return status;
3446 }
3447 }
3448 else
3449 {
3450 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3451 "dxeTXPushFrame LONG Descriptor Format!!!");
3452 }
3453 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003454
3455 /* Program Source address register
3456 * This address is already programmed into DXE Descriptor
3457 * But register also upadte */
3458 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3459 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3460 if(eWLAN_PAL_STATUS_SUCCESS != status)
3461 {
3462 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3463 "dxeTXPushFrame Program src address register fail");
3464 return status;
3465 }
3466 /* If descriptor format is SHORT */
3467 if(channelEntry->channelConfig.useShortDescFmt)
3468 {
3469 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3470 0);
3471 if(eWLAN_PAL_STATUS_SUCCESS != status)
3472 {
3473 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3474 "dxeTXPushFrame Program dest address register fail");
3475 return status;
3476 }
3477 }
3478 else
3479 {
3480 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3481 "dxeTXPushFrame LONG Descriptor Format!!!");
3482 }
3483
3484 /* Linked list Descriptor pointer */
3485 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3486 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3487 if(eWLAN_PAL_STATUS_SUCCESS != status)
3488 {
3489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3490 "dxeTXPushFrame Write DESC Address register fail");
3491 return status;
3492 }
3493 /* If descriptor format is SHORT */
3494 if(channelEntry->channelConfig.useShortDescFmt)
3495 {
3496 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3497 0);
3498 if(eWLAN_PAL_STATUS_SUCCESS != status)
3499 {
3500 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3501 "dxeTXPushFrame Program dest address register fail");
3502 return status;
3503 }
3504 }
3505 else
3506 {
3507 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3508 "dxeTXPushFrame LONG Descriptor Format!!!");
3509 }
3510
3511 /* Transfer Size */
3512 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3513 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3514 xferSize);
3515 if(eWLAN_PAL_STATUS_SUCCESS != status)
3516 {
3517 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3518 "dxeTXPushFrame Write DESC Address register fail");
3519 return status;
3520 }
3521
3522 /* Everything is ready
3523 * Trigger to start DMA */
3524 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3525 channelEntry->extraConfig.chan_mask);
3526 if(eWLAN_PAL_STATUS_SUCCESS != status)
3527 {
3528 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3529 "dxeTXPushFrame Write Channel Ctrl Register fail");
3530 return status;
3531 }
3532
3533 /* Update channel head as next avaliable linked slot */
3534 channelEntry->headCtrlBlk = currentCtrlBlk;
3535
3536 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003537 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003538 return status;
3539}
3540
3541/*==========================================================================
3542 @ Function Name
3543 dxeTXCompFrame
3544
3545 @ Description
3546 TX Frame transfer complete event handler
3547
3548 @ Parameters
3549 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3550 DXE host driver main control block
3551 WLANDXE_ChannelCBType *channelEntry
3552 Channel specific control block
3553
3554 @ Return
3555 PAL_STATUS_T
3556===========================================================================*/
3557static wpt_status dxeTXCompFrame
3558(
3559 WLANDXE_CtrlBlkType *hostCtxt,
3560 WLANDXE_ChannelCBType *channelEntry
3561)
3562{
3563 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3564 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3565 WLANDXE_DescType *currentDesc = NULL;
3566 wpt_uint32 descCtrlValue = 0;
3567 unsigned int *lowThreshold = NULL;
3568
3569 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003570 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003571
3572 /* Sanity */
3573 if((NULL == hostCtxt) || (NULL == channelEntry))
3574 {
3575 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3576 "dxeTXCompFrame Invalid ARG");
3577 return eWLAN_PAL_STATUS_E_INVAL;
3578 }
3579
3580 if(NULL == hostCtxt->txCompCB)
3581 {
3582 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3583 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003584 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003585 }
3586
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003587 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3588 if(eWLAN_PAL_STATUS_SUCCESS != status)
3589 {
3590 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3591 "dxeTXCompFrame Mutex Acquire fail");
3592 return status;
3593 }
3594
Jeff Johnson295189b2012-06-20 16:38:30 -07003595 currentCtrlBlk = channelEntry->tailCtrlBlk;
3596 currentDesc = currentCtrlBlk->linkedDesc;
3597
3598 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3599 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003600 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3601 if(eWLAN_PAL_STATUS_SUCCESS != status)
3602 {
3603 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3604 "dxeTXCompFrame Mutex Release fail");
3605 return status;
3606 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003607 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003608 }
3609
Kiet Lam842dad02014-02-18 18:44:02 -08003610
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 while(1)
3612 {
3613// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3614 descCtrlValue = currentDesc->descCtrl.ctrl;
3615 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3616 {
3617 /* caught up with head, bail out */
3618 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3619 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3620 break;
3621 }
3622
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003623 if(currentCtrlBlk->xfrFrame == NULL)
3624 {
3625 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3626 "Invalid transfer frame");
3627 HDXE_ASSERT(0);
3628 break;
3629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 channelEntry->numFreeDesc++;
3631 channelEntry->numRsvdDesc--;
3632
3633 /* Send Frame TX Complete notification with frame start fragment location */
3634 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3635 {
3636 hostCtxt->txCompletedFrames--;
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3638 if (eWLAN_PAL_STATUS_SUCCESS != status)
3639 {
3640 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3641 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003642 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3643 if(eWLAN_PAL_STATUS_SUCCESS != status)
3644 {
3645 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3646 "dxeTXCompFrame Mutex Release fail");
3647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003648 return status;
3649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003650 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3651 currentCtrlBlk->xfrFrame,
3652 eWLAN_PAL_STATUS_SUCCESS);
3653 channelEntry->numFragmentCurrentChain = 0;
3654 }
3655 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3656 currentDesc = currentCtrlBlk->linkedDesc;
3657
3658 /* Break condition
3659 * Head control block is the control block must be programed for the next TX
3660 * so, head control block is not programmed control block yet
3661 * if loop encounte head control block, stop to complete
3662 * in theory, COMP CB must be called already ??? */
3663 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3664 {
3665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3666 "dxeTXCompFrame caught up with head ptr");
3667 break;
3668 }
3669 /* VALID Bit check ???? */
3670 }
3671
3672 /* Tail and Head Control block must be same */
3673 channelEntry->tailCtrlBlk = currentCtrlBlk;
3674
3675 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3676 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3677 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3678
3679 /* If specific channel hit low resource condition send notification to upper layer */
3680 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3681 (channelEntry->numFreeDesc > *lowThreshold))
3682 {
3683 /* Change it back if we raised it for fetching a remaining packet from TL */
3684 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3685 {
3686 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3687 }
3688
3689 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3690 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3691 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3692 channelEntry->channelType,
3693 eWLAN_PAL_TRUE);
3694 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3695 }
3696
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003697 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3698 if(eWLAN_PAL_STATUS_SUCCESS != status)
3699 {
3700 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3701 "dxeTXCompFrame Mutex Release fail");
3702 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003703
3704 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003705 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 return status;
3707}
3708
3709/*==========================================================================
Mihir Shetedfc33ec2014-10-15 13:14:38 +05303710 @ Function Name
3711 dxeTXCleanup
3712
3713 @ Description
3714 Cleanup the TX channels after DXE Error
3715
3716 @ Parameters
3717 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3718 DXE host driver main control block
3719
3720 @ Return
3721 PAL_STATUS_T
3722===========================================================================*/
3723static wpt_status dxeTXCleanup
3724(
3725 WLANDXE_CtrlBlkType *hostCtxt
3726)
3727{
3728 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3729 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3730 WLANDXE_DescType *currentDesc = NULL;
3731 wpt_uint32 descCtrlValue = 0;
3732 unsigned int *lowThreshold = NULL;
3733 unsigned int idx;
3734 WLANDXE_ChannelCBType *channelEntry;
3735
3736 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3737 "%s Enter", __func__);
3738
3739 /* Sanity */
3740 if((NULL == hostCtxt))
3741 {
3742 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3743 "%s: Invalid ARG", __func__);
3744 return eWLAN_PAL_STATUS_E_INVAL;
3745 }
3746
3747 if(NULL == hostCtxt->txCompCB)
3748 {
3749 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3750 "%s: TXCompCB is not registered",__func__);
3751 return eWLAN_PAL_STATUS_SUCCESS;
3752 }
3753
3754 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3755 {
3756 channelEntry = &tempDxeCtrlBlk->dxeChannel[idx];
3757 if(idx != WDTS_CHANNEL_TX_LOW_PRI && idx != WDTS_CHANNEL_TX_HIGH_PRI)
3758 {
3759 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3760 "%s: %11s continue",__func__,
3761 channelType[channelEntry->channelType]);
3762 continue;
3763 }
3764
3765 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3766 if(eWLAN_PAL_STATUS_SUCCESS != status)
3767 {
3768 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3769 "%s: %11s Mutex Acquire fail",__func__,
3770 channelType[channelEntry->channelType]);
3771 return status;
3772 }
3773
3774 currentCtrlBlk = channelEntry->tailCtrlBlk;
3775 currentDesc = currentCtrlBlk->linkedDesc;
3776
3777 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3778 {
3779 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3780 "%s: %11s Head and Tail are Same",__func__,
3781 channelType[channelEntry->channelType]);
3782
3783 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3784 if(eWLAN_PAL_STATUS_SUCCESS != status)
3785 {
3786 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3787 "%s: %11s Mutex Release fail",__func__,
3788 channelType[channelEntry->channelType]);
3789 return status;
3790 }
3791 continue;
3792 }
3793
3794 while(1)
3795 {
3796 descCtrlValue = currentDesc->descCtrl.ctrl;
3797 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3798 {
3799 /* invalidate... */
3800 currentDesc->descCtrl.ctrl &= ~WLANDXE_DESC_CTRL_VALID;
3801 }
3802
3803 if(currentCtrlBlk->xfrFrame == NULL)
3804 {
3805 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3806 "%s: %11s Invalid transfer frame",__func__,
3807 channelType[channelEntry->channelType]);
3808 HDXE_ASSERT(0);
3809 break;
3810 }
3811 channelEntry->numFreeDesc++;
3812 channelEntry->numRsvdDesc--;
3813
3814 /* Send Frame TX Complete notification with frame start fragment location */
3815 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3816 {
3817 hostCtxt->txCompletedFrames--;
3818 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3819 if (eWLAN_PAL_STATUS_SUCCESS != status)
3820 {
3821 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3822 "%s: unable to unlock packet",__func__);
3823 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3824 if(eWLAN_PAL_STATUS_SUCCESS != status)
3825 {
3826 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3827 "%s: Mutex Release fail",__func__);
3828 }
3829 return status;
3830 }
3831 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3832 currentCtrlBlk->xfrFrame,
3833 eWLAN_PAL_STATUS_SUCCESS); //mir: SUCCESS or FAILURE?
3834 channelEntry->numFragmentCurrentChain = 0;
3835 }
3836 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3837 currentDesc = currentCtrlBlk->linkedDesc;
3838
3839 /* Break condition
3840 * Head control block is the control block must be programed for the next TX
3841 * so, head control block is not programmed control block yet
3842 * if loop encounte head control block, stop to complete
3843 * in theory, COMP CB must be called already ??? */
3844 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3845 {
3846 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3847 "%s: %11s caught up with head ptr",__func__,
3848 channelType[channelEntry->channelType]);
3849 break;
3850 }
3851 /* VALID Bit check ???? */
3852 }
3853
3854 /* Tail and Head Control block must be same */
3855 channelEntry->tailCtrlBlk = currentCtrlBlk;
3856 /* Re-Sync Head and CDR */
3857 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3858 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3859 if(eWLAN_PAL_STATUS_SUCCESS != status)
3860 {
3861 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3862 "dxeChannelInitProgram Write DESC Address register fail");
3863 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3864 if(eWLAN_PAL_STATUS_SUCCESS != status)
3865 {
3866 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3867 "%s: %11s Mutex Release fail", __func__,
3868 channelType[channelEntry->channelType]);
3869 }
3870 return status;
3871 }
3872
3873 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3874 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3875 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3876
3877 /* If specific channel hit low resource condition send notification to upper layer */
3878 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3879 (channelEntry->numFreeDesc > *lowThreshold))
3880 {
3881 /* Change it back if we raised it for fetching a remaining packet from TL */
3882 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3883 {
3884 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3885 }
3886
3887 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3888 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3889 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3890 channelEntry->channelType,
3891 eWLAN_PAL_TRUE);
3892 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3893 }
3894 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3895 if(eWLAN_PAL_STATUS_SUCCESS != status)
3896 {
3897 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3898 "%s: %11s Mutex Release fail", __func__,
3899 channelType[channelEntry->channelType]);
3900 }
3901 }
3902
3903 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3904 "%s Exit", __func__);
3905 return status;
3906}
3907/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 @ Function Name
3909 dxeTXEventHandler
3910
3911 @ Description
3912 If DXE HW sends TX related interrupt, this event handler will be called
3913 Handle higher priority channel first
3914 Figureout why interrupt happen and call appropriate final even handler
3915 TX complete or error happen
3916
3917 @ Parameters
3918 void *msgPtr
3919 Even MSG
3920
3921 @ Return
3922 PAL_STATUS_T
3923===========================================================================*/
3924void dxeTXEventHandler
3925(
3926 wpt_msg *msgPtr
3927)
3928{
3929 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3930 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3931 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3932 wpt_uint32 intSrc = 0;
3933 wpt_uint32 chStat = 0;
3934 WLANDXE_ChannelCBType *channelCb = NULL;
3935
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003936 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003937 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003938
3939 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003940 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003941
3942 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003943 dxeCtxt->ucTxMsgCnt = 0;
3944
3945 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3946 {
3947 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3948 "wlan: TX COMP WLAN Driver re-loading in progress");
3949 return;
3950 }
3951
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303952 /* Read whole interrupt mask register and exclusive only this channel int */
3953 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3954 &intSrc);
3955 if(eWLAN_PAL_STATUS_SUCCESS != status)
3956 {
3957 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3958 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3959 return;
3960 }
3961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3962 "TX Event Handler INT Source 0x%x", intSrc);
3963
3964 dxeEnvBlk.txCmpIntChanlSrc = intSrc&0xFF;
3965
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 /* Return from here if the RIVA is in IMPS, to avoid register access */
3967 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3968 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003969 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003970 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003971 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003972 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3973 if(eWLAN_PAL_STATUS_SUCCESS != status)
3974 {
3975 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003976 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003977 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003978
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003979 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
3980 if(eWLAN_PAL_STATUS_SUCCESS != status)
3981 {
3982 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3983 "dxeTXEventHandler IMPS LC COMP interrupt fail");
3984 }
3985
3986 if(((dxeCtxt->txCompletedFrames) &&
3987 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
3988 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07003989 {
3990 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3991 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3992 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08003993 "TX COMP INT Enabled, remain TX frame count on ring %d",
3994 dxeCtxt->txCompletedFrames);
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303995
3996 dxeEnvBlk.txCmpIntChanlSrc = 0;
3997
Jeff Johnsone7245742012-09-05 17:12:55 -07003998 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3999 the posibility of a race*/
4000 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4001 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004002 else
4003 {
4004 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4006 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
4007 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
4008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004009 return;
4010 }
4011
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004012 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004013 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
4014 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
4015 {
4016 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4017 "DXE already stopped in TX event handler. Just return");
4018 return;
4019 }
4020
Jeff Johnson295189b2012-06-20 16:38:30 -07004021 /* Test High Priority Channel is the INT source or not */
4022 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4023 if(intSrc & (1 << channelCb->assignedDMAChannel))
4024 {
4025 status = dxeChannelCleanInt(channelCb, &chStat);
4026 if(eWLAN_PAL_STATUS_SUCCESS != status)
4027 {
4028 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4029 "dxeTXEventHandler INT Clean up fail");
4030 return;
4031 }
4032
4033 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4034 {
4035 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004036 "%11s : 0x%x Error Reported, Reload Driver",
4037 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304038
Mihir Shetedfc33ec2014-10-15 13:14:38 +05304039 if (eWLAN_PAL_STATUS_SUCCESS !=
4040 dxeErrHandler(channelCb, chStat))
4041 {
4042 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4043 wpalWlanReload();
4044 dxeStartSSRTimer(dxeCtxt);
4045 }
4046 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004047 }
4048 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4049 {
4050 /* Handle TX complete for high priority channel */
4051 status = dxeTXCompFrame(dxeCtxt,
4052 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004053 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004054 }
4055 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4056 {
4057 /* Handle TX complete for high priority channel */
4058 status = dxeTXCompFrame(dxeCtxt,
4059 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004060 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004061 }
4062 else
4063 {
4064 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4065 "dxeTXEventHandler TX HI status=%x", chStat);
4066 }
4067
4068 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4069 {
4070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4071 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
4072 }
4073
4074 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4075 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4076 }
4077
4078 /* Test Low Priority Channel interrupt is enabled or not */
4079 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4080 if(intSrc & (1 << channelCb->assignedDMAChannel))
4081 {
4082 status = dxeChannelCleanInt(channelCb, &chStat);
4083 if(eWLAN_PAL_STATUS_SUCCESS != status)
4084 {
4085 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4086 "dxeTXEventHandler INT Clean up fail");
4087 return;
4088 }
4089
4090 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4091 {
4092 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004093 "%11s : 0x%x Error Reported, Reload Driver",
4094 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304095
Mihir Shetedfc33ec2014-10-15 13:14:38 +05304096 if (eWLAN_PAL_STATUS_SUCCESS !=
4097 dxeErrHandler(channelCb, chStat))
4098 {
4099 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4100 wpalWlanReload();
4101 dxeStartSSRTimer(dxeCtxt);
4102 }
4103 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 }
4105 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4106 {
4107 /* Handle TX complete for low priority channel */
4108 status = dxeTXCompFrame(dxeCtxt,
4109 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004110 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004111 }
4112 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4113 {
4114 /* Handle TX complete for low priority channel */
4115 status = dxeTXCompFrame(dxeCtxt,
4116 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004117 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004118 }
4119 else
4120 {
4121 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4122 "dxeTXEventHandler TX LO status=%x", chStat);
4123 }
4124
4125 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4126 {
4127 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4128 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
4129 }
4130 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4131 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4132 }
4133
Jeff Johnson295189b2012-06-20 16:38:30 -07004134 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
4135 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4136 {
4137 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4138 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004139 if(0 != dxeCtxt->txCompletedFrames)
4140 {
4141 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4142 "TX COMP INT Enabled, remain TX frame count on ring %d",
4143 dxeCtxt->txCompletedFrames);
4144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004145 }
4146
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05304147 dxeEnvBlk.txCmpIntChanlSrc = 0;
4148
Jeff Johnson295189b2012-06-20 16:38:30 -07004149 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4150 the posibility of a race*/
4151 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4152
4153 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004154 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004155 return;
4156}
4157
4158
4159/*==========================================================================
4160 @ Function Name
4161 dxeTXCompleteProcessing
4162
4163 @ Description
4164 If DXE HW sends TX related interrupt, this event handler will be called
4165 Handle higher priority channel first
4166 Figureout why interrupt happen and call appropriate final even handler
4167 TX complete or error happen
4168
4169 @ Parameters
4170 dxeCtxt DXE context
4171
4172 @ Return
4173 PAL_STATUS_T
4174===========================================================================*/
4175void dxeTXCompleteProcessing
4176(
4177 WLANDXE_CtrlBlkType *dxeCtxt
4178)
4179{
4180 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4181 WLANDXE_ChannelCBType *channelCb = NULL;
4182
4183 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004184 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004185
4186 /* Test High Priority Channel is the INT source or not */
4187 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4188
4189 /* Handle TX complete for high priority channel */
4190 status = dxeTXCompFrame(dxeCtxt, channelCb);
4191
4192 /* Test Low Priority Channel interrupt is enabled or not */
4193 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4194
4195 /* Handle TX complete for low priority channel */
4196 status = dxeTXCompFrame(dxeCtxt, channelCb);
4197
4198 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
4199 ((dxeCtxt->txCompletedFrames > 0) ||
4200 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
4201 {
4202 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4203 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4204 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004205 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004206 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
4207 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
4208 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
4209 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07004210
4211 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
4212 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
4213 {
4214 /* After TX Comp processing, still remaining frame on the DXE TX ring
4215 * And when push frame, RING was not empty marked
4216 * Then when push frame, no SMSM toggle happen
4217 * To avoid permanent TX stall, SMSM toggle is needed at here
4218 * With this toggle, host should gaurantee SMSM state should be changed */
Karthick S39823072015-07-08 18:16:41 +05304219 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4220 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Changac1d3612013-07-01 15:15:51 -07004221 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 }
4223
4224 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4225 the posibility of a race*/
4226 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
4227
4228 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004229 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 return;
4231}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004232
4233/*==========================================================================
4234 @ Function Name
4235 dxeTXReSyncDesc
4236
4237 @ Description
4238 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
4239 And HW programmed descriptor.
4240 If any async happen between HW/SW TX stall will happen
4241
4242 @ Parameters
4243 void *msgPtr
4244 Message pointer to sync with TX thread
4245
4246 @ Return
4247 NONE
4248===========================================================================*/
4249void dxeTXReSyncDesc
4250(
4251 wpt_msg *msgPtr
4252)
4253{
4254 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4255 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4256 wpt_uint32 nextDescReg;
4257 WLANDXE_ChannelCBType *channelEntry;
4258 WLANDXE_DescCtrlBlkType *validCtrlBlk;
4259 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004260 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004261
4262 if(NULL == msgContent)
4263 {
4264 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4265 "dxeTXReSyncDesc Invalid Control Block");
4266 return;
4267 }
4268
4269 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4270 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
4271 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4272
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004273 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004274 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004275 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4276 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4277 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
4278 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4279 &nextDescReg);
4280 /* Async detect without TX pending frame */
4281 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004282 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004283 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004284 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004285 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4286 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304287
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004288 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
4289 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304290
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004291 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004292 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004293 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004294 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004295 /* Async detect with some TX pending frames
4296 * next descriptor register should sync with first valid descriptor */
4297 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004298 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004299 validCtrlBlk = channelEntry->tailCtrlBlk;
4300 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004301 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004302 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4303 {
4304 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
4305 {
4306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4307 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304308
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004309 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4310 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304311
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004312 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4313 validCtrlBlk->linkedDescPhyAddr);
4314 }
4315 break;
4316 }
4317 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4318 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4319 {
4320 /* Finished to test till head control blcok, but could not find valid descriptor
4321 * from head to tail all descriptors are invalidated
4322 * host point of view head descriptor is next TX candidate
4323 * So, next descriptor control have to be programmed with head descriptor
4324 * check */
4325 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
4326 {
4327 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004328 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304329
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004330 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4331 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304332
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004333 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4334 validCtrlBlk->linkedDescPhyAddr);
4335 }
4336 break;
4337 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004338 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004339 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004340 }
4341
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07004342 /* HW/SW descriptor resync is done.
4343 * Next if there are any valid descriptor in chain, Push to HW again */
4344 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
4345 {
4346 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4347 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
4348 {
4349 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4350 "%11s : No TX Pending frame",
4351 channelType[channelEntry->channelType]);
4352 /* No Pending frame, Do nothing */
4353 }
4354 else
4355 {
4356 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4357 "%11s : TX Pending frame, process it",
4358 channelType[channelEntry->channelType]);
4359 validCtrlBlk = channelEntry->tailCtrlBlk;
4360 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
4361 {
4362 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4363 {
4364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4365 "%11s : when exit IMPS found valid descriptor",
4366 channelType[channelEntry->channelType]);
4367
4368 /* Found valid descriptor, kick DXE */
4369 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
4370 channelEntry->extraConfig.chan_mask);
4371 break;
4372 }
4373 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4374 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4375 {
4376 /* Finished to test till head control blcok, but could not find valid descriptor
4377 * from head to tail all descriptors are invalidated */
4378 break;
4379 }
4380 }
4381 }
4382 }
4383
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004384 wpalMemoryFree(msgPtr);
4385 return;
4386}
4387
Jeff Johnson295189b2012-06-20 16:38:30 -07004388/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05304389 @ Function Name
4390 dxeDebugTxDescReSync
4391
4392 @ Description
4393 Check DXE Tx channel state and correct it in
4394 case Tx Data stall is detected by calling
4395 %dxeTXReSyncDesc. Also ensure that WCN SS
4396 is not power collapsed before calling
4397 %dxeTXReSyncDesc
4398
4399 @ Parameters
4400 void *msgPtr
4401 Message pointer to sync with TX thread
4402
4403 @ Return
4404 NONE
4405===========================================================================*/
4406void dxeDebugTxDescReSync
4407(
4408 wpt_msg *msgPtr
4409)
4410{
4411 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4412 "%s: Check for DXE TX Async",__func__);
4413 /* Make wake up HW */
4414 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4415 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4416
4417 wpalSleep(10);
4418
4419 dxeTXReSyncDesc(msgPtr);
4420}
4421/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 @ Function Name
4423 dxeTXISR
4424
4425 @ Description
4426 TX interrupt ISR
4427 Platform will call this function if INT is happen
4428 This function must be registered into platform interrupt module
4429
4430 @ Parameters
4431 void *hostCtxt
4432 DXE host driver control context,
4433 pre registerd during interrupt registration
4434
4435 @ Return
4436 PAL_STATUS_T
4437===========================================================================*/
4438static void dxeTXISR
4439(
4440 void *hostCtxt
4441)
4442{
4443 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
4444 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07004445
4446 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004447 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004448
4449 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004450 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004451 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004452 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 /* Disable interrupt at here,
4454 IMPS or IMPS Pending state should not access RIVA register */
4455 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4456 if(eWLAN_PAL_STATUS_SUCCESS != status)
4457 {
4458 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4459 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4460 return;
4461 }
4462 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4463 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004464 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004465 return;
4466 }
4467
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 /* Disable TX Complete Interrupt at here */
4469 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4470 if(eWLAN_PAL_STATUS_SUCCESS != status)
4471 {
4472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4473 "dxeTXCompISR Disable TX complete interrupt fail");
4474 return;
4475 }
4476 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4477
4478
4479 if( dxeCtxt->ucTxMsgCnt )
4480 {
4481 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4482 "Avoiding serializing TX Complete event");
4483 return;
4484 }
4485
4486 dxeCtxt->ucTxMsgCnt = 1;
4487
4488 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004489 if(NULL == dxeCtxt->txIsrMsg)
4490 {
4491 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4492 "Invalid message");
4493 HDXE_ASSERT(0);
4494 return;
4495 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4497 dxeCtxt->txIsrMsg);
4498 if(eWLAN_PAL_STATUS_SUCCESS != status)
4499 {
4500 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4501 "dxeTXCompISR interrupt serialize fail status=%d", status);
4502 }
4503
4504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004505 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004506 return;
4507}
4508
4509/*-------------------------------------------------------------------------
4510 * Global Function
4511 *-------------------------------------------------------------------------*/
4512/*==========================================================================
4513 @ Function Name
4514 WLANDXE_Open
4515
4516 @ Description
4517 Open host DXE driver, allocate DXE resources
4518 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4519
4520 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004521 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004522
4523 @ Return
4524 pVoid DXE local module control block pointer
4525===========================================================================*/
4526void *WLANDXE_Open
4527(
4528 void
4529)
4530{
4531 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4532 unsigned int idx;
4533 WLANDXE_ChannelCBType *currentChannel = NULL;
4534 int smsmInitState;
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304535 wpt_uint8 chanMask = WDTS_TRANSPORT_CHANNELS_MASK;
Jeff Johnson295189b2012-06-20 16:38:30 -07004536
4537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004538 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004539
Mihir Shetee6618162015-03-16 14:48:42 +05304540 if (wpalIsFwLoggingEnabled())
4541 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304542 chanMask |= WDTS_RX_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304543 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304544
4545 if (wpalIsFwEvLoggingEnabled())
Mihir Shetee6618162015-03-16 14:48:42 +05304546 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304547 chanMask |= WDTS_RX_FW_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304548 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304549 dxeSetEnabledChannels(chanMask);
Mihir Shetee6618162015-03-16 14:48:42 +05304550
Jeff Johnson295189b2012-06-20 16:38:30 -07004551 /* This is temporary allocation */
4552 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4553 if(NULL == tempDxeCtrlBlk)
4554 {
4555 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4556 "WLANDXE_Open Control Block Alloc Fail");
4557 return NULL;
4558 }
4559 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4560
jagadeeshf869bba2015-04-07 20:06:21 +05304561 dxeCommonDefaultConfig(tempDxeCtrlBlk);
Jeff Johnson295189b2012-06-20 16:38:30 -07004562
Mihir Shetee6618162015-03-16 14:48:42 +05304563 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004564 {
4565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4566 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4567 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304568 currentChannel->channelType = idx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004569
4570 /* Config individual channels from channel default setup table */
4571 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4572 currentChannel);
4573 if(eWLAN_PAL_STATUS_SUCCESS != status)
4574 {
4575 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4576 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4577 WLANDXE_Close(tempDxeCtrlBlk);
4578 return NULL;
4579 }
4580
4581 /* Allocate DXE Control Block will be used by host DXE driver */
4582 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4583 if(eWLAN_PAL_STATUS_SUCCESS != status)
4584 {
4585 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4586 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4587
4588 WLANDXE_Close(tempDxeCtrlBlk);
4589 return NULL;
4590 }
4591 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4592 if(eWLAN_PAL_STATUS_SUCCESS != status)
4593 {
4594 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4595 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4596 WLANDXE_Close(tempDxeCtrlBlk);
4597 return NULL;
4598 }
4599
4600 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4601 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4602 }
4603
4604 /* Allocate and Init RX READY ISR Serialize Buffer */
4605 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4606 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4607 {
4608 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4609 "WLANDXE_Open Alloc RX ISR Fail");
4610 WLANDXE_Close(tempDxeCtrlBlk);
4611 return NULL;
4612 }
4613 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4614 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4615 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4616
4617 /* Allocate and Init TX COMP ISR Serialize Buffer */
4618 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4619 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4620 {
4621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4622 "WLANDXE_Open Alloc TX ISR Fail");
4623 WLANDXE_Close(tempDxeCtrlBlk);
4624 return NULL;
4625 }
4626 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4627 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4628 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4629
4630 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4631 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4632 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4633 {
4634 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4635 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4636 WLANDXE_Close(tempDxeCtrlBlk);
4637 return NULL;
4638 }
4639 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4640 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4641 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4642
4643 tempDxeCtrlBlk->freeRXPacket = NULL;
4644 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4645 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4646 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004647 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004648 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Karthick Sc6ec8362015-08-12 18:18:47 +05304649 tempDxeCtrlBlk->smsmRingsEmptyHistogram = 0;
4650 tempDxeCtrlBlk->smsmDxeHistogram = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004651
4652 /* Initialize SMSM state
4653 * Init State is
4654 * Clear TX Enable
4655 * RING EMPTY STATE */
4656 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4657 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4658 if(0 != smsmInitState)
4659 {
4660 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4661 "SMSM Channel init fail %d", smsmInitState);
Mihir Shetee6618162015-03-16 14:48:42 +05304662 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004663 {
4664 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4665 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004666 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4667 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004668 wpalMemoryFree(tempDxeCtrlBlk);
4669 return NULL;
4670 }
4671
Mihir Shete44547fb2014-03-10 14:15:42 +05304672#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004673 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4674 dxeRXResourceAvailableTimerExpHandler,
4675 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304676#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004677
Mihir Shetefdc9f532014-01-09 15:03:02 +05304678 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4679 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4680
Jeff Johnson295189b2012-06-20 16:38:30 -07004681 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4682 "WLANDXE_Open Success");
4683 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004684 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 return (void *)tempDxeCtrlBlk;
4686}
4687
4688/*==========================================================================
4689 @ Function Name
4690 WLANDXE_ClientRegistration
4691
4692 @ Description
4693 Make callback functions registration into DXE driver from DXE driver client
4694
4695 @ Parameters
4696 pVoid pDXEContext : DXE module control block
Mihir Shetec4093f92015-05-28 15:21:11 +05304697 WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events
Jeff Johnson295189b2012-06-20 16:38:30 -07004698 void *userContext : DXE Cliennt control block
4699
4700 @ Return
4701 wpt_status
4702===========================================================================*/
4703wpt_status WLANDXE_ClientRegistration
4704(
4705 void *pDXEContext,
Mihir Shetec4093f92015-05-28 15:21:11 +05304706 WDTS_ClientCallbacks WDTSCb,
Jeff Johnson295189b2012-06-20 16:38:30 -07004707 void *userContext
4708)
4709{
4710 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4711 WLANDXE_CtrlBlkType *dxeCtxt;
4712
4713 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004714 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004715
4716 /* Sanity */
4717 if(NULL == pDXEContext)
4718 {
4719 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4720 "WLANDXE_ClientRegistration Invalid DXE CB");
4721 return eWLAN_PAL_STATUS_E_INVAL;
4722 }
4723
Jeff Johnson295189b2012-06-20 16:38:30 -07004724 if(NULL == userContext)
4725 {
4726 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4727 "WLANDXE_ClientRegistration Invalid userContext");
4728 return eWLAN_PAL_STATUS_E_INVAL;
4729 }
4730
4731 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4732
4733 /* Assign */
Mihir Shetec4093f92015-05-28 15:21:11 +05304734 dxeCtxt->rxReadyCB = WDTSCb.rxFrameReadyCB;
4735 dxeCtxt->txCompCB = WDTSCb.txCompleteCB;
4736 dxeCtxt->lowResourceCB = WDTSCb.lowResourceCB;
4737 dxeCtxt->receiveMbMsgCB = WDTSCb.receiveMbMsgCB;
Mihir Shete5affadc2015-05-29 20:54:57 +05304738 dxeCtxt->receiveLogCompleteCB = WDTSCb.receiveLogCompleteCB;
Jeff Johnson295189b2012-06-20 16:38:30 -07004739 dxeCtxt->clientCtxt = userContext;
4740
4741 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004742 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004743 return status;
4744}
4745
4746/*==========================================================================
4747 @ Function Name
4748 WLANDXE_Start
4749
4750 @ Description
4751 Start Host DXE driver
4752 Initialize DXE channels and start channel
4753
4754 @ Parameters
4755 pVoid pDXEContext : DXE module control block
4756
4757 @ Return
4758 wpt_status
4759===========================================================================*/
4760wpt_status WLANDXE_Start
4761(
4762 void *pDXEContext
4763)
4764{
4765 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4766 wpt_uint32 idx;
4767 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4768
4769 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004770 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004771
4772 /* Sanity */
4773 if(NULL == pDXEContext)
4774 {
4775 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4776 "WLANDXE_Start Invalid DXE CB");
4777 return eWLAN_PAL_STATUS_E_INVAL;
4778 }
4779 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4780
4781 /* WLANDXE_Start called means DXE engine already initiates
4782 * And DXE HW is reset and init finished
4783 * But here to make sure HW is initialized, reset again */
jagadeeshf869bba2015-04-07 20:06:21 +05304784 dxeEngineCoreStart(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004785
4786 /* Individual Channel Start */
Mihir Shetee6618162015-03-16 14:48:42 +05304787 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004788 {
4789 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4790 "WLANDXE_Start Channel %s Start", channelType[idx]);
4791
4792 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4793 /* Make connection between DXE descriptor and DXE control block */
4794 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4795 if(eWLAN_PAL_STATUS_SUCCESS != status)
4796 {
4797 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4798 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4799 return status;
4800 }
4801
4802 /* Program each channel register with configuration arguments */
4803 status = dxeChannelInitProgram(dxeCtxt,
4804 &dxeCtxt->dxeChannel[idx]);
4805 if(eWLAN_PAL_STATUS_SUCCESS != status)
4806 {
4807 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4808 "WLANDXE_Start %d Program DMA channel Fail", idx);
4809 return status;
4810 }
4811
4812 /* ??? Trigger to start DMA channel
4813 * This must be seperated from ??? */
4814 status = dxeChannelStart(dxeCtxt,
4815 &dxeCtxt->dxeChannel[idx]);
4816 if(eWLAN_PAL_STATUS_SUCCESS != status)
4817 {
4818 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4819 "WLANDXE_Start %d Channel Start Fail", idx);
4820 return status;
4821 }
4822 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4823 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4824 }
4825
4826 /* Register ISR to OS */
4827 /* Register TX complete interrupt into platform */
4828 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4829 dxeTXISR,
4830 dxeCtxt);
4831 if(eWLAN_PAL_STATUS_SUCCESS != status)
4832 {
4833 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4834 "WLANDXE_Start TX comp interrupt registration Fail");
4835 return status;
4836 }
4837
4838 /* Register RX ready interrupt into platform */
4839 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4840 dxeRXISR,
4841 dxeCtxt);
4842 if(eWLAN_PAL_STATUS_SUCCESS != status)
4843 {
4844 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4845 "WLANDXE_Start RX Ready interrupt registration Fail");
4846 return status;
4847 }
4848
4849 /* Enable system level ISR */
4850 /* Enable RX ready Interrupt at here */
4851 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4852 if(eWLAN_PAL_STATUS_SUCCESS != status)
4853 {
4854 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4855 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4856 return status;
4857 }
4858
4859 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004860 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004861 return status;
4862}
4863
4864/*==========================================================================
4865 @ Function Name
4866 WLANDXE_TXFrame
4867
4868 @ Description
4869 Trigger frame transmit from host to RIVA
4870
4871 @ Parameters
4872 pVoid pDXEContext : DXE Control Block
4873 wpt_packet pPacket : transmit packet structure
4874 WDTS_ChannelType channel : TX channel
4875
4876 @ Return
4877 wpt_status
4878===========================================================================*/
4879wpt_status WLANDXE_TxFrame
4880(
4881 void *pDXEContext,
4882 wpt_packet *pPacket,
4883 WDTS_ChannelType channel
4884)
4885{
4886 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4887 WLANDXE_ChannelCBType *currentChannel = NULL;
4888 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4889 unsigned int *lowThreshold = NULL;
4890
4891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004892 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004893
4894 /* Sanity */
4895 if(NULL == pDXEContext)
4896 {
4897 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4898 "WLANDXE_Start Invalid DXE CB");
4899 return eWLAN_PAL_STATUS_E_INVAL;
4900 }
4901
4902 if(NULL == pPacket)
4903 {
4904 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4905 "WLANDXE_Start Invalid pPacket");
4906 return eWLAN_PAL_STATUS_E_INVAL;
4907 }
4908
Mihir Shetee6618162015-03-16 14:48:42 +05304909 if(WDTS_CHANNEL_MAX <= channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004910 {
4911 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4912 "WLANDXE_Start Invalid channel");
4913 return eWLAN_PAL_STATUS_E_INVAL;
4914 }
4915
4916 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4917
4918 currentChannel = &dxeCtxt->dxeChannel[channel];
4919
4920
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004921 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
4922 if(eWLAN_PAL_STATUS_SUCCESS != status)
4923 {
4924 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4925 "WLANDXE_TxFrame Mutex Acquire fail");
4926 return status;
4927 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004928
4929 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
4930 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
4931 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
4932
4933 /* Decide have to activate TX complete event or not */
4934 switch(dxeCtxt->txCompInt.txIntEnable)
4935 {
4936 /* TX complete interrupt will be activated when low DXE resource */
4937 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
4938 if((currentChannel->numFreeDesc <= *lowThreshold) &&
4939 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4940 {
4941 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4942 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4943 channel,
4944 eWLAN_PAL_FALSE);
4945 }
4946 break;
4947
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004948 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
4950 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
4951 {
4952 currentChannel->numFrameBeforeInt++;
4953 }
4954 break;
4955
4956 /* TX complete interrupt will be activated periodically */
4957 case WLANDXE_TX_COMP_INT_TIMER:
4958 break;
4959 }
4960
4961 dxeCtxt->txCompletedFrames++;
4962
4963 /* Update DXE descriptor, this is frame based
4964 * if a frame consist of N fragments, N Descriptor will be programed */
4965 status = dxeTXPushFrame(currentChannel, pPacket);
4966 if(eWLAN_PAL_STATUS_SUCCESS != status)
4967 {
4968 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4969 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004970 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4971 if(eWLAN_PAL_STATUS_SUCCESS != status)
4972 {
4973 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4974 "WLANDXE_TxFrame Mutex Release fail");
4975 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 return status;
4977 }
4978
4979 /* If specific channel hit low resource condition, send notification to upper layer */
4980 if(currentChannel->numFreeDesc <= *lowThreshold)
4981 {
4982 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
4983 channel,
4984 eWLAN_PAL_FALSE);
4985 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07004986
4987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4988 "%11s : Low Resource currentChannel->numRsvdDesc %d",
4989 channelType[currentChannel->channelType],
4990 currentChannel->numRsvdDesc);
Mihir Shete68ed77a2014-10-10 10:47:12 +05304991 if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4992 {
4993 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4994 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4995 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004996 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08004997 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
4998 if(eWLAN_PAL_STATUS_SUCCESS != status)
4999 {
5000 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5001 "WLANDXE_TxFrame Mutex Release fail");
5002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005003
5004 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005005 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005006 return status;
5007}
5008
5009/*==========================================================================
5010 @ Function Name
5011 WLANDXE_CompleteTX
5012
5013 @ Description
5014 Informs DXE that the current series of Tx packets is complete
5015
5016 @ Parameters
5017 pContext pDXEContext : DXE Control Block
5018 ucTxResReq TX resource number required by TL/WDI
5019
5020 @ Return
5021 wpt_status
5022===========================================================================*/
5023wpt_status
5024WLANDXE_CompleteTX
5025(
5026 void* pContext,
5027 wpt_uint32 ucTxResReq
5028)
5029{
5030 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5031 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
5032 WLANDXE_ChannelCBType *channelCb = NULL;
5033 wpt_boolean inLowRes;
5034
5035 /* Sanity Check */
5036 if( NULL == pContext )
5037 {
5038 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5039 "WLANDXE_CompleteTX invalid param");
5040 return eWLAN_PAL_STATUS_E_INVAL;
5041 }
5042
5043 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
5044 inLowRes = channelCb->hitLowResource;
5045
5046 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
5047 {
5048 /* Raise threshold temporarily if necessary */
5049 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
5050
5051 if(eWLAN_PAL_FALSE == inLowRes)
5052 {
5053 /* Put the channel to low resource condition */
5054 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5055 WDTS_CHANNEL_TX_LOW_PRI,
5056 eWLAN_PAL_FALSE);
5057 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
5058 }
5059 }
5060
5061 /*Try to reclaim resources*/
5062 dxeTXCompleteProcessing(dxeCtxt);
5063
5064 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
5065 because its fragment size is larger than DXE free resource. */
5066 if(0 < ucTxResReq)
5067 {
5068 /* DXE successfully claimed enough free DXE resouces for next fetch. */
5069 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
5070 {
5071 /* DXE has not been in low resource condition. DXE forces to kick off
5072 TX tranmit */
5073 if((eWLAN_PAL_FALSE == inLowRes) &&
5074 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
5075 {
5076 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5077 WDTS_CHANNEL_TX_LOW_PRI,
5078 eWLAN_PAL_FALSE);
5079 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5080 WDTS_CHANNEL_TX_LOW_PRI,
5081 eWLAN_PAL_TRUE);
5082 channelCb->hitLowResource = eWLAN_PAL_FALSE;
5083 }
5084 }
5085 else
5086 {
5087 /* DXE doesn't have enough free DXE resources. Put the channel
5088 to low resource condition. */
5089 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
5090 {
5091 /* Put the channel to low resource condition */
5092 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5093 WDTS_CHANNEL_TX_LOW_PRI,
5094 eWLAN_PAL_FALSE);
5095 channelCb->hitLowResource = eWLAN_PAL_TRUE;
5096 }
5097 }
5098 }
5099
5100 return status;
5101}
5102
5103/*==========================================================================
5104 @ Function Name
5105 WLANDXE_Stop
5106
5107 @ Description
5108 Stop DXE channels and DXE engine operations
5109 Disable all channel interrupt
5110 Stop all channel operation
5111
5112 @ Parameters
5113 pVoid pDXEContext : DXE Control Block
5114
5115 @ Return
5116 wpt_status
5117===========================================================================*/
5118wpt_status WLANDXE_Stop
5119(
5120 void *pDXEContext
5121)
5122{
5123 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5124 wpt_uint32 idx;
5125 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5126
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
5130 /* Sanity */
5131 if(NULL == pDXEContext)
5132 {
5133 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5134 "WLANDXE_Stop Invalid DXE CB");
5135 return eWLAN_PAL_STATUS_E_INVAL;
5136 }
5137
5138 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shetee6618162015-03-16 14:48:42 +05305139 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 {
5141 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5142 if(eWLAN_PAL_STATUS_SUCCESS != status)
5143 {
5144 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5145 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 }
5147 }
5148
5149 /* During Stop unregister interrupt */
5150 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
5151 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
5152
Mihir Shete44547fb2014-03-10 14:15:42 +05305153#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005154 if(VOS_TIMER_STATE_STOPPED !=
5155 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
5156 {
5157 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
5158 }
Mihir Shete44547fb2014-03-10 14:15:42 +05305159#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07005160
Jeff Johnson295189b2012-06-20 16:38:30 -07005161 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005162 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 return status;
5164}
5165
5166/*==========================================================================
5167 @ Function Name
5168 WLANDXE_Close
5169
5170 @ Description
5171 Close DXE channels
5172 Free DXE related resources
5173 DXE descriptor free
5174 Descriptor control block free
5175 Pre allocated RX buffer free
5176
5177 @ Parameters
5178 pVoid pDXEContext : DXE Control Block
5179
5180 @ Return
5181 wpt_status
5182===========================================================================*/
5183wpt_status WLANDXE_Close
5184(
5185 void *pDXEContext
5186)
5187{
5188 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5189 wpt_uint32 idx;
5190 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005191
5192 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005193 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005194
5195 /* Sanity */
5196 if(NULL == pDXEContext)
5197 {
5198 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5199 "WLANDXE_Stop Invalid DXE CB");
5200 return eWLAN_PAL_STATUS_E_INVAL;
5201 }
5202
5203 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05305204#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005205 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05305206#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05305207 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Mihir Shetee6618162015-03-16 14:48:42 +05305208 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 {
5210 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
5211 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
Jeff Johnson295189b2012-06-20 16:38:30 -07005212 }
5213
5214 if(NULL != dxeCtxt->rxIsrMsg)
5215 {
5216 wpalMemoryFree(dxeCtxt->rxIsrMsg);
5217 }
5218 if(NULL != dxeCtxt->txIsrMsg)
5219 {
5220 wpalMemoryFree(dxeCtxt->txIsrMsg);
5221 }
5222 if(NULL != dxeCtxt->rxPktAvailMsg)
5223 {
5224 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
5225 }
5226
5227 wpalMemoryFree(pDXEContext);
5228
5229 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005230 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005231 return status;
5232}
5233
5234/*==========================================================================
5235 @ Function Name
5236 WLANDXE_TriggerTX
5237
5238 @ Description
5239 TBD
5240
5241 @ Parameters
5242 pVoid pDXEContext : DXE Control Block
5243
5244 @ Return
5245 wpt_status
5246===========================================================================*/
5247wpt_status WLANDXE_TriggerTX
5248(
5249 void *pDXEContext
5250)
5251{
5252 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5253
5254 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005255 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005256
5257 /* TBD */
5258
5259 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005260 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005261 return status;
5262}
5263
5264/*==========================================================================
5265 @ Function Name
5266 dxeTxThreadSetPowerStateEventHandler
5267
5268 @ Description
5269 If WDI sends set power state req, this event handler will be called in Tx
5270 thread context
5271
5272 @ Parameters
5273 void *msgPtr
5274 Event MSG
5275
5276 @ Return
5277 None
5278===========================================================================*/
5279void dxeTxThreadSetPowerStateEventHandler
5280(
5281 wpt_msg *msgPtr
5282)
5283{
5284 wpt_msg *msgContent = (wpt_msg *)msgPtr;
5285 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05305286 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05305288 wpt_int8 i;
5289 WLANDXE_ChannelCBType *channelEntry;
5290 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07005291
5292 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005293 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005294
Jeff Johnson295189b2012-06-20 16:38:30 -07005295 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
5296 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
5297 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
5298
5299 switch(reqPowerState)
5300 {
5301 case WLANDXE_POWER_STATE_BMPS:
5302 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5303 {
5304 //don't block MC waiting for num_rsvd to become 0 since it may take a while
5305 //based on amount of TX and RX activity - during this time any received
5306 // management frames will remain un-processed consuming RX buffers
5307 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5308 dxeCtxt->hostPowerState = reqPowerState;
5309 }
5310 else
5311 {
5312 status = eWLAN_PAL_STATUS_E_INVAL;
5313 }
5314 break;
5315 case WLANDXE_POWER_STATE_IMPS:
5316 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5317 {
Mihir Shetea4306052014-03-25 00:02:54 +05305318
5319 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
5320 {
5321 channelEntry = &dxeCtxt->dxeChannel[i];
5322 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
5323 {
5324 status = eWLAN_PAL_STATUS_E_FAILURE;
5325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
5326 "%11s : %s :TX Pending frame",
5327 channelType[channelEntry->channelType], __func__);
5328
5329 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
5330 dxeDescriptorDump(channelEntry,
5331 channelEntry->headCtrlBlk->linkedDesc, 0);
5332 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
5333 &channelLog);
5334 dxeChannelAllDescDump(channelEntry,
5335 channelEntry->channelType,
5336 &channelLog);
5337 }
5338 }
5339
5340 if (eWLAN_PAL_STATUS_SUCCESS == status)
5341 {
5342 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
5343 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 }
5346 else
5347 {
5348 status = eWLAN_PAL_STATUS_E_INVAL;
5349 }
5350 break;
5351 case WLANDXE_POWER_STATE_FULL:
5352 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5353 {
5354 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5355 }
5356 dxeCtxt->hostPowerState = reqPowerState;
5357 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5358 break;
5359 case WLANDXE_POWER_STATE_DOWN:
5360 WLANDXE_Stop((void *)dxeCtxt);
5361 break;
5362 default:
5363 //assert
5364 break;
5365 }
5366
5367 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
5368 {
5369 dxeCtxt->setPowerStateCb(status,
5370 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
5371 }
Ravali85acf6b2012-12-12 14:01:38 -08005372 else
5373 {
5374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5375 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
5376 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005377 /* Free MSG buffer */
5378 wpalMemoryFree(msgPtr);
5379 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005380 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005381 return;
5382}
5383
5384
5385/*==========================================================================
5386 @ Function Name
5387 dxeRxThreadSetPowerStateEventHandler
5388
5389 @ Description
5390 If WDI sends set power state req, this event handler will be called in Rx
5391 thread context
5392
5393 @ Parameters
5394 void *msgPtr
5395 Event MSG
5396
5397 @ Return
5398 None
5399===========================================================================*/
5400void dxeRxThreadSetPowerStateEventHandler
5401(
5402 wpt_msg *msgPtr
5403)
5404{
5405 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5406
5407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005408 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005409
5410 /* Now serialise the message through Tx thread also to make sure
5411 * no register access when RIVA is in powersave */
5412 /*Use the same message pointer just change the call back function */
5413 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5414 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5415 msgPtr);
5416 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5417 {
5418 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5419 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005420 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 }
5422
5423 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005424 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005425}
5426
5427/*==========================================================================
5428 @ Function Name
5429 WLANDXE_SetPowerState
5430
5431 @ Description
5432 From Client let DXE knows what is the WLAN HW(RIVA) power state
5433
5434 @ Parameters
5435 pVoid pDXEContext : DXE Control Block
5436 WLANDXE_PowerStateType powerState
5437
5438 @ Return
5439 wpt_status
5440===========================================================================*/
5441wpt_status WLANDXE_SetPowerState
5442(
5443 void *pDXEContext,
5444 WDTS_PowerStateType powerState,
5445 WDTS_SetPSCbType cBack
5446)
5447{
5448 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5449 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5450 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005451 wpt_msg *rxCompMsg;
5452 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005453
5454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005455 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 if(NULL == pDXEContext)
5457 {
5458 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005459 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 return eWLAN_PAL_STATUS_E_FAILURE;
5461 }
5462 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5463
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 switch(powerState)
5465 {
5466 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005467 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5468 {
5469 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5470 if(NULL == txDescReSyncMsg)
5471 {
5472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5473 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5474 }
5475 else
5476 {
5477 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5478 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5479 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5480 txDescReSyncMsg);
5481 if(eWLAN_PAL_STATUS_SUCCESS != status)
5482 {
5483 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5484 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5485 }
5486 }
5487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 hostPowerState = WLANDXE_POWER_STATE_FULL;
5489 break;
5490 case WDTS_POWER_STATE_BMPS:
5491 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5492 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5493 break;
5494 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5496 break;
5497 case WDTS_POWER_STATE_DOWN:
5498 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5499 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5500 break;
5501 default:
5502 hostPowerState = WLANDXE_POWER_STATE_MAX;
5503 }
5504
5505 // A callback i.e. ACK back is needed only when we want to enable BMPS
5506 // and the data/management path is active because we want to ensure
5507 // DXE registers are not accessed when RIVA may be power-collapsed. So
5508 // we need a callback in enter_bmps_req (the request to RIVA is sent
5509 // only after ACK back from TX thread). A callback is not needed in
5510 // finish_scan_req during BMPS since data-path is resumed only in
5511 // finish_scan_rsp and no management frames are sent in between. No
5512 // callback is needed when going from BMPS enabled to BMPS suspended/
5513 // disabled when it is known that RIVA is awake and cannot enter power
5514 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5515 // init_scan_rsp
5516 if ( cBack )
5517 {
5518 //serialize through Rx thread
5519 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5520 if(NULL == rxCompMsg)
5521 {
5522 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5523 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5524 return eWLAN_PAL_STATUS_E_RESOURCES;
5525 }
5526
5527 /* Event type, where it must be defined???? */
5528 /* THIS MUST BE CLEARED ASAP
5529 txCompMsg->type = TX_COMPLETE; */
5530 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5531 rxCompMsg->pContext = pDxeCtrlBlk;
5532 rxCompMsg->val = hostPowerState;
5533 rxCompMsg->ptr = cBack;
5534 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5535 rxCompMsg);
5536 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5537 {
5538 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5539 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005540 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 }
5542 }
5543 else
5544 {
5545 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5546 {
5547 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5548 {
5549 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5550 }
5551 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5552 {
5553 /* Requested Full power from exit IMPS, reenable the interrupts*/
5554 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5555 {
5556 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5557 /* Enable RX interrupt at here, if new PS is not IMPS */
5558 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5559 if(eWLAN_PAL_STATUS_SUCCESS != status)
5560 {
5561 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005562 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 return status;
5564 }
5565 }
5566 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5567 {
5568 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005569 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 /* Enable RX interrupt at here, if new PS is not IMPS */
5571 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5572 if(eWLAN_PAL_STATUS_SUCCESS != status)
5573 {
5574 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005575 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 return status;
5577 }
5578 }
5579 }
5580 pDxeCtrlBlk->hostPowerState = hostPowerState;
5581 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5582 }
5583 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5584 {
5585 pDxeCtrlBlk->hostPowerState = hostPowerState;
5586 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5587 }
Mihir Shetea4306052014-03-25 00:02:54 +05305588 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5589 {
5590 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 else
5593 {
5594 HDXE_ASSERT(0);
5595 }
5596 }
5597
5598 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005599 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005600
5601 return status;
5602}
5603
5604/*==========================================================================
5605 @ Function Name
5606 WLANDXE_GetFreeTxDataResNumber
5607
5608 @ Description
5609 Returns free descriptor numbers for TX data channel (TX high priority)
5610
5611 @ Parameters
5612 pVoid pDXEContext : DXE Control Block
5613
5614 @ Return
5615 wpt_uint32 Free descriptor number of TX high pri ch
5616===========================================================================*/
5617wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5618(
5619 void *pDXEContext
5620)
5621{
5622 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005623 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005624
5625 if(NULL == pDXEContext)
5626 {
5627 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005628 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 return (0);
5630 }
5631
Mihir Shetee6618162015-03-16 14:48:42 +05305632 return ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005633}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005634
5635/*==========================================================================
5636 @ Function Name
5637 WLANDXE_ChannelDebug
5638
5639 @ Description
5640 Display DXE Channel debugging information
5641 User may request to display DXE channel snapshot
5642 Or if host driver detects any abnormal stcuk may display
5643
5644 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005645 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305646 debugFlags : Enable stall detect features
5647 defined by WPAL_DeviceDebugFlags
5648 These features may effect
5649 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005650
5651 @ Return
5652 NONE
5653
5654===========================================================================*/
5655void WLANDXE_ChannelDebug
5656(
Mihir Shete40a55652014-03-02 14:14:47 +05305657 wpt_boolean displaySnapshot,
5658 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005659)
5660{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005661 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305662 wpt_msg *txDescReSyncMsg ;
Mihir Shete41c41bb2014-08-18 17:37:12 +05305663 wpt_uint32 regValue, regValueLocal = 0;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005664 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5665
5666 /* Debug Type 1, Display current snapshot */
5667 if(displaySnapshot)
5668 {
5669 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5670 * This will not simply wakeup RIVA
5671 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005672 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5673 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005674 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005675 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005676 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
Mihir Shete41c41bb2014-08-18 17:37:12 +05305677#ifdef WCN_PRONTO
5678 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
5679#endif
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005680 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305681 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====",
Leo Chang345ef992013-07-12 10:17:29 -07005682 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305683 tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005684
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005685 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5686 &regValue,
5687 NULL,
5688 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005689
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005690 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5691 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005692 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005693 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5694 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5695 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005696 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005697
5698 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5699 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5700 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005701 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005702 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5703 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005704 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005705 }
5706 }
5707
Mihir Shete40a55652014-03-02 14:14:47 +05305708 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005709 {
Mihir Shete40a55652014-03-02 14:14:47 +05305710 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5711 if(NULL == txDescReSyncMsg)
5712 {
5713 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5714 "%s: Resync MSG MEM alloc Fail",__func__);
5715 }
5716 else
5717 {
5718 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5719 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5720 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5721 txDescReSyncMsg);
5722 if(eWLAN_PAL_STATUS_SUCCESS != status)
5723 {
5724 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5725 "%s: Post TX re-sync MSG fail",__func__);
5726 }
5727 }
5728 }
5729
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005730 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005731}
Mihir Shete5affadc2015-05-29 20:54:57 +05305732
5733wpt_uint32 WLANDXE_SetupLogTransfer(wpt_uint64 bufferAddr, wpt_uint32 bufferLen)
5734{
5735 WLANDXE_ChannelCBType *channelEntry;
5736
5737 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5738
5739
5740 return dxeRXLogRefillRing(tempDxeCtrlBlk, channelEntry, bufferAddr,
5741 bufferLen);
5742}
5743
5744wpt_status WLANDXE_StartLogTransfer(void)
5745{
5746 WLANDXE_ChannelCBType *channelEntry;
5747 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5748
5749 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5750
5751 tempDxeCtrlBlk->hostInitiatedH2H = 1;
5752 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
5753 channelEntry->headCtrlBlk->linkedDescPhyAddr);
5754 if(eWLAN_PAL_STATUS_SUCCESS != status)
5755 {
5756 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5757 "%s Write DESC Address register fail", __func__);
5758 return status;
5759 }
5760
Abhishek Singh2b055852015-10-07 14:14:13 +05305761 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
Mihir Shete5affadc2015-05-29 20:54:57 +05305762 channelEntry->extraConfig.chan_mask);
5763 if(eWLAN_PAL_STATUS_SUCCESS != status)
5764 {
5765 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5766 "dxeChannelInitProgram Write RX Control register fail");
5767 return status;
5768 }
5769 return status;
5770}