blob: 4d3d3f908c85b55f2961e6646cb81f20649ad7c0 [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
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +053093/* DXETRACE max records count */
94#define MAX_DXE_TRACE_RECORDS 512
95#define INVALID_TRACE_ADDR 0xffffffff
Leo Chang00708f62013-12-03 20:21:51 -080096
Jeff Johnson295189b2012-06-20 16:38:30 -070097/* This is temporary fot the compile
98 * WDI will release official version
99 * This must be removed */
100#define WDI_GET_PAL_CTX() NULL
101
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +0530102#define TRACE_WLANDXE_VAR_ENABLE 1
103#define TRACE_WLANDXE_VAR_DISABLE 0
Jeff Johnson295189b2012-06-20 16:38:30 -0700104/*-------------------------------------------------------------------------
105 * Local Varables
106 *-------------------------------------------------------------------------*/
107/* This is temp, someone have to allocate for me, and must be part of global context */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700108static WLANDXE_CtrlBlkType *tempDxeCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -0700109static char *channelType[WDTS_CHANNEL_MAX] =
110 {
111 "TX_LOW_PRI",
112 "TX_HIGH_PRI",
113 "RX_LOW_PRI",
Jeff Johnson295189b2012-06-20 16:38:30 -0700114 "RX_HIGH_PRI",
Mihir Shetebe94ebb2015-05-26 12:07:14 +0530115 "RX_LOGS",
Mihir Shetee6618162015-03-16 14:48:42 +0530116 "RX_FW_LOGS",
Jeff Johnson295189b2012-06-20 16:38:30 -0700117 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700118static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +0530119static WLANDXE_EnvInformation dxeEnvBlk;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +0530120static dxeTraceData gdxeTraceData;
121static dxeTraceRecord gdxeTraceTbl[MAX_DXE_TRACE_RECORDS];
122static spinlock_t dtraceLock;
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124/*-------------------------------------------------------------------------
125 * External Function Proto Type
126 *-------------------------------------------------------------------------*/
127
128/*-------------------------------------------------------------------------
129 * Local Function Proto Type
130 *-------------------------------------------------------------------------*/
131static wpt_status dxeRXFrameSingleBufferAlloc
132(
133 WLANDXE_CtrlBlkType *dxeCtxt,
134 WLANDXE_ChannelCBType *channelEntry,
135 WLANDXE_DescCtrlBlkType *currentCtrlBlock
136);
137
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700138static wpt_status dxeNotifySmsm
139(
140 wpt_boolean kickDxe,
141 wpt_boolean ringEmpty
142);
143
Mihir Shetefdc9f532014-01-09 15:03:02 +0530144static void dxeStartSSRTimer
145(
146 WLANDXE_CtrlBlkType *dxeCtxt
147);
148
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530149static wpt_status dxeTXCleanup
150(
151 WLANDXE_CtrlBlkType *hostCtxt
152);
153
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +0530154static void dxeTrace
155(
156 v_U8_t chan, v_U8_t code, v_U32_t data
157);
158
Jeff Johnson295189b2012-06-20 16:38:30 -0700159/*-------------------------------------------------------------------------
160 * Local Function
161 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700162/*==========================================================================
163 @ Function Name
164 dxeChannelMonitor
165
166 @ Description
167
168 @ Parameters
169 WLANDXE_ChannelCBType *channelEntry
170 Channel specific control block
171
172 @ Return
173 wpt_status
174
175===========================================================================*/
176static wpt_status dxeChannelMonitor
177(
178 char *monitorDescription,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530179 WLANDXE_ChannelCBType *channelEntry,
180 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700181)
182{
183 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
184
Jeff Johnsone7245742012-09-05 17:12:55 -0700185 if((NULL == monitorDescription) || (NULL == channelEntry))
186 {
187 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
188 "INVALID Input ARG");
189 return eWLAN_PAL_STATUS_E_INVAL;
190 }
191
Mihir Shetee6618162015-03-16 14:48:42 +0530192 if(channelEntry->channelType >= WDTS_CHANNEL_MAX)
Jeff Johnsone7245742012-09-05 17:12:55 -0700193 {
194 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
195 "INVALID Channel type");
196 return eWLAN_PAL_STATUS_E_INVAL;
197 }
198
Leo Chang345ef992013-07-12 10:17:29 -0700199 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
200 "%11s : HCBO %d, HCBDP 0x%x, HCBDC 0x%x,",
201 channelType[channelEntry->channelType],
202 channelEntry->headCtrlBlk->ctrlBlkOrder,
203 channelEntry->headCtrlBlk->linkedDescPhyAddr,
204 channelEntry->headCtrlBlk->linkedDesc->descCtrl.ctrl);
205 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
206 "%11s : TCBO %d, TCBDP 0x%x, TCBDC 0x%x",
207 channelType[channelEntry->channelType],
208 channelEntry->tailCtrlBlk->ctrlBlkOrder,
209 channelEntry->tailCtrlBlk->linkedDescPhyAddr,
210 channelEntry->tailCtrlBlk->linkedDesc->descCtrl.ctrl);
211 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
212 "%11s : FDC %d, RDC %d, TFC %d",
213 channelType[channelEntry->channelType],
214 channelEntry->numFreeDesc,
215 channelEntry->numRsvdDesc,
216 channelEntry->numTotalFrame);
Jeff Johnson295189b2012-06-20 16:38:30 -0700217
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700218 if(channelLog)
219 {
220 channelLog->numDesc = channelEntry->numDesc;
221 channelLog->numFreeDesc = channelEntry->numFreeDesc;
222 channelLog->numRsvdDesc = channelEntry->numRsvdDesc;
223 channelLog->headDescOrder = channelEntry->headCtrlBlk->ctrlBlkOrder;
224 channelLog->tailDescOrder = channelEntry->tailCtrlBlk->ctrlBlkOrder;
225 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530226
Jeff Johnson295189b2012-06-20 16:38:30 -0700227 return status;
228}
229
Jeff Johnsone7245742012-09-05 17:12:55 -0700230#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700231/*==========================================================================
232 @ Function Name
233 dxeMemoryDump
234
235 @ Description
236
237 @ Parameters
238 WLANDXE_ChannelCBType *channelEntry
239 Channel specific control block
240
241 @ Return
242 wpt_status
243
244===========================================================================*/
245static wpt_status dxeMemoryDump
246(
247 wpt_uint8 *dumpPointer,
248 wpt_uint32 dumpSize,
249 char *dumpTarget
250)
251{
252 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
253 wpt_uint32 numBytes = 0;
254 wpt_uint32 idx;
255
Jeff Johnsone7245742012-09-05 17:12:55 -0700256 if((NULL == dumpPointer) ||
257 (NULL == dumpTarget))
258 {
259 return status;
260 }
261
Jeff Johnson295189b2012-06-20 16:38:30 -0700262 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
263 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
264 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
265 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
266
267 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
268 for(idx = 0; idx < dumpSize; idx++)
269 {
270 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
271 "0x%2x ", dumpPointer[idx]);
272 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
273 {
274 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
275 }
276 }
277 if(0 != numBytes)
278 {
279 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
280 }
281 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
282 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
283
284 return status;
285}
Jeff Johnsone7245742012-09-05 17:12:55 -0700286#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700287
288/*==========================================================================
289 @ Function Name
290 dxeDescriptorDump
291
292 @ Description
293
294 @ Parameters
295 WLANDXE_ChannelCBType *channelEntry
296 Channel specific control block
297
298 @ Return
299 wpt_status
300
301===========================================================================*/
302wpt_status dxeDescriptorDump
303(
304 WLANDXE_ChannelCBType *channelEntry,
305 WLANDXE_DescType *targetDesc,
306 wpt_uint32 fragmentOrder
307)
308{
309 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
310
311
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 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700314 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700315 "Descriptor Dump for channel %s, %d / %d fragment",
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700317 fragmentOrder + 1,
318 channelEntry->numFragmentCurrentChain);
Jeff Johnson295189b2012-06-20 16:38:30 -0700319
Jeff Johnsone7245742012-09-05 17:12:55 -0700320 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 "CTRL WORD 0x%x, TransferSize %d",
322 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
323 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
326 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
327 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
328 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700329 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700330 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
331
332 return status;
333}
334
335/*==========================================================================
336 @ Function Name
337 dxeChannelRegisterDump
338
339 @ Description
340
341 @ Parameters
342 WLANDXE_ChannelCBType *channelEntry
343 Channel specific control block
344
345 @ Return
346 wpt_status
347
348===========================================================================*/
349wpt_status dxeChannelRegisterDump
350(
351 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530352 char *dumpTarget,
353 wpt_log_data_stall_channel_type *channelLog
Jeff Johnson295189b2012-06-20 16:38:30 -0700354)
355{
Leo Chang345ef992013-07-12 10:17:29 -0700356 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
357 wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg;
358
359 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
360 * This will not simply wakeup RIVA
361 * Just incase TX not wanted stuck, Trigger TX again */
362 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
363 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
364 wpalSleep(10);
Jeff Johnson295189b2012-06-20 16:38:30 -0700365
Mihir Shetee6618162015-03-16 14:48:42 +0530366 if(channelEntry->channelType >= WDTS_CHANNEL_MAX)
Tushnim Bhattacharyya5dd94562013-03-20 20:15:03 -0700367 {
368 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
369 "INVALID Channel type");
370 return eWLAN_PAL_STATUS_E_INVAL;
371 }
372
Leo Chang345ef992013-07-12 10:17:29 -0700373 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &chDescReg);
374 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
375 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &chControlReg);
376 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &chStatusReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700377
Leo Chang345ef992013-07-12 10:17:29 -0700378 wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
379 "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x",
380 channelType[channelEntry->channelType],
381 chControlReg, chStatusReg, chDescReg, chLDescReg);
Jeff Johnson295189b2012-06-20 16:38:30 -0700382
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700383 if(channelLog)
384 {
385 channelLog->ctrlRegVal = chControlReg;
386 channelLog->statRegVal = chStatusReg;
387 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700388
Jeff Johnson295189b2012-06-20 16:38:30 -0700389 return status;
390}
Jeff Johnsone7245742012-09-05 17:12:55 -0700391
392/*==========================================================================
393 @ Function Name
394 dxeChannelAllDescDump
395
396 @ Description
397 Dump all DXE descriptors within assigned channe;
398
399 @ Parameters
400 WLANDXE_ChannelCBType *channelEntry
401
402 @ Return
403 NONE
404
405===========================================================================*/
406void dxeChannelAllDescDump
407(
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700408 WLANDXE_ChannelCBType *channelEntry,
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530409 WDTS_ChannelType channel,
410 wpt_log_data_stall_channel_type *channelLog
Jeff Johnsone7245742012-09-05 17:12:55 -0700411)
412{
413 wpt_uint32 channelLoop;
414 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700415 wpt_uint32 previousCtrlValue = 0;
Leo Chang345ef992013-07-12 10:17:29 -0700416 wpt_uint32 previousCtrlValid = 0;
417 wpt_uint32 currentCtrlValid = 0;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700418 wpt_uint32 valDescCount = 0;
419 wpt_uint32 invalDescCount = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -0700420
421 targetCtrlBlk = channelEntry->headCtrlBlk;
422
423 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Leo Chang345ef992013-07-12 10:17:29 -0700424 "%11s : %d descriptor chains, head desc ctrl 0x%x",
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700425 channelType[channelEntry->channelType],
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700426 channelEntry->numDesc,
427 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700428 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
429
430 if((WDTS_CHANNEL_RX_LOW_PRI == channel) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530431 (WDTS_CHANNEL_RX_HIGH_PRI == channel)||
432 (WDTS_CHANNEL_RX_LOG == channel))
Jeff Johnsone7245742012-09-05 17:12:55 -0700433 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700434 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700435 {
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700436 if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl)
437 {
438 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
439 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
440 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
441 }
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700442 if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
443 {
444 valDescCount++;
445 }
446 else
447 {
448 invalDescCount++;
449 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700450 previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl;
451 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi94d4c192012-09-24 14:06:14 -0700452 }
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700453 }
454 else
455 {
Leo Chang345ef992013-07-12 10:17:29 -0700456 /* Head Descriptor is valid or not */
457 previousCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
458 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700459 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
460 {
Leo Chang345ef992013-07-12 10:17:29 -0700461 currentCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700462 if(currentCtrlValid)
463 {
464 valDescCount++;
465 }
466 else
467 {
468 invalDescCount++;
469 }
Leo Chang345ef992013-07-12 10:17:29 -0700470 if(currentCtrlValid != previousCtrlValid)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700471 {
472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
473 "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder,
474 targetCtrlBlk->linkedDesc->descCtrl.ctrl);
475 }
Leo Chang345ef992013-07-12 10:17:29 -0700476 previousCtrlValid = currentCtrlValid;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700477 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
478 }
479 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530480
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700481 if(channelLog)
482 {
483 channelLog->numValDesc = valDescCount;
484 channelLog->numInvalDesc = invalDescCount;
485 }
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530486
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700487 return;
488}
489
490/*==========================================================================
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530491 @ Function Name
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530492 dxeErrHandler
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530493
494 @ Description
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530495 Dump channel information for which Error interrupt has occured and
496 try to recover from the Error
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530497
498 @ Parameters
499 WLANDXE_ChannelCBType *channelCb
500
501 @ Return
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530502 wpt_status: eWLAN_PAL_STATUS_SUCCESS if recovery is possible and
503 successful
504 eWLAN_PAL_STATUS_E_FAILURE if recovery is not possible
505 or recovery fails
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530506===========================================================================*/
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530507wpt_status dxeErrHandler
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530508(
Mihir Shete79d6b582014-03-12 17:54:07 +0530509 WLANDXE_ChannelCBType *channelCb,
510 wpt_uint32 chStatusReg
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530511)
512{
513 wpt_log_data_stall_channel_type channelLog;
Mihir Shete79d6b582014-03-12 17:54:07 +0530514 wpt_uint32 chLDescReg, channelLoop;
515 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530516
517 dxeChannelMonitor("INT_ERR", channelCb, &channelLog);
518 dxeDescriptorDump(channelCb, channelCb->headCtrlBlk->linkedDesc, 0);
519 dxeChannelRegisterDump(channelCb, "INT_ERR", &channelLog);
520 dxeChannelAllDescDump(channelCb, channelCb->channelType, &channelLog);
521 wpalMemoryCopy(channelLog.channelName,
522 "INT_ERR",
523 WPT_TRPT_CHANNEL_NAME);
524 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelCb->channelType);
525#ifdef FEATURE_WLAN_DIAG_SUPPORT
526 wpalPacketStallDumpLog();
527#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Mihir Shete79d6b582014-03-12 17:54:07 +0530528 switch ((chStatusReg & WLANDXE_CH_STAT_ERR_CODE_MASK) >>
529 WLANDXE_CH_STAT_ERR_CODE_OFFSET)
530 {
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530531
Mihir Shete79d6b582014-03-12 17:54:07 +0530532 case WLANDXE_ERROR_PRG_INV_B2H_SRC_QID:
533 case WLANDXE_ERROR_PRG_INV_B2H_DST_QID:
534 case WLANDXE_ERROR_PRG_INV_B2H_SRC_IDX:
535 case WLANDXE_ERROR_PRG_INV_H2B_SRC_QID:
536 case WLANDXE_ERROR_PRG_INV_H2B_DST_QID:
537 case WLANDXE_ERROR_PRG_INV_H2B_DST_IDX:
538 {
539 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
540 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
541 wpalSleep(10);
542
543 if(channelCb->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
544 {
545 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
546 "%s: Invalid Channel", __func__);
547 break;
548 }
549
550 wpalReadRegister(channelCb->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
551
552 targetCtrlBlk = channelCb->headCtrlBlk;
553
554 for(channelLoop = 0; channelLoop < channelCb->numDesc; channelLoop++)
555 {
556 if (targetCtrlBlk->linkedDescPhyAddr == chLDescReg)
557 {
558 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
559 "%11s :CHx_DESCL: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
560 channelType[channelCb->channelType],
561 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
562 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
563 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
564 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
565
566 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
567
568 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
569 "%11s :Next Desc: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
570 channelType[channelCb->channelType],
571 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
572 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
573 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
574 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
575 break;
576 }
577 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
578 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530579 wpalFwDumpReq(17, 0, 0, 0, 0, 1);
Mihir Shete79d6b582014-03-12 17:54:07 +0530580 break;
581 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530582 case WLANDXE_ERROR_ABORT:
583 {
584 wpt_uint32 regValue, regValueLocal;
585 wpt_uint32 count = 0;
586 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
587 "%s: DXE Abort Error from S/W", __func__);
588
589 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &regValue);
590 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
591 "%s: DXE CSR Value: %08x", __func__,regValue);
592
593 //Execute the BMU recovery only if firmware triggered the ABORT
594 if (regValue & WLANDXE_DMA_CSR_FW_BMU_RECOVERY)
595 {
596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
597 "%s: Firmware BMU recovery On %08x", __func__,regValue);
598
599 // Clean up the descriptors
600 if (eWLAN_PAL_STATUS_SUCCESS !=
601 dxeTXCleanup(tempDxeCtrlBlk))
602 {
603 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
604 "%s: Host DXE Cleanup Failed!!!!", __func__);
605 }
606
607 // Debug DXE channel after cleanup
608 dxeChannelMonitor("INT_ERR", channelCb, &channelLog);
609 dxeDescriptorDump(channelCb, channelCb->headCtrlBlk->linkedDesc, 0);
610 dxeChannelRegisterDump(channelCb, "INT_ERR", &channelLog);
611 dxeChannelAllDescDump(channelCb, channelCb->channelType, &channelLog);
612
613 // Unblock the firmware
614 regValue |= WLANDXE_DMA_CSR_HOST_RECOVERY_DONE;
615 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
616 "%s: Host DXE Cleanup done %08x", __func__,regValue);
617 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS, regValue);
618
619 // Wait for firmware to complete the cleanup
620 do
621 {
622 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &regValue);
623 wpalBusyWait(5000);
624 count++;
625 //count is 60 because wait is for 5 ms and 60*5=300ms
626 //which is the time WD bark happens in firmware
627 } while(count < 60 && !(regValue & WLANDXE_DMA_CSR_RECOVERY_DONE));
628 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
629 "%s: FW Cleanup done %08x", __func__,regValue);
630
631 //clear all spare bits in CSR
632 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,regValue &
633 ~(WLANDXE_DMA_CSR_RECOVERY_DONE |
634 WLANDXE_DMA_CSR_FW_BMU_RECOVERY |
635 WLANDXE_DMA_CSR_HOST_RECOVERY_DONE));
636
637 //check if the h/w resources have recovered
638 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
639 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
640 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
641 "===== count %d ABD %d, ABD LOCAL %d =====", count,
642 regValue, regValueLocal);
643 if(regValue == 0 || regValueLocal == 0)
644 {
645 return eWLAN_PAL_STATUS_E_FAILURE;
646 }
647
648 return eWLAN_PAL_STATUS_SUCCESS;
649 }
650 break;
651 }
Mihir Shete79d6b582014-03-12 17:54:07 +0530652 default:
653 {
654 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
655 "%s: No Debug Inormation", __func__);
656 break;
657 }
658
659 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530660 return eWLAN_PAL_STATUS_E_FAILURE;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530661}
662/*==========================================================================
663 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700664 dxeTxThreadChannelDebugHandler
665
666 @ Description
667 Dump TX channel information
668
669 @ Parameters
670 Wwpt_msg *msgPtr
671
672 @ Return
673 NONE
674
675===========================================================================*/
676void dxeTxThreadChannelDebugHandler
677(
678 wpt_msg *msgPtr
679)
680{
681 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700682 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700683
684 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700685 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700686
687 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
688 * This will not simply wakeup RIVA
689 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700690 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
691 {
692 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530693 &tempDxeCtrlBlk->dxeChannel[channelLoop],
694 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700695 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530696 "Abnormal successive empty interrupt",
697 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700698 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530699 channelLoop,
700 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700701
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700702 wpalMemoryCopy(channelLog.channelName,
703 channelType[channelLoop],
704 WPT_TRPT_CHANNEL_NAME);
705 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700706 }
707
Leo Chang345ef992013-07-12 10:17:29 -0700708 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700709 "================== DXE Dump End ======================");
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700710 wpalMemoryFree(msgPtr);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700711
712#ifdef FEATURE_WLAN_DIAG_SUPPORT
713 wpalPacketStallDumpLog();
714#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700716 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700717 return;
718}
719
720/*==========================================================================
721 @ Function Name
722 dxeRxThreadChannelDebugHandler
723
724 @ Description
725 Dump RX channel information
726
727 @ Parameters
728 Wwpt_msg *msgPtr
729
730 @ Return
731 NONE
732
733===========================================================================*/
734void dxeRxThreadChannelDebugHandler
735(
736 wpt_msg *msgPtr
737)
738{
739 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
740 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700741 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700742
743 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700744 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700745
746 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
747 * This will not simply wakeup RIVA
748 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700749 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
750 {
Mihir Shetee6618162015-03-16 14:48:42 +0530751 if (!WLANDXE_IS_VALID_CHANNEL(channelLoop))
752 continue;
753
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700754 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530755 &tempDxeCtrlBlk->dxeChannel[channelLoop],
756 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700757 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530758 "Abnormal successive empty interrupt",
759 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700760 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530761 channelLoop, &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700762
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700763 wpalMemoryCopy(channelLog.channelName,
764 channelType[channelLoop],
765 WPT_TRPT_CHANNEL_NAME);
766 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530767
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700768 }
769
770 /* Now serialise the message through Tx thread also to make sure
771 * no register access when RIVA is in powersave */
772 /*Use the same message pointer just change the call back function */
773 msgPtr->callback = dxeTxThreadChannelDebugHandler;
774 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
775 msgPtr);
776 if ( eWLAN_PAL_STATUS_SUCCESS != status )
777 {
778 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700779 "Tx thread state dump req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700780 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700781 }
782
783 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700784 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700785 return;
786}
Jeff Johnson295189b2012-06-20 16:38:30 -0700787
788/*==========================================================================
789 @ Function Name
790 dxeCtrlBlkAlloc
791
792 @ Description
793 Allocate DXE Control block
794 DXE control block will used by Host DXE driver only, internal structure
795 Will make ring linked list
796
797 @ Parameters
798 WLANDXE_CtrlBlkType *dxeCtrlBlk,
799 DXE host driver main control block
800 WLANDXE_ChannelCBType *channelEntry
801 Channel specific control block
802
803 @ Return
804 wpt_status
805
806===========================================================================*/
807static wpt_status dxeCtrlBlkAlloc
808(
809 WLANDXE_CtrlBlkType *dxeCtrlBlk,
810 WLANDXE_ChannelCBType *channelEntry
811)
812{
813 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
814 unsigned int idx, fIdx;
815 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
816 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
817 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
818 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
819
820 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700821 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700822
823 /* Sanity check */
824 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
825 {
826 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
827 "dxeCtrlBlkAlloc Channel Entry is not valid");
828 return eWLAN_PAL_STATUS_E_INVAL;
829 }
830
831 /* Allocate pre asigned number of control blocks */
832 for(idx = 0; idx < channelEntry->numDesc; idx++)
833 {
834 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
835 if(NULL == currentCtrlBlk)
836 {
837 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
838 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
839 channelEntry->channelType);
840 freeCtrlBlk = channelEntry->headCtrlBlk;
841 for(fIdx = 0; fIdx < idx; fIdx++)
842 {
843 if(NULL == freeCtrlBlk)
844 {
845 break;
846 }
847
848 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
849 wpalMemoryFree((void *)freeCtrlBlk);
850 freeCtrlBlk = nextCtrlBlk;
851 }
852 return eWLAN_PAL_STATUS_E_FAULT;
853 }
854
855 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
856 /* Initialize common elements first */
857 currentCtrlBlk->xfrFrame = NULL;
858 currentCtrlBlk->linkedDesc = NULL;
859 currentCtrlBlk->linkedDescPhyAddr = 0;
860 currentCtrlBlk->ctrlBlkOrder = idx;
861
862 /* This is the first control block allocated
863 * Next Control block is not allocated yet
864 * head and tail must be first control block */
865 if(0 == idx)
866 {
867 currentCtrlBlk->nextCtrlBlk = NULL;
868 channelEntry->headCtrlBlk = currentCtrlBlk;
869 channelEntry->tailCtrlBlk = currentCtrlBlk;
870 }
871 /* This is not first, not last control block
872 * previous control block may has next linked block */
873 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
874 {
875 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
876 }
877 /* This is last control blocl
878 * next control block for the last control block is head, first control block
879 * then whole linked list made RING */
880 else if((channelEntry->numDesc - 1) == idx)
881 {
882 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
883 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
884 }
885 else
886 {
887 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
888 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
889 channelEntry->channelType);
890 wpalMemoryFree(currentCtrlBlk);
891 return eWLAN_PAL_STATUS_E_FAULT;
892 }
893
894 prevCtrlBlk = currentCtrlBlk;
895 channelEntry->numFreeDesc++;
896 }
897
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700898 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700899 return status;
900}
901
902/*==========================================================================
903 @ Function Name
904 dxeDescLinkAlloc
905
906 @ Description
907 Allocate DXE descriptor
908 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
909 Will make RING linked list
910 Will be linked with Descriptor control block one by one
911
912 @ Parameters
913 WLANDXE_CtrlBlkType *dxeCtrlBlk,
914 DXE host driver main control block
915 WLANDXE_ChannelCBType *channelEntry
916 Channel specific control block
917 @ Return
918 wpt_status
919
920===========================================================================*/
921static wpt_status dxeDescAllocAndLink
922(
923 WLANDXE_CtrlBlkType *dxeCtrlBlk,
924 WLANDXE_ChannelCBType *channelEntry
925)
926{
927 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
928 WLANDXE_DescType *currentDesc = NULL;
929 WLANDXE_DescType *prevDesc = NULL;
930 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
931 unsigned int idx;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530932 void *physAddressAlloc = NULL;
933 wpt_uint32 physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700934
935 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700936 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700937
938 /* Sanity Check */
939 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
940 {
941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
942 "dxeDescLinkAlloc Channel Entry is not valid");
943 return eWLAN_PAL_STATUS_E_INVAL;
944 }
945
946 currentCtrlBlk = channelEntry->headCtrlBlk;
947
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 /* allocate all DXE descriptors for this channel in one chunk */
949 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
950 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530951 &physAddressAlloc);
952 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700953 if(NULL == channelEntry->descriptorAllocation)
954 {
955 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
956 "dxeDescLinkAlloc Descriptor Alloc Fail");
957 return eWLAN_PAL_STATUS_E_RESOURCES;
958 }
959 currentDesc = channelEntry->descriptorAllocation;
Jeff Johnson295189b2012-06-20 16:38:30 -0700960
961 /* Allocate pre asigned number of descriptor */
962 for(idx = 0; idx < channelEntry->numDesc; idx++)
963 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 // descriptors were allocated in a chunk -- use the current one
Jeff Johnson295189b2012-06-20 16:38:30 -0700965 if(NULL == currentDesc)
966 {
967 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
968 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
969 channelEntry->channelType);
970 return eWLAN_PAL_STATUS_E_FAULT;
971 }
Mihir Shete96cd1902015-03-04 15:47:31 +0530972 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
973 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
974 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700975
Jeff Johnson295189b2012-06-20 16:38:30 -0700976 currentCtrlBlk->linkedDesc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530977 currentCtrlBlk->linkedDescPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700978 /* First descriptor, next none
979 * descriptor bottom location is first descriptor address */
980 if(0 == idx)
981 {
982 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
983 channelEntry->DescBottomLoc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530984 channelEntry->descBottomLocPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 }
986 /* Not first, not last descriptor
987 * may make link for previous descriptor with current descriptor
988 * ENDIAN SWAP needed ????? */
989 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
990 {
991 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530992 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700993 }
994 /* Last descriptor
995 * make a ring by asign next pointer as first descriptor
996 * ENDIAN SWAP NEEDED ??? */
997 else if((channelEntry->numDesc - 1) == idx)
998 {
999 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301000 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07001001 currentDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301002 WLANDXE_U32_SWAP_ENDIAN(channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 }
1004
1005 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
1006 * Pre allocated and physical address must be assigned into
1007 * Corresponding DXE Descriptor */
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301009 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1010 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 {
1012 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
1013 channelEntry,
1014 currentCtrlBlk);
1015 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1016 {
1017 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1018 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1019 channelEntry->channelType);
1020 return status;
1021 }
1022 --channelEntry->numFreeDesc;
1023 }
1024
Leo Chang7e05f212013-07-01 19:54:15 -07001025 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1026 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1027 {
1028 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1029 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1030 }
1031 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301032 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
1033 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Leo Chang7e05f212013-07-01 19:54:15 -07001034 {
1035 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1036 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1037 }
1038 else
1039 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05301040 /* Just in case. H2H RX channel, do nothing
Leo Chang7e05f212013-07-01 19:54:15 -07001041 * By Definition this must not happen */
1042 }
1043
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1045 prevDesc = currentDesc;
1046
Jeff Johnson295189b2012-06-20 16:38:30 -07001047 // advance to the next pre-allocated descriptor in the chunk
1048 currentDesc++;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301049 physAddress = (physAddress + sizeof(WLANDXE_DescType));
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 }
1051
1052 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001053 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 return status;
1055}
1056
1057/*==========================================================================
1058 @ Function Name
1059
1060 @ Description
1061
1062 @ Parameters
1063
1064 @ Return
1065 wpt_status
1066
1067===========================================================================*/
1068static wpt_status dxeSetInterruptPath
1069(
1070 WLANDXE_CtrlBlkType *dxeCtrlBlk
1071)
1072{
1073 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1074 wpt_uint32 interruptPath = 0;
1075 wpt_uint32 idx;
1076 WLANDXE_ChannelCBType *channelEntry = NULL;
1077
1078 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001079 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001080
Mihir Shetee6618162015-03-16 14:48:42 +05301081 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 {
1083 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
Jeff Johnson295189b2012-06-20 16:38:30 -07001084 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1085 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 {
1087 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1088 }
1089 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301090 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
Mihir Shetec4093f92015-05-28 15:21:11 +05301091 (WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301092 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 {
1094 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1095 }
1096 else
1097 {
1098 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1099 "H2H TEST RX???? %d", channelEntry->channelType);
1100 }
1101 }
1102 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1103 "Interrupt Path Must be 0x%x", interruptPath);
1104 dxeCtrlBlk->interruptPath = interruptPath;
1105 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1106
1107 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001108 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 return status;
1110}
1111
1112/*==========================================================================
1113 @ Function Name
1114 dxeEngineCoreStart
1115
1116 @ Description
1117 Trigger to start RIVA DXE Hardware
1118
1119 @ Parameters
1120 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1121 DXE host driver main control block
1122
1123 @ Return
jagadeeshf869bba2015-04-07 20:06:21 +05301124 void
Jeff Johnson295189b2012-06-20 16:38:30 -07001125
1126===========================================================================*/
jagadeeshf869bba2015-04-07 20:06:21 +05301127static void dxeEngineCoreStart
Jeff Johnson295189b2012-06-20 16:38:30 -07001128(
1129 WLANDXE_CtrlBlkType *dxeCtrlBlk
1130)
1131{
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 wpt_uint32 registerData = 0;
Leo Chang00708f62013-12-03 20:21:51 -08001133 wpt_uint8 readRetry;
Jeff Johnson295189b2012-06-20 16:38:30 -07001134
1135 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001136 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001137
Leo Chang00708f62013-12-03 20:21:51 -08001138#ifdef WCN_PRONTO
1139 /* Read default */
1140 wpalReadRegister(WLANDXE_CCU_SOFT_RESET, &registerData);
1141 registerData |= WLANDXE_DMA_CCU_DXE_RESET_MASK;
1142
1143 /* Make reset */
1144 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1145
1146 /* Clear reset */
1147 registerData &= ~WLANDXE_DMA_CCU_DXE_RESET_MASK;
1148 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1149#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 /* START This core init is not needed for the integrated system */
1151 /* Reset First */
1152 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1153 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1154 registerData);
Leo Chang00708f62013-12-03 20:21:51 -08001155#endif /* WCN_PRONTO */
Jeff Johnson295189b2012-06-20 16:38:30 -07001156
Leo Chang00708f62013-12-03 20:21:51 -08001157 for(readRetry = 0; readRetry < WLANDXE_CSR_MAX_READ_COUNT; readRetry++)
1158 {
1159 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1160 WLANDXE_CSR_DEFAULT_ENABLE);
1161 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &registerData);
1162 if(!(registerData & WLANDXE_DMA_CSR_EN_MASK))
1163 {
1164 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1165 "%s CSR 0x%x, count %d",
1166 __func__, registerData, readRetry);
1167 /* CSR is not valid value, re-try to write */
1168 wpalBusyWait(WLANDXE_CSR_NEXT_READ_WAIT);
1169 }
1170 else
1171 {
1172 break;
1173 }
1174 }
1175 if(WLANDXE_CSR_MAX_READ_COUNT == readRetry)
1176 {
1177 /* MAX wait, still cannot write correct value
1178 * Panic device */
1179 wpalDevicePanic();
1180 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001181
1182 /* Is This needed?
1183 * Not sure, revisit with integrated system */
1184 /* END This core init is not needed for the integrated system */
1185
1186 dxeSetInterruptPath(dxeCtrlBlk);
1187 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001188 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001189}
1190
1191/*==========================================================================
1192 @ Function Name
1193 dxeChannelInitProgram
1194
1195 @ Description
1196 Program RIVA DXE engine register with initial value
1197 What must be programmed
1198 - Source Address (SADRL, chDXESadrlRegAddr)
1199 - Destination address (DADRL, chDXEDadrlRegAddr)
1200 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1201 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1202
1203 Not need to program now
1204 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1205 TX : Have to program to trigger send out frame
1206 RX : programmed by DXE engine
1207
1208 @ Parameters
1209 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1210 DXE host driver main control block
1211 WLANDXE_ChannelCBType *channelEntry
1212 Channel specific control block
1213 @ Return
1214 wpt_status
1215
1216===========================================================================*/
1217static wpt_status dxeChannelInitProgram
1218(
1219 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1220 WLANDXE_ChannelCBType *channelEntry
1221)
1222{
1223 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1224 wpt_uint32 idx;
1225 WLANDXE_DescType *currentDesc = NULL;
1226 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1227
1228 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001229 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001230
1231 /* Sanity Check */
1232 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1233 {
1234 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1235 "dxeChannelInitProgram Channel Entry is not valid");
1236 return eWLAN_PAL_STATUS_E_INVAL;
1237 }
1238
1239 /* Program Source address and destination adderss */
1240 if(!channelEntry->channelConfig.useShortDescFmt)
1241 {
1242 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1243 "dxeChannelInitProgram Long Descriptor not support yet");
1244 return eWLAN_PAL_STATUS_E_FAILURE;
1245 }
1246
1247 /* Common register area */
1248 /* Next linked list Descriptor pointer */
1249 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1250 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1251 if(eWLAN_PAL_STATUS_SUCCESS != status)
1252 {
1253 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1254 "dxeChannelInitProgram Write DESC Address register fail");
1255 return status;
1256 }
1257
1258 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1259 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1260 {
1261 /* Program default registers */
1262 /* TX DMA channel, DMA destination address is work Q */
1263 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1264 channelEntry->channelConfig.refWQ);
1265 if(eWLAN_PAL_STATUS_SUCCESS != status)
1266 {
1267 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1268 "dxeChannelInitProgram Write TX DAddress register fail");
1269 return status;
1270 }
1271 }
1272 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301273 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1274 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001275 {
1276 /* Initialize Descriptor control Word First */
1277 currentCtrlBlk = channelEntry->headCtrlBlk;
1278 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1279 {
1280 currentDesc = currentCtrlBlk->linkedDesc;
1281 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1282 }
1283
1284 /* RX DMA channel, DMA source address is work Q */
1285 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1286 channelEntry->channelConfig.refWQ);
1287 if(eWLAN_PAL_STATUS_SUCCESS != status)
1288 {
1289 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1290 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1291 return status;
1292 }
1293
1294 /* RX DMA channel, Program pre allocated destination Address */
1295 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1296 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1297 if(eWLAN_PAL_STATUS_SUCCESS != status)
1298 {
1299 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1300 "dxeChannelInitProgram Write RX DAddress register fail");
1301 return status;
1302 }
1303
1304 /* RX Channels, default Control registers MUST BE ENABLED */
jagadeeshf869bba2015-04-07 20:06:21 +05301305 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07001306 channelEntry->extraConfig.chan_mask);
1307 if(eWLAN_PAL_STATUS_SUCCESS != status)
1308 {
1309 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1310 "dxeChannelInitProgram Write RX Control register fail");
1311 return status;
1312 }
1313 }
1314 else
1315 {
1316 /* H2H test channel, not use work Q */
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 }
1318
1319 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001320 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001321 return status;
1322}
1323
1324
1325/*==========================================================================
1326 @ Function Name
1327 dxeChannelStart
1328
1329 @ Description
1330 Start Specific Channel
1331
1332 @ Parameters
1333 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1334 DXE host driver main control block
1335 WLANDXE_ChannelCBType *channelEntry
1336 Channel specific control block
1337
1338 @ Return
1339 wpt_status
1340
1341===========================================================================*/
1342static wpt_status dxeChannelStart
1343(
1344 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1345 WLANDXE_ChannelCBType *channelEntry
1346)
1347{
1348 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1349 wpt_uint32 regValue = 0;
1350 wpt_uint32 intMaskVal = 0;
1351
1352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001353 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001354
1355 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1356 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1357
1358 /* Enable individual channel
1359 * not to break current channel setup, first read register */
1360 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1361 &regValue);
1362 if(eWLAN_PAL_STATUS_SUCCESS != status)
1363 {
1364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1365 "dxeChannelStart Read Channel Enable register fail");
1366 return status;
1367 }
1368
1369 /* Enable Channel specific Interrupt */
1370 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1371 &intMaskVal);
1372 if(eWLAN_PAL_STATUS_SUCCESS != status)
1373 {
1374 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1375 "dxeChannelStart Read INT_MASK register fail");
1376 return status;
1377 }
1378 intMaskVal |= channelEntry->extraConfig.intMask;
1379 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1380 intMaskVal);
1381 if(eWLAN_PAL_STATUS_SUCCESS != status)
1382 {
1383 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1384 "dxeChannelStart Write INT_MASK register fail");
1385 return status;
1386 }
1387
1388 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001389 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001390 return status;
1391}
1392
1393/*==========================================================================
1394 @ Function Name
1395 dxeChannelStop
1396
1397 @ Description
1398 Stop Specific Channel
1399
1400 @ Parameters
1401 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1402 DXE host driver main control block
1403 WLANDXE_ChannelCBType *channelEntry
1404 Channel specific control block
1405
1406 @ Return
1407 wpt_status
1408
1409===========================================================================*/
1410static wpt_status dxeChannelStop
1411(
1412 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1413 WLANDXE_ChannelCBType *channelEntry
1414)
1415{
1416 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1417 wpt_uint32 intMaskVal = 0;
1418
1419 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001420 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001421
1422 /* Sanity */
1423 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1424 {
1425 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1426 "dxeChannelStop Invalid arg input");
1427 return eWLAN_PAL_STATUS_E_INVAL;
1428 }
1429
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001430 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1431 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1432 {
1433 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1434 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001435 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001436 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 /* Maskout interrupt */
1438 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1439 &intMaskVal);
1440 if(eWLAN_PAL_STATUS_SUCCESS != status)
1441 {
1442 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1443 "dxeChannelStop Read INT_MASK register fail");
1444 return status;
1445 }
1446 intMaskVal ^= channelEntry->extraConfig.intMask;
1447 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1448 intMaskVal);
1449 if(eWLAN_PAL_STATUS_SUCCESS != status)
1450 {
1451 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1452 "dxeChannelStop Write INT_MASK register fail");
1453 return status;
1454 }
1455
1456 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1457
1458 /* Stop Channel ??? */
1459 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001460 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001461 return status;
1462}
1463
1464/*==========================================================================
1465 @ Function Name
1466 dxeChannelClose
1467
1468 @ Description
1469 Close Specific Channel
1470 Free pre allocated RX frame buffer if RX channel
1471 Free DXE descriptor for each channel
1472 Free Descriptor control block for each channel
1473
1474 @ Parameters
1475 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1476 DXE host driver main control block
1477 WLANDXE_ChannelCBType *channelEntry
1478 Channel specific control block
1479
1480 @ Return
1481 wpt_status
1482
1483===========================================================================*/
1484static wpt_status dxeChannelClose
1485(
1486 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1487 WLANDXE_ChannelCBType *channelEntry
1488)
1489{
1490 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1491 wpt_uint32 idx;
1492 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1493 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1494 WLANDXE_DescType *currentDescriptor = NULL;
1495 WLANDXE_DescType *nextDescriptor = NULL;
1496
1497 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001498 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001499
1500 /* Sanity */
1501 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1502 {
1503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1504 "dxeChannelStop Invalid arg input");
1505 return eWLAN_PAL_STATUS_E_INVAL;
1506 }
1507
1508 currentCtrlBlk = channelEntry->headCtrlBlk;
1509 if(NULL != currentCtrlBlk)
1510 {
1511 currentDescriptor = currentCtrlBlk->linkedDesc;
1512 for(idx = 0; idx < channelEntry->numDesc; idx++)
1513 {
1514 if (idx + 1 != channelEntry->numDesc)
1515 {
1516 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1517 nextDescriptor = nextCtrlBlk->linkedDesc;
1518 }
1519 else
1520 {
1521 nextCtrlBlk = NULL;
1522 nextDescriptor = NULL;
1523 }
1524 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301525 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1526 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 {
1528 if (NULL != currentCtrlBlk->xfrFrame)
1529 {
1530 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1531 wpalPacketFree(currentCtrlBlk->xfrFrame);
1532 }
1533 }
1534 /*
1535 * It is the responsibility of DXE to walk through the
1536 * descriptor chain and unlock any pending packets (if
1537 * locked).
1538 */
1539 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1540 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1541 {
1542 if((NULL != currentCtrlBlk->xfrFrame) &&
1543 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1544 {
1545 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1546 wpalPacketFree(currentCtrlBlk->xfrFrame);
1547 }
1548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001549 wpalMemoryFree(currentCtrlBlk);
1550
1551 currentCtrlBlk = nextCtrlBlk;
1552 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001553 if(NULL == currentCtrlBlk)
1554 {
1555 /* Already reach last of the control block
1556 * Not need to process anymore, break */
1557 break;
1558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 }
1560 }
1561
Jeff Johnson295189b2012-06-20 16:38:30 -07001562 // descriptors were allocated as a single chunk so free the chunk
1563 if(NULL != channelEntry->descriptorAllocation)
1564 {
1565 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1566 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001567
1568 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001569 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 return status;
1571}
1572
1573/*==========================================================================
1574 @ Function Name
1575 dxeChannelCleanInt
1576
1577 @ Description
1578 Clean up interrupt from RIVA HW
1579 After Host finish to handle interrupt, interrupt signal must be cleaned up
1580 Otherwise next interrupt will not be generated
1581
1582 @ Parameters
1583 WLANDXE_ChannelCBType *channelEntry
1584 Channel specific control block
1585 wpt_uint32 *chStat
1586 Channel Status register value
1587
1588 @ Return
1589 wpt_status
1590
1591===========================================================================*/
1592static wpt_status dxeChannelCleanInt
1593(
1594 WLANDXE_ChannelCBType *channelEntry,
1595 wpt_uint32 *chStat
1596)
1597{
1598 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1599
1600 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001601 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001602
1603 /* Read Channel Status Register to know why INT Happen */
1604 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1605 chStat);
1606 if(eWLAN_PAL_STATUS_SUCCESS != status)
1607 {
1608 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1609 "dxeChannelCleanInt Read CH STAT register fail");
1610 return eWLAN_PAL_STATUS_E_FAULT;
1611 }
1612 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1613 "%s Channel INT Clean, Status 0x%x",
1614 channelType[channelEntry->channelType], *chStat);
1615
1616 /* Clean up all the INT within this channel */
1617 status = wpalWriteRegister(WLANDXE_INT_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 Write CH Clean register fail");
1623 return eWLAN_PAL_STATUS_E_FAULT;
1624 }
1625
Jeff Johnsone7245742012-09-05 17:12:55 -07001626 /* Clean up Error INT Bit */
1627 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1628 {
1629 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1630 (1 << channelEntry->assignedDMAChannel));
1631 if(eWLAN_PAL_STATUS_SUCCESS != status)
1632 {
1633 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1634 "dxeChannelCleanInt Read CH STAT register fail");
1635 return eWLAN_PAL_STATUS_E_FAULT;
1636 }
1637 }
1638
1639 /* Clean up DONE INT Bit */
1640 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1641 {
1642 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1643 (1 << channelEntry->assignedDMAChannel));
1644 if(eWLAN_PAL_STATUS_SUCCESS != status)
1645 {
1646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1647 "dxeChannelCleanInt Read CH STAT register fail");
1648 return eWLAN_PAL_STATUS_E_FAULT;
1649 }
1650 }
1651
1652 /* Clean up ED INT Bit */
1653 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1654 {
1655 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1656 (1 << channelEntry->assignedDMAChannel));
1657 if(eWLAN_PAL_STATUS_SUCCESS != status)
1658 {
1659 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1660 "dxeChannelCleanInt Read CH STAT register fail");
1661 return eWLAN_PAL_STATUS_E_FAULT;
1662 }
1663 }
1664
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001666 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001667 return status;
1668}
1669
Mihir Shete44547fb2014-03-10 14:15:42 +05301670#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Jeff Johnson295189b2012-06-20 16:38:30 -07001671/*==========================================================================
Leo Chang72cdfd32013-10-17 20:36:30 -07001672 @ Function Name
1673 dxeRXResourceAvailableTimerExpHandler
1674
1675 @ Description
1676 During pre-set timeperiod, if free available RX buffer is not allocated
1677 Trigger Driver re-loading to recover RX dead end
1678
1679 @ Parameters
1680 v_VOID_t *usrData
1681 DXE context
1682
1683 @ Return
1684 NONE
1685
1686===========================================================================*/
1687void dxeRXResourceAvailableTimerExpHandler
1688(
1689 void *usrData
1690)
1691{
Katya Nigam93888ff2014-02-10 17:58:11 +05301692 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Mihir Shete058fcff2014-06-26 18:54:06 +05301693 wpt_uint32 numRxFreePackets;
Mihir Sheted183cef2014-09-26 19:17:56 +05301694 wpt_uint32 numAllocFailures;
Katya Nigam93888ff2014-02-10 17:58:11 +05301695
1696 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1697
Leo Chang72cdfd32013-10-17 20:36:30 -07001698 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1699 "RX Low resource, Durign wait time period %d, RX resource not allocated",
Katya Nigama6fbf662015-03-17 18:35:47 +05301700 wpalGetDxeReplenishRXTimerVal());
Katya Nigam93888ff2014-02-10 17:58:11 +05301701
Mihir Shete058fcff2014-06-26 18:54:06 +05301702 //This API wil also try to replenish packets
1703 wpalGetNumRxFreePacket(&numRxFreePackets);
Mihir Sheted183cef2014-09-26 19:17:56 +05301704 wpalGetNumRxPacketAllocFailures(&numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301705
Mihir Sheted183cef2014-09-26 19:17:56 +05301706 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1707 "Free Packets: %u, Alloc Failures: %u",
1708 numRxFreePackets, numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301709 if (numRxFreePackets > 0)
1710 {
1711 /* If no. of free packets is greater than 0, it means
1712 * that some packets were replenished and can be used
1713 * by DXE to receive frames. So try to restart the
1714 * resourceAvailable timer here, it will be stopped
1715 * by the DXE's low resource callback if atleast one
1716 * free packet reaches DXE.
1717 */
1718 if (NULL != dxeCtxt)
1719 {
1720 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1721 "%s: Replenish successful. Restart the Rx Low resource timer",
1722 __func__);
1723 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301724 wpalGetDxeReplenishRXTimerVal());
Mihir Shete058fcff2014-06-26 18:54:06 +05301725 return;
1726 }
1727 }
Katya Nigama6fbf662015-03-17 18:35:47 +05301728 if(wpalIsDxeSSREnable())
1729 {
1730 if (NULL != dxeCtxt)
1731 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
Mihir Shete058fcff2014-06-26 18:54:06 +05301732
Katya Nigama6fbf662015-03-17 18:35:47 +05301733 wpalWlanReload();
Katya Nigam93888ff2014-02-10 17:58:11 +05301734
Katya Nigama6fbf662015-03-17 18:35:47 +05301735 if (NULL != usrData)
1736 dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
1737 }
1738 else
1739 {
1740 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
1741 wpalGetDxeReplenishRXTimerVal());
1742 }
Mihir Shetefdc9f532014-01-09 15:03:02 +05301743 return;
1744}
Mihir Shete44547fb2014-03-10 14:15:42 +05301745#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05301746
1747/*==========================================================================
1748 @ Function Name
1749 dxeStartSSRTimer
1750
1751 @ Description
1752 Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip,
1753 this makes sure that if the chip does not respond to the FIQ within
1754 the timeout period the dxeSSRTimer expiration handler will take the
1755 appropriate action.
1756
1757 @ Parameters
1758 NONE
1759
1760 @ Return
1761 NONE
1762
1763===========================================================================*/
1764static void dxeStartSSRTimer
1765(
1766 WLANDXE_CtrlBlkType *dxeCtxt
1767)
1768{
1769 if(VOS_TIMER_STATE_RUNNING !=
1770 wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer))
1771 {
1772 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1773 "%s: Starting SSR Timer",__func__);
1774 wpalTimerStart(&dxeCtxt->dxeSSRTimer,
1775 T_WLANDXE_SSR_TIMEOUT);
1776 }
1777}
1778
1779/*==========================================================================
1780 @ Function Name
1781 dxeSSRTimerExpHandler
1782
1783 @ Description
1784 Issue an explicit subsystem restart of the wcnss subsystem if the
1785 WCN chip does not respond to the FIQ within the timeout period
1786
1787 @ Parameters
1788 v_VOID_t *usrData
1789
1790 @ Return
1791 NONE
1792
1793===========================================================================*/
1794void dxeSSRTimerExpHandler
1795(
1796 void *usrData
1797)
1798{
1799 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1800 "DXE not shutdown %d ms after FIQ!! Issue SSR",
1801 T_WLANDXE_SSR_TIMEOUT);
1802 wpalRivaSubystemRestart();
1803
Leo Chang72cdfd32013-10-17 20:36:30 -07001804 return;
1805}
1806
1807/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001808 @ Function Name
1809 dxeRXPacketAvailableCB
1810
1811 @ Description
1812 If RX frame handler encounts RX buffer pool empty condition,
1813 DXE RX handle loop will be blocked till get available RX buffer pool.
1814 When new RX buffer pool available, Packet available CB function will
1815 be called.
1816
1817 @ Parameters
1818 wpt_packet *freePacket
1819 Newly allocated RX buffer
1820 v_VOID_t *usrData
1821 DXE context
1822
1823 @ Return
1824 NONE
1825
1826===========================================================================*/
1827void dxeRXPacketAvailableCB
1828(
1829 wpt_packet *freePacket,
1830 v_VOID_t *usrData
1831)
1832{
1833 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1834 wpt_status status;
1835
1836 /* Simple Sanity */
1837 if((NULL == freePacket) || (NULL == usrData))
1838 {
1839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1840 "Get Free RX Buffer fail, Critical Error");
1841 HDXE_ASSERT(0);
1842 return;
1843 }
1844
1845 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1846
1847 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1848 {
1849 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1850 "DXE Context data corrupted, Critical Error");
1851 HDXE_ASSERT(0);
1852 return;
1853 }
1854
1855 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1856 "DXE RX packet available, post MSG to RX Thread");
1857
1858 dxeCtxt->freeRXPacket = freePacket;
1859
1860 /* Serialize RX Packet Available message upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08001861 if (NULL == dxeCtxt->rxPktAvailMsg)
1862 {
1863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1864 "DXE NULL pkt");
1865 HDXE_ASSERT(0);
1866 return;
1867 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001868
1869 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1870 dxeCtxt->rxPktAvailMsg);
1871 if(eWLAN_PAL_STATUS_SUCCESS != status)
1872 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001873 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1874 "dxeRXPacketAvailableCB serialize fail");
1875 }
1876
1877 return;
1878}
1879
1880/*==========================================================================
1881 @ Function Name
1882 dxeRXFrameSingleBufferAlloc
1883
1884 @ Description
1885 Allocate Platform packet buffer to prepare RX frame
1886 RX frame memory space must be pre allocted and must be asigned to
1887 descriptor
1888 then whenever DMA engine want to tranfer frame from BMU,
1889 buffer must be ready
1890
1891 @ Parameters
1892 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1893 DXE host driver main control block
1894 WLANDXE_ChannelCBType *channelEntry
1895 Channel specific control block
1896 WLANDXE_DescCtrlBlkType currentCtrlBlock
1897 current control block which have to be asigned
1898 frame buffer
1899
1900 @ Return
1901 wpt_status
1902
1903===========================================================================*/
1904static wpt_status dxeRXFrameSingleBufferAlloc
1905(
1906 WLANDXE_CtrlBlkType *dxeCtxt,
1907 WLANDXE_ChannelCBType *channelEntry,
1908 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1909)
1910{
1911 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1912 wpt_packet *currentPalPacketBuffer = NULL;
1913 WLANDXE_DescType *currentDesc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 wpt_iterator iterator;
1915 wpt_uint32 allocatedSize = 0;
1916 void *physAddress = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001917
1918 currentDesc = currentCtrlBlock->linkedDesc;
1919
Leo Chang7e05f212013-07-01 19:54:15 -07001920 if(currentDesc->descCtrl.valid)
1921 {
1922 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1923 "This Descriptor is valid, Do not refill");
1924 return eWLAN_PAL_STATUS_E_EXISTS;
1925 }
1926
Jeff Johnson295189b2012-06-20 16:38:30 -07001927 /* First check if a packet pointer has already been provided by a previously
1928 invoked Rx packet available callback. If so use that packet. */
1929 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1930 {
1931 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1932 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1933 dxeCtxt->freeRXPacket = NULL;
Mihir Sheted183cef2014-09-26 19:17:56 +05301934
1935 if (channelEntry->doneIntDisabled)
1936 {
1937 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1938 channelEntry->extraConfig.chan_mask);
1939 channelEntry->doneIntDisabled = 0;
1940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 }
1942 else if(!dxeCtxt->rxPalPacketUnavailable)
1943 {
Leo Chang72cdfd32013-10-17 20:36:30 -07001944 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1945 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1947 dxeRXPacketAvailableCB,
1948 (void *)dxeCtxt);
1949
1950 if(NULL == currentPalPacketBuffer)
1951 {
1952 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
Mihir Shete44547fb2014-03-10 14:15:42 +05301953#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07001954 /* Out of RX free buffer,
1955 * Start timer to recover from RX dead end */
1956 if(VOS_TIMER_STATE_RUNNING !=
1957 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
1958 {
1959 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1960 "RX Low resource, wait available resource");
1961 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301962 wpalGetDxeReplenishRXTimerVal());
Leo Chang72cdfd32013-10-17 20:36:30 -07001963 }
Mihir Shete44547fb2014-03-10 14:15:42 +05301964#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 }
1966 }
1967
1968 if(NULL == currentPalPacketBuffer)
1969 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 return eWLAN_PAL_STATUS_E_RESOURCES;
1971 }
1972
1973 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1974 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1975 currentPalPacketBuffer->pBD = NULL;
1976 currentPalPacketBuffer->pBDPhys = NULL;
1977 currentPalPacketBuffer->BDLength = 0;
Mihir Shete5affadc2015-05-29 20:54:57 +05301978
1979 if (channelEntry->channelType == WDTS_CHANNEL_RX_FW_LOG)
Hanumantha Reddy Pothulabd3303c2015-07-15 17:22:00 +05301980 wpalPacketRawTrimHead(currentCtrlBlock->xfrFrame, WLANDXE_NL_HEADER_SZ);
Mihir Shete5affadc2015-05-29 20:54:57 +05301981
Jeff Johnson295189b2012-06-20 16:38:30 -07001982 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
Mihir Shetebc338242015-03-04 15:34:19 +05301983
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 if(eWLAN_PAL_STATUS_SUCCESS != status)
1985 {
1986 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1987 "dxeRXFrameBufferAlloc unable to lock packet");
1988 return status;
1989 }
1990
1991 /* Init iterator to get physical os buffer address */
1992 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1993 if(eWLAN_PAL_STATUS_SUCCESS != status)
1994 {
1995 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1996 "dxeRXFrameBufferAlloc iterator init fail");
1997 return status;
1998 }
1999 status = wpalIteratorNext(&iterator,
2000 currentPalPacketBuffer,
2001 &physAddress,
2002 &allocatedSize);
2003 if(eWLAN_PAL_STATUS_SUCCESS != status)
2004 {
2005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2006 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
2007 return status;
2008 }
2009 currentPalPacketBuffer->pBDPhys = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07002010
2011 /* DXE descriptor must have SWAPPED addres in it's structure
2012 * !!! SWAPPED !!! */
2013 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05302014 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07002015
Jeff Johnson295189b2012-06-20 16:38:30 -07002016 return status;
2017}
2018
2019/*==========================================================================
2020 @ Function Name
2021 dxeRXFrameRefillRing
2022
2023 @ Description
2024 Allocate Platform packet buffers to try to fill up the DXE Rx ring
2025
2026 @ Parameters
2027 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2028 DXE host driver main control block
2029 WLANDXE_ChannelCBType *channelEntry
2030 Channel specific control block
2031
2032 @ Return
2033 wpt_status
2034
2035===========================================================================*/
2036static wpt_status dxeRXFrameRefillRing
2037(
2038 WLANDXE_CtrlBlkType *dxeCtxt,
2039 WLANDXE_ChannelCBType *channelEntry
2040)
2041{
2042 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2043 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2044 WLANDXE_DescType *currentDesc = NULL;
2045
2046 while(channelEntry->numFreeDesc > 0)
2047 {
2048 /* Current Control block is free
2049 * and associated frame buffer is not linked with control block anymore
2050 * allocate new frame buffer for current control block */
2051 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2052 channelEntry,
2053 currentCtrlBlk);
2054
Leo Chang7e05f212013-07-01 19:54:15 -07002055 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2056 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 {
2058 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2059 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2060 break;
2061 }
2062
Leo Chang7e05f212013-07-01 19:54:15 -07002063 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2064 {
2065 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2066 "dxeRXFrameRefillRing, Descriptor Non-Empry");
2067 }
2068
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 currentDesc = currentCtrlBlk->linkedDesc;
2070 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2071
2072 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2073 that any posted writes are reflected in memory before DXE looks at
2074 the descriptor. */
2075 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2076 {
Karthick S3254c5d2015-04-28 15:06:17 +05302077 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2078 "dxeRXFrameRefillRing, Descriptor write failed");
2079 ++channelEntry->desc_write_fail_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 //HDXE_ASSERT(0);
2081 }
2082
2083 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07002084 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002085 {
2086 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2087 1 << channelEntry->assignedDMAChannel);
2088 }
2089 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07002090 if(eWLAN_PAL_STATUS_E_EXISTS != status)
2091 {
2092 --channelEntry->numFreeDesc;
2093 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 }
2095
2096 channelEntry->tailCtrlBlk = currentCtrlBlk;
2097
2098 return status;
2099}
2100
Mihir Shete5affadc2015-05-29 20:54:57 +05302101static wpt_uint32 dxeRXLogRefillRing
2102(
2103 WLANDXE_CtrlBlkType *dxeCtxt,
2104 WLANDXE_ChannelCBType *channelEntry,
2105 wpt_uint64 bufferAddr,
2106 wpt_uint32 bufferLen
2107)
2108{
2109 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2110 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2111 WLANDXE_DescType *currentDesc = NULL;
2112 wpt_uint32 xfrSize, allocatedLen = 0;
2113
Karthick Sed59a282015-08-10 14:52:16 +05302114 while(bufferLen > 0 && channelEntry->numFreeDesc > 0)
Mihir Shete5affadc2015-05-29 20:54:57 +05302115 {
2116 /* Current Control block is free
2117 * and associated frame buffer is not linked with control block anymore
2118 * allocate new frame buffer for current control block */
2119 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2120 channelEntry,
2121 currentCtrlBlk);
2122
Karthick S122fa9e2015-07-24 17:20:03 +05302123 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2124 (eWLAN_PAL_STATUS_E_EXISTS != status))
Mihir Shete5affadc2015-05-29 20:54:57 +05302125 {
2126 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Karthick S122fa9e2015-07-24 17:20:03 +05302127 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
Mihir Shete5affadc2015-05-29 20:54:57 +05302128 break;
2129 }
2130
2131 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2132 {
2133 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2134 "%s, Descriptor Non-Empty",__func__);
2135 }
2136
2137 currentDesc = currentCtrlBlk->linkedDesc;
2138 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
Hanumantha Reddy Pothulabd3303c2015-07-15 17:22:00 +05302139 xfrSize = WLANDXE_FW_LOGGING_XFSIZE > bufferLen ?
2140 bufferLen : WLANDXE_FW_LOGGING_XFSIZE;
Mihir Shete5affadc2015-05-29 20:54:57 +05302141 currentDesc->xfrSize = xfrSize;
2142 allocatedLen += xfrSize;
2143 bufferLen -= xfrSize;
2144 wpalPacketSetRxLength(currentCtrlBlk->xfrFrame,
2145 xfrSize);
2146
2147 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2148 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)bufferAddr);
2149
2150 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2151 that any posted writes are reflected in memory before DXE looks at
2152 the descriptor. */
2153 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2154 {
2155 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2156 "%s, Descriptor write failed",__func__);
2157 ++channelEntry->desc_write_fail_count;
2158 }
2159
2160 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2161 --channelEntry->numFreeDesc;
2162 bufferAddr += xfrSize;
2163 }
2164
2165 channelEntry->tailCtrlBlk = currentCtrlBlk;
2166
2167 return allocatedLen;
2168}
Jeff Johnson295189b2012-06-20 16:38:30 -07002169/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002170 @ Function Name
2171 dxeRXFrameRouteUpperLayer
2172
2173 @ Description
2174 Test DXE descriptors and if any RX frame pending within RING,
2175 Route to upper layer
2176
2177 @ Parameters
2178 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2179 DXE host driver main control block
2180 WLANDXE_ChannelCBType *channelEntry
2181 Channel specific control block
2182 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002183 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002184 0 No frame pulled from RX RING
2185 int number of RX frames pulled from RX ring
2186
2187===========================================================================*/
2188static wpt_int32 dxeRXFrameRouteUpperLayer
2189(
2190 WLANDXE_CtrlBlkType *dxeCtxt,
2191 WLANDXE_ChannelCBType *channelEntry
2192)
2193{
2194 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2195 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2196 WLANDXE_DescType *currentDesc = NULL;
2197 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002198 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002199
2200 currentCtrlBlk = channelEntry->headCtrlBlk;
2201 currentDesc = currentCtrlBlk->linkedDesc;
2202
2203 /* Descriptoe should be SWAPPED ???? */
2204 descCtrl = currentDesc->descCtrl.ctrl;
2205
2206 /* Get frames while VALID bit is not set (DMA complete) and a data
2207 * associated with it */
2208 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2209 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2210 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2211 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2212 {
2213 channelEntry->numTotalFrame++;
2214 channelEntry->numFreeDesc++;
Jeff Johnsone7245742012-09-05 17:12:55 -07002215 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
Mihir Shetebc338242015-03-04 15:34:19 +05302216
Jeff Johnsone7245742012-09-05 17:12:55 -07002217 if (eWLAN_PAL_STATUS_SUCCESS != status)
2218 {
2219 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2220 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002221 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002222 }
Mihir Shetebc338242015-03-04 15:34:19 +05302223
Jeff Johnsone7245742012-09-05 17:12:55 -07002224 /* This Descriptor is valid, so linked Control block is also valid
2225 * Linked Control block has pre allocated packet buffer
2226 * So, just let upper layer knows preallocated frame pointer will be OK */
2227 /* Reap Rx frames */
2228 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2229 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002230 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002231
2232 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Mihir Shete5affadc2015-05-29 20:54:57 +05302233 if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType)
2234 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002235
2236 /* Test next contorl block
2237 * if valid, this control block also has new RX frame must be handled */
2238 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2239 currentDesc = currentCtrlBlk->linkedDesc;
2240 descCtrl = currentDesc->descCtrl.ctrl;
2241 }
2242
2243 /* Update head control block
2244 * current control block's valid bit was 0
2245 * next trial first control block must be current control block */
2246 channelEntry->headCtrlBlk = currentCtrlBlk;
2247
2248 /* Deliver all the reaped RX frames to upper layers */
2249 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002250 while(i < frameCount)
2251 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002252 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2253 i++;
2254 }
2255
2256 return frameCount;
2257}
2258
2259/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 @ Function Name
2261 dxeRXFrameReady
2262
2263 @ Description
2264 Pop frame from descriptor and route frame to upper transport layer
2265 Assign new platform packet buffer into used descriptor
2266 Actual frame pop and resource realloc
2267
2268 @ Parameters
2269 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2270 DXE host driver main control block
2271 WLANDXE_ChannelCBType *channelEntry
2272 Channel specific control block
2273
2274 @ Return
2275 wpt_status
2276
2277===========================================================================*/
2278static wpt_status dxeRXFrameReady
2279(
2280 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002281 WLANDXE_ChannelCBType *channelEntry,
2282 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002283)
2284{
2285 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2286 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2287 WLANDXE_DescType *currentDesc = NULL;
2288 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002289 wpt_int32 frameCount = 0;
2290
2291 wpt_uint32 descLoop;
2292 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002293
2294 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002295 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002296
2297 /* Sanity Check */
2298 if((NULL == dxeCtxt) || (NULL == channelEntry))
2299 {
2300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2301 "dxeRXFrameReady Channel Entry is not valid");
2302 return eWLAN_PAL_STATUS_E_INVAL;
2303 }
2304
Jeff Johnsone7245742012-09-05 17:12:55 -07002305 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002306
Jeff Johnsone7245742012-09-05 17:12:55 -07002307 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002308 {
2309 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002310 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002311 return eWLAN_PAL_STATUS_E_INVAL;
2312 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002313
Leo Changd6de1c22013-03-21 15:42:41 -07002314 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002315 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2316 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2317 {
Leo Changd6de1c22013-03-21 15:42:41 -07002318 /* None of the frame handled and CH is not enabled
2319 * RX CH wrap around happen and No RX free frame
2320 * RX side should wait till new free frame available in the pool
2321 * Do not try reload driver at here*/
2322 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2323 {
Leo Changbbf86b72013-06-19 16:13:00 -07002324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002325 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2326 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002327 /* This is not empty interrupt case
2328 * If handle this as empty interrupt, false SSR might be issued
2329 * Frame count '1' is dummy frame count to avoid SSR */
2330 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002331 return eWLAN_PAL_STATUS_SUCCESS;
2332 }
2333
Jeff Johnsone7245742012-09-05 17:12:55 -07002334 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002335 currentDesc = currentCtrlBlk->linkedDesc;
2336 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002337
2338 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2339 {
2340 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2341 "RX ISR called but no frame handled PWS %d, channel %s",
2342 (int)dxeCtxt->hostPowerState,
2343 channelType[channelEntry->channelType]);
2344 }
2345
2346 /* Current interupt empty and previous interrupt also empty
2347 * detected successive empty interrupt
2348 * or first interrupt empty, this should not happen */
2349 if(0 == channelEntry->numFragmentCurrentChain)
2350 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002351 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2352 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2353 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2354 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002355 /* Abnormal interrupt detected, try to find not validated descriptor */
2356 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2357 {
2358 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
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 "Found Invalidated Descriptor %d", (int)descLoop);
2362 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2363 {
Leo Chang416afe02013-07-01 13:58:13 -07002364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002365 "Packet locked, Resync Host and HW");
2366 channelEntry->headCtrlBlk = currentCtrlBlk;
2367 invalidatedFound = 1;
2368 break;
2369 }
2370 else
2371 {
Leo Chang416afe02013-07-01 13:58:13 -07002372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002373 "Packet Not Locked, cannot transfer frame");
2374 }
2375 }
2376 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2377 currentDesc = currentCtrlBlk->linkedDesc;
2378 descCtrl = currentDesc->descCtrl.ctrl;
2379 }
2380
Jeff Johnson32d95a32012-09-10 13:15:23 -07002381 /* Invalidated descriptor found, and that is not head descriptor
2382 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2383 * Try re-sync here */
2384 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002385 {
2386 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2387 "Found New Sync location with HW, handle frames from there");
2388 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2389 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2390 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002391 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002392 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002393 /* Successive Empty interrupt
2394 * But this case, first descriptor also invalidated, then it means head descriptor
2395 * is linked with already handled RX frame, then could not unlock RX frame
2396 * This is just Out of RX buffer pool, not need to anything here */
2397 else if((invalidatedFound) && (0 == descLoop))
2398 {
2399 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2400 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2401 }
2402 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002403 else
2404 {
2405 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2406 "Could not found invalidated descriptor");
2407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2408 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2409 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2410 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302411 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002412 }
2413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002415 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002417 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002418 return status;
2419}
2420
2421/*==========================================================================
2422 @ Function Name
2423 dxeNotifySmsm
2424
2425 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2426 buffer
2427
2428 @ Parameters
2429
2430 @ Return
2431 wpt_status
2432
2433===========================================================================*/
2434static wpt_status dxeNotifySmsm
2435(
2436 wpt_boolean kickDxe,
2437 wpt_boolean ringEmpty
2438)
2439{
2440 wpt_uint32 clrSt = 0;
2441 wpt_uint32 setSt = 0;
2442
2443 if(kickDxe)
2444 {
2445 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2446
2447 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2448 {
2449 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2450 tempDxeCtrlBlk->lastKickOffDxe = 1;
2451 }
2452 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2453 {
2454 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2455 tempDxeCtrlBlk->lastKickOffDxe = 0;
2456 }
2457 else
2458 {
2459 HDXE_ASSERT(0);
2460 }
2461 }
2462 else
2463 {
2464 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2465 }
2466
Mihir Shete68ed77a2014-10-10 10:47:12 +05302467 tempDxeCtrlBlk->txRingsEmpty = ringEmpty;
Jeff Johnson295189b2012-06-20 16:38:30 -07002468 if(ringEmpty)
2469 {
2470 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2471 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2472 }
2473 else
2474 {
2475 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2476 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2477 }
2478
2479 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2480
Karthick Sc6ec8362015-08-12 18:18:47 +05302481 /* Store the smsm notification sent to firmware */
2482 tempDxeCtrlBlk->smsmDxeHistogram = (tempDxeCtrlBlk->smsmDxeHistogram << 1);
2483 if(setSt & WPAL_SMSM_WLAN_TX_ENABLE)
2484 {
2485 tempDxeCtrlBlk->smsmDxeHistogram |= 1;
2486 }
2487 else
2488 {
2489 tempDxeCtrlBlk->smsmDxeHistogram &= ~((wpt_uint32)1);
2490 }
2491 tempDxeCtrlBlk->smsmRingsEmptyHistogram = (tempDxeCtrlBlk->smsmRingsEmptyHistogram << 1);
2492 if(setSt & WPAL_SMSM_WLAN_TX_RINGS_EMPTY)
2493 {
2494 tempDxeCtrlBlk->smsmRingsEmptyHistogram |= 1;
2495 }
2496 else
2497 {
2498 tempDxeCtrlBlk->smsmRingsEmptyHistogram &= ~((wpt_uint32)1);
2499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002500 wpalNotifySmsm(clrSt, setSt);
2501
2502 return eWLAN_PAL_STATUS_SUCCESS;
2503}
2504
2505/*==========================================================================
2506 @ Function Name
2507 dxePsComplete
2508
2509 @ Description: Utility function to check the resv desc to deside if we can
2510 get into Power Save mode now
2511
2512 @ Parameters
2513
2514 @ Return
2515 None
2516
2517===========================================================================*/
2518static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2519{
2520 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2521 {
2522 return;
2523 }
2524
2525 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2526 //must have been consumed by RIVA, OK to get into BMPS
2527 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2528 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2529 {
2530 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2531 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2532 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2533 {
2534 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2535 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2536 }
2537 }
2538 else //still more pkts to be served by RIVA
2539 {
2540 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2541
2542 switch(dxeCtxt->rivaPowerState)
2543 {
2544 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2545 //NOP
2546 break;
2547 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2548 if(intr_based)
2549 {
2550 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2551 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2552 }
2553 break;
2554 default:
2555 //assert
2556 break;
2557 }
2558 }
2559}
2560
2561/*==========================================================================
2562 @ Function Name
2563 dxeRXEventHandler
2564
2565 @ Description
2566 Handle serailized RX frame ready event
2567 First disable interrupt then pick up frame from pre allocated buffer
2568 Since frame handle is doen, clear interrupt bit to ready next interrupt
2569 Finally re enable interrupt
2570
2571 @ Parameters
2572 wpt_msg *rxReadyMsg
2573 RX frame ready MSG pointer
2574 include DXE control context
2575
2576 @ Return
2577 NONE
2578
2579===========================================================================*/
2580void dxeRXEventHandler
2581(
2582 wpt_msg *rxReadyMsg
2583)
2584{
2585 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2586 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2587 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2588 wpt_uint32 intSrc = 0;
2589 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002590 wpt_uint32 chHighStat = 0;
2591 wpt_uint32 chLowStat = 0;
Mihir Shetee6618162015-03-16 14:48:42 +05302592 wpt_uint32 chLogRxStat = 0;
Mihir Shetec4093f92015-05-28 15:21:11 +05302593 wpt_uint32 chLogRxFwStat = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302594 wpt_uint32 regValue, chanMask;
Jeff Johnson295189b2012-06-20 16:38:30 -07002595
Jeff Johnsone7245742012-09-05 17:12:55 -07002596 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002597
Jeff Johnsone7245742012-09-05 17:12:55 -07002598 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002599 {
2600 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002601 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002602 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 }
2604
Jeff Johnsone7245742012-09-05 17:12:55 -07002605 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2606 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2607 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
Mihir Shetee6618162015-03-16 14:48:42 +05302608 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2609 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002610
2611 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
Mihir Shetee6618162015-03-16 14:48:42 +05302612 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled) ||
2613 (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) &&
2614 !dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chEnabled))
Jeff Johnson295189b2012-06-20 16:38:30 -07002615 {
2616 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2617 "DXE already stopped in RX event handler. Just return");
2618 return;
2619 }
2620
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302621 /* Disable device interrupt */
2622 /* Read whole interrupt mask register and exclusive only this channel int */
2623 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2624 &intSrc);
2625 if(eWLAN_PAL_STATUS_SUCCESS != status)
2626 {
2627 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2628 "dxeRXEventHandler Read INT_SRC register fail");
2629 return;
2630 }
2631 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2632 "RX Event Handler INT Source 0x%x", intSrc);
2633
2634 dxeEnvBlk.rxIntChanlSrc = intSrc&0xFF;
2635
Jeff Johnson295189b2012-06-20 16:38:30 -07002636 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2637 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2638 {
Mihir Shetec4093f92015-05-28 15:21:11 +05302639 if (WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
2640 {
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302641 if(0 == intSrc)
Mihir Shetec4093f92015-05-28 15:21:11 +05302642 {
2643 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2644 "%s: Read status: %d, regVal: %d",
2645 __func__, status, intSrc);
2646 }
2647 else
2648 {
2649 /* Register Read was succesful and we have a valid interrupt
2650 * source, so WCN is not power collapsed yet and it should
2651 * not power collapse till we set the synchronization bit
2652 * at the end of this function, safe to pull frames...
2653 */
2654 goto pull_frames;
2655 }
2656 }
2657
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2659 "%s Riva is in %d, Just Pull frames without any register touch ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002660 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002661
2662 /* Not to touch any register, just pull frame directly from chain ring
2663 * First high priority */
2664 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2665 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002666 channelCb,
2667 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 if(eWLAN_PAL_STATUS_SUCCESS != status)
2669 {
2670 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2671 "dxeRXEventHandler Pull from RX high channel fail");
2672 }
Leo Chang46f36162014-01-14 21:47:24 -08002673 /* In case FW could not power collapse in IMPS mode
2674 * Next power restore might have empty interrupt
2675 * If IMPS mode has empty interrupt since RX thread race,
2676 * Invalid re-load driver might happen
2677 * To prevent invalid re-load driver,
2678 * IMPS event handler set dummpy frame count */
2679 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002680
2681 /* Second low priority */
2682 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2683 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002684 channelCb,
2685 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002686 if(eWLAN_PAL_STATUS_SUCCESS != status)
2687 {
2688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Mihir Shetee6618162015-03-16 14:48:42 +05302689 "dxeRXEventHandler Pull from RX low channel fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002690 }
Leo Chang46f36162014-01-14 21:47:24 -08002691 /* LOW Priority CH same above */
2692 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002693
Mihir Shetee6618162015-03-16 14:48:42 +05302694 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2695 {
2696 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2697 status = dxeRXFrameReady(dxeCtxt,
2698 channelCb,
2699 chLogRxStat);
2700 if(eWLAN_PAL_STATUS_SUCCESS != status)
2701 {
2702 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2703 "dxeRXEventHandler Pull from RX log channel fail");
2704 }
2705 channelCb->numFragmentCurrentChain = 1;
2706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002707 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2708 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302709 dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002710
2711 return;
2712 }
2713
Mihir Shetec4093f92015-05-28 15:21:11 +05302714pull_frames:
Jeff Johnson295189b2012-06-20 16:38:30 -07002715 /* Test High Priority Channel interrupt is enabled or not */
2716 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2717 if(intSrc & (1 << channelCb->assignedDMAChannel))
2718 {
2719 status = dxeChannelCleanInt(channelCb, &chHighStat);
2720 if(eWLAN_PAL_STATUS_SUCCESS != status)
2721 {
2722 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2723 "dxeRXEventHandler INT Clean up fail");
2724 return;
2725 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002726 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2727 {
2728 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002729 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2730 "%11s : 0x%x Error Reported, Reload Driver",
2731 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302732
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302733 if (eWLAN_PAL_STATUS_SUCCESS != dxeErrHandler(channelCb, chHighStat))
2734 {
2735 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2736 wpalWlanReload();
2737 dxeStartSSRTimer(dxeCtxt);
2738 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002739 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002740 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2741 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002742 {
2743 /* Handle RX Ready for high priority channel */
2744 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002745 channelCb,
2746 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002747 }
2748 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2749 {
2750 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002751 channelCb,
2752 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 }
2754 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2755 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002756 /* Update the Rx DONE histogram */
2757 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2758 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2759 {
2760 channelCb->rxDoneHistogram |= 1;
2761 }
2762 else
2763 {
jagadeeshf869bba2015-04-07 20:06:21 +05302764 channelCb->rxDoneHistogram &= ~((wpt_uint64)1);
Jeff Johnsone7245742012-09-05 17:12:55 -07002765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002766 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002767
2768 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002769 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002770 if(intSrc & (1 << channelCb->assignedDMAChannel))
2771 {
2772 status = dxeChannelCleanInt(channelCb, &chLowStat);
2773 if(eWLAN_PAL_STATUS_SUCCESS != status)
2774 {
2775 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2776 "dxeRXEventHandler INT Clean up fail");
2777 return;
2778 }
2779
2780 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2781 {
2782 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002783 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2784 "%11s : 0x%x Error Reported, Reload Driver",
2785 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302786
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302787 if (eWLAN_PAL_STATUS_SUCCESS !=
2788 dxeErrHandler(channelCb, chLowStat))
2789 {
2790 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2791 wpalWlanReload();
2792 dxeStartSSRTimer(dxeCtxt);
2793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002794 }
Mihir Shetef2000552014-05-12 16:21:34 +05302795 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) ||
2796 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 {
2798 /* Handle RX Ready for low priority channel */
2799 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002800 channelCb,
2801 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07002802 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002803
2804 /* Update the Rx DONE histogram */
2805 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2806 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2807 {
2808 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002809 }
2810 else
2811 {
jagadeeshf869bba2015-04-07 20:06:21 +05302812 channelCb->rxDoneHistogram &= ~((wpt_uint64)1);
Jeff Johnson295189b2012-06-20 16:38:30 -07002813 }
2814 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2815 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2816 }
Mihir Shetee6618162015-03-16 14:48:42 +05302817
2818 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2819 {
2820 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2821
2822 if(intSrc & (1 << channelCb->assignedDMAChannel))
2823 {
2824 status = dxeChannelCleanInt(channelCb,&chLogRxStat);
2825 if(eWLAN_PAL_STATUS_SUCCESS != status)
2826 {
2827 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2828 "dxeRXEventHandler INT Clean up fail");
2829 return;
2830 }
2831
2832 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxStat)
2833 {
2834 /* Error Happen during transaction, Handle it */
2835 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2836 "%11s : 0x%x Error Reported, Reload Driver",
2837 channelType[channelCb->channelType], chLogRxStat);
2838
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302839 if (eWLAN_PAL_STATUS_SUCCESS !=
2840 dxeErrHandler(channelCb, chLogRxStat))
2841 {
2842 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2843 wpalWlanReload();
2844 dxeStartSSRTimer(dxeCtxt);
2845 }
Mihir Shetee6618162015-03-16 14:48:42 +05302846
Mihir Shetee6618162015-03-16 14:48:42 +05302847 }
2848 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxStat) ||
2849 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2850 {
2851 /* Handle RX Ready for low priority channel */
2852 status = dxeRXFrameReady(dxeCtxt,
2853 channelCb,
2854 chLogRxStat);
2855 }
2856
2857 /* Update the Rx DONE histogram */
2858 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2859 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)
2860 {
2861 channelCb->rxDoneHistogram |= 1;
2862 }
2863 else
2864 {
2865 channelCb->rxDoneHistogram &= ~1;
2866 }
2867 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2868 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxStat, channelCb->numFragmentCurrentChain);
2869 }
2870 }
2871
Mihir Shetec4093f92015-05-28 15:21:11 +05302872 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_FW_LOG))
2873 {
2874 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
2875
2876 if(intSrc & (1 << channelCb->assignedDMAChannel))
2877 {
2878 status = dxeChannelCleanInt(channelCb,&chLogRxFwStat);
2879 if(eWLAN_PAL_STATUS_SUCCESS != status)
2880 {
2881 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2882 "dxeRXEventHandler INT Clean up fail");
2883 return;
2884 }
2885
2886 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxFwStat)
2887 {
2888 /* Error Happen during transaction, Handle it */
2889 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2890 "%11s : 0x%x Error Reported, Reload Driver",
2891 channelType[channelCb->channelType], chLogRxFwStat);
2892
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302893 if (eWLAN_PAL_STATUS_SUCCESS !=
2894 dxeErrHandler(channelCb, chLogRxFwStat))
2895 {
2896 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2897 wpalWlanReload();
2898 dxeStartSSRTimer(dxeCtxt);
2899 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302900
Mihir Shetec4093f92015-05-28 15:21:11 +05302901 }
2902 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxFwStat) ||
2903 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat))
2904 {
2905 if (!dxeCtxt->hostInitiatedH2H)
2906 {
2907 dxeCtxt->receiveMbMsgCB(dxeCtxt->clientCtxt);
2908 }
2909 else
2910 {
2911 status = dxeRXFrameReady(dxeCtxt,
2912 channelCb,
2913 chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302914 if (channelCb->numFreeDesc == channelCb->numDesc)
2915 {
Mihir Shete0b090bf2015-06-09 14:00:44 +05302916 /*
2917 * We have already cleared the interrupts before coming here,
2918 * but it can happen that DXE will copy some new packets after
2919 * that and raise interrupts for those. The packets will be
2920 * processed above but the interrupts will still be pending.
2921 * Its safe to clear those interrupts here because we have
2922 * pulled data from all the allocated descriptors.
2923 */
2924 dxeChannelCleanInt(channelCb,&chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302925 dxeCtxt->hostInitiatedH2H = 0;
2926 dxeCtxt->receiveLogCompleteCB(dxeCtxt->clientCtxt);
2927 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302928 }
2929 }
2930
2931 /* Update the Rx DONE histogram */
2932 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2933 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat)
2934 {
2935 channelCb->rxDoneHistogram |= 1;
2936 }
2937 else
2938 {
2939 channelCb->rxDoneHistogram &= ~1;
2940 }
2941 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2942 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxFwStat, channelCb->numFragmentCurrentChain);
2943 }
2944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002945 if(eWLAN_PAL_STATUS_SUCCESS != status)
2946 {
2947 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2948 "dxeRXEventHandler Handle Frame Ready Fail");
2949 return;
2950 }
2951
Jeff Johnson295189b2012-06-20 16:38:30 -07002952 /* Prepare Control Register EN Channel */
2953 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2954 {
2955 HDXE_ASSERT(0);
2956 }
Mihir Shetef2000552014-05-12 16:21:34 +05302957
2958 if (dxeCtxt->rxPalPacketUnavailable &&
2959 (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat))
2960 {
2961 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask &
2962 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302963 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302964 }
2965 else
2966 {
2967 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302968 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302969 }
Leo Chang094ece82013-04-23 17:57:41 -07002970 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302971 chanMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002972
2973 /* Prepare Control Register EN Channel */
2974 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2975 {
2976 HDXE_ASSERT(0);
2977 }
Leo Chang094ece82013-04-23 17:57:41 -07002978
Mihir Shetef2000552014-05-12 16:21:34 +05302979 if (dxeCtxt->rxPalPacketUnavailable &&
2980 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
2981 {
2982 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask &
2983 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302984 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302985 }
2986 else
2987 {
2988 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302989 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302990 }
Leo Chang094ece82013-04-23 17:57:41 -07002991 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302992 chanMask);
2993
Mihir Shetec01157f2015-06-18 14:13:34 +05302994 /* We do not have knowledge of firmare capabilities when the
2995 * RX_LOG channel is enabled. But when we get the first interrupt
2996 * we have all the required information. So if MGMT Logging is not
2997 * supported by the firmware, do not re-enable RX_LOG channel
2998 */
2999 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) && wpalIsFwLoggingSupported())
Mihir Shetee6618162015-03-16 14:48:42 +05303000 {
3001 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
3002 {
3003 HDXE_ASSERT(0);
3004 }
3005
3006 if (dxeCtxt->rxPalPacketUnavailable &&
3007 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
3008 {
3009 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask &
3010 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
3011 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 1;
3012 }
3013 else
3014 {
3015 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask;
3016 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 0;
3017 }
3018 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].channelRegister.chDXECtrlRegAddr,
3019 chanMask);
3020 }
Leo Chang094ece82013-04-23 17:57:41 -07003021
3022 /* Clear Interrupt handle processing bit
3023 * RIVA may power down */
Mihir Shete0670b402015-05-13 17:51:41 +05303024 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303025 {
3026 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3027 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
3028 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3029 }
3030 else
3031 {
Karthick S09d5dd02015-05-27 16:58:32 +05303032 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3033 regValue &= (~WLAN_PMU_POWER_DOWN_MASK);
3034 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303035 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003036
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303037 dxeEnvBlk.rxIntChanlSrc = 0;
3038
Leo Chang416afe02013-07-01 13:58:13 -07003039 /* Enable system level ISR */
3040 /* Enable RX ready Interrupt at here */
3041 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
3042 if(eWLAN_PAL_STATUS_SUCCESS != status)
3043 {
3044 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3045 "dxeRXEventHandler Enable RX Ready interrupt fail");
3046 return;
3047 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303048 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_RXINT_STATE,
3049 TRACE_WLANDXE_VAR_ENABLE));
Jeff Johnson295189b2012-06-20 16:38:30 -07003050 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003051 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003052 return;
3053}
3054
3055/*==========================================================================
3056 @ Function Name
3057 dxeRXPacketAvailableEventHandler
3058
3059 @ Description
3060 Handle serialized RX Packet Available event when the corresponding callback
3061 is invoked by WPAL.
3062 Try to fill up any completed DXE descriptors with available Rx packet buffer
3063 pointers.
3064
3065 @ Parameters
3066 wpt_msg *rxPktAvailMsg
3067 RX frame ready MSG pointer
3068 include DXE control context
3069
3070 @ Return
3071 NONE
3072
3073===========================================================================*/
3074void dxeRXPacketAvailableEventHandler
3075(
3076 wpt_msg *rxPktAvailMsg
3077)
3078{
3079 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3080 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3081 WLANDXE_ChannelCBType *channelCb = NULL;
3082
3083 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003084 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003085
3086 /* Sanity Check */
3087 if(NULL == rxPktAvailMsg)
3088 {
3089 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3090 "dxeRXPacketAvailableEventHandler Context is not valid");
3091 return;
3092 }
3093
3094 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05303095
3096#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07003097 /* Available resource allocated
3098 * Stop timer not needed */
3099 if(VOS_TIMER_STATE_RUNNING ==
3100 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
3101 {
3102 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
3103 }
Mihir Shete44547fb2014-03-10 14:15:42 +05303104#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003105
3106 do
3107 {
3108 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3109 "dxeRXPacketAvailableEventHandler, start refilling ring");
3110
3111 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
3112 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3113
3114 // Wait for another callback to indicate when Rx resources are available
3115 // again.
3116 if(eWLAN_PAL_STATUS_SUCCESS != status)
3117 {
3118 break;
3119 }
3120
3121 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
3122 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3123 if(eWLAN_PAL_STATUS_SUCCESS != status)
3124 {
3125 break;
3126 }
Mihir Shetee6618162015-03-16 14:48:42 +05303127
3128 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
3129 {
3130 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
3131 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3132 if(eWLAN_PAL_STATUS_SUCCESS != status)
3133 {
3134 break;
3135 }
3136 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003137 } while(0);
3138
3139 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
3140 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
3141 {
3142 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
3143 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303144 dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003145 }
3146}
3147
3148/*==========================================================================
3149 @ Function Name
3150 dxeRXISR
3151
3152 @ Description
3153 RX frame ready interrupt service routine
3154 interrupt entry function, this function called based on ISR context
3155 Must be serialized
3156
3157 @ Parameters
3158 void *hostCtxt
3159 DXE host driver control context,
3160 pre registerd during interrupt registration
3161
3162 @ Return
3163 NONE
3164
3165===========================================================================*/
3166static void dxeRXISR
3167(
3168 void *hostCtxt
3169)
3170{
3171 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3172 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003173 wpt_uint32 regValue;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303174 wpt_uint32 intSrc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003175
Leo Chang094ece82013-04-23 17:57:41 -07003176 /* Set Interrupt processing bit
3177 * During this bit set, WLAN HW may not power collapse */
Mihir Shete0670b402015-05-13 17:51:41 +05303178 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303179 {
3180 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3181 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
3182 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3183 }
3184 else
3185 {
Karthick S09d5dd02015-05-27 16:58:32 +05303186 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3187 regValue |= WLAN_PMU_POWER_DOWN_MASK;
3188 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303189 }
Leo Chang094ece82013-04-23 17:57:41 -07003190
Jeff Johnson295189b2012-06-20 16:38:30 -07003191 /* Disable interrupt at here
3192 * Disable RX Ready system level Interrupt at here
3193 * Otherwise infinite loop might happen */
3194 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
3195 if(eWLAN_PAL_STATUS_SUCCESS != status)
3196 {
3197 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3198 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3199 return;
3200 }
3201
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303202 wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3203 &intSrc);
3204 /* Note: intSrc which holds the INT_SRC_RAW_ADDRESS reg value
3205 While debugging crash dump convert to power of 2 for channel type */
3206 DXTRACE(dxeTrace(intSrc, TRACE_RXINT_STATE, TRACE_WLANDXE_VAR_DISABLE));
3207
Jeff Johnson295189b2012-06-20 16:38:30 -07003208 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003209 if(NULL == dxeCtxt->rxIsrMsg)
3210 {
3211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3212 "dxeRXFrameReadyISR NULL message");
3213 HDXE_ASSERT(0);
3214 return;
3215 }
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
3218 dxeCtxt->rxIsrMsg);
3219 if(eWLAN_PAL_STATUS_SUCCESS != status)
3220 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3222 "dxeRXFrameReadyISR interrupt serialize fail");
3223 }
3224
Jeff Johnson295189b2012-06-20 16:38:30 -07003225 return;
3226}
3227
3228/*==========================================================================
3229 @ Function Name
3230 dxeTXPushFrame
3231
3232 @ Description
3233 Push TX frame into DXE descriptor and DXE register
3234 Send notification to DXE register that TX frame is ready to transfer
3235
3236 @ Parameters
3237 WLANDXE_ChannelCBType *channelEntry
3238 Channel specific control block
3239 wpt_packet *palPacket
3240 Packet pointer ready to transfer
3241
3242 @ Return
3243 PAL_STATUS_T
3244===========================================================================*/
3245static wpt_status dxeTXPushFrame
3246(
3247 WLANDXE_ChannelCBType *channelEntry,
3248 wpt_packet *palPacket
3249)
3250{
3251 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3252 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3253 WLANDXE_DescType *currentDesc = NULL;
3254 WLANDXE_DescType *firstDesc = NULL;
3255 WLANDXE_DescType *LastDesc = NULL;
3256 void *sourcePhysicalAddress = NULL;
3257 wpt_uint32 xferSize = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003258 wpt_iterator iterator;
Karthick S8a7e2862015-09-14 09:13:37 +05303259 wpt_uint32 KickDxe = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003260
3261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003262 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003263
Leo Changac1d3612013-07-01 15:15:51 -07003264 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3265 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3266 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003267 {
Karthick S8a7e2862015-09-14 09:13:37 +05303268 KickDxe = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003269 }
3270
Karthick S8a7e2862015-09-14 09:13:37 +05303271 /* Kick DXE when the ring is about to fill */
3272 if (WLANDXE_TX_LOW_RES_THRESHOLD >= channelEntry->numFreeDesc)
3273 KickDxe = 1;
3274
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 channelEntry->numFragmentCurrentChain = 0;
3276 currentCtrlBlk = channelEntry->headCtrlBlk;
3277
3278 /* Initialize interator, TX is fragmented */
Jeff Johnson295189b2012-06-20 16:38:30 -07003279 status = wpalLockPacketForTransfer(palPacket);
3280 if(eWLAN_PAL_STATUS_SUCCESS != status)
3281 {
3282 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3283 "dxeTXPushFrame unable to lock packet");
3284 return status;
3285 }
3286
3287 status = wpalIteratorInit(&iterator, palPacket);
Jeff Johnson295189b2012-06-20 16:38:30 -07003288 if(eWLAN_PAL_STATUS_SUCCESS != status)
3289 {
3290 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3291 "dxeTXPushFrame iterator init fail");
3292 return status;
3293 }
3294
3295 /* !!!! Revisit break condition !!!!!!! */
3296 while(1)
3297 {
3298 /* Get current descriptor pointer from current control block */
3299 currentDesc = currentCtrlBlk->linkedDesc;
3300 if(NULL == firstDesc)
3301 {
3302 firstDesc = currentCtrlBlk->linkedDesc;
3303 }
3304 /* All control block will have same palPacket Pointer
3305 * to make logic simpler */
3306 currentCtrlBlk->xfrFrame = palPacket;
3307
3308 /* Get next fragment physical address and fragment size
3309 * if this is the first trial, will get first physical address
3310 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
Jeff Johnson295189b2012-06-20 16:38:30 -07003311 status = wpalIteratorNext(&iterator,
3312 palPacket,
3313 &sourcePhysicalAddress,
3314 &xferSize);
jagadeeshf869bba2015-04-07 20:06:21 +05303315 if(eWLAN_PAL_STATUS_SUCCESS != status)
3316 {
3317 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3318 "dxeTXPushFrame Get next frame fail");
3319 return status;
3320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003321 if((NULL == sourcePhysicalAddress) ||
3322 (0 == xferSize))
3323 {
3324 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3325 "dxeTXPushFrame end of current frame");
3326 break;
3327 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003328
3329 /* This is the LAST descriptor valid for this transaction */
3330 LastDesc = currentCtrlBlk->linkedDesc;
3331
3332 /* Program DXE descriptor */
3333 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303334 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003335
3336 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3337 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3338 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3339 {
3340 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3341 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3342 }
3343 else
3344 {
3345 /* Test specific H2H transfer, destination address already set
3346 * Do Nothing */
3347 }
3348 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3349
3350 /* Program channel control register */
3351 /* First frame not set VAL bit, why ??? */
3352 if(0 == channelEntry->numFragmentCurrentChain)
3353 {
3354 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3355 }
3356 else
3357 {
3358 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3359 }
3360
3361 /* Update statistics */
3362 channelEntry->numFragmentCurrentChain++;
3363 channelEntry->numFreeDesc--;
3364 channelEntry->numRsvdDesc++;
3365
3366 /* Get next control block */
3367 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3368 }
3369 channelEntry->numTotalFrame++;
3370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3371 "NUM TX FRAG %d, Total Frame %d",
3372 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3373
3374 /* Program Channel control register
3375 * Set as end of packet
3376 * Enable interrupt also for first code lock down
3377 * performace optimization, this will be revisited */
3378 if(NULL == LastDesc)
3379 {
3380 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3381 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3382 return eWLAN_PAL_STATUS_E_FAULT;
3383 }
3384 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3385 /* Now First one also Valid ????
3386 * this procedure will prevent over handle descriptor from previous
3387 * TX trigger */
3388 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3389
3390 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3391 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3392 {
3393 /* Update channel head as next avaliable linked slot */
3394 channelEntry->headCtrlBlk = currentCtrlBlk;
Karthick S8a7e2862015-09-14 09:13:37 +05303395 if(KickDxe)
Leo Changac1d3612013-07-01 15:15:51 -07003396 {
3397 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3398 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3399 "SMSM_ret LO=%d HI=%d",
3400 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3401 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
Karthick S39823072015-07-08 18:16:41 +05303402 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Leo Changac1d3612013-07-01 15:15:51 -07003403 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3404 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303405 DXTRACE(dxeTrace(channelEntry->channelType, TRACE_SMSM_NOTIFY, TRACE_WLANDXE_VAR_ENABLE));
Leo Changac1d3612013-07-01 15:15:51 -07003406 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003407 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 }
3409
3410 /* If DXE use external descriptor, registers are not needed to be programmed
3411 * Just after finish to program descriptor, tirigger to send */
3412 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3413 {
3414 /* Issue a dummy read from the DXE descriptor DDR location to
3415 ensure that any previously posted write to the descriptor
3416 completes. */
3417 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3418 {
3419 //HDXE_ASSERT(0);
3420 }
3421
3422 /* Everything is ready
3423 * Trigger to start DMA */
3424 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3425 channelEntry->extraConfig.chan_mask);
3426 if(eWLAN_PAL_STATUS_SUCCESS != status)
3427 {
3428 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3429 "dxeTXPushFrame Write Channel Ctrl Register fail");
3430 return status;
3431 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303432 DXTRACE(dxeTrace(channelEntry->channelType, TRACE_CH_ENABLE, TRACE_WLANDXE_VAR_ENABLE));
Jeff Johnson295189b2012-06-20 16:38:30 -07003433
3434 /* Update channel head as next avaliable linked slot */
3435 channelEntry->headCtrlBlk = currentCtrlBlk;
3436
3437 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003438 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003439 return status;
3440 }
3441
3442 /* If DXE not use external descriptor, program each registers */
3443 /* Circular buffer handle not need to program DESC register???
3444 * GEN5 code not programed RING buffer case
3445 * REVISIT THIS !!!!!! */
3446 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3447 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3448 {
3449 /* Destination address, assigned Work Q */
3450 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3451 channelEntry->channelConfig.refWQ);
3452 if(eWLAN_PAL_STATUS_SUCCESS != status)
3453 {
3454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3455 "dxeTXPushFrame Program dest address register fail");
3456 return status;
3457 }
3458 /* If descriptor format is SHORT */
3459 if(channelEntry->channelConfig.useShortDescFmt)
3460 {
3461 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3462 0);
3463 if(eWLAN_PAL_STATUS_SUCCESS != status)
3464 {
3465 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3466 "dxeTXPushFrame Program dest address register fail");
3467 return status;
3468 }
3469 }
3470 else
3471 {
3472 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3473 "dxeTXPushFrame LONG Descriptor Format!!!");
3474 }
3475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003476
3477 /* Program Source address register
3478 * This address is already programmed into DXE Descriptor
3479 * But register also upadte */
3480 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3481 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3482 if(eWLAN_PAL_STATUS_SUCCESS != status)
3483 {
3484 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3485 "dxeTXPushFrame Program src address register fail");
3486 return status;
3487 }
3488 /* If descriptor format is SHORT */
3489 if(channelEntry->channelConfig.useShortDescFmt)
3490 {
3491 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3492 0);
3493 if(eWLAN_PAL_STATUS_SUCCESS != status)
3494 {
3495 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3496 "dxeTXPushFrame Program dest address register fail");
3497 return status;
3498 }
3499 }
3500 else
3501 {
3502 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3503 "dxeTXPushFrame LONG Descriptor Format!!!");
3504 }
3505
3506 /* Linked list Descriptor pointer */
3507 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3508 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3509 if(eWLAN_PAL_STATUS_SUCCESS != status)
3510 {
3511 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3512 "dxeTXPushFrame Write DESC Address register fail");
3513 return status;
3514 }
3515 /* If descriptor format is SHORT */
3516 if(channelEntry->channelConfig.useShortDescFmt)
3517 {
3518 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3519 0);
3520 if(eWLAN_PAL_STATUS_SUCCESS != status)
3521 {
3522 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3523 "dxeTXPushFrame Program dest address register fail");
3524 return status;
3525 }
3526 }
3527 else
3528 {
3529 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3530 "dxeTXPushFrame LONG Descriptor Format!!!");
3531 }
3532
3533 /* Transfer Size */
3534 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3535 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3536 xferSize);
3537 if(eWLAN_PAL_STATUS_SUCCESS != status)
3538 {
3539 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3540 "dxeTXPushFrame Write DESC Address register fail");
3541 return status;
3542 }
3543
3544 /* Everything is ready
3545 * Trigger to start DMA */
3546 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3547 channelEntry->extraConfig.chan_mask);
3548 if(eWLAN_PAL_STATUS_SUCCESS != status)
3549 {
3550 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3551 "dxeTXPushFrame Write Channel Ctrl Register fail");
3552 return status;
3553 }
3554
3555 /* Update channel head as next avaliable linked slot */
3556 channelEntry->headCtrlBlk = currentCtrlBlk;
3557
3558 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003559 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003560 return status;
3561}
3562
3563/*==========================================================================
3564 @ Function Name
3565 dxeTXCompFrame
3566
3567 @ Description
3568 TX Frame transfer complete event handler
3569
3570 @ Parameters
3571 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3572 DXE host driver main control block
3573 WLANDXE_ChannelCBType *channelEntry
3574 Channel specific control block
3575
3576 @ Return
3577 PAL_STATUS_T
3578===========================================================================*/
3579static wpt_status dxeTXCompFrame
3580(
3581 WLANDXE_CtrlBlkType *hostCtxt,
3582 WLANDXE_ChannelCBType *channelEntry
3583)
3584{
3585 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3586 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3587 WLANDXE_DescType *currentDesc = NULL;
3588 wpt_uint32 descCtrlValue = 0;
3589 unsigned int *lowThreshold = NULL;
3590
3591 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003592 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003593
3594 /* Sanity */
3595 if((NULL == hostCtxt) || (NULL == channelEntry))
3596 {
3597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3598 "dxeTXCompFrame Invalid ARG");
3599 return eWLAN_PAL_STATUS_E_INVAL;
3600 }
3601
3602 if(NULL == hostCtxt->txCompCB)
3603 {
3604 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3605 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003606 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003607 }
3608
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003609 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3610 if(eWLAN_PAL_STATUS_SUCCESS != status)
3611 {
3612 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3613 "dxeTXCompFrame Mutex Acquire fail");
3614 return status;
3615 }
3616
Jeff Johnson295189b2012-06-20 16:38:30 -07003617 currentCtrlBlk = channelEntry->tailCtrlBlk;
3618 currentDesc = currentCtrlBlk->linkedDesc;
3619
3620 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3621 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003622 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3623 if(eWLAN_PAL_STATUS_SUCCESS != status)
3624 {
3625 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3626 "dxeTXCompFrame Mutex Release fail");
3627 return status;
3628 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003629 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 }
3631
Kiet Lam842dad02014-02-18 18:44:02 -08003632
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 while(1)
3634 {
3635// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3636 descCtrlValue = currentDesc->descCtrl.ctrl;
3637 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3638 {
3639 /* caught up with head, bail out */
3640 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3641 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3642 break;
3643 }
3644
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003645 if(currentCtrlBlk->xfrFrame == NULL)
3646 {
3647 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3648 "Invalid transfer frame");
3649 HDXE_ASSERT(0);
3650 break;
3651 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003652 channelEntry->numFreeDesc++;
3653 channelEntry->numRsvdDesc--;
3654
3655 /* Send Frame TX Complete notification with frame start fragment location */
3656 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3657 {
3658 hostCtxt->txCompletedFrames--;
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3660 if (eWLAN_PAL_STATUS_SUCCESS != status)
3661 {
3662 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3663 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003664 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3665 if(eWLAN_PAL_STATUS_SUCCESS != status)
3666 {
3667 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3668 "dxeTXCompFrame Mutex Release fail");
3669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003670 return status;
3671 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3673 currentCtrlBlk->xfrFrame,
3674 eWLAN_PAL_STATUS_SUCCESS);
3675 channelEntry->numFragmentCurrentChain = 0;
3676 }
3677 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3678 currentDesc = currentCtrlBlk->linkedDesc;
3679
3680 /* Break condition
3681 * Head control block is the control block must be programed for the next TX
3682 * so, head control block is not programmed control block yet
3683 * if loop encounte head control block, stop to complete
3684 * in theory, COMP CB must be called already ??? */
3685 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3686 {
3687 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3688 "dxeTXCompFrame caught up with head ptr");
3689 break;
3690 }
3691 /* VALID Bit check ???? */
3692 }
3693
3694 /* Tail and Head Control block must be same */
3695 channelEntry->tailCtrlBlk = currentCtrlBlk;
3696
3697 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3698 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3699 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3700
3701 /* If specific channel hit low resource condition send notification to upper layer */
3702 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3703 (channelEntry->numFreeDesc > *lowThreshold))
3704 {
3705 /* Change it back if we raised it for fetching a remaining packet from TL */
3706 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3707 {
3708 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3709 }
3710
3711 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3712 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3713 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3714 channelEntry->channelType,
3715 eWLAN_PAL_TRUE);
3716 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3717 }
3718
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003719 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3720 if(eWLAN_PAL_STATUS_SUCCESS != status)
3721 {
3722 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3723 "dxeTXCompFrame Mutex Release fail");
3724 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003725
3726 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003727 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 return status;
3729}
3730
3731/*==========================================================================
Mihir Shetedfc33ec2014-10-15 13:14:38 +05303732 @ Function Name
3733 dxeTXCleanup
3734
3735 @ Description
3736 Cleanup the TX channels after DXE Error
3737
3738 @ Parameters
3739 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3740 DXE host driver main control block
3741
3742 @ Return
3743 PAL_STATUS_T
3744===========================================================================*/
3745static wpt_status dxeTXCleanup
3746(
3747 WLANDXE_CtrlBlkType *hostCtxt
3748)
3749{
3750 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3751 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3752 WLANDXE_DescType *currentDesc = NULL;
3753 wpt_uint32 descCtrlValue = 0;
3754 unsigned int *lowThreshold = NULL;
3755 unsigned int idx;
3756 WLANDXE_ChannelCBType *channelEntry;
3757
3758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3759 "%s Enter", __func__);
3760
3761 /* Sanity */
3762 if((NULL == hostCtxt))
3763 {
3764 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3765 "%s: Invalid ARG", __func__);
3766 return eWLAN_PAL_STATUS_E_INVAL;
3767 }
3768
3769 if(NULL == hostCtxt->txCompCB)
3770 {
3771 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3772 "%s: TXCompCB is not registered",__func__);
3773 return eWLAN_PAL_STATUS_SUCCESS;
3774 }
3775
3776 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3777 {
3778 channelEntry = &tempDxeCtrlBlk->dxeChannel[idx];
3779 if(idx != WDTS_CHANNEL_TX_LOW_PRI && idx != WDTS_CHANNEL_TX_HIGH_PRI)
3780 {
3781 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3782 "%s: %11s continue",__func__,
3783 channelType[channelEntry->channelType]);
3784 continue;
3785 }
3786
3787 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3788 if(eWLAN_PAL_STATUS_SUCCESS != status)
3789 {
3790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3791 "%s: %11s Mutex Acquire fail",__func__,
3792 channelType[channelEntry->channelType]);
3793 return status;
3794 }
3795
3796 currentCtrlBlk = channelEntry->tailCtrlBlk;
3797 currentDesc = currentCtrlBlk->linkedDesc;
3798
3799 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3800 {
3801 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3802 "%s: %11s Head and Tail are Same",__func__,
3803 channelType[channelEntry->channelType]);
3804
3805 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3806 if(eWLAN_PAL_STATUS_SUCCESS != status)
3807 {
3808 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3809 "%s: %11s Mutex Release fail",__func__,
3810 channelType[channelEntry->channelType]);
3811 return status;
3812 }
3813 continue;
3814 }
3815
3816 while(1)
3817 {
3818 descCtrlValue = currentDesc->descCtrl.ctrl;
3819 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3820 {
3821 /* invalidate... */
3822 currentDesc->descCtrl.ctrl &= ~WLANDXE_DESC_CTRL_VALID;
3823 }
3824
3825 if(currentCtrlBlk->xfrFrame == NULL)
3826 {
3827 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3828 "%s: %11s Invalid transfer frame",__func__,
3829 channelType[channelEntry->channelType]);
3830 HDXE_ASSERT(0);
3831 break;
3832 }
3833 channelEntry->numFreeDesc++;
3834 channelEntry->numRsvdDesc--;
3835
3836 /* Send Frame TX Complete notification with frame start fragment location */
3837 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3838 {
3839 hostCtxt->txCompletedFrames--;
3840 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3841 if (eWLAN_PAL_STATUS_SUCCESS != status)
3842 {
3843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3844 "%s: unable to unlock packet",__func__);
3845 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3846 if(eWLAN_PAL_STATUS_SUCCESS != status)
3847 {
3848 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3849 "%s: Mutex Release fail",__func__);
3850 }
3851 return status;
3852 }
3853 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3854 currentCtrlBlk->xfrFrame,
3855 eWLAN_PAL_STATUS_SUCCESS); //mir: SUCCESS or FAILURE?
3856 channelEntry->numFragmentCurrentChain = 0;
3857 }
3858 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3859 currentDesc = currentCtrlBlk->linkedDesc;
3860
3861 /* Break condition
3862 * Head control block is the control block must be programed for the next TX
3863 * so, head control block is not programmed control block yet
3864 * if loop encounte head control block, stop to complete
3865 * in theory, COMP CB must be called already ??? */
3866 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3867 {
3868 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3869 "%s: %11s caught up with head ptr",__func__,
3870 channelType[channelEntry->channelType]);
3871 break;
3872 }
3873 /* VALID Bit check ???? */
3874 }
3875
3876 /* Tail and Head Control block must be same */
3877 channelEntry->tailCtrlBlk = currentCtrlBlk;
3878 /* Re-Sync Head and CDR */
3879 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3880 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3881 if(eWLAN_PAL_STATUS_SUCCESS != status)
3882 {
3883 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3884 "dxeChannelInitProgram Write DESC Address register fail");
3885 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3886 if(eWLAN_PAL_STATUS_SUCCESS != status)
3887 {
3888 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3889 "%s: %11s Mutex Release fail", __func__,
3890 channelType[channelEntry->channelType]);
3891 }
3892 return status;
3893 }
3894
3895 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3896 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3897 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3898
3899 /* If specific channel hit low resource condition send notification to upper layer */
3900 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3901 (channelEntry->numFreeDesc > *lowThreshold))
3902 {
3903 /* Change it back if we raised it for fetching a remaining packet from TL */
3904 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3905 {
3906 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3907 }
3908
3909 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3910 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3911 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3912 channelEntry->channelType,
3913 eWLAN_PAL_TRUE);
3914 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3915 }
3916 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3917 if(eWLAN_PAL_STATUS_SUCCESS != status)
3918 {
3919 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3920 "%s: %11s Mutex Release fail", __func__,
3921 channelType[channelEntry->channelType]);
3922 }
3923 }
3924
3925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3926 "%s Exit", __func__);
3927 return status;
3928}
3929/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 @ Function Name
3931 dxeTXEventHandler
3932
3933 @ Description
3934 If DXE HW sends TX related interrupt, this event handler will be called
3935 Handle higher priority channel first
3936 Figureout why interrupt happen and call appropriate final even handler
3937 TX complete or error happen
3938
3939 @ Parameters
3940 void *msgPtr
3941 Even MSG
3942
3943 @ Return
3944 PAL_STATUS_T
3945===========================================================================*/
3946void dxeTXEventHandler
3947(
3948 wpt_msg *msgPtr
3949)
3950{
3951 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3952 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3953 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3954 wpt_uint32 intSrc = 0;
3955 wpt_uint32 chStat = 0;
3956 WLANDXE_ChannelCBType *channelCb = NULL;
3957
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003958 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003959 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003960
3961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003962 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003963
3964 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003965 dxeCtxt->ucTxMsgCnt = 0;
3966
3967 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3968 {
3969 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3970 "wlan: TX COMP WLAN Driver re-loading in progress");
3971 return;
3972 }
3973
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303974 /* Read whole interrupt mask register and exclusive only this channel int */
3975 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3976 &intSrc);
3977 if(eWLAN_PAL_STATUS_SUCCESS != status)
3978 {
3979 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3980 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
3981 return;
3982 }
3983 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3984 "TX Event Handler INT Source 0x%x", intSrc);
3985
3986 dxeEnvBlk.txCmpIntChanlSrc = intSrc&0xFF;
3987
Jeff Johnson295189b2012-06-20 16:38:30 -07003988 /* Return from here if the RIVA is in IMPS, to avoid register access */
3989 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
3990 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003991 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07003992 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003993 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07003994 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
3995 if(eWLAN_PAL_STATUS_SUCCESS != status)
3996 {
3997 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003998 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07003999 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004000
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004001 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
4002 if(eWLAN_PAL_STATUS_SUCCESS != status)
4003 {
4004 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4005 "dxeTXEventHandler IMPS LC COMP interrupt fail");
4006 }
4007
4008 if(((dxeCtxt->txCompletedFrames) &&
4009 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
4010 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07004011 {
4012 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4013 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4014 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004015 "TX COMP INT Enabled, remain TX frame count on ring %d",
4016 dxeCtxt->txCompletedFrames);
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05304017
4018 dxeEnvBlk.txCmpIntChanlSrc = 0;
4019
Jeff Johnsone7245742012-09-05 17:12:55 -07004020 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4021 the posibility of a race*/
4022 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4023 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004024 else
4025 {
4026 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4027 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4028 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
4029 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
4030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004031 return;
4032 }
4033
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004034 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004035 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
4036 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
4037 {
4038 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4039 "DXE already stopped in TX event handler. Just return");
4040 return;
4041 }
4042
Jeff Johnson295189b2012-06-20 16:38:30 -07004043 /* Test High Priority Channel is the INT source or not */
4044 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4045 if(intSrc & (1 << channelCb->assignedDMAChannel))
4046 {
4047 status = dxeChannelCleanInt(channelCb, &chStat);
4048 if(eWLAN_PAL_STATUS_SUCCESS != status)
4049 {
4050 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4051 "dxeTXEventHandler INT Clean up fail");
4052 return;
4053 }
4054
4055 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4056 {
4057 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004058 "%11s : 0x%x Error Reported, Reload Driver",
4059 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304060
Mihir Shetedfc33ec2014-10-15 13:14:38 +05304061 if (eWLAN_PAL_STATUS_SUCCESS !=
4062 dxeErrHandler(channelCb, chStat))
4063 {
4064 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4065 wpalWlanReload();
4066 dxeStartSSRTimer(dxeCtxt);
4067 }
4068 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 }
4070 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4071 {
4072 /* Handle TX complete for high priority channel */
4073 status = dxeTXCompFrame(dxeCtxt,
4074 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004075 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 }
4077 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4078 {
4079 /* Handle TX complete for high priority channel */
4080 status = dxeTXCompFrame(dxeCtxt,
4081 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004082 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004083 }
4084 else
4085 {
4086 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4087 "dxeTXEventHandler TX HI status=%x", chStat);
4088 }
4089
4090 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4091 {
4092 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4093 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
4094 }
4095
4096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4097 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4098 }
4099
4100 /* Test Low Priority Channel interrupt is enabled or not */
4101 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4102 if(intSrc & (1 << channelCb->assignedDMAChannel))
4103 {
4104 status = dxeChannelCleanInt(channelCb, &chStat);
4105 if(eWLAN_PAL_STATUS_SUCCESS != status)
4106 {
4107 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4108 "dxeTXEventHandler INT Clean up fail");
4109 return;
4110 }
4111
4112 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4113 {
4114 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004115 "%11s : 0x%x Error Reported, Reload Driver",
4116 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304117
Mihir Shetedfc33ec2014-10-15 13:14:38 +05304118 if (eWLAN_PAL_STATUS_SUCCESS !=
4119 dxeErrHandler(channelCb, chStat))
4120 {
4121 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4122 wpalWlanReload();
4123 dxeStartSSRTimer(dxeCtxt);
4124 }
4125 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004126 }
4127 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4128 {
4129 /* Handle TX complete for low priority channel */
4130 status = dxeTXCompFrame(dxeCtxt,
4131 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004132 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004133 }
4134 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4135 {
4136 /* Handle TX complete for low priority channel */
4137 status = dxeTXCompFrame(dxeCtxt,
4138 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004139 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 }
4141 else
4142 {
4143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4144 "dxeTXEventHandler TX LO status=%x", chStat);
4145 }
4146
4147 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4148 {
4149 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4150 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
4151 }
4152 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4153 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4154 }
4155
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
4157 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4158 {
4159 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4160 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004161 if(0 != dxeCtxt->txCompletedFrames)
4162 {
4163 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4164 "TX COMP INT Enabled, remain TX frame count on ring %d",
4165 dxeCtxt->txCompletedFrames);
4166 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 }
4168
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304169 if(eWLAN_PAL_TRUE == dxeCtxt->txIntEnable)
4170 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_TXINT_STATE,
4171 TRACE_WLANDXE_VAR_ENABLE));
4172
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05304173 dxeEnvBlk.txCmpIntChanlSrc = 0;
4174
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4176 the posibility of a race*/
4177 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4178
4179 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004180 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004181 return;
4182}
4183
4184
4185/*==========================================================================
4186 @ Function Name
4187 dxeTXCompleteProcessing
4188
4189 @ Description
4190 If DXE HW sends TX related interrupt, this event handler will be called
4191 Handle higher priority channel first
4192 Figureout why interrupt happen and call appropriate final even handler
4193 TX complete or error happen
4194
4195 @ Parameters
4196 dxeCtxt DXE context
4197
4198 @ Return
4199 PAL_STATUS_T
4200===========================================================================*/
4201void dxeTXCompleteProcessing
4202(
4203 WLANDXE_CtrlBlkType *dxeCtxt
4204)
4205{
4206 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4207 WLANDXE_ChannelCBType *channelCb = NULL;
4208
4209 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004210 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004211
4212 /* Test High Priority Channel is the INT source or not */
4213 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4214
4215 /* Handle TX complete for high priority channel */
4216 status = dxeTXCompFrame(dxeCtxt, channelCb);
4217
4218 /* Test Low Priority Channel interrupt is enabled or not */
4219 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4220
4221 /* Handle TX complete for low priority channel */
4222 status = dxeTXCompFrame(dxeCtxt, channelCb);
4223
4224 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
4225 ((dxeCtxt->txCompletedFrames > 0) ||
4226 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
4227 {
4228 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4229 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004231 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004232 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
4233 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
4234 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
4235 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07004236
4237 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
4238 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
4239 {
4240 /* After TX Comp processing, still remaining frame on the DXE TX ring
4241 * And when push frame, RING was not empty marked
4242 * Then when push frame, no SMSM toggle happen
4243 * To avoid permanent TX stall, SMSM toggle is needed at here
4244 * With this toggle, host should gaurantee SMSM state should be changed */
Karthick S39823072015-07-08 18:16:41 +05304245 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4246 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Changac1d3612013-07-01 15:15:51 -07004247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004248 }
4249
4250 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4251 the posibility of a race*/
4252 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
4253
4254 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004255 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004256 return;
4257}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004258
4259/*==========================================================================
4260 @ Function Name
4261 dxeTXReSyncDesc
4262
4263 @ Description
4264 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
4265 And HW programmed descriptor.
4266 If any async happen between HW/SW TX stall will happen
4267
4268 @ Parameters
4269 void *msgPtr
4270 Message pointer to sync with TX thread
4271
4272 @ Return
4273 NONE
4274===========================================================================*/
4275void dxeTXReSyncDesc
4276(
4277 wpt_msg *msgPtr
4278)
4279{
4280 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4281 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4282 wpt_uint32 nextDescReg;
4283 WLANDXE_ChannelCBType *channelEntry;
4284 WLANDXE_DescCtrlBlkType *validCtrlBlk;
4285 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004286 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004287
4288 if(NULL == msgContent)
4289 {
4290 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4291 "dxeTXReSyncDesc Invalid Control Block");
4292 return;
4293 }
4294
4295 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4296 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
4297 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4298
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004299 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004300 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004301 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4302 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4303 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
4304 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4305 &nextDescReg);
4306 /* Async detect without TX pending frame */
4307 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004308 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004309 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004310 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004311 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4312 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304313
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004314 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
4315 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304316
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004317 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004318 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004319 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004320 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004321 /* Async detect with some TX pending frames
4322 * next descriptor register should sync with first valid descriptor */
4323 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004324 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004325 validCtrlBlk = channelEntry->tailCtrlBlk;
4326 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004327 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004328 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4329 {
4330 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
4331 {
4332 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4333 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304334
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004335 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4336 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304337
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004338 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4339 validCtrlBlk->linkedDescPhyAddr);
4340 }
4341 break;
4342 }
4343 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4344 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4345 {
4346 /* Finished to test till head control blcok, but could not find valid descriptor
4347 * from head to tail all descriptors are invalidated
4348 * host point of view head descriptor is next TX candidate
4349 * So, next descriptor control have to be programmed with head descriptor
4350 * check */
4351 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
4352 {
4353 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004354 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304355
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004356 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4357 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304358
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004359 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4360 validCtrlBlk->linkedDescPhyAddr);
4361 }
4362 break;
4363 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004364 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004365 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004366 }
4367
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07004368 /* HW/SW descriptor resync is done.
4369 * Next if there are any valid descriptor in chain, Push to HW again */
4370 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
4371 {
4372 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4373 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
4374 {
4375 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4376 "%11s : No TX Pending frame",
4377 channelType[channelEntry->channelType]);
4378 /* No Pending frame, Do nothing */
4379 }
4380 else
4381 {
4382 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4383 "%11s : TX Pending frame, process it",
4384 channelType[channelEntry->channelType]);
4385 validCtrlBlk = channelEntry->tailCtrlBlk;
4386 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
4387 {
4388 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4389 {
4390 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4391 "%11s : when exit IMPS found valid descriptor",
4392 channelType[channelEntry->channelType]);
4393
4394 /* Found valid descriptor, kick DXE */
4395 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
4396 channelEntry->extraConfig.chan_mask);
4397 break;
4398 }
4399 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4400 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4401 {
4402 /* Finished to test till head control blcok, but could not find valid descriptor
4403 * from head to tail all descriptors are invalidated */
4404 break;
4405 }
4406 }
4407 }
4408 }
4409
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004410 wpalMemoryFree(msgPtr);
4411 return;
4412}
4413
Jeff Johnson295189b2012-06-20 16:38:30 -07004414/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05304415 @ Function Name
4416 dxeDebugTxDescReSync
4417
4418 @ Description
4419 Check DXE Tx channel state and correct it in
4420 case Tx Data stall is detected by calling
4421 %dxeTXReSyncDesc. Also ensure that WCN SS
4422 is not power collapsed before calling
4423 %dxeTXReSyncDesc
4424
4425 @ Parameters
4426 void *msgPtr
4427 Message pointer to sync with TX thread
4428
4429 @ Return
4430 NONE
4431===========================================================================*/
4432void dxeDebugTxDescReSync
4433(
4434 wpt_msg *msgPtr
4435)
4436{
4437 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4438 "%s: Check for DXE TX Async",__func__);
4439 /* Make wake up HW */
4440 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4441 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4442
4443 wpalSleep(10);
4444
4445 dxeTXReSyncDesc(msgPtr);
4446}
4447/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004448 @ Function Name
4449 dxeTXISR
4450
4451 @ Description
4452 TX interrupt ISR
4453 Platform will call this function if INT is happen
4454 This function must be registered into platform interrupt module
4455
4456 @ Parameters
4457 void *hostCtxt
4458 DXE host driver control context,
4459 pre registerd during interrupt registration
4460
4461 @ Return
4462 PAL_STATUS_T
4463===========================================================================*/
4464static void dxeTXISR
4465(
4466 void *hostCtxt
4467)
4468{
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304469 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
Jeff Johnson295189b2012-06-20 16:38:30 -07004470 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304471 wpt_uint32 intSrc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004472
4473 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004474 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004475
4476 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004477 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004478 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004479 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 /* Disable interrupt at here,
4481 IMPS or IMPS Pending state should not access RIVA register */
4482 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4483 if(eWLAN_PAL_STATUS_SUCCESS != status)
4484 {
4485 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4486 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4487 return;
4488 }
4489 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4490 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004491 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004492 return;
4493 }
4494
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 /* Disable TX Complete Interrupt at here */
4496 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4497 if(eWLAN_PAL_STATUS_SUCCESS != status)
4498 {
4499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4500 "dxeTXCompISR Disable TX complete interrupt fail");
4501 return;
4502 }
4503 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4504
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304505 wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
4506 &intSrc);
4507 /* intSrc which holds the INT_SRC_RAW_ADDRESS reg value
4508 While debugging crash dump convert to power of 2 for channel type */
4509 DXTRACE(dxeTrace(intSrc, TRACE_TXINT_STATE, TRACE_WLANDXE_VAR_DISABLE));
Jeff Johnson295189b2012-06-20 16:38:30 -07004510
4511 if( dxeCtxt->ucTxMsgCnt )
4512 {
4513 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4514 "Avoiding serializing TX Complete event");
4515 return;
4516 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304517
Jeff Johnson295189b2012-06-20 16:38:30 -07004518 dxeCtxt->ucTxMsgCnt = 1;
4519
4520 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004521 if(NULL == dxeCtxt->txIsrMsg)
4522 {
4523 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4524 "Invalid message");
4525 HDXE_ASSERT(0);
4526 return;
4527 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304528
Jeff Johnson295189b2012-06-20 16:38:30 -07004529 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4530 dxeCtxt->txIsrMsg);
4531 if(eWLAN_PAL_STATUS_SUCCESS != status)
4532 {
4533 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4534 "dxeTXCompISR interrupt serialize fail status=%d", status);
4535 }
4536
4537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004538 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004539 return;
4540}
4541
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304542/*==========================================================================
4543 @ Function Name
4544 dxeTraceInit
4545
4546 @ Description
4547 Initialize the DXTRACE when enabled
4548
4549 @ Parameters
4550 NONE
4551
4552 @ Return
4553 NONE
4554===========================================================================*/
4555void dxeTraceInit(void)
4556{
4557 gdxeTraceData.head = INVALID_VOS_TRACE_ADDR;
4558 gdxeTraceData.tail = INVALID_VOS_TRACE_ADDR;
4559 gdxeTraceData.num = 0;
4560 gdxeTraceData.enable = eWLAN_PAL_TRUE;
4561}
4562
4563/*==========================================================================
4564 @ Function Name
4565 dxeTrace
4566
4567 @ Description
4568 puts the messages in to ring-buffer
4569
4570 @ Parameters
4571 v_U8_t chan
4572 Rx/Tx path record
4573 v_U8_t code
4574 Rx/Tx Event
4575 v_U32_t data
4576 Actual message contents
4577 @ Return
4578 NONE
4579===========================================================================*/
4580void dxeTrace(v_U8_t chan, v_U8_t code, v_U32_t data)
4581{
4582 pdxeTraceRecord rec = NULL;
4583 unsigned long flags;
4584
4585 if (!gdxeTraceData.enable)
4586 {
4587 return;
4588 }
4589
4590 /* Aquire the lock and only one thread can access the buffer at a time */
4591 spin_lock_irqsave(&dtraceLock, flags);
4592
4593 gdxeTraceData.num++;
4594
4595 if (gdxeTraceData.num > MAX_DXE_TRACE_RECORDS)
4596 {
4597 gdxeTraceData.num = MAX_DXE_TRACE_RECORDS;
4598 }
4599 if (INVALID_VOS_TRACE_ADDR == gdxeTraceData.head)
4600 {
4601 /* first record */
4602 gdxeTraceData.head = 0;
4603 gdxeTraceData.tail = 0;
4604 }
4605 else
4606 {
4607 /* queue is not empty */
4608 v_U32_t tail = gdxeTraceData.tail + 1;
4609 if (MAX_DXE_TRACE_RECORDS == tail)
4610 {
4611 tail = 0;
4612 }
4613 if (gdxeTraceData.head == tail)
4614 {
4615 /* full */
4616 if (MAX_DXE_TRACE_RECORDS == ++gdxeTraceData.head)
4617 {
4618 gdxeTraceData.head = 0;
4619 }
4620 }
4621 gdxeTraceData.tail = tail;
4622 }
4623
4624 rec = &gdxeTraceTbl[gdxeTraceData.tail];
4625 rec->code = code;
4626 rec->data = data;
4627 rec->time = vos_timer_get_system_time();
4628 rec->chan = chan;
4629
4630 spin_unlock_irqrestore(&dtraceLock, flags);
4631}
4632
Jeff Johnson295189b2012-06-20 16:38:30 -07004633/*-------------------------------------------------------------------------
4634 * Global Function
4635 *-------------------------------------------------------------------------*/
4636/*==========================================================================
4637 @ Function Name
4638 WLANDXE_Open
4639
4640 @ Description
4641 Open host DXE driver, allocate DXE resources
4642 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4643
4644 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004645 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004646
4647 @ Return
4648 pVoid DXE local module control block pointer
4649===========================================================================*/
4650void *WLANDXE_Open
4651(
4652 void
4653)
4654{
4655 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4656 unsigned int idx;
4657 WLANDXE_ChannelCBType *currentChannel = NULL;
4658 int smsmInitState;
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304659 wpt_uint8 chanMask = WDTS_TRANSPORT_CHANNELS_MASK;
Jeff Johnson295189b2012-06-20 16:38:30 -07004660
4661 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004662 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004663
Mihir Shetee6618162015-03-16 14:48:42 +05304664 if (wpalIsFwLoggingEnabled())
4665 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304666 chanMask |= WDTS_RX_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304667 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304668
4669 if (wpalIsFwEvLoggingEnabled())
Mihir Shetee6618162015-03-16 14:48:42 +05304670 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304671 chanMask |= WDTS_RX_FW_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304672 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304673 dxeSetEnabledChannels(chanMask);
Mihir Shetee6618162015-03-16 14:48:42 +05304674
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 /* This is temporary allocation */
4676 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4677 if(NULL == tempDxeCtrlBlk)
4678 {
4679 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4680 "WLANDXE_Open Control Block Alloc Fail");
4681 return NULL;
4682 }
4683 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4684
jagadeeshf869bba2015-04-07 20:06:21 +05304685 dxeCommonDefaultConfig(tempDxeCtrlBlk);
Jeff Johnson295189b2012-06-20 16:38:30 -07004686
Mihir Shetee6618162015-03-16 14:48:42 +05304687 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004688 {
4689 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4690 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4691 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304692 currentChannel->channelType = idx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004693
4694 /* Config individual channels from channel default setup table */
4695 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4696 currentChannel);
4697 if(eWLAN_PAL_STATUS_SUCCESS != status)
4698 {
4699 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4700 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4701 WLANDXE_Close(tempDxeCtrlBlk);
4702 return NULL;
4703 }
4704
4705 /* Allocate DXE Control Block will be used by host DXE driver */
4706 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4707 if(eWLAN_PAL_STATUS_SUCCESS != status)
4708 {
4709 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4710 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4711
4712 WLANDXE_Close(tempDxeCtrlBlk);
4713 return NULL;
4714 }
4715 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4716 if(eWLAN_PAL_STATUS_SUCCESS != status)
4717 {
4718 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4719 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4720 WLANDXE_Close(tempDxeCtrlBlk);
4721 return NULL;
4722 }
4723
4724 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4725 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4726 }
4727
4728 /* Allocate and Init RX READY ISR Serialize Buffer */
4729 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4730 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4731 {
4732 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4733 "WLANDXE_Open Alloc RX ISR Fail");
4734 WLANDXE_Close(tempDxeCtrlBlk);
4735 return NULL;
4736 }
4737 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4738 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4739 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4740
4741 /* Allocate and Init TX COMP ISR Serialize Buffer */
4742 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4743 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4744 {
4745 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4746 "WLANDXE_Open Alloc TX ISR Fail");
4747 WLANDXE_Close(tempDxeCtrlBlk);
4748 return NULL;
4749 }
4750 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4751 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4752 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4753
4754 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4755 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4756 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4757 {
4758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4759 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4760 WLANDXE_Close(tempDxeCtrlBlk);
4761 return NULL;
4762 }
4763 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4764 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4765 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4766
4767 tempDxeCtrlBlk->freeRXPacket = NULL;
4768 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4769 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4770 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004771 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004772 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Karthick Sc6ec8362015-08-12 18:18:47 +05304773 tempDxeCtrlBlk->smsmRingsEmptyHistogram = 0;
4774 tempDxeCtrlBlk->smsmDxeHistogram = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004775
4776 /* Initialize SMSM state
4777 * Init State is
4778 * Clear TX Enable
4779 * RING EMPTY STATE */
4780 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4781 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4782 if(0 != smsmInitState)
4783 {
4784 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4785 "SMSM Channel init fail %d", smsmInitState);
Mihir Shetee6618162015-03-16 14:48:42 +05304786 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004787 {
4788 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4789 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004790 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4791 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 wpalMemoryFree(tempDxeCtrlBlk);
4793 return NULL;
4794 }
4795
Mihir Shete44547fb2014-03-10 14:15:42 +05304796#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004797 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4798 dxeRXResourceAvailableTimerExpHandler,
4799 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304800#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004801
Mihir Shetefdc9f532014-01-09 15:03:02 +05304802 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4803 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4804
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304805#ifdef DXE_TRACE
4806 DXTRACE(dxeTraceInit());
4807#endif
4808
Jeff Johnson295189b2012-06-20 16:38:30 -07004809 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4810 "WLANDXE_Open Success");
4811 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004812 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004813 return (void *)tempDxeCtrlBlk;
4814}
4815
4816/*==========================================================================
4817 @ Function Name
4818 WLANDXE_ClientRegistration
4819
4820 @ Description
4821 Make callback functions registration into DXE driver from DXE driver client
4822
4823 @ Parameters
4824 pVoid pDXEContext : DXE module control block
Mihir Shetec4093f92015-05-28 15:21:11 +05304825 WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events
Jeff Johnson295189b2012-06-20 16:38:30 -07004826 void *userContext : DXE Cliennt control block
4827
4828 @ Return
4829 wpt_status
4830===========================================================================*/
4831wpt_status WLANDXE_ClientRegistration
4832(
4833 void *pDXEContext,
Mihir Shetec4093f92015-05-28 15:21:11 +05304834 WDTS_ClientCallbacks WDTSCb,
Jeff Johnson295189b2012-06-20 16:38:30 -07004835 void *userContext
4836)
4837{
4838 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4839 WLANDXE_CtrlBlkType *dxeCtxt;
4840
4841 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004842 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004843
4844 /* Sanity */
4845 if(NULL == pDXEContext)
4846 {
4847 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4848 "WLANDXE_ClientRegistration Invalid DXE CB");
4849 return eWLAN_PAL_STATUS_E_INVAL;
4850 }
4851
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 if(NULL == userContext)
4853 {
4854 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4855 "WLANDXE_ClientRegistration Invalid userContext");
4856 return eWLAN_PAL_STATUS_E_INVAL;
4857 }
4858
4859 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4860
4861 /* Assign */
Mihir Shetec4093f92015-05-28 15:21:11 +05304862 dxeCtxt->rxReadyCB = WDTSCb.rxFrameReadyCB;
4863 dxeCtxt->txCompCB = WDTSCb.txCompleteCB;
4864 dxeCtxt->lowResourceCB = WDTSCb.lowResourceCB;
4865 dxeCtxt->receiveMbMsgCB = WDTSCb.receiveMbMsgCB;
Mihir Shete5affadc2015-05-29 20:54:57 +05304866 dxeCtxt->receiveLogCompleteCB = WDTSCb.receiveLogCompleteCB;
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 dxeCtxt->clientCtxt = userContext;
4868
4869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004870 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 return status;
4872}
4873
4874/*==========================================================================
4875 @ Function Name
4876 WLANDXE_Start
4877
4878 @ Description
4879 Start Host DXE driver
4880 Initialize DXE channels and start channel
4881
4882 @ Parameters
4883 pVoid pDXEContext : DXE module control block
4884
4885 @ Return
4886 wpt_status
4887===========================================================================*/
4888wpt_status WLANDXE_Start
4889(
4890 void *pDXEContext
4891)
4892{
4893 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4894 wpt_uint32 idx;
4895 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4896
4897 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004898 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004899
4900 /* Sanity */
4901 if(NULL == pDXEContext)
4902 {
4903 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4904 "WLANDXE_Start Invalid DXE CB");
4905 return eWLAN_PAL_STATUS_E_INVAL;
4906 }
4907 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4908
4909 /* WLANDXE_Start called means DXE engine already initiates
4910 * And DXE HW is reset and init finished
4911 * But here to make sure HW is initialized, reset again */
jagadeeshf869bba2015-04-07 20:06:21 +05304912 dxeEngineCoreStart(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004913
4914 /* Individual Channel Start */
Mihir Shetee6618162015-03-16 14:48:42 +05304915 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004916 {
4917 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4918 "WLANDXE_Start Channel %s Start", channelType[idx]);
4919
4920 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4921 /* Make connection between DXE descriptor and DXE control block */
4922 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4923 if(eWLAN_PAL_STATUS_SUCCESS != status)
4924 {
4925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4926 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4927 return status;
4928 }
4929
4930 /* Program each channel register with configuration arguments */
4931 status = dxeChannelInitProgram(dxeCtxt,
4932 &dxeCtxt->dxeChannel[idx]);
4933 if(eWLAN_PAL_STATUS_SUCCESS != status)
4934 {
4935 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4936 "WLANDXE_Start %d Program DMA channel Fail", idx);
4937 return status;
4938 }
4939
4940 /* ??? Trigger to start DMA channel
4941 * This must be seperated from ??? */
4942 status = dxeChannelStart(dxeCtxt,
4943 &dxeCtxt->dxeChannel[idx]);
4944 if(eWLAN_PAL_STATUS_SUCCESS != status)
4945 {
4946 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4947 "WLANDXE_Start %d Channel Start Fail", idx);
4948 return status;
4949 }
4950 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4951 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4952 }
4953
4954 /* Register ISR to OS */
4955 /* Register TX complete interrupt into platform */
4956 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4957 dxeTXISR,
4958 dxeCtxt);
4959 if(eWLAN_PAL_STATUS_SUCCESS != status)
4960 {
4961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4962 "WLANDXE_Start TX comp interrupt registration Fail");
4963 return status;
4964 }
4965
4966 /* Register RX ready interrupt into platform */
4967 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4968 dxeRXISR,
4969 dxeCtxt);
4970 if(eWLAN_PAL_STATUS_SUCCESS != status)
4971 {
4972 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4973 "WLANDXE_Start RX Ready interrupt registration Fail");
4974 return status;
4975 }
4976
4977 /* Enable system level ISR */
4978 /* Enable RX ready Interrupt at here */
4979 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4980 if(eWLAN_PAL_STATUS_SUCCESS != status)
4981 {
4982 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4983 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
4984 return status;
4985 }
4986
4987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004988 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 return status;
4990}
4991
4992/*==========================================================================
4993 @ Function Name
4994 WLANDXE_TXFrame
4995
4996 @ Description
4997 Trigger frame transmit from host to RIVA
4998
4999 @ Parameters
5000 pVoid pDXEContext : DXE Control Block
5001 wpt_packet pPacket : transmit packet structure
5002 WDTS_ChannelType channel : TX channel
5003
5004 @ Return
5005 wpt_status
5006===========================================================================*/
5007wpt_status WLANDXE_TxFrame
5008(
5009 void *pDXEContext,
5010 wpt_packet *pPacket,
5011 WDTS_ChannelType channel
5012)
5013{
5014 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5015 WLANDXE_ChannelCBType *currentChannel = NULL;
5016 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5017 unsigned int *lowThreshold = NULL;
5018
5019 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005020 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005021
5022 /* Sanity */
5023 if(NULL == pDXEContext)
5024 {
5025 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5026 "WLANDXE_Start Invalid DXE CB");
5027 return eWLAN_PAL_STATUS_E_INVAL;
5028 }
5029
5030 if(NULL == pPacket)
5031 {
5032 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5033 "WLANDXE_Start Invalid pPacket");
5034 return eWLAN_PAL_STATUS_E_INVAL;
5035 }
5036
Mihir Shetee6618162015-03-16 14:48:42 +05305037 if(WDTS_CHANNEL_MAX <= channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005038 {
5039 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5040 "WLANDXE_Start Invalid channel");
5041 return eWLAN_PAL_STATUS_E_INVAL;
5042 }
5043
5044 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
5045
5046 currentChannel = &dxeCtxt->dxeChannel[channel];
5047
5048
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005049 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
5050 if(eWLAN_PAL_STATUS_SUCCESS != status)
5051 {
5052 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5053 "WLANDXE_TxFrame Mutex Acquire fail");
5054 return status;
5055 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005056
5057 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
5058 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
5059 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
5060
5061 /* Decide have to activate TX complete event or not */
5062 switch(dxeCtxt->txCompInt.txIntEnable)
5063 {
5064 /* TX complete interrupt will be activated when low DXE resource */
5065 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
5066 if((currentChannel->numFreeDesc <= *lowThreshold) &&
5067 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
5068 {
5069 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
5070 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5071 channel,
5072 eWLAN_PAL_FALSE);
5073 }
5074 break;
5075
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08005076 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
5078 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
5079 {
5080 currentChannel->numFrameBeforeInt++;
5081 }
5082 break;
5083
5084 /* TX complete interrupt will be activated periodically */
5085 case WLANDXE_TX_COMP_INT_TIMER:
5086 break;
5087 }
5088
5089 dxeCtxt->txCompletedFrames++;
5090
5091 /* Update DXE descriptor, this is frame based
5092 * if a frame consist of N fragments, N Descriptor will be programed */
5093 status = dxeTXPushFrame(currentChannel, pPacket);
5094 if(eWLAN_PAL_STATUS_SUCCESS != status)
5095 {
5096 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5097 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005098 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5099 if(eWLAN_PAL_STATUS_SUCCESS != status)
5100 {
5101 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5102 "WLANDXE_TxFrame Mutex Release fail");
5103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 return status;
5105 }
5106
5107 /* If specific channel hit low resource condition, send notification to upper layer */
5108 if(currentChannel->numFreeDesc <= *lowThreshold)
5109 {
5110 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5111 channel,
5112 eWLAN_PAL_FALSE);
5113 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005114
5115 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5116 "%11s : Low Resource currentChannel->numRsvdDesc %d",
5117 channelType[currentChannel->channelType],
5118 currentChannel->numRsvdDesc);
Mihir Shete68ed77a2014-10-10 10:47:12 +05305119 if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5120 {
5121 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5122 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
5123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005125 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5126 if(eWLAN_PAL_STATUS_SUCCESS != status)
5127 {
5128 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5129 "WLANDXE_TxFrame Mutex Release fail");
5130 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005131
5132 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005133 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 return status;
5135}
5136
5137/*==========================================================================
5138 @ Function Name
5139 WLANDXE_CompleteTX
5140
5141 @ Description
5142 Informs DXE that the current series of Tx packets is complete
5143
5144 @ Parameters
5145 pContext pDXEContext : DXE Control Block
5146 ucTxResReq TX resource number required by TL/WDI
5147
5148 @ Return
5149 wpt_status
5150===========================================================================*/
5151wpt_status
5152WLANDXE_CompleteTX
5153(
5154 void* pContext,
5155 wpt_uint32 ucTxResReq
5156)
5157{
5158 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5159 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
5160 WLANDXE_ChannelCBType *channelCb = NULL;
5161 wpt_boolean inLowRes;
5162
5163 /* Sanity Check */
5164 if( NULL == pContext )
5165 {
5166 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5167 "WLANDXE_CompleteTX invalid param");
5168 return eWLAN_PAL_STATUS_E_INVAL;
5169 }
5170
5171 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
5172 inLowRes = channelCb->hitLowResource;
5173
5174 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
5175 {
5176 /* Raise threshold temporarily if necessary */
5177 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
5178
5179 if(eWLAN_PAL_FALSE == inLowRes)
5180 {
5181 /* Put the channel to low resource condition */
5182 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5183 WDTS_CHANNEL_TX_LOW_PRI,
5184 eWLAN_PAL_FALSE);
5185 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
5186 }
5187 }
5188
5189 /*Try to reclaim resources*/
5190 dxeTXCompleteProcessing(dxeCtxt);
5191
5192 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
5193 because its fragment size is larger than DXE free resource. */
5194 if(0 < ucTxResReq)
5195 {
5196 /* DXE successfully claimed enough free DXE resouces for next fetch. */
5197 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
5198 {
5199 /* DXE has not been in low resource condition. DXE forces to kick off
5200 TX tranmit */
5201 if((eWLAN_PAL_FALSE == inLowRes) &&
5202 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
5203 {
5204 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5205 WDTS_CHANNEL_TX_LOW_PRI,
5206 eWLAN_PAL_FALSE);
5207 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5208 WDTS_CHANNEL_TX_LOW_PRI,
5209 eWLAN_PAL_TRUE);
5210 channelCb->hitLowResource = eWLAN_PAL_FALSE;
5211 }
5212 }
5213 else
5214 {
5215 /* DXE doesn't have enough free DXE resources. Put the channel
5216 to low resource condition. */
5217 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
5218 {
5219 /* Put the channel to low resource condition */
5220 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5221 WDTS_CHANNEL_TX_LOW_PRI,
5222 eWLAN_PAL_FALSE);
5223 channelCb->hitLowResource = eWLAN_PAL_TRUE;
5224 }
5225 }
5226 }
5227
5228 return status;
5229}
5230
5231/*==========================================================================
5232 @ Function Name
5233 WLANDXE_Stop
5234
5235 @ Description
5236 Stop DXE channels and DXE engine operations
5237 Disable all channel interrupt
5238 Stop all channel operation
5239
5240 @ Parameters
5241 pVoid pDXEContext : DXE Control Block
5242
5243 @ Return
5244 wpt_status
5245===========================================================================*/
5246wpt_status WLANDXE_Stop
5247(
5248 void *pDXEContext
5249)
5250{
5251 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5252 wpt_uint32 idx;
5253 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5254
5255 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005256 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005257
5258 /* Sanity */
5259 if(NULL == pDXEContext)
5260 {
5261 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5262 "WLANDXE_Stop Invalid DXE CB");
5263 return eWLAN_PAL_STATUS_E_INVAL;
5264 }
5265
5266 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shetee6618162015-03-16 14:48:42 +05305267 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005268 {
5269 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5270 if(eWLAN_PAL_STATUS_SUCCESS != status)
5271 {
5272 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5273 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005274 }
5275 }
5276
5277 /* During Stop unregister interrupt */
5278 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
5279 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
5280
Mihir Shete44547fb2014-03-10 14:15:42 +05305281#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005282 if(VOS_TIMER_STATE_STOPPED !=
5283 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
5284 {
5285 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
5286 }
Mihir Shete44547fb2014-03-10 14:15:42 +05305287#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07005288
Jeff Johnson295189b2012-06-20 16:38:30 -07005289 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005290 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 return status;
5292}
5293
5294/*==========================================================================
5295 @ Function Name
5296 WLANDXE_Close
5297
5298 @ Description
5299 Close DXE channels
5300 Free DXE related resources
5301 DXE descriptor free
5302 Descriptor control block free
5303 Pre allocated RX buffer free
5304
5305 @ Parameters
5306 pVoid pDXEContext : DXE Control Block
5307
5308 @ Return
5309 wpt_status
5310===========================================================================*/
5311wpt_status WLANDXE_Close
5312(
5313 void *pDXEContext
5314)
5315{
5316 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5317 wpt_uint32 idx;
5318 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005319
5320 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005321 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005322
5323 /* Sanity */
5324 if(NULL == pDXEContext)
5325 {
5326 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5327 "WLANDXE_Stop Invalid DXE CB");
5328 return eWLAN_PAL_STATUS_E_INVAL;
5329 }
5330
5331 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05305332#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005333 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05305334#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05305335 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Mihir Shetee6618162015-03-16 14:48:42 +05305336 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 {
5338 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
5339 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
Jeff Johnson295189b2012-06-20 16:38:30 -07005340 }
5341
5342 if(NULL != dxeCtxt->rxIsrMsg)
5343 {
5344 wpalMemoryFree(dxeCtxt->rxIsrMsg);
5345 }
5346 if(NULL != dxeCtxt->txIsrMsg)
5347 {
5348 wpalMemoryFree(dxeCtxt->txIsrMsg);
5349 }
5350 if(NULL != dxeCtxt->rxPktAvailMsg)
5351 {
5352 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
5353 }
5354
5355 wpalMemoryFree(pDXEContext);
5356
5357 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005358 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 return status;
5360}
5361
5362/*==========================================================================
5363 @ Function Name
5364 WLANDXE_TriggerTX
5365
5366 @ Description
5367 TBD
5368
5369 @ Parameters
5370 pVoid pDXEContext : DXE Control Block
5371
5372 @ Return
5373 wpt_status
5374===========================================================================*/
5375wpt_status WLANDXE_TriggerTX
5376(
5377 void *pDXEContext
5378)
5379{
5380 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5381
5382 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005383 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005384
5385 /* TBD */
5386
5387 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005388 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 return status;
5390}
5391
5392/*==========================================================================
5393 @ Function Name
5394 dxeTxThreadSetPowerStateEventHandler
5395
5396 @ Description
5397 If WDI sends set power state req, this event handler will be called in Tx
5398 thread context
5399
5400 @ Parameters
5401 void *msgPtr
5402 Event MSG
5403
5404 @ Return
5405 None
5406===========================================================================*/
5407void dxeTxThreadSetPowerStateEventHandler
5408(
5409 wpt_msg *msgPtr
5410)
5411{
5412 wpt_msg *msgContent = (wpt_msg *)msgPtr;
5413 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05305414 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05305416 wpt_int8 i;
5417 WLANDXE_ChannelCBType *channelEntry;
5418 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07005419
5420 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005421 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005422
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
5424 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
5425 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
5426
5427 switch(reqPowerState)
5428 {
5429 case WLANDXE_POWER_STATE_BMPS:
5430 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5431 {
5432 //don't block MC waiting for num_rsvd to become 0 since it may take a while
5433 //based on amount of TX and RX activity - during this time any received
5434 // management frames will remain un-processed consuming RX buffers
5435 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5436 dxeCtxt->hostPowerState = reqPowerState;
5437 }
5438 else
5439 {
5440 status = eWLAN_PAL_STATUS_E_INVAL;
5441 }
5442 break;
5443 case WLANDXE_POWER_STATE_IMPS:
5444 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5445 {
Mihir Shetea4306052014-03-25 00:02:54 +05305446
5447 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
5448 {
5449 channelEntry = &dxeCtxt->dxeChannel[i];
5450 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
5451 {
5452 status = eWLAN_PAL_STATUS_E_FAILURE;
5453 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
5454 "%11s : %s :TX Pending frame",
5455 channelType[channelEntry->channelType], __func__);
5456
5457 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
5458 dxeDescriptorDump(channelEntry,
5459 channelEntry->headCtrlBlk->linkedDesc, 0);
5460 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
5461 &channelLog);
5462 dxeChannelAllDescDump(channelEntry,
5463 channelEntry->channelType,
5464 &channelLog);
5465 }
5466 }
5467
5468 if (eWLAN_PAL_STATUS_SUCCESS == status)
5469 {
5470 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
5471 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 }
5474 else
5475 {
5476 status = eWLAN_PAL_STATUS_E_INVAL;
5477 }
5478 break;
5479 case WLANDXE_POWER_STATE_FULL:
5480 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5481 {
5482 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5483 }
5484 dxeCtxt->hostPowerState = reqPowerState;
5485 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5486 break;
5487 case WLANDXE_POWER_STATE_DOWN:
5488 WLANDXE_Stop((void *)dxeCtxt);
5489 break;
5490 default:
5491 //assert
5492 break;
5493 }
5494
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05305495 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_POWER_STATE, dxeCtxt->hostPowerState));
5496
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
5498 {
5499 dxeCtxt->setPowerStateCb(status,
5500 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
5501 }
Ravali85acf6b2012-12-12 14:01:38 -08005502 else
5503 {
5504 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5505 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
5506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 /* Free MSG buffer */
5508 wpalMemoryFree(msgPtr);
5509 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005510 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 return;
5512}
5513
5514
5515/*==========================================================================
5516 @ Function Name
5517 dxeRxThreadSetPowerStateEventHandler
5518
5519 @ Description
5520 If WDI sends set power state req, this event handler will be called in Rx
5521 thread context
5522
5523 @ Parameters
5524 void *msgPtr
5525 Event MSG
5526
5527 @ Return
5528 None
5529===========================================================================*/
5530void dxeRxThreadSetPowerStateEventHandler
5531(
5532 wpt_msg *msgPtr
5533)
5534{
5535 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5536
5537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005538 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005539
5540 /* Now serialise the message through Tx thread also to make sure
5541 * no register access when RIVA is in powersave */
5542 /*Use the same message pointer just change the call back function */
5543 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5544 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5545 msgPtr);
5546 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5547 {
5548 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5549 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005550 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 }
5552
5553 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005554 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005555}
5556
5557/*==========================================================================
5558 @ Function Name
5559 WLANDXE_SetPowerState
5560
5561 @ Description
5562 From Client let DXE knows what is the WLAN HW(RIVA) power state
5563
5564 @ Parameters
5565 pVoid pDXEContext : DXE Control Block
5566 WLANDXE_PowerStateType powerState
5567
5568 @ Return
5569 wpt_status
5570===========================================================================*/
5571wpt_status WLANDXE_SetPowerState
5572(
5573 void *pDXEContext,
5574 WDTS_PowerStateType powerState,
5575 WDTS_SetPSCbType cBack
5576)
5577{
5578 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5579 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5580 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005581 wpt_msg *rxCompMsg;
5582 wpt_msg *txDescReSyncMsg;
Jeff Johnson295189b2012-06-20 16:38:30 -07005583
5584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005585 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 if(NULL == pDXEContext)
5587 {
5588 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005589 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 return eWLAN_PAL_STATUS_E_FAILURE;
5591 }
5592 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5593
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 switch(powerState)
5595 {
5596 case WDTS_POWER_STATE_FULL:
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005597 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5598 {
5599 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5600 if(NULL == txDescReSyncMsg)
5601 {
5602 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5603 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5604 }
5605 else
5606 {
5607 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5608 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5609 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5610 txDescReSyncMsg);
5611 if(eWLAN_PAL_STATUS_SUCCESS != status)
5612 {
5613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5614 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5615 }
5616 }
5617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 hostPowerState = WLANDXE_POWER_STATE_FULL;
5619 break;
5620 case WDTS_POWER_STATE_BMPS:
5621 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5622 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5623 break;
5624 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5626 break;
5627 case WDTS_POWER_STATE_DOWN:
5628 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5629 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5630 break;
5631 default:
5632 hostPowerState = WLANDXE_POWER_STATE_MAX;
5633 }
5634
5635 // A callback i.e. ACK back is needed only when we want to enable BMPS
5636 // and the data/management path is active because we want to ensure
5637 // DXE registers are not accessed when RIVA may be power-collapsed. So
5638 // we need a callback in enter_bmps_req (the request to RIVA is sent
5639 // only after ACK back from TX thread). A callback is not needed in
5640 // finish_scan_req during BMPS since data-path is resumed only in
5641 // finish_scan_rsp and no management frames are sent in between. No
5642 // callback is needed when going from BMPS enabled to BMPS suspended/
5643 // disabled when it is known that RIVA is awake and cannot enter power
5644 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5645 // init_scan_rsp
5646 if ( cBack )
5647 {
5648 //serialize through Rx thread
5649 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5650 if(NULL == rxCompMsg)
5651 {
5652 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5653 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5654 return eWLAN_PAL_STATUS_E_RESOURCES;
5655 }
5656
5657 /* Event type, where it must be defined???? */
5658 /* THIS MUST BE CLEARED ASAP
5659 txCompMsg->type = TX_COMPLETE; */
5660 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5661 rxCompMsg->pContext = pDxeCtrlBlk;
5662 rxCompMsg->val = hostPowerState;
5663 rxCompMsg->ptr = cBack;
5664 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5665 rxCompMsg);
5666 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5667 {
5668 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5669 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005670 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005671 }
5672 }
5673 else
5674 {
5675 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5676 {
5677 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5678 {
5679 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5680 }
5681 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5682 {
5683 /* Requested Full power from exit IMPS, reenable the interrupts*/
5684 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5685 {
5686 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5687 /* Enable RX interrupt at here, if new PS is not IMPS */
5688 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5689 if(eWLAN_PAL_STATUS_SUCCESS != status)
5690 {
5691 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005692 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 return status;
5694 }
5695 }
5696 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5697 {
5698 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005699 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 /* Enable RX interrupt at here, if new PS is not IMPS */
5701 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5702 if(eWLAN_PAL_STATUS_SUCCESS != status)
5703 {
5704 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005705 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 return status;
5707 }
5708 }
5709 }
5710 pDxeCtrlBlk->hostPowerState = hostPowerState;
5711 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5712 }
5713 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5714 {
5715 pDxeCtrlBlk->hostPowerState = hostPowerState;
5716 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5717 }
Mihir Shetea4306052014-03-25 00:02:54 +05305718 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5719 {
5720 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 else
5723 {
5724 HDXE_ASSERT(0);
5725 }
5726 }
5727
5728 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005729 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005730
5731 return status;
5732}
5733
5734/*==========================================================================
5735 @ Function Name
5736 WLANDXE_GetFreeTxDataResNumber
5737
5738 @ Description
5739 Returns free descriptor numbers for TX data channel (TX high priority)
5740
5741 @ Parameters
5742 pVoid pDXEContext : DXE Control Block
5743
5744 @ Return
5745 wpt_uint32 Free descriptor number of TX high pri ch
5746===========================================================================*/
5747wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5748(
5749 void *pDXEContext
5750)
5751{
5752 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005753 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005754
5755 if(NULL == pDXEContext)
5756 {
5757 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005758 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 return (0);
5760 }
5761
Mihir Shetee6618162015-03-16 14:48:42 +05305762 return ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005763}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005764
5765/*==========================================================================
5766 @ Function Name
5767 WLANDXE_ChannelDebug
5768
5769 @ Description
5770 Display DXE Channel debugging information
5771 User may request to display DXE channel snapshot
5772 Or if host driver detects any abnormal stcuk may display
5773
5774 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005775 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305776 debugFlags : Enable stall detect features
5777 defined by WPAL_DeviceDebugFlags
5778 These features may effect
5779 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005780
5781 @ Return
5782 NONE
5783
5784===========================================================================*/
5785void WLANDXE_ChannelDebug
5786(
Mihir Shete40a55652014-03-02 14:14:47 +05305787 wpt_boolean displaySnapshot,
5788 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005789)
5790{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005791 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305792 wpt_msg *txDescReSyncMsg ;
Mihir Shete41c41bb2014-08-18 17:37:12 +05305793 wpt_uint32 regValue, regValueLocal = 0;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005794 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5795
5796 /* Debug Type 1, Display current snapshot */
5797 if(displaySnapshot)
5798 {
5799 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5800 * This will not simply wakeup RIVA
5801 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005802 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5803 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005804 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005805 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005806 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
Mihir Shete41c41bb2014-08-18 17:37:12 +05305807#ifdef WCN_PRONTO
5808 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
5809#endif
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005810 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305811 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====",
Leo Chang345ef992013-07-12 10:17:29 -07005812 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305813 tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005814
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005815 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5816 &regValue,
5817 NULL,
5818 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005819
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005820 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5821 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005822 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005823 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5824 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5825 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005826 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005827
5828 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5829 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5830 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005831 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005832 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5833 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005834 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005835 }
5836 }
5837
Mihir Shete40a55652014-03-02 14:14:47 +05305838 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005839 {
Mihir Shete40a55652014-03-02 14:14:47 +05305840 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5841 if(NULL == txDescReSyncMsg)
5842 {
5843 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5844 "%s: Resync MSG MEM alloc Fail",__func__);
5845 }
5846 else
5847 {
5848 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5849 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5850 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5851 txDescReSyncMsg);
5852 if(eWLAN_PAL_STATUS_SUCCESS != status)
5853 {
5854 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5855 "%s: Post TX re-sync MSG fail",__func__);
5856 }
5857 }
5858 }
5859
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005860 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005861}
Mihir Shete5affadc2015-05-29 20:54:57 +05305862
5863wpt_uint32 WLANDXE_SetupLogTransfer(wpt_uint64 bufferAddr, wpt_uint32 bufferLen)
5864{
5865 WLANDXE_ChannelCBType *channelEntry;
5866
5867 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5868
5869
5870 return dxeRXLogRefillRing(tempDxeCtrlBlk, channelEntry, bufferAddr,
5871 bufferLen);
5872}
5873
5874wpt_status WLANDXE_StartLogTransfer(void)
5875{
5876 WLANDXE_ChannelCBType *channelEntry;
5877 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5878
5879 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5880
5881 tempDxeCtrlBlk->hostInitiatedH2H = 1;
5882 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
5883 channelEntry->headCtrlBlk->linkedDescPhyAddr);
5884 if(eWLAN_PAL_STATUS_SUCCESS != status)
5885 {
5886 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5887 "%s Write DESC Address register fail", __func__);
5888 return status;
5889 }
5890
Abhishek Singh2b055852015-10-07 14:14:13 +05305891 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
Mihir Shete5affadc2015-05-29 20:54:57 +05305892 channelEntry->extraConfig.chan_mask);
5893 if(eWLAN_PAL_STATUS_SUCCESS != status)
5894 {
5895 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5896 "dxeChannelInitProgram Write RX Control register fail");
5897 return status;
5898 }
5899 return status;
5900}