blob: c7f7235b0a81289b566d2ba9a9570477b5f0fb3a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Sravan Kumar Kairamcebb2182016-01-25 20:50:11 +05302 * Copyright (c) 2012-2016 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{
Mihir Shete79d6b582014-03-12 17:54:07 +0530513 wpt_uint32 chLDescReg, channelLoop;
514 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530515
Mihir Shete79d6b582014-03-12 17:54:07 +0530516 switch ((chStatusReg & WLANDXE_CH_STAT_ERR_CODE_MASK) >>
517 WLANDXE_CH_STAT_ERR_CODE_OFFSET)
518 {
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530519
Mihir Shete79d6b582014-03-12 17:54:07 +0530520 case WLANDXE_ERROR_PRG_INV_B2H_SRC_QID:
521 case WLANDXE_ERROR_PRG_INV_B2H_DST_QID:
522 case WLANDXE_ERROR_PRG_INV_B2H_SRC_IDX:
523 case WLANDXE_ERROR_PRG_INV_H2B_SRC_QID:
524 case WLANDXE_ERROR_PRG_INV_H2B_DST_QID:
525 case WLANDXE_ERROR_PRG_INV_H2B_DST_IDX:
526 {
527 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
528 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
529 wpalSleep(10);
530
531 if(channelCb->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
532 {
533 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
534 "%s: Invalid Channel", __func__);
535 break;
536 }
537
538 wpalReadRegister(channelCb->channelRegister.chDXELstDesclRegAddr, &chLDescReg);
539
540 targetCtrlBlk = channelCb->headCtrlBlk;
541
542 for(channelLoop = 0; channelLoop < channelCb->numDesc; channelLoop++)
543 {
544 if (targetCtrlBlk->linkedDescPhyAddr == chLDescReg)
545 {
546 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
547 "%11s :CHx_DESCL: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
548 channelType[channelCb->channelType],
549 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
550 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
551 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
552 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
553
554 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
555
556 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
557 "%11s :Next Desc: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x",
558 channelType[channelCb->channelType],
559 targetCtrlBlk->linkedDesc->descCtrl.ctrl,
560 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL,
561 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL,
562 targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL);
563 break;
564 }
565 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
566 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530567 wpalFwDumpReq(17, 0, 0, 0, 0, 1);
Mihir Shete79d6b582014-03-12 17:54:07 +0530568 break;
569 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530570 case WLANDXE_ERROR_ABORT:
571 {
572 wpt_uint32 regValue, regValueLocal;
573 wpt_uint32 count = 0;
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +0530574 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530575 "%s: DXE Abort Error from S/W", __func__);
576
577 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &regValue);
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +0530578 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530579 "%s: DXE CSR Value: %08x", __func__,regValue);
580
581 //Execute the BMU recovery only if firmware triggered the ABORT
582 if (regValue & WLANDXE_DMA_CSR_FW_BMU_RECOVERY)
583 {
584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
585 "%s: Firmware BMU recovery On %08x", __func__,regValue);
586
587 // Clean up the descriptors
588 if (eWLAN_PAL_STATUS_SUCCESS !=
589 dxeTXCleanup(tempDxeCtrlBlk))
590 {
591 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
592 "%s: Host DXE Cleanup Failed!!!!", __func__);
593 }
594
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530595 // Unblock the firmware
596 regValue |= WLANDXE_DMA_CSR_HOST_RECOVERY_DONE;
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +0530597 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530598 "%s: Host DXE Cleanup done %08x", __func__,regValue);
599 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS, regValue);
600
601 // Wait for firmware to complete the cleanup
602 do
603 {
604 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &regValue);
605 wpalBusyWait(5000);
606 count++;
607 //count is 60 because wait is for 5 ms and 60*5=300ms
608 //which is the time WD bark happens in firmware
609 } while(count < 60 && !(regValue & WLANDXE_DMA_CSR_RECOVERY_DONE));
610 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
611 "%s: FW Cleanup done %08x", __func__,regValue);
612
613 //clear all spare bits in CSR
614 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,regValue &
615 ~(WLANDXE_DMA_CSR_RECOVERY_DONE |
616 WLANDXE_DMA_CSR_FW_BMU_RECOVERY |
617 WLANDXE_DMA_CSR_HOST_RECOVERY_DONE));
618
619 //check if the h/w resources have recovered
620 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
621 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +0530622 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530623 "===== count %d ABD %d, ABD LOCAL %d =====", count,
624 regValue, regValueLocal);
625 if(regValue == 0 || regValueLocal == 0)
626 {
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +0530627 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
628 "%s: HW resources have not recovered", __func__);
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530629 return eWLAN_PAL_STATUS_E_FAILURE;
630 }
631
632 return eWLAN_PAL_STATUS_SUCCESS;
633 }
634 break;
635 }
Mihir Shete79d6b582014-03-12 17:54:07 +0530636 default:
637 {
638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
639 "%s: No Debug Inormation", __func__);
640 break;
641 }
642
643 }
Mihir Shetedfc33ec2014-10-15 13:14:38 +0530644 return eWLAN_PAL_STATUS_E_FAILURE;
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530645}
646/*==========================================================================
647 @ Function Name
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700648 dxeTxThreadChannelDebugHandler
649
650 @ Description
651 Dump TX channel information
652
653 @ Parameters
654 Wwpt_msg *msgPtr
655
656 @ Return
657 NONE
658
659===========================================================================*/
660void dxeTxThreadChannelDebugHandler
661(
662 wpt_msg *msgPtr
663)
664{
665 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700666 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700667
668 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700669 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700670
671 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
672 * This will not simply wakeup RIVA
673 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700674 for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
675 {
676 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530677 &tempDxeCtrlBlk->dxeChannel[channelLoop],
678 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700679 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530680 "Abnormal successive empty interrupt",
681 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700682 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530683 channelLoop,
684 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700685
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700686 wpalMemoryCopy(channelLog.channelName,
687 channelType[channelLoop],
688 WPT_TRPT_CHANNEL_NAME);
689 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Jeff Johnsone7245742012-09-05 17:12:55 -0700690 }
691
Leo Chang345ef992013-07-12 10:17:29 -0700692 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700693 "================== DXE Dump End ======================");
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -0700694 wpalMemoryFree(msgPtr);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700695
696#ifdef FEATURE_WLAN_DIAG_SUPPORT
697 wpalPacketStallDumpLog();
698#endif /* FEATURE_WLAN_DIAG_SUPPORT */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700699 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700700 "%s Exit", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700701 return;
702}
703
704/*==========================================================================
705 @ Function Name
706 dxeRxThreadChannelDebugHandler
707
708 @ Description
709 Dump RX channel information
710
711 @ Parameters
712 Wwpt_msg *msgPtr
713
714 @ Return
715 NONE
716
717===========================================================================*/
718void dxeRxThreadChannelDebugHandler
719(
720 wpt_msg *msgPtr
721)
722{
723 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
724 wpt_uint8 channelLoop;
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700725 wpt_log_data_stall_channel_type channelLog;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700726
727 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700728 "%s Enter", __func__);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700729
730 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
731 * This will not simply wakeup RIVA
732 * Just incase TX not wanted stuck, Trigger TX again */
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700733 for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++)
734 {
Mihir Shetee6618162015-03-16 14:48:42 +0530735 if (!WLANDXE_IS_VALID_CHANNEL(channelLoop))
736 continue;
737
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700738 dxeChannelMonitor("******** Get Descriptor Snapshot ",
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530739 &tempDxeCtrlBlk->dxeChannel[channelLoop],
740 &channelLog);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700741 dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530742 "Abnormal successive empty interrupt",
743 &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700744 dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop],
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530745 channelLoop, &channelLog);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700746
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -0700747 wpalMemoryCopy(channelLog.channelName,
748 channelType[channelLoop],
749 WPT_TRPT_CHANNEL_NAME);
750 wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +0530751
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700752 }
753
754 /* Now serialise the message through Tx thread also to make sure
755 * no register access when RIVA is in powersave */
756 /*Use the same message pointer just change the call back function */
757 msgPtr->callback = dxeTxThreadChannelDebugHandler;
758 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
759 msgPtr);
760 if ( eWLAN_PAL_STATUS_SUCCESS != status )
761 {
762 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -0700763 "Tx thread state dump req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -0700764 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700765 }
766
767 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700768 "%s Exit", __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -0700769 return;
770}
Jeff Johnson295189b2012-06-20 16:38:30 -0700771
772/*==========================================================================
773 @ Function Name
774 dxeCtrlBlkAlloc
775
776 @ Description
777 Allocate DXE Control block
778 DXE control block will used by Host DXE driver only, internal structure
779 Will make ring linked list
780
781 @ Parameters
782 WLANDXE_CtrlBlkType *dxeCtrlBlk,
783 DXE host driver main control block
784 WLANDXE_ChannelCBType *channelEntry
785 Channel specific control block
786
787 @ Return
788 wpt_status
789
790===========================================================================*/
791static wpt_status dxeCtrlBlkAlloc
792(
793 WLANDXE_CtrlBlkType *dxeCtrlBlk,
794 WLANDXE_ChannelCBType *channelEntry
795)
796{
797 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
798 unsigned int idx, fIdx;
799 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
800 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
801 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
802 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
803
804 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700805 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700806
807 /* Sanity check */
808 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
809 {
810 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
811 "dxeCtrlBlkAlloc Channel Entry is not valid");
812 return eWLAN_PAL_STATUS_E_INVAL;
813 }
814
815 /* Allocate pre asigned number of control blocks */
816 for(idx = 0; idx < channelEntry->numDesc; idx++)
817 {
818 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
819 if(NULL == currentCtrlBlk)
820 {
821 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
822 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
823 channelEntry->channelType);
824 freeCtrlBlk = channelEntry->headCtrlBlk;
825 for(fIdx = 0; fIdx < idx; fIdx++)
826 {
827 if(NULL == freeCtrlBlk)
828 {
829 break;
830 }
831
832 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
833 wpalMemoryFree((void *)freeCtrlBlk);
834 freeCtrlBlk = nextCtrlBlk;
835 }
836 return eWLAN_PAL_STATUS_E_FAULT;
837 }
838
839 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
840 /* Initialize common elements first */
841 currentCtrlBlk->xfrFrame = NULL;
842 currentCtrlBlk->linkedDesc = NULL;
843 currentCtrlBlk->linkedDescPhyAddr = 0;
844 currentCtrlBlk->ctrlBlkOrder = idx;
845
846 /* This is the first control block allocated
847 * Next Control block is not allocated yet
848 * head and tail must be first control block */
849 if(0 == idx)
850 {
851 currentCtrlBlk->nextCtrlBlk = NULL;
852 channelEntry->headCtrlBlk = currentCtrlBlk;
853 channelEntry->tailCtrlBlk = currentCtrlBlk;
854 }
855 /* This is not first, not last control block
856 * previous control block may has next linked block */
857 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
858 {
859 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
860 }
861 /* This is last control blocl
862 * next control block for the last control block is head, first control block
863 * then whole linked list made RING */
864 else if((channelEntry->numDesc - 1) == idx)
865 {
866 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
867 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
868 }
869 else
870 {
871 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
872 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
873 channelEntry->channelType);
874 wpalMemoryFree(currentCtrlBlk);
875 return eWLAN_PAL_STATUS_E_FAULT;
876 }
877
878 prevCtrlBlk = currentCtrlBlk;
879 channelEntry->numFreeDesc++;
880 }
881
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700882 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700883 return status;
884}
885
886/*==========================================================================
887 @ Function Name
888 dxeDescLinkAlloc
889
890 @ Description
891 Allocate DXE descriptor
892 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
893 Will make RING linked list
894 Will be linked with Descriptor control block one by one
895
896 @ Parameters
897 WLANDXE_CtrlBlkType *dxeCtrlBlk,
898 DXE host driver main control block
899 WLANDXE_ChannelCBType *channelEntry
900 Channel specific control block
901 @ Return
902 wpt_status
903
904===========================================================================*/
905static wpt_status dxeDescAllocAndLink
906(
907 WLANDXE_CtrlBlkType *dxeCtrlBlk,
908 WLANDXE_ChannelCBType *channelEntry
909)
910{
911 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
912 WLANDXE_DescType *currentDesc = NULL;
913 WLANDXE_DescType *prevDesc = NULL;
914 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
915 unsigned int idx;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530916 void *physAddressAlloc = NULL;
917 wpt_uint32 physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700918
919 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700920 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700921
922 /* Sanity Check */
923 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
924 {
925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
926 "dxeDescLinkAlloc Channel Entry is not valid");
927 return eWLAN_PAL_STATUS_E_INVAL;
928 }
929
930 currentCtrlBlk = channelEntry->headCtrlBlk;
931
Jeff Johnson295189b2012-06-20 16:38:30 -0700932 /* allocate all DXE descriptors for this channel in one chunk */
933 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
934 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530935 &physAddressAlloc);
936 physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700937 if(NULL == channelEntry->descriptorAllocation)
938 {
939 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
940 "dxeDescLinkAlloc Descriptor Alloc Fail");
941 return eWLAN_PAL_STATUS_E_RESOURCES;
942 }
943 currentDesc = channelEntry->descriptorAllocation;
Jeff Johnson295189b2012-06-20 16:38:30 -0700944
945 /* Allocate pre asigned number of descriptor */
946 for(idx = 0; idx < channelEntry->numDesc; idx++)
947 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 // descriptors were allocated in a chunk -- use the current one
Jeff Johnson295189b2012-06-20 16:38:30 -0700949 if(NULL == currentDesc)
950 {
951 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
952 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
953 channelEntry->channelType);
954 return eWLAN_PAL_STATUS_E_FAULT;
955 }
Mihir Shete96cd1902015-03-04 15:47:31 +0530956 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
957 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
958 "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc);
Jeff Johnson295189b2012-06-20 16:38:30 -0700959
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 currentCtrlBlk->linkedDesc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530961 currentCtrlBlk->linkedDescPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 /* First descriptor, next none
963 * descriptor bottom location is first descriptor address */
964 if(0 == idx)
965 {
966 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
967 channelEntry->DescBottomLoc = currentDesc;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530968 channelEntry->descBottomLocPhyAddr = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -0700969 }
970 /* Not first, not last descriptor
971 * may make link for previous descriptor with current descriptor
972 * ENDIAN SWAP needed ????? */
973 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
974 {
975 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530976 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700977 }
978 /* Last descriptor
979 * make a ring by asign next pointer as first descriptor
980 * ENDIAN SWAP NEEDED ??? */
981 else if((channelEntry->numDesc - 1) == idx)
982 {
983 prevDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530984 WLANDXE_U32_SWAP_ENDIAN(physAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -0700985 currentDesc->dxedesc.dxe_short_desc.phyNextL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +0530986 WLANDXE_U32_SWAP_ENDIAN(channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnson295189b2012-06-20 16:38:30 -0700987 }
988
989 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
990 * Pre allocated and physical address must be assigned into
991 * Corresponding DXE Descriptor */
Jeff Johnson295189b2012-06-20 16:38:30 -0700992 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +0530993 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
994 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 {
996 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
997 channelEntry,
998 currentCtrlBlk);
999 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
1000 {
1001 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1002 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
1003 channelEntry->channelType);
1004 return status;
1005 }
1006 --channelEntry->numFreeDesc;
1007 }
1008
Leo Chang7e05f212013-07-01 19:54:15 -07001009 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1010 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1011 {
1012 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
1013 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1014 }
1015 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301016 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
1017 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Leo Chang7e05f212013-07-01 19:54:15 -07001018 {
1019 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1020 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
1021 }
1022 else
1023 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05301024 /* Just in case. H2H RX channel, do nothing
Leo Chang7e05f212013-07-01 19:54:15 -07001025 * By Definition this must not happen */
1026 }
1027
Jeff Johnson295189b2012-06-20 16:38:30 -07001028 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1029 prevDesc = currentDesc;
1030
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 // advance to the next pre-allocated descriptor in the chunk
1032 currentDesc++;
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05301033 physAddress = (physAddress + sizeof(WLANDXE_DescType));
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 }
1035
1036 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001037 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 return status;
1039}
1040
1041/*==========================================================================
1042 @ Function Name
1043
1044 @ Description
1045
1046 @ Parameters
1047
1048 @ Return
1049 wpt_status
1050
1051===========================================================================*/
1052static wpt_status dxeSetInterruptPath
1053(
1054 WLANDXE_CtrlBlkType *dxeCtrlBlk
1055)
1056{
1057 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1058 wpt_uint32 interruptPath = 0;
1059 wpt_uint32 idx;
1060 WLANDXE_ChannelCBType *channelEntry = NULL;
1061
1062 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001063 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001064
Mihir Shetee6618162015-03-16 14:48:42 +05301065 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07001066 {
1067 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
Jeff Johnson295189b2012-06-20 16:38:30 -07001068 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1069 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001070 {
1071 interruptPath |= (1 << channelEntry->assignedDMAChannel);
1072 }
1073 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301074 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)||
Mihir Shetec4093f92015-05-28 15:21:11 +05301075 (WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301076 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001077 {
1078 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
1079 }
1080 else
1081 {
1082 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1083 "H2H TEST RX???? %d", channelEntry->channelType);
1084 }
1085 }
1086 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1087 "Interrupt Path Must be 0x%x", interruptPath);
1088 dxeCtrlBlk->interruptPath = interruptPath;
1089 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
1090
1091 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001092 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 return status;
1094}
1095
1096/*==========================================================================
1097 @ Function Name
1098 dxeEngineCoreStart
1099
1100 @ Description
1101 Trigger to start RIVA DXE Hardware
1102
1103 @ Parameters
1104 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1105 DXE host driver main control block
1106
1107 @ Return
jagadeeshf869bba2015-04-07 20:06:21 +05301108 void
Jeff Johnson295189b2012-06-20 16:38:30 -07001109
1110===========================================================================*/
jagadeeshf869bba2015-04-07 20:06:21 +05301111static void dxeEngineCoreStart
Jeff Johnson295189b2012-06-20 16:38:30 -07001112(
1113 WLANDXE_CtrlBlkType *dxeCtrlBlk
1114)
1115{
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 wpt_uint32 registerData = 0;
Leo Chang00708f62013-12-03 20:21:51 -08001117 wpt_uint8 readRetry;
Jeff Johnson295189b2012-06-20 16:38:30 -07001118
1119 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001120 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001121
Leo Chang00708f62013-12-03 20:21:51 -08001122#ifdef WCN_PRONTO
1123 /* Read default */
1124 wpalReadRegister(WLANDXE_CCU_SOFT_RESET, &registerData);
1125 registerData |= WLANDXE_DMA_CCU_DXE_RESET_MASK;
1126
1127 /* Make reset */
1128 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1129
1130 /* Clear reset */
1131 registerData &= ~WLANDXE_DMA_CCU_DXE_RESET_MASK;
1132 wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData);
1133#else
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 /* START This core init is not needed for the integrated system */
1135 /* Reset First */
1136 registerData = WLANDXE_DMA_CSR_RESET_MASK;
1137 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1138 registerData);
Leo Chang00708f62013-12-03 20:21:51 -08001139#endif /* WCN_PRONTO */
Jeff Johnson295189b2012-06-20 16:38:30 -07001140
Leo Chang00708f62013-12-03 20:21:51 -08001141 for(readRetry = 0; readRetry < WLANDXE_CSR_MAX_READ_COUNT; readRetry++)
1142 {
1143 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
1144 WLANDXE_CSR_DEFAULT_ENABLE);
1145 wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, &registerData);
1146 if(!(registerData & WLANDXE_DMA_CSR_EN_MASK))
1147 {
1148 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1149 "%s CSR 0x%x, count %d",
1150 __func__, registerData, readRetry);
1151 /* CSR is not valid value, re-try to write */
1152 wpalBusyWait(WLANDXE_CSR_NEXT_READ_WAIT);
1153 }
1154 else
1155 {
1156 break;
1157 }
1158 }
1159 if(WLANDXE_CSR_MAX_READ_COUNT == readRetry)
1160 {
1161 /* MAX wait, still cannot write correct value
1162 * Panic device */
1163 wpalDevicePanic();
1164 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001165
1166 /* Is This needed?
1167 * Not sure, revisit with integrated system */
1168 /* END This core init is not needed for the integrated system */
1169
1170 dxeSetInterruptPath(dxeCtrlBlk);
1171 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001172 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001173}
1174
1175/*==========================================================================
1176 @ Function Name
1177 dxeChannelInitProgram
1178
1179 @ Description
1180 Program RIVA DXE engine register with initial value
1181 What must be programmed
1182 - Source Address (SADRL, chDXESadrlRegAddr)
1183 - Destination address (DADRL, chDXEDadrlRegAddr)
1184 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
1185 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
1186
1187 Not need to program now
1188 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
1189 TX : Have to program to trigger send out frame
1190 RX : programmed by DXE engine
1191
1192 @ Parameters
1193 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1194 DXE host driver main control block
1195 WLANDXE_ChannelCBType *channelEntry
1196 Channel specific control block
1197 @ Return
1198 wpt_status
1199
1200===========================================================================*/
1201static wpt_status dxeChannelInitProgram
1202(
1203 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1204 WLANDXE_ChannelCBType *channelEntry
1205)
1206{
1207 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1208 wpt_uint32 idx;
1209 WLANDXE_DescType *currentDesc = NULL;
1210 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1211
1212 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001213 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001214
1215 /* Sanity Check */
1216 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1217 {
1218 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1219 "dxeChannelInitProgram Channel Entry is not valid");
1220 return eWLAN_PAL_STATUS_E_INVAL;
1221 }
1222
1223 /* Program Source address and destination adderss */
1224 if(!channelEntry->channelConfig.useShortDescFmt)
1225 {
1226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1227 "dxeChannelInitProgram Long Descriptor not support yet");
1228 return eWLAN_PAL_STATUS_E_FAILURE;
1229 }
1230
1231 /* Common register area */
1232 /* Next linked list Descriptor pointer */
1233 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
1234 channelEntry->headCtrlBlk->linkedDescPhyAddr);
1235 if(eWLAN_PAL_STATUS_SUCCESS != status)
1236 {
1237 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1238 "dxeChannelInitProgram Write DESC Address register fail");
1239 return status;
1240 }
1241
1242 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1243 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1244 {
1245 /* Program default registers */
1246 /* TX DMA channel, DMA destination address is work Q */
1247 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1248 channelEntry->channelConfig.refWQ);
1249 if(eWLAN_PAL_STATUS_SUCCESS != status)
1250 {
1251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1252 "dxeChannelInitProgram Write TX DAddress register fail");
1253 return status;
1254 }
1255 }
1256 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301257 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1258 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001259 {
1260 /* Initialize Descriptor control Word First */
1261 currentCtrlBlk = channelEntry->headCtrlBlk;
1262 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
1263 {
1264 currentDesc = currentCtrlBlk->linkedDesc;
1265 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1266 }
1267
1268 /* RX DMA channel, DMA source address is work Q */
1269 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
1270 channelEntry->channelConfig.refWQ);
1271 if(eWLAN_PAL_STATUS_SUCCESS != status)
1272 {
1273 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1274 "dxeChannelInitProgram Write RX SAddress WQ register fail");
1275 return status;
1276 }
1277
1278 /* RX DMA channel, Program pre allocated destination Address */
1279 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
1280 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
1281 if(eWLAN_PAL_STATUS_SUCCESS != status)
1282 {
1283 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1284 "dxeChannelInitProgram Write RX DAddress register fail");
1285 return status;
1286 }
1287
1288 /* RX Channels, default Control registers MUST BE ENABLED */
jagadeeshf869bba2015-04-07 20:06:21 +05301289 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07001290 channelEntry->extraConfig.chan_mask);
1291 if(eWLAN_PAL_STATUS_SUCCESS != status)
1292 {
1293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1294 "dxeChannelInitProgram Write RX Control register fail");
1295 return status;
1296 }
1297 }
1298 else
1299 {
1300 /* H2H test channel, not use work Q */
Jeff Johnson295189b2012-06-20 16:38:30 -07001301 }
1302
1303 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001304 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001305 return status;
1306}
1307
1308
1309/*==========================================================================
1310 @ Function Name
1311 dxeChannelStart
1312
1313 @ Description
1314 Start Specific Channel
1315
1316 @ Parameters
1317 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1318 DXE host driver main control block
1319 WLANDXE_ChannelCBType *channelEntry
1320 Channel specific control block
1321
1322 @ Return
1323 wpt_status
1324
1325===========================================================================*/
1326static wpt_status dxeChannelStart
1327(
1328 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1329 WLANDXE_ChannelCBType *channelEntry
1330)
1331{
1332 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1333 wpt_uint32 regValue = 0;
1334 wpt_uint32 intMaskVal = 0;
1335
1336 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001337 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001338
1339 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
1340 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
1341
1342 /* Enable individual channel
1343 * not to break current channel setup, first read register */
1344 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
1345 &regValue);
1346 if(eWLAN_PAL_STATUS_SUCCESS != status)
1347 {
1348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1349 "dxeChannelStart Read Channel Enable register fail");
1350 return status;
1351 }
1352
1353 /* Enable Channel specific Interrupt */
1354 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1355 &intMaskVal);
1356 if(eWLAN_PAL_STATUS_SUCCESS != status)
1357 {
1358 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1359 "dxeChannelStart Read INT_MASK register fail");
1360 return status;
1361 }
1362 intMaskVal |= channelEntry->extraConfig.intMask;
1363 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1364 intMaskVal);
1365 if(eWLAN_PAL_STATUS_SUCCESS != status)
1366 {
1367 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1368 "dxeChannelStart Write INT_MASK register fail");
1369 return status;
1370 }
1371
1372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001373 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 return status;
1375}
1376
1377/*==========================================================================
1378 @ Function Name
1379 dxeChannelStop
1380
1381 @ Description
1382 Stop Specific Channel
1383
1384 @ Parameters
1385 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1386 DXE host driver main control block
1387 WLANDXE_ChannelCBType *channelEntry
1388 Channel specific control block
1389
1390 @ Return
1391 wpt_status
1392
1393===========================================================================*/
1394static wpt_status dxeChannelStop
1395(
1396 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1397 WLANDXE_ChannelCBType *channelEntry
1398)
1399{
1400 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1401 wpt_uint32 intMaskVal = 0;
1402
1403 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001404 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001405
1406 /* Sanity */
1407 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1408 {
1409 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1410 "dxeChannelStop Invalid arg input");
1411 return eWLAN_PAL_STATUS_E_INVAL;
1412 }
1413
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001414 if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) ||
1415 (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE))
1416 {
1417 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1418 "dxeChannelStop channels are not enabled ");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08001419 return status;
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08001420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 /* Maskout interrupt */
1422 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1423 &intMaskVal);
1424 if(eWLAN_PAL_STATUS_SUCCESS != status)
1425 {
1426 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1427 "dxeChannelStop Read INT_MASK register fail");
1428 return status;
1429 }
1430 intMaskVal ^= channelEntry->extraConfig.intMask;
1431 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1432 intMaskVal);
1433 if(eWLAN_PAL_STATUS_SUCCESS != status)
1434 {
1435 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1436 "dxeChannelStop Write INT_MASK register fail");
1437 return status;
1438 }
1439
1440 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1441
1442 /* Stop Channel ??? */
1443 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001444 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001445 return status;
1446}
1447
1448/*==========================================================================
1449 @ Function Name
1450 dxeChannelClose
1451
1452 @ Description
1453 Close Specific Channel
1454 Free pre allocated RX frame buffer if RX channel
1455 Free DXE descriptor for each channel
1456 Free Descriptor control block for each channel
1457
1458 @ Parameters
1459 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1460 DXE host driver main control block
1461 WLANDXE_ChannelCBType *channelEntry
1462 Channel specific control block
1463
1464 @ Return
1465 wpt_status
1466
1467===========================================================================*/
1468static wpt_status dxeChannelClose
1469(
1470 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1471 WLANDXE_ChannelCBType *channelEntry
1472)
1473{
1474 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1475 wpt_uint32 idx;
1476 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1477 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1478 WLANDXE_DescType *currentDescriptor = NULL;
1479 WLANDXE_DescType *nextDescriptor = NULL;
1480
1481 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001482 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001483
1484 /* Sanity */
1485 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1486 {
1487 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1488 "dxeChannelStop Invalid arg input");
1489 return eWLAN_PAL_STATUS_E_INVAL;
1490 }
1491
1492 currentCtrlBlk = channelEntry->headCtrlBlk;
1493 if(NULL != currentCtrlBlk)
1494 {
1495 currentDescriptor = currentCtrlBlk->linkedDesc;
1496 for(idx = 0; idx < channelEntry->numDesc; idx++)
1497 {
1498 if (idx + 1 != channelEntry->numDesc)
1499 {
1500 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1501 nextDescriptor = nextCtrlBlk->linkedDesc;
1502 }
1503 else
1504 {
1505 nextCtrlBlk = NULL;
1506 nextDescriptor = NULL;
1507 }
1508 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
Mihir Shetee6618162015-03-16 14:48:42 +05301509 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
1510 (WDTS_CHANNEL_RX_LOG == channelEntry->channelType))
Jeff Johnson295189b2012-06-20 16:38:30 -07001511 {
1512 if (NULL != currentCtrlBlk->xfrFrame)
1513 {
1514 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1515 wpalPacketFree(currentCtrlBlk->xfrFrame);
1516 }
1517 }
1518 /*
1519 * It is the responsibility of DXE to walk through the
1520 * descriptor chain and unlock any pending packets (if
1521 * locked).
1522 */
1523 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1524 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1525 {
1526 if((NULL != currentCtrlBlk->xfrFrame) &&
1527 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1528 {
1529 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1530 wpalPacketFree(currentCtrlBlk->xfrFrame);
1531 }
1532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001533 wpalMemoryFree(currentCtrlBlk);
1534
1535 currentCtrlBlk = nextCtrlBlk;
1536 currentDescriptor = nextDescriptor;
Madan Mohan Koyyalamudi74719a12012-10-21 12:09:36 -07001537 if(NULL == currentCtrlBlk)
1538 {
1539 /* Already reach last of the control block
1540 * Not need to process anymore, break */
1541 break;
1542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 }
1544 }
1545
Jeff Johnson295189b2012-06-20 16:38:30 -07001546 // descriptors were allocated as a single chunk so free the chunk
1547 if(NULL != channelEntry->descriptorAllocation)
1548 {
1549 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1550 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001551
1552 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001553 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 return status;
1555}
1556
1557/*==========================================================================
1558 @ Function Name
1559 dxeChannelCleanInt
1560
1561 @ Description
1562 Clean up interrupt from RIVA HW
1563 After Host finish to handle interrupt, interrupt signal must be cleaned up
1564 Otherwise next interrupt will not be generated
1565
1566 @ Parameters
1567 WLANDXE_ChannelCBType *channelEntry
1568 Channel specific control block
1569 wpt_uint32 *chStat
1570 Channel Status register value
1571
1572 @ Return
1573 wpt_status
1574
1575===========================================================================*/
1576static wpt_status dxeChannelCleanInt
1577(
1578 WLANDXE_ChannelCBType *channelEntry,
1579 wpt_uint32 *chStat
1580)
1581{
1582 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1583
1584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001585 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001586
1587 /* Read Channel Status Register to know why INT Happen */
1588 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1589 chStat);
1590 if(eWLAN_PAL_STATUS_SUCCESS != status)
1591 {
1592 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1593 "dxeChannelCleanInt Read CH STAT register fail");
1594 return eWLAN_PAL_STATUS_E_FAULT;
1595 }
1596 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1597 "%s Channel INT Clean, Status 0x%x",
1598 channelType[channelEntry->channelType], *chStat);
1599
1600 /* Clean up all the INT within this channel */
1601 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1602 (1 << channelEntry->assignedDMAChannel));
1603 if(eWLAN_PAL_STATUS_SUCCESS != status)
1604 {
1605 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1606 "dxeChannelCleanInt Write CH Clean register fail");
1607 return eWLAN_PAL_STATUS_E_FAULT;
1608 }
1609
Jeff Johnsone7245742012-09-05 17:12:55 -07001610 /* Clean up Error INT Bit */
1611 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1612 {
1613 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1614 (1 << channelEntry->assignedDMAChannel));
1615 if(eWLAN_PAL_STATUS_SUCCESS != status)
1616 {
1617 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1618 "dxeChannelCleanInt Read CH STAT register fail");
1619 return eWLAN_PAL_STATUS_E_FAULT;
1620 }
1621 }
1622
1623 /* Clean up DONE INT Bit */
1624 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1625 {
1626 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1627 (1 << channelEntry->assignedDMAChannel));
1628 if(eWLAN_PAL_STATUS_SUCCESS != status)
1629 {
1630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1631 "dxeChannelCleanInt Read CH STAT register fail");
1632 return eWLAN_PAL_STATUS_E_FAULT;
1633 }
1634 }
1635
1636 /* Clean up ED INT Bit */
1637 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1638 {
1639 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1640 (1 << channelEntry->assignedDMAChannel));
1641 if(eWLAN_PAL_STATUS_SUCCESS != status)
1642 {
1643 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1644 "dxeChannelCleanInt Read CH STAT register fail");
1645 return eWLAN_PAL_STATUS_E_FAULT;
1646 }
1647 }
1648
Jeff Johnson295189b2012-06-20 16:38:30 -07001649 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001650 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 return status;
1652}
1653
Mihir Shete44547fb2014-03-10 14:15:42 +05301654#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Jeff Johnson295189b2012-06-20 16:38:30 -07001655/*==========================================================================
Leo Chang72cdfd32013-10-17 20:36:30 -07001656 @ Function Name
1657 dxeRXResourceAvailableTimerExpHandler
1658
1659 @ Description
1660 During pre-set timeperiod, if free available RX buffer is not allocated
1661 Trigger Driver re-loading to recover RX dead end
1662
1663 @ Parameters
1664 v_VOID_t *usrData
1665 DXE context
1666
1667 @ Return
1668 NONE
1669
1670===========================================================================*/
1671void dxeRXResourceAvailableTimerExpHandler
1672(
1673 void *usrData
1674)
1675{
Katya Nigam93888ff2014-02-10 17:58:11 +05301676 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Mihir Shete058fcff2014-06-26 18:54:06 +05301677 wpt_uint32 numRxFreePackets;
Mihir Sheted183cef2014-09-26 19:17:56 +05301678 wpt_uint32 numAllocFailures;
Katya Nigam93888ff2014-02-10 17:58:11 +05301679
1680 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1681
Leo Chang72cdfd32013-10-17 20:36:30 -07001682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1683 "RX Low resource, Durign wait time period %d, RX resource not allocated",
Katya Nigama6fbf662015-03-17 18:35:47 +05301684 wpalGetDxeReplenishRXTimerVal());
Katya Nigam93888ff2014-02-10 17:58:11 +05301685
Mihir Shete058fcff2014-06-26 18:54:06 +05301686 //This API wil also try to replenish packets
1687 wpalGetNumRxFreePacket(&numRxFreePackets);
Mihir Sheted183cef2014-09-26 19:17:56 +05301688 wpalGetNumRxPacketAllocFailures(&numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301689
Mihir Sheted183cef2014-09-26 19:17:56 +05301690 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1691 "Free Packets: %u, Alloc Failures: %u",
1692 numRxFreePackets, numAllocFailures);
Mihir Shete058fcff2014-06-26 18:54:06 +05301693 if (numRxFreePackets > 0)
1694 {
1695 /* If no. of free packets is greater than 0, it means
1696 * that some packets were replenished and can be used
1697 * by DXE to receive frames. So try to restart the
1698 * resourceAvailable timer here, it will be stopped
1699 * by the DXE's low resource callback if atleast one
1700 * free packet reaches DXE.
1701 */
1702 if (NULL != dxeCtxt)
1703 {
1704 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1705 "%s: Replenish successful. Restart the Rx Low resource timer",
1706 __func__);
1707 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
Katya Nigama6fbf662015-03-17 18:35:47 +05301708 wpalGetDxeReplenishRXTimerVal());
Mihir Shete058fcff2014-06-26 18:54:06 +05301709 return;
1710 }
1711 }
Katya Nigama6fbf662015-03-17 18:35:47 +05301712 if(wpalIsDxeSSREnable())
1713 {
1714 if (NULL != dxeCtxt)
1715 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
Mihir Shete058fcff2014-06-26 18:54:06 +05301716
Katya Nigama6fbf662015-03-17 18:35:47 +05301717 wpalWlanReload();
Katya Nigam93888ff2014-02-10 17:58:11 +05301718
Katya Nigama6fbf662015-03-17 18:35:47 +05301719 if (NULL != usrData)
1720 dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData);
1721 }
1722 else
1723 {
1724 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
1725 wpalGetDxeReplenishRXTimerVal());
1726 }
Mihir Shetefdc9f532014-01-09 15:03:02 +05301727 return;
1728}
Mihir Shete44547fb2014-03-10 14:15:42 +05301729#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05301730
1731/*==========================================================================
1732 @ Function Name
1733 dxeStartSSRTimer
1734
1735 @ Description
1736 Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip,
1737 this makes sure that if the chip does not respond to the FIQ within
1738 the timeout period the dxeSSRTimer expiration handler will take the
1739 appropriate action.
1740
1741 @ Parameters
1742 NONE
1743
1744 @ Return
1745 NONE
1746
1747===========================================================================*/
1748static void dxeStartSSRTimer
1749(
1750 WLANDXE_CtrlBlkType *dxeCtxt
1751)
1752{
1753 if(VOS_TIMER_STATE_RUNNING !=
1754 wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer))
1755 {
1756 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1757 "%s: Starting SSR Timer",__func__);
1758 wpalTimerStart(&dxeCtxt->dxeSSRTimer,
1759 T_WLANDXE_SSR_TIMEOUT);
1760 }
1761}
1762
1763/*==========================================================================
1764 @ Function Name
1765 dxeSSRTimerExpHandler
1766
1767 @ Description
1768 Issue an explicit subsystem restart of the wcnss subsystem if the
1769 WCN chip does not respond to the FIQ within the timeout period
1770
1771 @ Parameters
1772 v_VOID_t *usrData
1773
1774 @ Return
1775 NONE
1776
1777===========================================================================*/
1778void dxeSSRTimerExpHandler
1779(
1780 void *usrData
1781)
1782{
1783 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1784 "DXE not shutdown %d ms after FIQ!! Issue SSR",
1785 T_WLANDXE_SSR_TIMEOUT);
1786 wpalRivaSubystemRestart();
1787
Leo Chang72cdfd32013-10-17 20:36:30 -07001788 return;
1789}
1790
1791/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001792 @ Function Name
1793 dxeRXPacketAvailableCB
1794
1795 @ Description
1796 If RX frame handler encounts RX buffer pool empty condition,
1797 DXE RX handle loop will be blocked till get available RX buffer pool.
1798 When new RX buffer pool available, Packet available CB function will
1799 be called.
1800
1801 @ Parameters
1802 wpt_packet *freePacket
1803 Newly allocated RX buffer
1804 v_VOID_t *usrData
1805 DXE context
1806
1807 @ Return
1808 NONE
1809
1810===========================================================================*/
1811void dxeRXPacketAvailableCB
1812(
1813 wpt_packet *freePacket,
1814 v_VOID_t *usrData
1815)
1816{
1817 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1818 wpt_status status;
1819
1820 /* Simple Sanity */
1821 if((NULL == freePacket) || (NULL == usrData))
1822 {
1823 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1824 "Get Free RX Buffer fail, Critical Error");
1825 HDXE_ASSERT(0);
1826 return;
1827 }
1828
1829 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1830
1831 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1832 {
1833 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1834 "DXE Context data corrupted, Critical Error");
1835 HDXE_ASSERT(0);
1836 return;
1837 }
1838
1839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1840 "DXE RX packet available, post MSG to RX Thread");
1841
1842 dxeCtxt->freeRXPacket = freePacket;
1843
1844 /* Serialize RX Packet Available message upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08001845 if (NULL == dxeCtxt->rxPktAvailMsg)
1846 {
1847 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1848 "DXE NULL pkt");
1849 HDXE_ASSERT(0);
1850 return;
1851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001852
1853 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1854 dxeCtxt->rxPktAvailMsg);
1855 if(eWLAN_PAL_STATUS_SUCCESS != status)
1856 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001857 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1858 "dxeRXPacketAvailableCB serialize fail");
1859 }
1860
1861 return;
1862}
1863
1864/*==========================================================================
1865 @ Function Name
1866 dxeRXFrameSingleBufferAlloc
1867
1868 @ Description
1869 Allocate Platform packet buffer to prepare RX frame
1870 RX frame memory space must be pre allocted and must be asigned to
1871 descriptor
1872 then whenever DMA engine want to tranfer frame from BMU,
1873 buffer must be ready
1874
1875 @ Parameters
1876 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1877 DXE host driver main control block
1878 WLANDXE_ChannelCBType *channelEntry
1879 Channel specific control block
1880 WLANDXE_DescCtrlBlkType currentCtrlBlock
1881 current control block which have to be asigned
1882 frame buffer
1883
1884 @ Return
1885 wpt_status
1886
1887===========================================================================*/
1888static wpt_status dxeRXFrameSingleBufferAlloc
1889(
1890 WLANDXE_CtrlBlkType *dxeCtxt,
1891 WLANDXE_ChannelCBType *channelEntry,
1892 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1893)
1894{
1895 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1896 wpt_packet *currentPalPacketBuffer = NULL;
1897 WLANDXE_DescType *currentDesc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001898 wpt_iterator iterator;
1899 wpt_uint32 allocatedSize = 0;
1900 void *physAddress = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07001901
1902 currentDesc = currentCtrlBlock->linkedDesc;
1903
Leo Chang7e05f212013-07-01 19:54:15 -07001904 if(currentDesc->descCtrl.valid)
1905 {
1906 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1907 "This Descriptor is valid, Do not refill");
1908 return eWLAN_PAL_STATUS_E_EXISTS;
1909 }
1910
Jeff Johnson295189b2012-06-20 16:38:30 -07001911 /* First check if a packet pointer has already been provided by a previously
1912 invoked Rx packet available callback. If so use that packet. */
Sravan Kumar Kairam7b8c3852016-03-28 15:54:05 +05301913 if (dxeCtxt->rxPalPacketUnavailable)
Jeff Johnson295189b2012-06-20 16:38:30 -07001914 {
Sravan Kumar Kairam7b8c3852016-03-28 15:54:05 +05301915 if (NULL != dxeCtxt->freeRXPacket)
Mihir Sheted183cef2014-09-26 19:17:56 +05301916 {
Sravan Kumar Kairam7b8c3852016-03-28 15:54:05 +05301917 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1918 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1919 dxeCtxt->freeRXPacket = NULL;
1920
1921 if (channelEntry->doneIntDisabled)
1922 {
1923 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
1924 channelEntry->extraConfig.chan_mask);
1925 channelEntry->doneIntDisabled = 0;
1926 }
1927 }
1928 else if (VOS_TIMER_STATE_RUNNING !=
1929 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
1930 {
1931 if (eWLAN_PAL_STATUS_SUCCESS !=
1932 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
1933 wpalGetDxeReplenishRXTimerVal()))
1934 {
1935 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1936 "RX resource available timer not started");
1937 }
1938 else
1939 dxeEnvBlk.rx_low_resource_timer = 1;
Mihir Sheted183cef2014-09-26 19:17:56 +05301940 }
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");
Sravan Kumar Kairam7b8c3852016-03-28 15:54:05 +05301961 if (eWLAN_PAL_STATUS_SUCCESS !=
1962 wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer,
1963 wpalGetDxeReplenishRXTimerVal()))
1964 {
1965 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1966 "RX resource available timer not started");
1967 }
1968 else
1969 dxeEnvBlk.rx_low_resource_timer = 1;
Leo Chang72cdfd32013-10-17 20:36:30 -07001970 }
Mihir Shete44547fb2014-03-10 14:15:42 +05301971#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 }
1973 }
1974
1975 if(NULL == currentPalPacketBuffer)
1976 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 return eWLAN_PAL_STATUS_E_RESOURCES;
1978 }
1979
1980 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1981 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1982 currentPalPacketBuffer->pBD = NULL;
1983 currentPalPacketBuffer->pBDPhys = NULL;
1984 currentPalPacketBuffer->BDLength = 0;
Mihir Shete5affadc2015-05-29 20:54:57 +05301985
1986 if (channelEntry->channelType == WDTS_CHANNEL_RX_FW_LOG)
Hanumantha Reddy Pothulabd3303c2015-07-15 17:22:00 +05301987 wpalPacketRawTrimHead(currentCtrlBlock->xfrFrame, WLANDXE_NL_HEADER_SZ);
Mihir Shete5affadc2015-05-29 20:54:57 +05301988
Jeff Johnson295189b2012-06-20 16:38:30 -07001989 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
Mihir Shetebc338242015-03-04 15:34:19 +05301990
Jeff Johnson295189b2012-06-20 16:38:30 -07001991 if(eWLAN_PAL_STATUS_SUCCESS != status)
1992 {
1993 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1994 "dxeRXFrameBufferAlloc unable to lock packet");
1995 return status;
1996 }
1997
1998 /* Init iterator to get physical os buffer address */
1999 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
2000 if(eWLAN_PAL_STATUS_SUCCESS != status)
2001 {
2002 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2003 "dxeRXFrameBufferAlloc iterator init fail");
2004 return status;
2005 }
2006 status = wpalIteratorNext(&iterator,
2007 currentPalPacketBuffer,
2008 &physAddress,
2009 &allocatedSize);
2010 if(eWLAN_PAL_STATUS_SUCCESS != status)
2011 {
2012 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2013 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
2014 return status;
2015 }
2016 currentPalPacketBuffer->pBDPhys = physAddress;
Jeff Johnson295189b2012-06-20 16:38:30 -07002017
2018 /* DXE descriptor must have SWAPPED addres in it's structure
2019 * !!! SWAPPED !!! */
2020 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05302021 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys);
Jeff Johnson295189b2012-06-20 16:38:30 -07002022
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 return status;
2024}
2025
2026/*==========================================================================
2027 @ Function Name
2028 dxeRXFrameRefillRing
2029
2030 @ Description
2031 Allocate Platform packet buffers to try to fill up the DXE Rx ring
2032
2033 @ Parameters
2034 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2035 DXE host driver main control block
2036 WLANDXE_ChannelCBType *channelEntry
2037 Channel specific control block
2038
2039 @ Return
2040 wpt_status
2041
2042===========================================================================*/
2043static wpt_status dxeRXFrameRefillRing
2044(
2045 WLANDXE_CtrlBlkType *dxeCtxt,
2046 WLANDXE_ChannelCBType *channelEntry
2047)
2048{
2049 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2050 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2051 WLANDXE_DescType *currentDesc = NULL;
2052
2053 while(channelEntry->numFreeDesc > 0)
2054 {
2055 /* Current Control block is free
2056 * and associated frame buffer is not linked with control block anymore
2057 * allocate new frame buffer for current control block */
2058 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2059 channelEntry,
2060 currentCtrlBlk);
2061
Leo Chang7e05f212013-07-01 19:54:15 -07002062 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2063 (eWLAN_PAL_STATUS_E_EXISTS != status))
Jeff Johnson295189b2012-06-20 16:38:30 -07002064 {
2065 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2066 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
2067 break;
2068 }
2069
Leo Chang7e05f212013-07-01 19:54:15 -07002070 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2071 {
2072 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2073 "dxeRXFrameRefillRing, Descriptor Non-Empry");
2074 }
2075
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 currentDesc = currentCtrlBlk->linkedDesc;
2077 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
2078
2079 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2080 that any posted writes are reflected in memory before DXE looks at
2081 the descriptor. */
2082 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2083 {
Karthick S3254c5d2015-04-28 15:06:17 +05302084 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2085 "dxeRXFrameRefillRing, Descriptor write failed");
2086 ++channelEntry->desc_write_fail_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 //HDXE_ASSERT(0);
2088 }
2089
2090 /* Kick off the DXE ring, if not in any power save mode */
Leo Chang094ece82013-04-23 17:57:41 -07002091 if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07002092 {
2093 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
2094 1 << channelEntry->assignedDMAChannel);
2095 }
2096 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
Leo Chang7e05f212013-07-01 19:54:15 -07002097 if(eWLAN_PAL_STATUS_E_EXISTS != status)
2098 {
2099 --channelEntry->numFreeDesc;
2100 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 }
2102
2103 channelEntry->tailCtrlBlk = currentCtrlBlk;
2104
2105 return status;
2106}
2107
Mihir Shete5affadc2015-05-29 20:54:57 +05302108static wpt_uint32 dxeRXLogRefillRing
2109(
2110 WLANDXE_CtrlBlkType *dxeCtxt,
2111 WLANDXE_ChannelCBType *channelEntry,
2112 wpt_uint64 bufferAddr,
2113 wpt_uint32 bufferLen
2114)
2115{
2116 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2117 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
2118 WLANDXE_DescType *currentDesc = NULL;
2119 wpt_uint32 xfrSize, allocatedLen = 0;
2120
Karthick Sed59a282015-08-10 14:52:16 +05302121 while(bufferLen > 0 && channelEntry->numFreeDesc > 0)
Mihir Shete5affadc2015-05-29 20:54:57 +05302122 {
2123 /* Current Control block is free
2124 * and associated frame buffer is not linked with control block anymore
2125 * allocate new frame buffer for current control block */
2126 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
2127 channelEntry,
2128 currentCtrlBlk);
2129
Karthick S122fa9e2015-07-24 17:20:03 +05302130 if((eWLAN_PAL_STATUS_SUCCESS != status) &&
2131 (eWLAN_PAL_STATUS_E_EXISTS != status))
Mihir Shete5affadc2015-05-29 20:54:57 +05302132 {
2133 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Karthick S122fa9e2015-07-24 17:20:03 +05302134 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
Mihir Shete5affadc2015-05-29 20:54:57 +05302135 break;
2136 }
2137
2138 if(eWLAN_PAL_STATUS_E_EXISTS == status)
2139 {
2140 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2141 "%s, Descriptor Non-Empty",__func__);
2142 }
2143
2144 currentDesc = currentCtrlBlk->linkedDesc;
2145 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
Hanumantha Reddy Pothulabd3303c2015-07-15 17:22:00 +05302146 xfrSize = WLANDXE_FW_LOGGING_XFSIZE > bufferLen ?
2147 bufferLen : WLANDXE_FW_LOGGING_XFSIZE;
Mihir Shete5affadc2015-05-29 20:54:57 +05302148 currentDesc->xfrSize = xfrSize;
2149 allocatedLen += xfrSize;
2150 bufferLen -= xfrSize;
2151 wpalPacketSetRxLength(currentCtrlBlk->xfrFrame,
2152 xfrSize);
2153
2154 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2155 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)bufferAddr);
2156
2157 /* Issue a dummy read from the DXE descriptor DDR location to ensure
2158 that any posted writes are reflected in memory before DXE looks at
2159 the descriptor. */
2160 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
2161 {
2162 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2163 "%s, Descriptor write failed",__func__);
2164 ++channelEntry->desc_write_fail_count;
2165 }
2166
2167 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2168 --channelEntry->numFreeDesc;
2169 bufferAddr += xfrSize;
2170 }
2171
2172 channelEntry->tailCtrlBlk = currentCtrlBlk;
2173
2174 return allocatedLen;
2175}
Jeff Johnson295189b2012-06-20 16:38:30 -07002176/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07002177 @ Function Name
2178 dxeRXFrameRouteUpperLayer
2179
2180 @ Description
2181 Test DXE descriptors and if any RX frame pending within RING,
2182 Route to upper layer
2183
2184 @ Parameters
2185 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2186 DXE host driver main control block
2187 WLANDXE_ChannelCBType *channelEntry
2188 Channel specific control block
2189 @ Return
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002190 < 0 Any error happen
Jeff Johnsone7245742012-09-05 17:12:55 -07002191 0 No frame pulled from RX RING
2192 int number of RX frames pulled from RX ring
2193
2194===========================================================================*/
2195static wpt_int32 dxeRXFrameRouteUpperLayer
2196(
2197 WLANDXE_CtrlBlkType *dxeCtxt,
2198 WLANDXE_ChannelCBType *channelEntry
2199)
2200{
2201 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2202 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2203 WLANDXE_DescType *currentDesc = NULL;
2204 wpt_uint32 descCtrl, frameCount = 0, i;
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002205 wpt_int32 ret_val = -1;
Jeff Johnsone7245742012-09-05 17:12:55 -07002206
2207 currentCtrlBlk = channelEntry->headCtrlBlk;
2208 currentDesc = currentCtrlBlk->linkedDesc;
2209
2210 /* Descriptoe should be SWAPPED ???? */
2211 descCtrl = currentDesc->descCtrl.ctrl;
2212
2213 /* Get frames while VALID bit is not set (DMA complete) and a data
2214 * associated with it */
2215 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
2216 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
2217 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
2218 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
2219 {
2220 channelEntry->numTotalFrame++;
2221 channelEntry->numFreeDesc++;
Jeff Johnsone7245742012-09-05 17:12:55 -07002222 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
Mihir Shetebc338242015-03-04 15:34:19 +05302223
Jeff Johnsone7245742012-09-05 17:12:55 -07002224 if (eWLAN_PAL_STATUS_SUCCESS != status)
2225 {
2226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2227 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08002228 return ret_val;
Jeff Johnsone7245742012-09-05 17:12:55 -07002229 }
Mihir Shetebc338242015-03-04 15:34:19 +05302230
Jeff Johnsone7245742012-09-05 17:12:55 -07002231 /* This Descriptor is valid, so linked Control block is also valid
2232 * Linked Control block has pre allocated packet buffer
2233 * So, just let upper layer knows preallocated frame pointer will be OK */
2234 /* Reap Rx frames */
2235 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
2236 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002237 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002238
2239 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
Mihir Shete5affadc2015-05-29 20:54:57 +05302240 if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType)
2241 dxeRXFrameRefillRing(dxeCtxt, channelEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07002242
2243 /* Test next contorl block
2244 * if valid, this control block also has new RX frame must be handled */
2245 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2246 currentDesc = currentCtrlBlk->linkedDesc;
2247 descCtrl = currentDesc->descCtrl.ctrl;
2248 }
2249
2250 /* Update head control block
2251 * current control block's valid bit was 0
2252 * next trial first control block must be current control block */
2253 channelEntry->headCtrlBlk = currentCtrlBlk;
2254
2255 /* Deliver all the reaped RX frames to upper layers */
2256 i = 0;
Leo Changd6de1c22013-03-21 15:42:41 -07002257 while(i < frameCount)
2258 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002259 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
2260 i++;
2261 }
2262
2263 return frameCount;
2264}
2265
2266/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 @ Function Name
2268 dxeRXFrameReady
2269
2270 @ Description
2271 Pop frame from descriptor and route frame to upper transport layer
2272 Assign new platform packet buffer into used descriptor
2273 Actual frame pop and resource realloc
2274
2275 @ Parameters
2276 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2277 DXE host driver main control block
2278 WLANDXE_ChannelCBType *channelEntry
2279 Channel specific control block
2280
2281 @ Return
2282 wpt_status
2283
2284===========================================================================*/
2285static wpt_status dxeRXFrameReady
2286(
2287 WLANDXE_CtrlBlkType *dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002288 WLANDXE_ChannelCBType *channelEntry,
2289 wpt_uint32 chStat
Jeff Johnson295189b2012-06-20 16:38:30 -07002290)
2291{
2292 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2293 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2294 WLANDXE_DescType *currentDesc = NULL;
2295 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002296 wpt_int32 frameCount = 0;
2297
2298 wpt_uint32 descLoop;
2299 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002300
2301 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002302 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002303
2304 /* Sanity Check */
2305 if((NULL == dxeCtxt) || (NULL == channelEntry))
2306 {
2307 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2308 "dxeRXFrameReady Channel Entry is not valid");
2309 return eWLAN_PAL_STATUS_E_INVAL;
2310 }
2311
Jeff Johnsone7245742012-09-05 17:12:55 -07002312 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002313
Jeff Johnsone7245742012-09-05 17:12:55 -07002314 if(0 > frameCount)
Leo Changd6de1c22013-03-21 15:42:41 -07002315 {
2316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002317 "dxeRXFrameReady RX frame route fail");
Leo Changd6de1c22013-03-21 15:42:41 -07002318 return eWLAN_PAL_STATUS_E_INVAL;
2319 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002320
Leo Changd6de1c22013-03-21 15:42:41 -07002321 if((0 == frameCount) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07002322 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
2323 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
2324 {
Leo Changd6de1c22013-03-21 15:42:41 -07002325 /* None of the frame handled and CH is not enabled
2326 * RX CH wrap around happen and No RX free frame
2327 * RX side should wait till new free frame available in the pool
2328 * Do not try reload driver at here*/
2329 if(!(chStat & WLANDXE_CH_CTRL_EN_MASK))
2330 {
Leo Changbbf86b72013-06-19 16:13:00 -07002331 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Leo Changd6de1c22013-03-21 15:42:41 -07002332 "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x",
2333 channelType[channelEntry->channelType], chStat);
Leo Chang3714c922013-07-10 20:33:30 -07002334 /* This is not empty interrupt case
2335 * If handle this as empty interrupt, false SSR might be issued
2336 * Frame count '1' is dummy frame count to avoid SSR */
2337 channelEntry->numFragmentCurrentChain = 1;
Leo Changd6de1c22013-03-21 15:42:41 -07002338 return eWLAN_PAL_STATUS_SUCCESS;
2339 }
2340
Jeff Johnsone7245742012-09-05 17:12:55 -07002341 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07002342 currentDesc = currentCtrlBlk->linkedDesc;
2343 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07002344
2345 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
2346 {
2347 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2348 "RX ISR called but no frame handled PWS %d, channel %s",
2349 (int)dxeCtxt->hostPowerState,
2350 channelType[channelEntry->channelType]);
2351 }
2352
2353 /* Current interupt empty and previous interrupt also empty
2354 * detected successive empty interrupt
2355 * or first interrupt empty, this should not happen */
2356 if(0 == channelEntry->numFragmentCurrentChain)
2357 {
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07002358 dxeChannelMonitor("RX Ready", channelEntry, NULL);
2359 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
2360 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL);
2361 dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL);
Jeff Johnsone7245742012-09-05 17:12:55 -07002362 /* Abnormal interrupt detected, try to find not validated descriptor */
2363 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
2364 {
2365 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
2366 {
Leo Chang416afe02013-07-01 13:58:13 -07002367 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002368 "Found Invalidated Descriptor %d", (int)descLoop);
2369 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
2370 {
Leo Chang416afe02013-07-01 13:58:13 -07002371 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002372 "Packet locked, Resync Host and HW");
2373 channelEntry->headCtrlBlk = currentCtrlBlk;
2374 invalidatedFound = 1;
2375 break;
2376 }
2377 else
2378 {
Leo Chang416afe02013-07-01 13:58:13 -07002379 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Jeff Johnsone7245742012-09-05 17:12:55 -07002380 "Packet Not Locked, cannot transfer frame");
2381 }
2382 }
2383 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
2384 currentDesc = currentCtrlBlk->linkedDesc;
2385 descCtrl = currentDesc->descCtrl.ctrl;
2386 }
2387
Jeff Johnson32d95a32012-09-10 13:15:23 -07002388 /* Invalidated descriptor found, and that is not head descriptor
2389 * This means HW/SW descriptor miss match happen, and we may recover with just resync
2390 * Try re-sync here */
2391 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07002392 {
2393 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2394 "Found New Sync location with HW, handle frames from there");
2395 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
2396 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2397 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07002398 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07002399 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002400 /* Successive Empty interrupt
2401 * But this case, first descriptor also invalidated, then it means head descriptor
2402 * is linked with already handled RX frame, then could not unlock RX frame
2403 * This is just Out of RX buffer pool, not need to anything here */
2404 else if((invalidatedFound) && (0 == descLoop))
2405 {
2406 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2407 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
2408 }
2409 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07002410 else
2411 {
2412 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2413 "Could not found invalidated descriptor");
2414 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2415 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
2416 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2417 wpalWlanReload();
Mihir Shetefdc9f532014-01-09 15:03:02 +05302418 dxeStartSSRTimer(dxeCtxt);
Jeff Johnsone7245742012-09-05 17:12:55 -07002419 }
2420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002421 }
Madan Mohan Koyyalamudi6646aad2012-09-24 14:10:39 -07002422 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002424 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002425 return status;
2426}
2427
2428/*==========================================================================
2429 @ Function Name
2430 dxeNotifySmsm
2431
2432 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
2433 buffer
2434
2435 @ Parameters
2436
2437 @ Return
2438 wpt_status
2439
2440===========================================================================*/
2441static wpt_status dxeNotifySmsm
2442(
2443 wpt_boolean kickDxe,
2444 wpt_boolean ringEmpty
2445)
2446{
2447 wpt_uint32 clrSt = 0;
2448 wpt_uint32 setSt = 0;
2449
2450 if(kickDxe)
2451 {
2452 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
2453
2454 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
2455 {
2456 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2457 tempDxeCtrlBlk->lastKickOffDxe = 1;
2458 }
2459 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
2460 {
2461 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
2462 tempDxeCtrlBlk->lastKickOffDxe = 0;
2463 }
2464 else
2465 {
2466 HDXE_ASSERT(0);
2467 }
2468 }
2469 else
2470 {
2471 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
2472 }
2473
Mihir Shete68ed77a2014-10-10 10:47:12 +05302474 tempDxeCtrlBlk->txRingsEmpty = ringEmpty;
Jeff Johnson295189b2012-06-20 16:38:30 -07002475 if(ringEmpty)
2476 {
2477 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
2478 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2479 }
2480 else
2481 {
2482 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
2483 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
2484 }
2485
2486 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
2487
Karthick Sc6ec8362015-08-12 18:18:47 +05302488 /* Store the smsm notification sent to firmware */
2489 tempDxeCtrlBlk->smsmDxeHistogram = (tempDxeCtrlBlk->smsmDxeHistogram << 1);
2490 if(setSt & WPAL_SMSM_WLAN_TX_ENABLE)
2491 {
2492 tempDxeCtrlBlk->smsmDxeHistogram |= 1;
2493 }
2494 else
2495 {
2496 tempDxeCtrlBlk->smsmDxeHistogram &= ~((wpt_uint32)1);
2497 }
2498 tempDxeCtrlBlk->smsmRingsEmptyHistogram = (tempDxeCtrlBlk->smsmRingsEmptyHistogram << 1);
2499 if(setSt & WPAL_SMSM_WLAN_TX_RINGS_EMPTY)
2500 {
2501 tempDxeCtrlBlk->smsmRingsEmptyHistogram |= 1;
2502 }
2503 else
2504 {
2505 tempDxeCtrlBlk->smsmRingsEmptyHistogram &= ~((wpt_uint32)1);
2506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002507 wpalNotifySmsm(clrSt, setSt);
2508
2509 return eWLAN_PAL_STATUS_SUCCESS;
2510}
2511
2512/*==========================================================================
2513 @ Function Name
2514 dxePsComplete
2515
2516 @ Description: Utility function to check the resv desc to deside if we can
2517 get into Power Save mode now
2518
2519 @ Parameters
2520
2521 @ Return
2522 None
2523
2524===========================================================================*/
2525static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
2526{
2527 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
2528 {
2529 return;
2530 }
2531
2532 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
2533 //must have been consumed by RIVA, OK to get into BMPS
2534 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2535 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
2536 {
2537 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
2538 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
2539 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
2540 {
2541 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
2542 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
2543 }
2544 }
2545 else //still more pkts to be served by RIVA
2546 {
2547 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2548
2549 switch(dxeCtxt->rivaPowerState)
2550 {
2551 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
2552 //NOP
2553 break;
2554 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
2555 if(intr_based)
2556 {
2557 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
2558 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2559 }
2560 break;
2561 default:
2562 //assert
2563 break;
2564 }
2565 }
2566}
2567
2568/*==========================================================================
2569 @ Function Name
2570 dxeRXEventHandler
2571
2572 @ Description
2573 Handle serailized RX frame ready event
2574 First disable interrupt then pick up frame from pre allocated buffer
2575 Since frame handle is doen, clear interrupt bit to ready next interrupt
2576 Finally re enable interrupt
2577
2578 @ Parameters
2579 wpt_msg *rxReadyMsg
2580 RX frame ready MSG pointer
2581 include DXE control context
2582
2583 @ Return
2584 NONE
2585
2586===========================================================================*/
2587void dxeRXEventHandler
2588(
2589 wpt_msg *rxReadyMsg
2590)
2591{
2592 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
2593 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2594 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2595 wpt_uint32 intSrc = 0;
2596 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07002597 wpt_uint32 chHighStat = 0;
2598 wpt_uint32 chLowStat = 0;
Mihir Shetee6618162015-03-16 14:48:42 +05302599 wpt_uint32 chLogRxStat = 0;
Mihir Shetec4093f92015-05-28 15:21:11 +05302600 wpt_uint32 chLogRxFwStat = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302601 wpt_uint32 regValue, chanMask;
Jeff Johnson295189b2012-06-20 16:38:30 -07002602
Jeff Johnsone7245742012-09-05 17:12:55 -07002603 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07002604
Jeff Johnsone7245742012-09-05 17:12:55 -07002605 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07002606 {
2607 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07002608 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07002609 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07002610 }
2611
Jeff Johnsone7245742012-09-05 17:12:55 -07002612 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
2613 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
2614 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
Mihir Shetee6618162015-03-16 14:48:42 +05302615 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2616 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]);
Jeff Johnson295189b2012-06-20 16:38:30 -07002617
2618 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
Mihir Shetee6618162015-03-16 14:48:42 +05302619 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled) ||
2620 (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) &&
2621 !dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chEnabled))
Jeff Johnson295189b2012-06-20 16:38:30 -07002622 {
2623 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2624 "DXE already stopped in RX event handler. Just return");
2625 return;
2626 }
2627
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302628 /* Disable device interrupt */
2629 /* Read whole interrupt mask register and exclusive only this channel int */
2630 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2631 &intSrc);
2632 if(eWLAN_PAL_STATUS_SUCCESS != status)
2633 {
2634 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2635 "dxeRXEventHandler Read INT_SRC register fail");
2636 return;
2637 }
2638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2639 "RX Event Handler INT Source 0x%x", intSrc);
2640
2641 dxeEnvBlk.rxIntChanlSrc = intSrc&0xFF;
2642
Jeff Johnson295189b2012-06-20 16:38:30 -07002643 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2644 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2645 {
Sravan Kumar Kairam3d22ec02016-08-01 12:58:44 +05302646 if (WLANDXE_POWER_STATE_DOWN != dxeCtxt->hostPowerState)
Mihir Shetec4093f92015-05-28 15:21:11 +05302647 {
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302648 if(0 == intSrc)
Mihir Shetec4093f92015-05-28 15:21:11 +05302649 {
2650 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2651 "%s: Read status: %d, regVal: %d",
2652 __func__, status, intSrc);
2653 }
2654 else
2655 {
2656 /* Register Read was succesful and we have a valid interrupt
2657 * source, so WCN is not power collapsed yet and it should
2658 * not power collapse till we set the synchronization bit
2659 * at the end of this function, safe to pull frames...
2660 */
2661 goto pull_frames;
2662 }
2663 }
2664
Sravan Kumar Kairam3d22ec02016-08-01 12:58:44 +05302665 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2666 "%s Riva is in %d, Just Pull frames without any register touch",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002667 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002668
2669 /* Not to touch any register, just pull frame directly from chain ring
2670 * First high priority */
2671 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2672 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002673 channelCb,
2674 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002675 if(eWLAN_PAL_STATUS_SUCCESS != status)
2676 {
2677 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Sravan Kumar Kairam3d22ec02016-08-01 12:58:44 +05302678 "dxeRXEventHandler Pull from RX high channel fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002679 }
Leo Chang46f36162014-01-14 21:47:24 -08002680 /* In case FW could not power collapse in IMPS mode
2681 * Next power restore might have empty interrupt
2682 * If IMPS mode has empty interrupt since RX thread race,
2683 * Invalid re-load driver might happen
2684 * To prevent invalid re-load driver,
2685 * IMPS event handler set dummpy frame count */
2686 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002687
2688 /* Second low priority */
2689 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2690 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002691 channelCb,
2692 chLowStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002693 if(eWLAN_PAL_STATUS_SUCCESS != status)
2694 {
2695 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Mihir Shetee6618162015-03-16 14:48:42 +05302696 "dxeRXEventHandler Pull from RX low channel fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07002697 }
Leo Chang46f36162014-01-14 21:47:24 -08002698 /* LOW Priority CH same above */
2699 channelCb->numFragmentCurrentChain = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002700
Mihir Shetee6618162015-03-16 14:48:42 +05302701 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2702 {
2703 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2704 status = dxeRXFrameReady(dxeCtxt,
2705 channelCb,
2706 chLogRxStat);
2707 if(eWLAN_PAL_STATUS_SUCCESS != status)
2708 {
2709 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2710 "dxeRXEventHandler Pull from RX log channel fail");
2711 }
2712 channelCb->numFragmentCurrentChain = 1;
2713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002714 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2715 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05302716 dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS;
Sravan Kumar Kairam84e995f2016-05-27 16:16:21 +05302717 dxeEnvBlk.rxIntDisableFrame = __builtin_frame_address(0);
2718 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Sravan Kumar Kairam3d22ec02016-08-01 12:58:44 +05302719 "%s Host is in %d RX Int Disabled",
2720 __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07002721 return;
2722 }
2723
Mihir Shetec4093f92015-05-28 15:21:11 +05302724pull_frames:
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 /* Test High Priority Channel interrupt is enabled or not */
2726 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2727 if(intSrc & (1 << channelCb->assignedDMAChannel))
2728 {
2729 status = dxeChannelCleanInt(channelCb, &chHighStat);
2730 if(eWLAN_PAL_STATUS_SUCCESS != status)
2731 {
2732 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2733 "dxeRXEventHandler INT Clean up fail");
2734 return;
2735 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002736 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2737 {
2738 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002739 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2740 "%11s : 0x%x Error Reported, Reload Driver",
2741 channelType[channelCb->channelType], chHighStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302742
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302743 if (eWLAN_PAL_STATUS_SUCCESS != dxeErrHandler(channelCb, chHighStat))
2744 {
2745 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2746 wpalWlanReload();
2747 dxeStartSSRTimer(dxeCtxt);
2748 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002750 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2751 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002752 {
2753 /* Handle RX Ready for high priority channel */
2754 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002755 channelCb,
2756 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002757 }
2758 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2759 {
2760 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002761 channelCb,
2762 chHighStat);
Jeff Johnson295189b2012-06-20 16:38:30 -07002763 }
2764 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2765 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002766 /* Update the Rx DONE histogram */
2767 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2768 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2769 {
2770 channelCb->rxDoneHistogram |= 1;
2771 }
2772 else
2773 {
jagadeeshf869bba2015-04-07 20:06:21 +05302774 channelCb->rxDoneHistogram &= ~((wpt_uint64)1);
Jeff Johnsone7245742012-09-05 17:12:55 -07002775 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002777
2778 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002779 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002780 if(intSrc & (1 << channelCb->assignedDMAChannel))
2781 {
2782 status = dxeChannelCleanInt(channelCb, &chLowStat);
2783 if(eWLAN_PAL_STATUS_SUCCESS != status)
2784 {
2785 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2786 "dxeRXEventHandler INT Clean up fail");
2787 return;
2788 }
2789
2790 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2791 {
2792 /* Error Happen during transaction, Handle it */
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08002793 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2794 "%11s : 0x%x Error Reported, Reload Driver",
2795 channelType[channelCb->channelType], chLowStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05302796
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302797 if (eWLAN_PAL_STATUS_SUCCESS !=
2798 dxeErrHandler(channelCb, chLowStat))
2799 {
2800 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2801 wpalWlanReload();
2802 dxeStartSSRTimer(dxeCtxt);
2803 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 }
Mihir Shetef2000552014-05-12 16:21:34 +05302805 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) ||
2806 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002807 {
2808 /* Handle RX Ready for low priority channel */
2809 status = dxeRXFrameReady(dxeCtxt,
Leo Changd6de1c22013-03-21 15:42:41 -07002810 channelCb,
2811 chLowStat);
Jeff Johnsone7245742012-09-05 17:12:55 -07002812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002813
2814 /* Update the Rx DONE histogram */
2815 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2816 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2817 {
2818 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002819 }
2820 else
2821 {
jagadeeshf869bba2015-04-07 20:06:21 +05302822 channelCb->rxDoneHistogram &= ~((wpt_uint64)1);
Jeff Johnson295189b2012-06-20 16:38:30 -07002823 }
2824 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2825 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2826 }
Mihir Shetee6618162015-03-16 14:48:42 +05302827
2828 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
2829 {
2830 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
2831
2832 if(intSrc & (1 << channelCb->assignedDMAChannel))
2833 {
2834 status = dxeChannelCleanInt(channelCb,&chLogRxStat);
2835 if(eWLAN_PAL_STATUS_SUCCESS != status)
2836 {
2837 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2838 "dxeRXEventHandler INT Clean up fail");
2839 return;
2840 }
2841
2842 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxStat)
2843 {
2844 /* Error Happen during transaction, Handle it */
2845 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2846 "%11s : 0x%x Error Reported, Reload Driver",
2847 channelType[channelCb->channelType], chLogRxStat);
2848
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302849 if (eWLAN_PAL_STATUS_SUCCESS !=
2850 dxeErrHandler(channelCb, chLogRxStat))
2851 {
2852 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2853 wpalWlanReload();
2854 dxeStartSSRTimer(dxeCtxt);
2855 }
Mihir Shetee6618162015-03-16 14:48:42 +05302856
Mihir Shetee6618162015-03-16 14:48:42 +05302857 }
2858 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxStat) ||
2859 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
2860 {
2861 /* Handle RX Ready for low priority channel */
2862 status = dxeRXFrameReady(dxeCtxt,
2863 channelCb,
2864 chLogRxStat);
2865 }
2866
2867 /* Update the Rx DONE histogram */
2868 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2869 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)
2870 {
2871 channelCb->rxDoneHistogram |= 1;
2872 }
2873 else
2874 {
2875 channelCb->rxDoneHistogram &= ~1;
2876 }
2877 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2878 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxStat, channelCb->numFragmentCurrentChain);
2879 }
2880 }
2881
Mihir Shetec4093f92015-05-28 15:21:11 +05302882 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_FW_LOG))
2883 {
2884 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
2885
2886 if(intSrc & (1 << channelCb->assignedDMAChannel))
2887 {
2888 status = dxeChannelCleanInt(channelCb,&chLogRxFwStat);
2889 if(eWLAN_PAL_STATUS_SUCCESS != status)
2890 {
2891 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2892 "dxeRXEventHandler INT Clean up fail");
2893 return;
2894 }
2895
2896 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxFwStat)
2897 {
2898 /* Error Happen during transaction, Handle it */
2899 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2900 "%11s : 0x%x Error Reported, Reload Driver",
2901 channelType[channelCb->channelType], chLogRxFwStat);
2902
Mihir Shetedfc33ec2014-10-15 13:14:38 +05302903 if (eWLAN_PAL_STATUS_SUCCESS !=
2904 dxeErrHandler(channelCb, chLogRxFwStat))
2905 {
2906 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
2907 wpalWlanReload();
2908 dxeStartSSRTimer(dxeCtxt);
2909 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302910
Mihir Shetec4093f92015-05-28 15:21:11 +05302911 }
2912 else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxFwStat) ||
2913 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat))
2914 {
2915 if (!dxeCtxt->hostInitiatedH2H)
2916 {
2917 dxeCtxt->receiveMbMsgCB(dxeCtxt->clientCtxt);
2918 }
2919 else
2920 {
2921 status = dxeRXFrameReady(dxeCtxt,
2922 channelCb,
2923 chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302924 if (channelCb->numFreeDesc == channelCb->numDesc)
2925 {
Mihir Shete0b090bf2015-06-09 14:00:44 +05302926 /*
2927 * We have already cleared the interrupts before coming here,
2928 * but it can happen that DXE will copy some new packets after
2929 * that and raise interrupts for those. The packets will be
2930 * processed above but the interrupts will still be pending.
2931 * Its safe to clear those interrupts here because we have
2932 * pulled data from all the allocated descriptors.
2933 */
2934 dxeChannelCleanInt(channelCb,&chLogRxFwStat);
Mihir Shete5affadc2015-05-29 20:54:57 +05302935 dxeCtxt->hostInitiatedH2H = 0;
2936 dxeCtxt->receiveLogCompleteCB(dxeCtxt->clientCtxt);
2937 }
Mihir Shetec4093f92015-05-28 15:21:11 +05302938 }
2939 }
2940
2941 /* Update the Rx DONE histogram */
2942 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2943 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat)
2944 {
2945 channelCb->rxDoneHistogram |= 1;
2946 }
2947 else
2948 {
2949 channelCb->rxDoneHistogram &= ~1;
2950 }
2951 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2952 "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxFwStat, channelCb->numFragmentCurrentChain);
2953 }
2954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 if(eWLAN_PAL_STATUS_SUCCESS != status)
2956 {
2957 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2958 "dxeRXEventHandler Handle Frame Ready Fail");
2959 return;
2960 }
2961
Jeff Johnson295189b2012-06-20 16:38:30 -07002962 /* Prepare Control Register EN Channel */
2963 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2964 {
2965 HDXE_ASSERT(0);
2966 }
Mihir Shetef2000552014-05-12 16:21:34 +05302967
2968 if (dxeCtxt->rxPalPacketUnavailable &&
2969 (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat))
2970 {
2971 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask &
2972 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302973 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302974 }
2975 else
2976 {
2977 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302978 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05302979 }
Leo Chang094ece82013-04-23 17:57:41 -07002980 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05302981 chanMask);
Jeff Johnson295189b2012-06-20 16:38:30 -07002982
2983 /* Prepare Control Register EN Channel */
2984 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2985 {
2986 HDXE_ASSERT(0);
2987 }
Leo Chang094ece82013-04-23 17:57:41 -07002988
Mihir Shetef2000552014-05-12 16:21:34 +05302989 if (dxeCtxt->rxPalPacketUnavailable &&
2990 (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat))
2991 {
2992 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask &
2993 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
Mihir Sheted183cef2014-09-26 19:17:56 +05302994 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1;
Mihir Shetef2000552014-05-12 16:21:34 +05302995 }
2996 else
2997 {
2998 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask;
Mihir Sheted183cef2014-09-26 19:17:56 +05302999 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0;
Mihir Shetef2000552014-05-12 16:21:34 +05303000 }
Leo Chang094ece82013-04-23 17:57:41 -07003001 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
Mihir Shetef2000552014-05-12 16:21:34 +05303002 chanMask);
3003
Mihir Shetec01157f2015-06-18 14:13:34 +05303004 /* We do not have knowledge of firmare capabilities when the
3005 * RX_LOG channel is enabled. But when we get the first interrupt
3006 * we have all the required information. So if MGMT Logging is not
3007 * supported by the firmware, do not re-enable RX_LOG channel
3008 */
3009 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) && wpalIsFwLoggingSupported())
Mihir Shetee6618162015-03-16 14:48:42 +05303010 {
3011 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
3012 {
3013 HDXE_ASSERT(0);
3014 }
3015
3016 if (dxeCtxt->rxPalPacketUnavailable &&
3017 (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat))
3018 {
3019 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask &
3020 (~WLANDXE_CH_CTRL_INE_DONE_MASK);
3021 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 1;
3022 }
3023 else
3024 {
3025 chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask;
3026 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 0;
3027 }
3028 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].channelRegister.chDXECtrlRegAddr,
3029 chanMask);
3030 }
Leo Chang094ece82013-04-23 17:57:41 -07003031
3032 /* Clear Interrupt handle processing bit
3033 * RIVA may power down */
Mihir Shete0670b402015-05-13 17:51:41 +05303034 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303035 {
3036 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3037 regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK;
3038 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3039 }
3040 else
3041 {
Karthick S09d5dd02015-05-27 16:58:32 +05303042 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3043 regValue &= (~WLAN_PMU_POWER_DOWN_MASK);
3044 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303045 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003046
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303047 dxeEnvBlk.rxIntChanlSrc = 0;
3048
Leo Chang416afe02013-07-01 13:58:13 -07003049 /* Enable system level ISR */
3050 /* Enable RX ready Interrupt at here */
3051 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
3052 if(eWLAN_PAL_STATUS_SUCCESS != status)
3053 {
3054 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3055 "dxeRXEventHandler Enable RX Ready interrupt fail");
3056 return;
3057 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303058 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_RXINT_STATE,
3059 TRACE_WLANDXE_VAR_ENABLE));
Jeff Johnson295189b2012-06-20 16:38:30 -07003060 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003061 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003062 return;
3063}
3064
3065/*==========================================================================
3066 @ Function Name
3067 dxeRXPacketAvailableEventHandler
3068
3069 @ Description
3070 Handle serialized RX Packet Available event when the corresponding callback
3071 is invoked by WPAL.
3072 Try to fill up any completed DXE descriptors with available Rx packet buffer
3073 pointers.
3074
3075 @ Parameters
3076 wpt_msg *rxPktAvailMsg
3077 RX frame ready MSG pointer
3078 include DXE control context
3079
3080 @ Return
3081 NONE
3082
3083===========================================================================*/
3084void dxeRXPacketAvailableEventHandler
3085(
3086 wpt_msg *rxPktAvailMsg
3087)
3088{
3089 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3090 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3091 WLANDXE_ChannelCBType *channelCb = NULL;
3092
3093 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003094 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003095
3096 /* Sanity Check */
3097 if(NULL == rxPktAvailMsg)
3098 {
3099 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3100 "dxeRXPacketAvailableEventHandler Context is not valid");
3101 return;
3102 }
3103
3104 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
Mihir Shete44547fb2014-03-10 14:15:42 +05303105
3106#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07003107 /* Available resource allocated
3108 * Stop timer not needed */
3109 if(VOS_TIMER_STATE_RUNNING ==
3110 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
3111 {
3112 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
Sravan Kumar Kairam7b8c3852016-03-28 15:54:05 +05303113 dxeEnvBlk.rx_low_resource_timer = 0;
Leo Chang72cdfd32013-10-17 20:36:30 -07003114 }
Mihir Shete44547fb2014-03-10 14:15:42 +05303115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003116
3117 do
3118 {
3119 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3120 "dxeRXPacketAvailableEventHandler, start refilling ring");
3121
3122 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
3123 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3124
3125 // Wait for another callback to indicate when Rx resources are available
3126 // again.
3127 if(eWLAN_PAL_STATUS_SUCCESS != status)
3128 {
3129 break;
3130 }
3131
3132 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
3133 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3134 if(eWLAN_PAL_STATUS_SUCCESS != status)
3135 {
3136 break;
3137 }
Mihir Shetee6618162015-03-16 14:48:42 +05303138
3139 if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG))
3140 {
3141 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG];
3142 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
3143 if(eWLAN_PAL_STATUS_SUCCESS != status)
3144 {
3145 break;
3146 }
3147 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003148 } while(0);
3149
3150 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
3151 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
3152 {
3153 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
3154 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05303155 dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS;
Sravan Kumar Kairam84e995f2016-05-27 16:16:21 +05303156 dxeEnvBlk.rxIntDisableFrame = __builtin_frame_address(0);
3157 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3158 "dxeRXPacketAvailableEventHandler Int Disabled by IMPS");
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 }
3160}
3161
3162/*==========================================================================
3163 @ Function Name
3164 dxeRXISR
3165
3166 @ Description
3167 RX frame ready interrupt service routine
3168 interrupt entry function, this function called based on ISR context
3169 Must be serialized
3170
3171 @ Parameters
3172 void *hostCtxt
3173 DXE host driver control context,
3174 pre registerd during interrupt registration
3175
3176 @ Return
3177 NONE
3178
3179===========================================================================*/
3180static void dxeRXISR
3181(
3182 void *hostCtxt
3183)
3184{
3185 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3186 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003187 wpt_uint32 regValue;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303188 wpt_uint32 intSrc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003189
Leo Chang094ece82013-04-23 17:57:41 -07003190 /* Set Interrupt processing bit
3191 * During this bit set, WLAN HW may not power collapse */
Mihir Shete0670b402015-05-13 17:51:41 +05303192 if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled()))
Mihir Sheted6274602015-04-28 16:13:21 +05303193 {
3194 wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, &regValue);
3195 regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK;
3196 wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue);
3197 }
3198 else
3199 {
Karthick S09d5dd02015-05-27 16:58:32 +05303200 wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, &regValue);
3201 regValue |= WLAN_PMU_POWER_DOWN_MASK;
3202 wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue);
Mihir Sheted6274602015-04-28 16:13:21 +05303203 }
Leo Chang094ece82013-04-23 17:57:41 -07003204
Jeff Johnson295189b2012-06-20 16:38:30 -07003205 /* Disable interrupt at here
3206 * Disable RX Ready system level Interrupt at here
3207 * Otherwise infinite loop might happen */
3208 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
3209 if(eWLAN_PAL_STATUS_SUCCESS != status)
3210 {
3211 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3212 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3213 return;
3214 }
3215
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303216 wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3217 &intSrc);
3218 /* Note: intSrc which holds the INT_SRC_RAW_ADDRESS reg value
3219 While debugging crash dump convert to power of 2 for channel type */
3220 DXTRACE(dxeTrace(intSrc, TRACE_RXINT_STATE, TRACE_WLANDXE_VAR_DISABLE));
3221
Jeff Johnson295189b2012-06-20 16:38:30 -07003222 /* Serialize RX Ready interrupt upon RX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003223 if(NULL == dxeCtxt->rxIsrMsg)
3224 {
3225 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3226 "dxeRXFrameReadyISR NULL message");
3227 HDXE_ASSERT(0);
3228 return;
3229 }
3230
Jeff Johnson295189b2012-06-20 16:38:30 -07003231 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
3232 dxeCtxt->rxIsrMsg);
3233 if(eWLAN_PAL_STATUS_SUCCESS != status)
3234 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003235 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3236 "dxeRXFrameReadyISR interrupt serialize fail");
3237 }
3238
Jeff Johnson295189b2012-06-20 16:38:30 -07003239 return;
3240}
3241
3242/*==========================================================================
3243 @ Function Name
3244 dxeTXPushFrame
3245
3246 @ Description
3247 Push TX frame into DXE descriptor and DXE register
3248 Send notification to DXE register that TX frame is ready to transfer
3249
3250 @ Parameters
3251 WLANDXE_ChannelCBType *channelEntry
3252 Channel specific control block
3253 wpt_packet *palPacket
3254 Packet pointer ready to transfer
3255
3256 @ Return
3257 PAL_STATUS_T
3258===========================================================================*/
3259static wpt_status dxeTXPushFrame
3260(
3261 WLANDXE_ChannelCBType *channelEntry,
3262 wpt_packet *palPacket
3263)
3264{
3265 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3266 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05303267 WLANDXE_DescCtrlBlkType *tailCtrlBlk = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003268 WLANDXE_DescType *currentDesc = NULL;
3269 WLANDXE_DescType *firstDesc = NULL;
3270 WLANDXE_DescType *LastDesc = NULL;
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05303271 WLANDXE_DescType *tailDesc = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07003272 void *sourcePhysicalAddress = NULL;
3273 wpt_uint32 xferSize = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003274 wpt_iterator iterator;
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05303275 wpt_uint8 KickDxe = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07003276
3277 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003278 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003279
Leo Changac1d3612013-07-01 15:15:51 -07003280 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
3281 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
3282 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07003283 {
Karthick S8a7e2862015-09-14 09:13:37 +05303284 KickDxe = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003285 }
3286
Karthick S8a7e2862015-09-14 09:13:37 +05303287 /* Kick DXE when the ring is about to fill */
3288 if (WLANDXE_TX_LOW_RES_THRESHOLD >= channelEntry->numFreeDesc)
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05303289 {
Karthick S8a7e2862015-09-14 09:13:37 +05303290 KickDxe = 1;
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05303291 tailCtrlBlk = channelEntry->tailCtrlBlk;
3292 tailDesc = tailCtrlBlk->linkedDesc;
3293
3294 if(tailDesc->descCtrl.ctrl& WLANDXE_DESC_CTRL_VALID)
3295 {
3296 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3297 "dxeTXPushFrame Descs threshold reached No DMA");
3298 }
3299 }
Karthick S8a7e2862015-09-14 09:13:37 +05303300
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 channelEntry->numFragmentCurrentChain = 0;
3302 currentCtrlBlk = channelEntry->headCtrlBlk;
3303
3304 /* Initialize interator, TX is fragmented */
Jeff Johnson295189b2012-06-20 16:38:30 -07003305 status = wpalLockPacketForTransfer(palPacket);
3306 if(eWLAN_PAL_STATUS_SUCCESS != status)
3307 {
3308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3309 "dxeTXPushFrame unable to lock packet");
3310 return status;
3311 }
3312
3313 status = wpalIteratorInit(&iterator, palPacket);
Jeff Johnson295189b2012-06-20 16:38:30 -07003314 if(eWLAN_PAL_STATUS_SUCCESS != status)
3315 {
3316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3317 "dxeTXPushFrame iterator init fail");
3318 return status;
3319 }
3320
3321 /* !!!! Revisit break condition !!!!!!! */
3322 while(1)
3323 {
3324 /* Get current descriptor pointer from current control block */
3325 currentDesc = currentCtrlBlk->linkedDesc;
3326 if(NULL == firstDesc)
3327 {
3328 firstDesc = currentCtrlBlk->linkedDesc;
3329 }
3330 /* All control block will have same palPacket Pointer
3331 * to make logic simpler */
3332 currentCtrlBlk->xfrFrame = palPacket;
3333
3334 /* Get next fragment physical address and fragment size
3335 * if this is the first trial, will get first physical address
3336 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
Jeff Johnson295189b2012-06-20 16:38:30 -07003337 status = wpalIteratorNext(&iterator,
3338 palPacket,
3339 &sourcePhysicalAddress,
3340 &xferSize);
jagadeeshf869bba2015-04-07 20:06:21 +05303341 if(eWLAN_PAL_STATUS_SUCCESS != status)
3342 {
3343 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3344 "dxeTXPushFrame Get next frame fail");
3345 return status;
3346 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003347 if((NULL == sourcePhysicalAddress) ||
3348 (0 == xferSize))
3349 {
3350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3351 "dxeTXPushFrame end of current frame");
3352 break;
3353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003354
3355 /* This is the LAST descriptor valid for this transaction */
3356 LastDesc = currentCtrlBlk->linkedDesc;
3357
3358 /* Program DXE descriptor */
3359 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
Arun Kumar Khandavalli6119f7d2013-12-18 00:16:17 +05303360 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07003361
3362 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
3363 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3364 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3365 {
3366 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
3367 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
3368 }
3369 else
3370 {
3371 /* Test specific H2H transfer, destination address already set
3372 * Do Nothing */
3373 }
3374 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
3375
3376 /* Program channel control register */
3377 /* First frame not set VAL bit, why ??? */
3378 if(0 == channelEntry->numFragmentCurrentChain)
3379 {
3380 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
3381 }
3382 else
3383 {
3384 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3385 }
3386
3387 /* Update statistics */
3388 channelEntry->numFragmentCurrentChain++;
3389 channelEntry->numFreeDesc--;
3390 channelEntry->numRsvdDesc++;
3391
3392 /* Get next control block */
3393 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3394 }
3395 channelEntry->numTotalFrame++;
3396 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3397 "NUM TX FRAG %d, Total Frame %d",
3398 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
3399
3400 /* Program Channel control register
3401 * Set as end of packet
3402 * Enable interrupt also for first code lock down
3403 * performace optimization, this will be revisited */
3404 if(NULL == LastDesc)
3405 {
3406 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3407 "dxeTXPushFrame NULL Last Descriptor, broken chain");
3408 return eWLAN_PAL_STATUS_E_FAULT;
3409 }
3410 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
3411 /* Now First one also Valid ????
3412 * this procedure will prevent over handle descriptor from previous
3413 * TX trigger */
3414 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
3415
3416 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
3417 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
3418 {
3419 /* Update channel head as next avaliable linked slot */
3420 channelEntry->headCtrlBlk = currentCtrlBlk;
Karthick S8a7e2862015-09-14 09:13:37 +05303421 if(KickDxe)
Leo Changac1d3612013-07-01 15:15:51 -07003422 {
3423 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
3424 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3425 "SMSM_ret LO=%d HI=%d",
3426 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
3427 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
Karthick S39823072015-07-08 18:16:41 +05303428 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
Leo Changac1d3612013-07-01 15:15:51 -07003429 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
3430 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303431 DXTRACE(dxeTrace(channelEntry->channelType, TRACE_SMSM_NOTIFY, TRACE_WLANDXE_VAR_ENABLE));
Leo Changac1d3612013-07-01 15:15:51 -07003432 }
Madan Mohan Koyyalamudi2edf6f62012-10-15 15:56:34 -07003433 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07003434 }
3435
3436 /* If DXE use external descriptor, registers are not needed to be programmed
3437 * Just after finish to program descriptor, tirigger to send */
3438 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
3439 {
3440 /* Issue a dummy read from the DXE descriptor DDR location to
3441 ensure that any previously posted write to the descriptor
3442 completes. */
3443 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
3444 {
3445 //HDXE_ASSERT(0);
3446 }
3447
3448 /* Everything is ready
3449 * Trigger to start DMA */
3450 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3451 channelEntry->extraConfig.chan_mask);
3452 if(eWLAN_PAL_STATUS_SUCCESS != status)
3453 {
3454 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3455 "dxeTXPushFrame Write Channel Ctrl Register fail");
3456 return status;
3457 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05303458 DXTRACE(dxeTrace(channelEntry->channelType, TRACE_CH_ENABLE, TRACE_WLANDXE_VAR_ENABLE));
Jeff Johnson295189b2012-06-20 16:38:30 -07003459
3460 /* Update channel head as next avaliable linked slot */
3461 channelEntry->headCtrlBlk = currentCtrlBlk;
3462
3463 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003464 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003465 return status;
3466 }
3467
3468 /* If DXE not use external descriptor, program each registers */
3469 /* Circular buffer handle not need to program DESC register???
3470 * GEN5 code not programed RING buffer case
3471 * REVISIT THIS !!!!!! */
3472 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
3473 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
3474 {
3475 /* Destination address, assigned Work Q */
3476 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
3477 channelEntry->channelConfig.refWQ);
3478 if(eWLAN_PAL_STATUS_SUCCESS != status)
3479 {
3480 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3481 "dxeTXPushFrame Program dest address register fail");
3482 return status;
3483 }
3484 /* If descriptor format is SHORT */
3485 if(channelEntry->channelConfig.useShortDescFmt)
3486 {
3487 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
3488 0);
3489 if(eWLAN_PAL_STATUS_SUCCESS != status)
3490 {
3491 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3492 "dxeTXPushFrame Program dest address register fail");
3493 return status;
3494 }
3495 }
3496 else
3497 {
3498 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3499 "dxeTXPushFrame LONG Descriptor Format!!!");
3500 }
3501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003502
3503 /* Program Source address register
3504 * This address is already programmed into DXE Descriptor
3505 * But register also upadte */
3506 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
3507 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
3508 if(eWLAN_PAL_STATUS_SUCCESS != status)
3509 {
3510 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3511 "dxeTXPushFrame Program src address register fail");
3512 return status;
3513 }
3514 /* If descriptor format is SHORT */
3515 if(channelEntry->channelConfig.useShortDescFmt)
3516 {
3517 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
3518 0);
3519 if(eWLAN_PAL_STATUS_SUCCESS != status)
3520 {
3521 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3522 "dxeTXPushFrame Program dest address register fail");
3523 return status;
3524 }
3525 }
3526 else
3527 {
3528 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3529 "dxeTXPushFrame LONG Descriptor Format!!!");
3530 }
3531
3532 /* Linked list Descriptor pointer */
3533 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3534 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3535 if(eWLAN_PAL_STATUS_SUCCESS != status)
3536 {
3537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3538 "dxeTXPushFrame Write DESC Address register fail");
3539 return status;
3540 }
3541 /* If descriptor format is SHORT */
3542 if(channelEntry->channelConfig.useShortDescFmt)
3543 {
3544 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
3545 0);
3546 if(eWLAN_PAL_STATUS_SUCCESS != status)
3547 {
3548 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3549 "dxeTXPushFrame Program dest address register fail");
3550 return status;
3551 }
3552 }
3553 else
3554 {
3555 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3556 "dxeTXPushFrame LONG Descriptor Format!!!");
3557 }
3558
3559 /* Transfer Size */
3560 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
3561 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
3562 xferSize);
3563 if(eWLAN_PAL_STATUS_SUCCESS != status)
3564 {
3565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3566 "dxeTXPushFrame Write DESC Address register fail");
3567 return status;
3568 }
3569
3570 /* Everything is ready
3571 * Trigger to start DMA */
3572 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
3573 channelEntry->extraConfig.chan_mask);
3574 if(eWLAN_PAL_STATUS_SUCCESS != status)
3575 {
3576 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3577 "dxeTXPushFrame Write Channel Ctrl Register fail");
3578 return status;
3579 }
3580
3581 /* Update channel head as next avaliable linked slot */
3582 channelEntry->headCtrlBlk = currentCtrlBlk;
3583
3584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003585 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003586 return status;
3587}
3588
3589/*==========================================================================
3590 @ Function Name
3591 dxeTXCompFrame
3592
3593 @ Description
3594 TX Frame transfer complete event handler
3595
3596 @ Parameters
3597 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3598 DXE host driver main control block
3599 WLANDXE_ChannelCBType *channelEntry
3600 Channel specific control block
3601
3602 @ Return
3603 PAL_STATUS_T
3604===========================================================================*/
3605static wpt_status dxeTXCompFrame
3606(
3607 WLANDXE_CtrlBlkType *hostCtxt,
3608 WLANDXE_ChannelCBType *channelEntry
3609)
3610{
3611 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3612 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3613 WLANDXE_DescType *currentDesc = NULL;
3614 wpt_uint32 descCtrlValue = 0;
3615 unsigned int *lowThreshold = NULL;
3616
3617 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003618 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003619
3620 /* Sanity */
3621 if((NULL == hostCtxt) || (NULL == channelEntry))
3622 {
3623 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3624 "dxeTXCompFrame Invalid ARG");
3625 return eWLAN_PAL_STATUS_E_INVAL;
3626 }
3627
3628 if(NULL == hostCtxt->txCompCB)
3629 {
3630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3631 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07003632 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 }
3634
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003635 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3636 if(eWLAN_PAL_STATUS_SUCCESS != status)
3637 {
3638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3639 "dxeTXCompFrame Mutex Acquire fail");
3640 return status;
3641 }
3642
Jeff Johnson295189b2012-06-20 16:38:30 -07003643 currentCtrlBlk = channelEntry->tailCtrlBlk;
3644 currentDesc = currentCtrlBlk->linkedDesc;
3645
3646 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3647 {
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003648 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3649 if(eWLAN_PAL_STATUS_SUCCESS != status)
3650 {
3651 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3652 "dxeTXCompFrame Mutex Release fail");
3653 return status;
3654 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003655 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003656 }
3657
Kiet Lam842dad02014-02-18 18:44:02 -08003658
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 while(1)
3660 {
3661// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
3662 descCtrlValue = currentDesc->descCtrl.ctrl;
3663 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3664 {
3665 /* caught up with head, bail out */
3666 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3667 "dxeTXCompFrame caught up with head - next DESC has VALID set");
3668 break;
3669 }
3670
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08003671 if(currentCtrlBlk->xfrFrame == NULL)
3672 {
3673 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3674 "Invalid transfer frame");
3675 HDXE_ASSERT(0);
3676 break;
3677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003678 channelEntry->numFreeDesc++;
3679 channelEntry->numRsvdDesc--;
3680
3681 /* Send Frame TX Complete notification with frame start fragment location */
3682 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3683 {
3684 hostCtxt->txCompletedFrames--;
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3686 if (eWLAN_PAL_STATUS_SUCCESS != status)
3687 {
3688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3689 "dxeRXFrameReady unable to unlock packet");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003690 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3691 if(eWLAN_PAL_STATUS_SUCCESS != status)
3692 {
3693 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3694 "dxeTXCompFrame Mutex Release fail");
3695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003696 return status;
3697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3699 currentCtrlBlk->xfrFrame,
3700 eWLAN_PAL_STATUS_SUCCESS);
3701 channelEntry->numFragmentCurrentChain = 0;
3702 }
3703 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3704 currentDesc = currentCtrlBlk->linkedDesc;
3705
3706 /* Break condition
3707 * Head control block is the control block must be programed for the next TX
3708 * so, head control block is not programmed control block yet
3709 * if loop encounte head control block, stop to complete
3710 * in theory, COMP CB must be called already ??? */
3711 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3712 {
3713 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
3714 "dxeTXCompFrame caught up with head ptr");
3715 break;
3716 }
3717 /* VALID Bit check ???? */
3718 }
3719
3720 /* Tail and Head Control block must be same */
3721 channelEntry->tailCtrlBlk = currentCtrlBlk;
3722
3723 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3724 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3725 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3726
3727 /* If specific channel hit low resource condition send notification to upper layer */
3728 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3729 (channelEntry->numFreeDesc > *lowThreshold))
3730 {
3731 /* Change it back if we raised it for fetching a remaining packet from TL */
3732 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3733 {
3734 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3735 }
3736
3737 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3738 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3739 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3740 channelEntry->channelType,
3741 eWLAN_PAL_TRUE);
3742 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3743 }
3744
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08003745 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3746 if(eWLAN_PAL_STATUS_SUCCESS != status)
3747 {
3748 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3749 "dxeTXCompFrame Mutex Release fail");
3750 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003751
3752 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003753 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003754 return status;
3755}
3756
3757/*==========================================================================
Mihir Shetedfc33ec2014-10-15 13:14:38 +05303758 @ Function Name
3759 dxeTXCleanup
3760
3761 @ Description
3762 Cleanup the TX channels after DXE Error
3763
3764 @ Parameters
3765 WLANDXE_CtrlBlkType *dxeCtrlBlk,
3766 DXE host driver main control block
3767
3768 @ Return
3769 PAL_STATUS_T
3770===========================================================================*/
3771static wpt_status dxeTXCleanup
3772(
3773 WLANDXE_CtrlBlkType *hostCtxt
3774)
3775{
3776 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3777 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
3778 WLANDXE_DescType *currentDesc = NULL;
3779 wpt_uint32 descCtrlValue = 0;
3780 unsigned int *lowThreshold = NULL;
3781 unsigned int idx;
3782 WLANDXE_ChannelCBType *channelEntry;
3783
3784 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3785 "%s Enter", __func__);
3786
3787 /* Sanity */
3788 if((NULL == hostCtxt))
3789 {
3790 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3791 "%s: Invalid ARG", __func__);
3792 return eWLAN_PAL_STATUS_E_INVAL;
3793 }
3794
3795 if(NULL == hostCtxt->txCompCB)
3796 {
3797 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3798 "%s: TXCompCB is not registered",__func__);
3799 return eWLAN_PAL_STATUS_SUCCESS;
3800 }
3801
3802 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3803 {
3804 channelEntry = &tempDxeCtrlBlk->dxeChannel[idx];
3805 if(idx != WDTS_CHANNEL_TX_LOW_PRI && idx != WDTS_CHANNEL_TX_HIGH_PRI)
3806 {
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +05303807 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +05303808 "%s: %11s continue",__func__,
3809 channelType[channelEntry->channelType]);
3810 continue;
3811 }
3812
3813 status = wpalMutexAcquire(&channelEntry->dxeChannelLock);
3814 if(eWLAN_PAL_STATUS_SUCCESS != status)
3815 {
3816 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3817 "%s: %11s Mutex Acquire fail",__func__,
3818 channelType[channelEntry->channelType]);
3819 return status;
3820 }
3821
3822 currentCtrlBlk = channelEntry->tailCtrlBlk;
3823 currentDesc = currentCtrlBlk->linkedDesc;
3824
3825 if( currentCtrlBlk == channelEntry->headCtrlBlk )
3826 {
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +05303827 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +05303828 "%s: %11s Head and Tail are Same",__func__,
3829 channelType[channelEntry->channelType]);
3830
3831 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3832 if(eWLAN_PAL_STATUS_SUCCESS != status)
3833 {
3834 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3835 "%s: %11s Mutex Release fail",__func__,
3836 channelType[channelEntry->channelType]);
3837 return status;
3838 }
3839 continue;
3840 }
3841
3842 while(1)
3843 {
3844 descCtrlValue = currentDesc->descCtrl.ctrl;
3845 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
3846 {
3847 /* invalidate... */
3848 currentDesc->descCtrl.ctrl &= ~WLANDXE_DESC_CTRL_VALID;
3849 }
3850
3851 if(currentCtrlBlk->xfrFrame == NULL)
3852 {
3853 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3854 "%s: %11s Invalid transfer frame",__func__,
3855 channelType[channelEntry->channelType]);
3856 HDXE_ASSERT(0);
3857 break;
3858 }
3859 channelEntry->numFreeDesc++;
3860 channelEntry->numRsvdDesc--;
3861
3862 /* Send Frame TX Complete notification with frame start fragment location */
3863 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
3864 {
3865 hostCtxt->txCompletedFrames--;
3866 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
3867 if (eWLAN_PAL_STATUS_SUCCESS != status)
3868 {
3869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3870 "%s: unable to unlock packet",__func__);
3871 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3872 if(eWLAN_PAL_STATUS_SUCCESS != status)
3873 {
3874 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3875 "%s: Mutex Release fail",__func__);
3876 }
3877 return status;
3878 }
3879 hostCtxt->txCompCB(hostCtxt->clientCtxt,
3880 currentCtrlBlk->xfrFrame,
3881 eWLAN_PAL_STATUS_SUCCESS); //mir: SUCCESS or FAILURE?
3882 channelEntry->numFragmentCurrentChain = 0;
3883 }
3884 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
3885 currentDesc = currentCtrlBlk->linkedDesc;
3886
3887 /* Break condition
3888 * Head control block is the control block must be programed for the next TX
3889 * so, head control block is not programmed control block yet
3890 * if loop encounte head control block, stop to complete
3891 * in theory, COMP CB must be called already ??? */
3892 if(currentCtrlBlk == channelEntry->headCtrlBlk)
3893 {
Sravan Kumar Kairam49d5c4b2016-03-29 15:26:44 +05303894 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Mihir Shetedfc33ec2014-10-15 13:14:38 +05303895 "%s: %11s caught up with head ptr",__func__,
3896 channelType[channelEntry->channelType]);
3897 break;
3898 }
3899 /* VALID Bit check ???? */
3900 }
3901
3902 /* Tail and Head Control block must be same */
3903 channelEntry->tailCtrlBlk = currentCtrlBlk;
3904 /* Re-Sync Head and CDR */
3905 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
3906 channelEntry->headCtrlBlk->linkedDescPhyAddr);
3907 if(eWLAN_PAL_STATUS_SUCCESS != status)
3908 {
3909 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3910 "dxeChannelInitProgram Write DESC Address register fail");
3911 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3912 if(eWLAN_PAL_STATUS_SUCCESS != status)
3913 {
3914 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3915 "%s: %11s Mutex Release fail", __func__,
3916 channelType[channelEntry->channelType]);
3917 }
3918 return status;
3919 }
3920
3921 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3922 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3923 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3924
3925 /* If specific channel hit low resource condition send notification to upper layer */
3926 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
3927 (channelEntry->numFreeDesc > *lowThreshold))
3928 {
3929 /* Change it back if we raised it for fetching a remaining packet from TL */
3930 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
3931 {
3932 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
3933 }
3934
3935 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3936 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
3937 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
3938 channelEntry->channelType,
3939 eWLAN_PAL_TRUE);
3940 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
3941 }
3942 status = wpalMutexRelease(&channelEntry->dxeChannelLock);
3943 if(eWLAN_PAL_STATUS_SUCCESS != status)
3944 {
3945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3946 "%s: %11s Mutex Release fail", __func__,
3947 channelType[channelEntry->channelType]);
3948 }
3949 }
3950
3951 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3952 "%s Exit", __func__);
3953 return status;
3954}
3955/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07003956 @ Function Name
3957 dxeTXEventHandler
3958
3959 @ Description
3960 If DXE HW sends TX related interrupt, this event handler will be called
3961 Handle higher priority channel first
3962 Figureout why interrupt happen and call appropriate final even handler
3963 TX complete or error happen
3964
3965 @ Parameters
3966 void *msgPtr
3967 Even MSG
3968
3969 @ Return
3970 PAL_STATUS_T
3971===========================================================================*/
3972void dxeTXEventHandler
3973(
3974 wpt_msg *msgPtr
3975)
3976{
3977 wpt_msg *msgContent = (wpt_msg *)msgPtr;
3978 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3979 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3980 wpt_uint32 intSrc = 0;
3981 wpt_uint32 chStat = 0;
3982 WLANDXE_ChannelCBType *channelCb = NULL;
3983
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07003984 wpt_uint8 bEnableISR = 0;
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -07003985 static wpt_uint8 successiveIntWithIMPS;
Jeff Johnson295189b2012-06-20 16:38:30 -07003986
3987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003988 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003989
3990 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07003991 dxeCtxt->ucTxMsgCnt = 0;
3992
3993 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
3994 {
3995 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3996 "wlan: TX COMP WLAN Driver re-loading in progress");
3997 return;
3998 }
3999
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05304000 /* Read whole interrupt mask register and exclusive only this channel int */
4001 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
4002 &intSrc);
4003 if(eWLAN_PAL_STATUS_SUCCESS != status)
4004 {
4005 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4006 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
4007 return;
4008 }
4009 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
4010 "TX Event Handler INT Source 0x%x", intSrc);
4011
4012 dxeEnvBlk.txCmpIntChanlSrc = intSrc&0xFF;
4013
Jeff Johnson295189b2012-06-20 16:38:30 -07004014 /* Return from here if the RIVA is in IMPS, to avoid register access */
4015 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
4016 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004017 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07004018 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004019 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07004020 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
4021 if(eWLAN_PAL_STATUS_SUCCESS != status)
4022 {
4023 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004024 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07004025 }
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004026
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004027 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
4028 if(eWLAN_PAL_STATUS_SUCCESS != status)
4029 {
4030 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4031 "dxeTXEventHandler IMPS LC COMP interrupt fail");
4032 }
4033
4034 if(((dxeCtxt->txCompletedFrames) &&
4035 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
4036 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07004037 {
4038 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4039 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4040 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004041 "TX COMP INT Enabled, remain TX frame count on ring %d",
4042 dxeCtxt->txCompletedFrames);
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05304043
4044 dxeEnvBlk.txCmpIntChanlSrc = 0;
4045
Jeff Johnsone7245742012-09-05 17:12:55 -07004046 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4047 the posibility of a race*/
4048 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4049 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004050 else
4051 {
4052 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4053 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4054 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
4055 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
4056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004057 return;
4058 }
4059
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07004060 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004061 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
4062 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
4063 {
4064 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4065 "DXE already stopped in TX event handler. Just return");
4066 return;
4067 }
4068
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 /* Test High Priority Channel is the INT source or not */
4070 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4071 if(intSrc & (1 << channelCb->assignedDMAChannel))
4072 {
4073 status = dxeChannelCleanInt(channelCb, &chStat);
4074 if(eWLAN_PAL_STATUS_SUCCESS != status)
4075 {
4076 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4077 "dxeTXEventHandler INT Clean up fail");
4078 return;
4079 }
4080
4081 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4082 {
4083 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004084 "%11s : 0x%x Error Reported, Reload Driver",
4085 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304086
Mihir Shetedfc33ec2014-10-15 13:14:38 +05304087 if (eWLAN_PAL_STATUS_SUCCESS !=
4088 dxeErrHandler(channelCb, chStat))
4089 {
4090 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4091 wpalWlanReload();
4092 dxeStartSSRTimer(dxeCtxt);
4093 }
4094 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004095 }
4096 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4097 {
4098 /* Handle TX complete for high priority channel */
4099 status = dxeTXCompFrame(dxeCtxt,
4100 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004101 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004102 }
4103 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4104 {
4105 /* Handle TX complete for high priority channel */
4106 status = dxeTXCompFrame(dxeCtxt,
4107 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004108 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004109 }
4110 else
4111 {
4112 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4113 "dxeTXEventHandler TX HI status=%x", chStat);
4114 }
4115
4116 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4117 {
4118 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4119 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
4120 }
4121
4122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4123 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4124 }
4125
4126 /* Test Low Priority Channel interrupt is enabled or not */
4127 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4128 if(intSrc & (1 << channelCb->assignedDMAChannel))
4129 {
4130 status = dxeChannelCleanInt(channelCb, &chStat);
4131 if(eWLAN_PAL_STATUS_SUCCESS != status)
4132 {
4133 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4134 "dxeTXEventHandler INT Clean up fail");
4135 return;
4136 }
4137
4138 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
4139 {
4140 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004141 "%11s : 0x%x Error Reported, Reload Driver",
4142 channelType[channelCb->channelType], chStat);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304143
Mihir Shetedfc33ec2014-10-15 13:14:38 +05304144 if (eWLAN_PAL_STATUS_SUCCESS !=
4145 dxeErrHandler(channelCb, chStat))
4146 {
4147 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
4148 wpalWlanReload();
4149 dxeStartSSRTimer(dxeCtxt);
4150 }
4151 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 }
4153 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
4154 {
4155 /* Handle TX complete for low priority channel */
4156 status = dxeTXCompFrame(dxeCtxt,
4157 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004158 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004159 }
4160 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
4161 {
4162 /* Handle TX complete for low priority channel */
4163 status = dxeTXCompFrame(dxeCtxt,
4164 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07004165 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07004166 }
4167 else
4168 {
4169 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4170 "dxeTXEventHandler TX LO status=%x", chStat);
4171 }
4172
4173 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
4174 {
4175 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
4176 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
4177 }
4178 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4179 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
4180 }
4181
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
4183 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
4184 {
4185 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4186 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
Madan Mohan Koyyalamudide2f8ab2012-11-08 15:08:14 -08004187 if(0 != dxeCtxt->txCompletedFrames)
4188 {
4189 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4190 "TX COMP INT Enabled, remain TX frame count on ring %d",
4191 dxeCtxt->txCompletedFrames);
4192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004193 }
4194
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304195 if(eWLAN_PAL_TRUE == dxeCtxt->txIntEnable)
4196 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_TXINT_STATE,
4197 TRACE_WLANDXE_VAR_ENABLE));
4198
Sravan Kumar Kairam8bbda362015-10-06 11:51:14 +05304199 dxeEnvBlk.txCmpIntChanlSrc = 0;
4200
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4202 the posibility of a race*/
4203 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
4204
4205 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004206 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 return;
4208}
4209
4210
4211/*==========================================================================
4212 @ Function Name
4213 dxeTXCompleteProcessing
4214
4215 @ Description
4216 If DXE HW sends TX related interrupt, this event handler will be called
4217 Handle higher priority channel first
4218 Figureout why interrupt happen and call appropriate final even handler
4219 TX complete or error happen
4220
4221 @ Parameters
4222 dxeCtxt DXE context
4223
4224 @ Return
4225 PAL_STATUS_T
4226===========================================================================*/
4227void dxeTXCompleteProcessing
4228(
4229 WLANDXE_CtrlBlkType *dxeCtxt
4230)
4231{
4232 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4233 WLANDXE_ChannelCBType *channelCb = NULL;
4234
4235 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004236 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004237
4238 /* Test High Priority Channel is the INT source or not */
4239 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
4240
4241 /* Handle TX complete for high priority channel */
4242 status = dxeTXCompFrame(dxeCtxt, channelCb);
4243
4244 /* Test Low Priority Channel interrupt is enabled or not */
4245 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
4246
4247 /* Handle TX complete for low priority channel */
4248 status = dxeTXCompFrame(dxeCtxt, channelCb);
4249
4250 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
4251 ((dxeCtxt->txCompletedFrames > 0) ||
4252 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
4253 {
4254 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
4255 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4256 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004257 "%s %s : %d, %s : %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
4259 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
4260 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
4261 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
Leo Changac1d3612013-07-01 15:15:51 -07004262
4263 if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) &&
4264 (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled))
4265 {
4266 /* After TX Comp processing, still remaining frame on the DXE TX ring
4267 * And when push frame, RING was not empty marked
4268 * Then when push frame, no SMSM toggle happen
4269 * To avoid permanent TX stall, SMSM toggle is needed at here
4270 * With this toggle, host should gaurantee SMSM state should be changed */
Karthick S39823072015-07-08 18:16:41 +05304271 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4272 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Leo Changac1d3612013-07-01 15:15:51 -07004273 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004274 }
4275
4276 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
4277 the posibility of a race*/
4278 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
4279
4280 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004281 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004282 return;
4283}
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004284
4285/*==========================================================================
4286 @ Function Name
4287 dxeTXReSyncDesc
4288
4289 @ Description
4290 When STA comeout from IMPS, check DXE TX next transfer candidate descriptor
4291 And HW programmed descriptor.
4292 If any async happen between HW/SW TX stall will happen
4293
4294 @ Parameters
4295 void *msgPtr
4296 Message pointer to sync with TX thread
4297
4298 @ Return
4299 NONE
4300===========================================================================*/
4301void dxeTXReSyncDesc
4302(
4303 wpt_msg *msgPtr
4304)
4305{
4306 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4307 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4308 wpt_uint32 nextDescReg;
4309 WLANDXE_ChannelCBType *channelEntry;
4310 WLANDXE_DescCtrlBlkType *validCtrlBlk;
4311 wpt_uint32 descLoop;
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004312 wpt_uint32 channelLoop;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004313
4314 if(NULL == msgContent)
4315 {
4316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4317 "dxeTXReSyncDesc Invalid Control Block");
4318 return;
4319 }
4320
4321 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4322 "dxeTXReSyncDesc Try to re-sync TX channel if any problem");
4323 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4324
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004325 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004326 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004327 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4328 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4329 "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]);
4330 wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4331 &nextDescReg);
4332 /* Async detect without TX pending frame */
4333 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004334 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004335 if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004336 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004337 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4338 "TX Async no Pending frame");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304339
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004340 dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL);
4341 dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304342
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004343 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004344 channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004345 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004346 }
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004347 /* Async detect with some TX pending frames
4348 * next descriptor register should sync with first valid descriptor */
4349 else
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004350 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004351 validCtrlBlk = channelEntry->tailCtrlBlk;
4352 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004353 {
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004354 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4355 {
4356 if(nextDescReg != validCtrlBlk->linkedDescPhyAddr)
4357 {
4358 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4359 "TX Async");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304360
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004361 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4362 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304363
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004364 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4365 validCtrlBlk->linkedDescPhyAddr);
4366 }
4367 break;
4368 }
4369 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4370 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4371 {
4372 /* Finished to test till head control blcok, but could not find valid descriptor
4373 * from head to tail all descriptors are invalidated
4374 * host point of view head descriptor is next TX candidate
4375 * So, next descriptor control have to be programmed with head descriptor
4376 * check */
4377 if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr)
4378 {
4379 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08004380 "TX Async with not completed transferred frames, next descriptor must be head");
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304381
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07004382 dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL);
4383 dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL);
Madan Mohan Koyyalamudi62080282013-08-05 12:51:17 +05304384
Madan Mohan Koyyalamudi01d7c532012-10-15 15:49:02 -07004385 wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
4386 validCtrlBlk->linkedDescPhyAddr);
4387 }
4388 break;
4389 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004390 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004391 }
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004392 }
4393
Madan Mohan Koyyalamudi5f57c102012-10-15 15:52:54 -07004394 /* HW/SW descriptor resync is done.
4395 * Next if there are any valid descriptor in chain, Push to HW again */
4396 for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++)
4397 {
4398 channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop];
4399 if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk)
4400 {
4401 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4402 "%11s : No TX Pending frame",
4403 channelType[channelEntry->channelType]);
4404 /* No Pending frame, Do nothing */
4405 }
4406 else
4407 {
4408 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4409 "%11s : TX Pending frame, process it",
4410 channelType[channelEntry->channelType]);
4411 validCtrlBlk = channelEntry->tailCtrlBlk;
4412 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
4413 {
4414 if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID)
4415 {
4416 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4417 "%11s : when exit IMPS found valid descriptor",
4418 channelType[channelEntry->channelType]);
4419
4420 /* Found valid descriptor, kick DXE */
4421 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
4422 channelEntry->extraConfig.chan_mask);
4423 break;
4424 }
4425 validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk;
4426 if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk)
4427 {
4428 /* Finished to test till head control blcok, but could not find valid descriptor
4429 * from head to tail all descriptors are invalidated */
4430 break;
4431 }
4432 }
4433 }
4434 }
4435
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07004436 wpalMemoryFree(msgPtr);
4437 return;
4438}
4439
Jeff Johnson295189b2012-06-20 16:38:30 -07004440/*==========================================================================
Mihir Shete40a55652014-03-02 14:14:47 +05304441 @ Function Name
4442 dxeDebugTxDescReSync
4443
4444 @ Description
4445 Check DXE Tx channel state and correct it in
4446 case Tx Data stall is detected by calling
4447 %dxeTXReSyncDesc. Also ensure that WCN SS
4448 is not power collapsed before calling
4449 %dxeTXReSyncDesc
4450
4451 @ Parameters
4452 void *msgPtr
4453 Message pointer to sync with TX thread
4454
4455 @ Return
4456 NONE
4457===========================================================================*/
4458void dxeDebugTxDescReSync
4459(
4460 wpt_msg *msgPtr
4461)
4462{
4463 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4464 "%s: Check for DXE TX Async",__func__);
4465 /* Make wake up HW */
4466 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4467 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
4468
4469 wpalSleep(10);
4470
4471 dxeTXReSyncDesc(msgPtr);
4472}
4473/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07004474 @ Function Name
4475 dxeTXISR
4476
4477 @ Description
4478 TX interrupt ISR
4479 Platform will call this function if INT is happen
4480 This function must be registered into platform interrupt module
4481
4482 @ Parameters
4483 void *hostCtxt
4484 DXE host driver control context,
4485 pre registerd during interrupt registration
4486
4487 @ Return
4488 PAL_STATUS_T
4489===========================================================================*/
4490static void dxeTXISR
4491(
4492 void *hostCtxt
4493)
4494{
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304495 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304497 wpt_uint32 intSrc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004498
4499 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004500 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004501
4502 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07004503 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07004504 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004505 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004506 /* Disable interrupt at here,
4507 IMPS or IMPS Pending state should not access RIVA register */
4508 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4509 if(eWLAN_PAL_STATUS_SUCCESS != status)
4510 {
4511 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4512 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
4513 return;
4514 }
4515 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
4516 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004517 "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState);
Jeff Johnson295189b2012-06-20 16:38:30 -07004518 return;
4519 }
4520
Jeff Johnson295189b2012-06-20 16:38:30 -07004521 /* Disable TX Complete Interrupt at here */
4522 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4523 if(eWLAN_PAL_STATUS_SUCCESS != status)
4524 {
4525 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4526 "dxeTXCompISR Disable TX complete interrupt fail");
4527 return;
4528 }
4529 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
4530
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304531 wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
4532 &intSrc);
4533 /* intSrc which holds the INT_SRC_RAW_ADDRESS reg value
4534 While debugging crash dump convert to power of 2 for channel type */
4535 DXTRACE(dxeTrace(intSrc, TRACE_TXINT_STATE, TRACE_WLANDXE_VAR_DISABLE));
Jeff Johnson295189b2012-06-20 16:38:30 -07004536
4537 if( dxeCtxt->ucTxMsgCnt )
4538 {
4539 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
4540 "Avoiding serializing TX Complete event");
4541 return;
4542 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304543
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 dxeCtxt->ucTxMsgCnt = 1;
4545
4546 /* Serialize TX complete interrupt upon TX thread */
Manjunathappa Prakashfb585462013-12-23 19:07:07 -08004547 if(NULL == dxeCtxt->txIsrMsg)
4548 {
4549 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4550 "Invalid message");
4551 HDXE_ASSERT(0);
4552 return;
4553 }
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304554
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4556 dxeCtxt->txIsrMsg);
4557 if(eWLAN_PAL_STATUS_SUCCESS != status)
4558 {
4559 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
4560 "dxeTXCompISR interrupt serialize fail status=%d", status);
4561 }
4562
4563 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004564 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004565 return;
4566}
4567
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304568/*==========================================================================
4569 @ Function Name
4570 dxeTraceInit
4571
4572 @ Description
4573 Initialize the DXTRACE when enabled
4574
4575 @ Parameters
4576 NONE
4577
4578 @ Return
4579 NONE
4580===========================================================================*/
4581void dxeTraceInit(void)
4582{
4583 gdxeTraceData.head = INVALID_VOS_TRACE_ADDR;
4584 gdxeTraceData.tail = INVALID_VOS_TRACE_ADDR;
4585 gdxeTraceData.num = 0;
4586 gdxeTraceData.enable = eWLAN_PAL_TRUE;
4587}
4588
4589/*==========================================================================
4590 @ Function Name
4591 dxeTrace
4592
4593 @ Description
4594 puts the messages in to ring-buffer
4595
4596 @ Parameters
4597 v_U8_t chan
4598 Rx/Tx path record
4599 v_U8_t code
4600 Rx/Tx Event
4601 v_U32_t data
4602 Actual message contents
4603 @ Return
4604 NONE
4605===========================================================================*/
4606void dxeTrace(v_U8_t chan, v_U8_t code, v_U32_t data)
4607{
4608 pdxeTraceRecord rec = NULL;
4609 unsigned long flags;
4610
4611 if (!gdxeTraceData.enable)
4612 {
4613 return;
4614 }
4615
4616 /* Aquire the lock and only one thread can access the buffer at a time */
4617 spin_lock_irqsave(&dtraceLock, flags);
4618
4619 gdxeTraceData.num++;
4620
4621 if (gdxeTraceData.num > MAX_DXE_TRACE_RECORDS)
4622 {
4623 gdxeTraceData.num = MAX_DXE_TRACE_RECORDS;
4624 }
4625 if (INVALID_VOS_TRACE_ADDR == gdxeTraceData.head)
4626 {
4627 /* first record */
4628 gdxeTraceData.head = 0;
4629 gdxeTraceData.tail = 0;
4630 }
4631 else
4632 {
4633 /* queue is not empty */
4634 v_U32_t tail = gdxeTraceData.tail + 1;
4635 if (MAX_DXE_TRACE_RECORDS == tail)
4636 {
4637 tail = 0;
4638 }
4639 if (gdxeTraceData.head == tail)
4640 {
4641 /* full */
4642 if (MAX_DXE_TRACE_RECORDS == ++gdxeTraceData.head)
4643 {
4644 gdxeTraceData.head = 0;
4645 }
4646 }
4647 gdxeTraceData.tail = tail;
4648 }
4649
4650 rec = &gdxeTraceTbl[gdxeTraceData.tail];
4651 rec->code = code;
4652 rec->data = data;
4653 rec->time = vos_timer_get_system_time();
4654 rec->chan = chan;
4655
4656 spin_unlock_irqrestore(&dtraceLock, flags);
4657}
4658
Jeff Johnson295189b2012-06-20 16:38:30 -07004659/*-------------------------------------------------------------------------
4660 * Global Function
4661 *-------------------------------------------------------------------------*/
4662/*==========================================================================
4663 @ Function Name
4664 WLANDXE_Open
4665
4666 @ Description
4667 Open host DXE driver, allocate DXE resources
4668 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
4669
4670 @ Parameters
Jeff Johnsona8a1a482012-12-12 16:49:33 -08004671 pVoid pAdapter : Driver global control block pointer
Jeff Johnson295189b2012-06-20 16:38:30 -07004672
4673 @ Return
4674 pVoid DXE local module control block pointer
4675===========================================================================*/
4676void *WLANDXE_Open
4677(
4678 void
4679)
4680{
4681 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4682 unsigned int idx;
4683 WLANDXE_ChannelCBType *currentChannel = NULL;
4684 int smsmInitState;
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304685 wpt_uint8 chanMask = WDTS_TRANSPORT_CHANNELS_MASK;
Jeff Johnson295189b2012-06-20 16:38:30 -07004686
4687 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004688 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004689
Mihir Shetee6618162015-03-16 14:48:42 +05304690 if (wpalIsFwLoggingEnabled())
4691 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304692 chanMask |= WDTS_RX_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304693 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304694
4695 if (wpalIsFwEvLoggingEnabled())
Mihir Shetee6618162015-03-16 14:48:42 +05304696 {
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304697 chanMask |= WDTS_RX_FW_LOG_CHANNEL_MASK;
Mihir Shetee6618162015-03-16 14:48:42 +05304698 }
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304699 dxeSetEnabledChannels(chanMask);
Mihir Shetee6618162015-03-16 14:48:42 +05304700
Jeff Johnson295189b2012-06-20 16:38:30 -07004701 /* This is temporary allocation */
4702 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
4703 if(NULL == tempDxeCtrlBlk)
4704 {
4705 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4706 "WLANDXE_Open Control Block Alloc Fail");
4707 return NULL;
4708 }
4709 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
4710
jagadeeshf869bba2015-04-07 20:06:21 +05304711 dxeCommonDefaultConfig(tempDxeCtrlBlk);
Jeff Johnson295189b2012-06-20 16:38:30 -07004712
Mihir Shetee6618162015-03-16 14:48:42 +05304713 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004714 {
4715 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4716 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
4717 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
Mihir Shetebe94ebb2015-05-26 12:07:14 +05304718 currentChannel->channelType = idx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004719
4720 /* Config individual channels from channel default setup table */
4721 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
4722 currentChannel);
4723 if(eWLAN_PAL_STATUS_SUCCESS != status)
4724 {
4725 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4726 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
4727 WLANDXE_Close(tempDxeCtrlBlk);
4728 return NULL;
4729 }
4730
4731 /* Allocate DXE Control Block will be used by host DXE driver */
4732 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
4733 if(eWLAN_PAL_STATUS_SUCCESS != status)
4734 {
4735 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4736 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
4737
4738 WLANDXE_Close(tempDxeCtrlBlk);
4739 return NULL;
4740 }
4741 status = wpalMutexInit(&currentChannel->dxeChannelLock);
4742 if(eWLAN_PAL_STATUS_SUCCESS != status)
4743 {
4744 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4745 "WLANDXE_Open Lock Init Fail for channel %d", idx);
4746 WLANDXE_Close(tempDxeCtrlBlk);
4747 return NULL;
4748 }
4749
4750 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4751 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
4752 }
4753
4754 /* Allocate and Init RX READY ISR Serialize Buffer */
4755 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4756 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
4757 {
4758 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4759 "WLANDXE_Open Alloc RX ISR Fail");
4760 WLANDXE_Close(tempDxeCtrlBlk);
4761 return NULL;
4762 }
4763 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
4764 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
4765 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4766
4767 /* Allocate and Init TX COMP ISR Serialize Buffer */
4768 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4769 if(NULL == tempDxeCtrlBlk->txIsrMsg)
4770 {
4771 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4772 "WLANDXE_Open Alloc TX ISR Fail");
4773 WLANDXE_Close(tempDxeCtrlBlk);
4774 return NULL;
4775 }
4776 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
4777 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
4778 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
4779
4780 /* Allocate and Init RX Packet Available Serialize Message Buffer */
4781 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4782 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
4783 {
4784 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4785 "WLANDXE_Open Alloc RX Packet Available Message Fail");
4786 WLANDXE_Close(tempDxeCtrlBlk);
4787 return NULL;
4788 }
4789 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
4790 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
4791 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
4792
4793 tempDxeCtrlBlk->freeRXPacket = NULL;
4794 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
4795 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4796 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004797 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Leo Changac1d3612013-07-01 15:15:51 -07004798 tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE;
Karthick Sc6ec8362015-08-12 18:18:47 +05304799 tempDxeCtrlBlk->smsmRingsEmptyHistogram = 0;
4800 tempDxeCtrlBlk->smsmDxeHistogram = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004801
4802 /* Initialize SMSM state
4803 * Init State is
4804 * Clear TX Enable
4805 * RING EMPTY STATE */
4806 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
4807 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
4808 if(0 != smsmInitState)
4809 {
4810 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4811 "SMSM Channel init fail %d", smsmInitState);
Mihir Shetee6618162015-03-16 14:48:42 +05304812 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004813 {
4814 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
4815 }
Madan Mohan Koyyalamudibe3597f2012-11-15 17:33:55 -08004816 wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg);
4817 wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg);
Jeff Johnson295189b2012-06-20 16:38:30 -07004818 wpalMemoryFree(tempDxeCtrlBlk);
4819 return NULL;
4820 }
4821
Mihir Shete44547fb2014-03-10 14:15:42 +05304822#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07004823 wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer,
4824 dxeRXResourceAvailableTimerExpHandler,
4825 tempDxeCtrlBlk);
Mihir Shete44547fb2014-03-10 14:15:42 +05304826#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07004827
Mihir Shetefdc9f532014-01-09 15:03:02 +05304828 wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer,
4829 dxeSSRTimerExpHandler, tempDxeCtrlBlk);
4830
Sravan Kumar Kairamf41f0742015-12-14 16:32:25 +05304831 spin_lock_init(&dtraceLock);
4832
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05304833#ifdef DXE_TRACE
4834 DXTRACE(dxeTraceInit());
4835#endif
4836
Jeff Johnson295189b2012-06-20 16:38:30 -07004837 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4838 "WLANDXE_Open Success");
4839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004840 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 return (void *)tempDxeCtrlBlk;
4842}
4843
4844/*==========================================================================
4845 @ Function Name
4846 WLANDXE_ClientRegistration
4847
4848 @ Description
4849 Make callback functions registration into DXE driver from DXE driver client
4850
4851 @ Parameters
4852 pVoid pDXEContext : DXE module control block
Mihir Shetec4093f92015-05-28 15:21:11 +05304853 WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events
Jeff Johnson295189b2012-06-20 16:38:30 -07004854 void *userContext : DXE Cliennt control block
4855
4856 @ Return
4857 wpt_status
4858===========================================================================*/
4859wpt_status WLANDXE_ClientRegistration
4860(
4861 void *pDXEContext,
Mihir Shetec4093f92015-05-28 15:21:11 +05304862 WDTS_ClientCallbacks WDTSCb,
Jeff Johnson295189b2012-06-20 16:38:30 -07004863 void *userContext
4864)
4865{
4866 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4867 WLANDXE_CtrlBlkType *dxeCtxt;
4868
4869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004870 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004871
4872 /* Sanity */
4873 if(NULL == pDXEContext)
4874 {
4875 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4876 "WLANDXE_ClientRegistration Invalid DXE CB");
4877 return eWLAN_PAL_STATUS_E_INVAL;
4878 }
4879
Jeff Johnson295189b2012-06-20 16:38:30 -07004880 if(NULL == userContext)
4881 {
4882 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4883 "WLANDXE_ClientRegistration Invalid userContext");
4884 return eWLAN_PAL_STATUS_E_INVAL;
4885 }
4886
4887 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4888
4889 /* Assign */
Mihir Shetec4093f92015-05-28 15:21:11 +05304890 dxeCtxt->rxReadyCB = WDTSCb.rxFrameReadyCB;
4891 dxeCtxt->txCompCB = WDTSCb.txCompleteCB;
4892 dxeCtxt->lowResourceCB = WDTSCb.lowResourceCB;
4893 dxeCtxt->receiveMbMsgCB = WDTSCb.receiveMbMsgCB;
Mihir Shete5affadc2015-05-29 20:54:57 +05304894 dxeCtxt->receiveLogCompleteCB = WDTSCb.receiveLogCompleteCB;
Jeff Johnson295189b2012-06-20 16:38:30 -07004895 dxeCtxt->clientCtxt = userContext;
4896
4897 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004898 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 return status;
4900}
4901
4902/*==========================================================================
4903 @ Function Name
4904 WLANDXE_Start
4905
4906 @ Description
4907 Start Host DXE driver
4908 Initialize DXE channels and start channel
4909
4910 @ Parameters
4911 pVoid pDXEContext : DXE module control block
4912
4913 @ Return
4914 wpt_status
4915===========================================================================*/
4916wpt_status WLANDXE_Start
4917(
4918 void *pDXEContext
4919)
4920{
4921 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4922 wpt_uint32 idx;
4923 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4924
4925 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004926 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004927
4928 /* Sanity */
4929 if(NULL == pDXEContext)
4930 {
4931 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4932 "WLANDXE_Start Invalid DXE CB");
4933 return eWLAN_PAL_STATUS_E_INVAL;
4934 }
4935 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4936
4937 /* WLANDXE_Start called means DXE engine already initiates
4938 * And DXE HW is reset and init finished
4939 * But here to make sure HW is initialized, reset again */
jagadeeshf869bba2015-04-07 20:06:21 +05304940 dxeEngineCoreStart(dxeCtxt);
Jeff Johnson295189b2012-06-20 16:38:30 -07004941
4942 /* Individual Channel Start */
Mihir Shetee6618162015-03-16 14:48:42 +05304943 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07004944 {
4945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4946 "WLANDXE_Start Channel %s Start", channelType[idx]);
4947
4948 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
4949 /* Make connection between DXE descriptor and DXE control block */
4950 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
4951 if(eWLAN_PAL_STATUS_SUCCESS != status)
4952 {
4953 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4954 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
4955 return status;
4956 }
4957
4958 /* Program each channel register with configuration arguments */
4959 status = dxeChannelInitProgram(dxeCtxt,
4960 &dxeCtxt->dxeChannel[idx]);
4961 if(eWLAN_PAL_STATUS_SUCCESS != status)
4962 {
4963 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4964 "WLANDXE_Start %d Program DMA channel Fail", idx);
4965 return status;
4966 }
4967
4968 /* ??? Trigger to start DMA channel
4969 * This must be seperated from ??? */
4970 status = dxeChannelStart(dxeCtxt,
4971 &dxeCtxt->dxeChannel[idx]);
4972 if(eWLAN_PAL_STATUS_SUCCESS != status)
4973 {
4974 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4975 "WLANDXE_Start %d Channel Start Fail", idx);
4976 return status;
4977 }
4978 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
4979 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
4980 }
4981
4982 /* Register ISR to OS */
4983 /* Register TX complete interrupt into platform */
4984 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
4985 dxeTXISR,
4986 dxeCtxt);
4987 if(eWLAN_PAL_STATUS_SUCCESS != status)
4988 {
4989 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4990 "WLANDXE_Start TX comp interrupt registration Fail");
4991 return status;
4992 }
4993
4994 /* Register RX ready interrupt into platform */
4995 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
4996 dxeRXISR,
4997 dxeCtxt);
4998 if(eWLAN_PAL_STATUS_SUCCESS != status)
4999 {
5000 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5001 "WLANDXE_Start RX Ready interrupt registration Fail");
5002 return status;
5003 }
5004
5005 /* Enable system level ISR */
5006 /* Enable RX ready Interrupt at here */
5007 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5008 if(eWLAN_PAL_STATUS_SUCCESS != status)
5009 {
5010 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5011 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
5012 return status;
5013 }
5014
5015 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005016 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 return status;
5018}
5019
5020/*==========================================================================
5021 @ Function Name
5022 WLANDXE_TXFrame
5023
5024 @ Description
5025 Trigger frame transmit from host to RIVA
5026
5027 @ Parameters
5028 pVoid pDXEContext : DXE Control Block
5029 wpt_packet pPacket : transmit packet structure
5030 WDTS_ChannelType channel : TX channel
5031
5032 @ Return
5033 wpt_status
5034===========================================================================*/
5035wpt_status WLANDXE_TxFrame
5036(
5037 void *pDXEContext,
5038 wpt_packet *pPacket,
5039 WDTS_ChannelType channel
5040)
5041{
5042 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5043 WLANDXE_ChannelCBType *currentChannel = NULL;
5044 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5045 unsigned int *lowThreshold = NULL;
5046
5047 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005048 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005049
5050 /* Sanity */
5051 if(NULL == pDXEContext)
5052 {
5053 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5054 "WLANDXE_Start Invalid DXE CB");
5055 return eWLAN_PAL_STATUS_E_INVAL;
5056 }
5057
5058 if(NULL == pPacket)
5059 {
5060 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5061 "WLANDXE_Start Invalid pPacket");
5062 return eWLAN_PAL_STATUS_E_INVAL;
5063 }
5064
Mihir Shetee6618162015-03-16 14:48:42 +05305065 if(WDTS_CHANNEL_MAX <= channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005066 {
5067 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5068 "WLANDXE_Start Invalid channel");
5069 return eWLAN_PAL_STATUS_E_INVAL;
5070 }
5071
5072 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
5073
5074 currentChannel = &dxeCtxt->dxeChannel[channel];
5075
5076
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005077 status = wpalMutexAcquire(&currentChannel->dxeChannelLock);
5078 if(eWLAN_PAL_STATUS_SUCCESS != status)
5079 {
5080 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5081 "WLANDXE_TxFrame Mutex Acquire fail");
5082 return status;
5083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005084
5085 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
5086 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
5087 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
5088
5089 /* Decide have to activate TX complete event or not */
5090 switch(dxeCtxt->txCompInt.txIntEnable)
5091 {
5092 /* TX complete interrupt will be activated when low DXE resource */
5093 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
5094 if((currentChannel->numFreeDesc <= *lowThreshold) &&
5095 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
5096 {
5097 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
5098 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5099 channel,
5100 eWLAN_PAL_FALSE);
5101 }
5102 break;
5103
Jeff Johnsonab79c8d2012-12-10 14:30:13 -08005104 /* TX complete interrupt will be activated n number of frames transferred */
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
5106 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
5107 {
5108 currentChannel->numFrameBeforeInt++;
5109 }
5110 break;
5111
5112 /* TX complete interrupt will be activated periodically */
5113 case WLANDXE_TX_COMP_INT_TIMER:
5114 break;
5115 }
5116
5117 dxeCtxt->txCompletedFrames++;
5118
5119 /* Update DXE descriptor, this is frame based
5120 * if a frame consist of N fragments, N Descriptor will be programed */
5121 status = dxeTXPushFrame(currentChannel, pPacket);
5122 if(eWLAN_PAL_STATUS_SUCCESS != status)
5123 {
5124 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5125 "WLANDXE_TxFrame TX Push Frame fail");
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005126 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5127 if(eWLAN_PAL_STATUS_SUCCESS != status)
5128 {
5129 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5130 "WLANDXE_TxFrame Mutex Release fail");
5131 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 return status;
5133 }
5134
5135 /* If specific channel hit low resource condition, send notification to upper layer */
5136 if(currentChannel->numFreeDesc <= *lowThreshold)
5137 {
5138 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5139 channel,
5140 eWLAN_PAL_FALSE);
5141 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
Madan Mohan Koyyalamudiea777012012-10-31 14:22:34 -07005142
5143 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
5144 "%11s : Low Resource currentChannel->numRsvdDesc %d",
5145 channelType[currentChannel->channelType],
5146 currentChannel->numRsvdDesc);
Mihir Shete68ed77a2014-10-10 10:47:12 +05305147 if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5148 {
5149 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5150 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
5151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 }
Madan Mohan Koyyalamudib2cb8be2012-11-27 15:07:43 -08005153 status = wpalMutexRelease(&currentChannel->dxeChannelLock);
5154 if(eWLAN_PAL_STATUS_SUCCESS != status)
5155 {
5156 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5157 "WLANDXE_TxFrame Mutex Release fail");
5158 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005159
5160 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005161 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005162 return status;
5163}
5164
5165/*==========================================================================
5166 @ Function Name
5167 WLANDXE_CompleteTX
5168
5169 @ Description
5170 Informs DXE that the current series of Tx packets is complete
5171
5172 @ Parameters
5173 pContext pDXEContext : DXE Control Block
5174 ucTxResReq TX resource number required by TL/WDI
5175
5176 @ Return
5177 wpt_status
5178===========================================================================*/
5179wpt_status
5180WLANDXE_CompleteTX
5181(
5182 void* pContext,
5183 wpt_uint32 ucTxResReq
5184)
5185{
5186 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5187 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
5188 WLANDXE_ChannelCBType *channelCb = NULL;
5189 wpt_boolean inLowRes;
5190
5191 /* Sanity Check */
5192 if( NULL == pContext )
5193 {
5194 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5195 "WLANDXE_CompleteTX invalid param");
5196 return eWLAN_PAL_STATUS_E_INVAL;
5197 }
5198
5199 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
5200 inLowRes = channelCb->hitLowResource;
5201
5202 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
5203 {
5204 /* Raise threshold temporarily if necessary */
5205 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
5206
5207 if(eWLAN_PAL_FALSE == inLowRes)
5208 {
5209 /* Put the channel to low resource condition */
5210 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5211 WDTS_CHANNEL_TX_LOW_PRI,
5212 eWLAN_PAL_FALSE);
5213 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
5214 }
5215 }
5216
5217 /*Try to reclaim resources*/
5218 dxeTXCompleteProcessing(dxeCtxt);
5219
5220 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
5221 because its fragment size is larger than DXE free resource. */
5222 if(0 < ucTxResReq)
5223 {
5224 /* DXE successfully claimed enough free DXE resouces for next fetch. */
5225 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
5226 {
5227 /* DXE has not been in low resource condition. DXE forces to kick off
5228 TX tranmit */
5229 if((eWLAN_PAL_FALSE == inLowRes) &&
5230 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
5231 {
5232 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5233 WDTS_CHANNEL_TX_LOW_PRI,
5234 eWLAN_PAL_FALSE);
5235 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5236 WDTS_CHANNEL_TX_LOW_PRI,
5237 eWLAN_PAL_TRUE);
5238 channelCb->hitLowResource = eWLAN_PAL_FALSE;
5239 }
5240 }
5241 else
5242 {
5243 /* DXE doesn't have enough free DXE resources. Put the channel
5244 to low resource condition. */
5245 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
5246 {
5247 /* Put the channel to low resource condition */
5248 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
5249 WDTS_CHANNEL_TX_LOW_PRI,
5250 eWLAN_PAL_FALSE);
5251 channelCb->hitLowResource = eWLAN_PAL_TRUE;
5252 }
5253 }
5254 }
5255
5256 return status;
5257}
5258
5259/*==========================================================================
5260 @ Function Name
5261 WLANDXE_Stop
5262
5263 @ Description
5264 Stop DXE channels and DXE engine operations
5265 Disable all channel interrupt
5266 Stop all channel operation
5267
5268 @ Parameters
5269 pVoid pDXEContext : DXE Control Block
5270
5271 @ Return
5272 wpt_status
5273===========================================================================*/
5274wpt_status WLANDXE_Stop
5275(
5276 void *pDXEContext
5277)
5278{
5279 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5280 wpt_uint32 idx;
5281 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
5282
5283 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005284 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005285
5286 /* Sanity */
5287 if(NULL == pDXEContext)
5288 {
5289 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5290 "WLANDXE_Stop Invalid DXE CB");
5291 return eWLAN_PAL_STATUS_E_INVAL;
5292 }
5293
5294 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shetee6618162015-03-16 14:48:42 +05305295 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005296 {
5297 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
5298 if(eWLAN_PAL_STATUS_SUCCESS != status)
5299 {
5300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5301 "WLANDXE_Stop Channel %d Stop Fail", idx);
Jeff Johnson295189b2012-06-20 16:38:30 -07005302 }
5303 }
5304
5305 /* During Stop unregister interrupt */
5306 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
5307 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
5308
Mihir Shete44547fb2014-03-10 14:15:42 +05305309#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005310 if(VOS_TIMER_STATE_STOPPED !=
5311 wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer))
5312 {
5313 wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer);
5314 }
Mihir Shete44547fb2014-03-10 14:15:42 +05305315#endif
Leo Chang72cdfd32013-10-17 20:36:30 -07005316
Jeff Johnson295189b2012-06-20 16:38:30 -07005317 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005318 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 return status;
5320}
5321
5322/*==========================================================================
5323 @ Function Name
5324 WLANDXE_Close
5325
5326 @ Description
5327 Close DXE channels
5328 Free DXE related resources
5329 DXE descriptor free
5330 Descriptor control block free
5331 Pre allocated RX buffer free
5332
5333 @ Parameters
5334 pVoid pDXEContext : DXE Control Block
5335
5336 @ Return
5337 wpt_status
5338===========================================================================*/
5339wpt_status WLANDXE_Close
5340(
5341 void *pDXEContext
5342)
5343{
5344 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5345 wpt_uint32 idx;
5346 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005347
5348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005349 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005350
5351 /* Sanity */
5352 if(NULL == pDXEContext)
5353 {
5354 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5355 "WLANDXE_Stop Invalid DXE CB");
5356 return eWLAN_PAL_STATUS_E_INVAL;
5357 }
5358
5359 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
Mihir Shete44547fb2014-03-10 14:15:42 +05305360#ifdef WLAN_DXE_LOW_RESOURCE_TIMER
Leo Chang72cdfd32013-10-17 20:36:30 -07005361 wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer);
Mihir Shete44547fb2014-03-10 14:15:42 +05305362#endif
Mihir Shetefdc9f532014-01-09 15:03:02 +05305363 wpalTimerDelete(&dxeCtxt->dxeSSRTimer);
Mihir Shetee6618162015-03-16 14:48:42 +05305364 foreach_valid_channel(idx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 {
5366 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
5367 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 }
5369
5370 if(NULL != dxeCtxt->rxIsrMsg)
5371 {
5372 wpalMemoryFree(dxeCtxt->rxIsrMsg);
5373 }
5374 if(NULL != dxeCtxt->txIsrMsg)
5375 {
5376 wpalMemoryFree(dxeCtxt->txIsrMsg);
5377 }
5378 if(NULL != dxeCtxt->rxPktAvailMsg)
5379 {
5380 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
5381 }
5382
5383 wpalMemoryFree(pDXEContext);
5384
5385 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005386 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 return status;
5388}
5389
5390/*==========================================================================
5391 @ Function Name
5392 WLANDXE_TriggerTX
5393
5394 @ Description
5395 TBD
5396
5397 @ Parameters
5398 pVoid pDXEContext : DXE Control Block
5399
5400 @ Return
5401 wpt_status
5402===========================================================================*/
5403wpt_status WLANDXE_TriggerTX
5404(
5405 void *pDXEContext
5406)
5407{
5408 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5409
5410 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005411 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005412
5413 /* TBD */
5414
5415 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005416 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 return status;
5418}
5419
5420/*==========================================================================
5421 @ Function Name
5422 dxeTxThreadSetPowerStateEventHandler
5423
5424 @ Description
5425 If WDI sends set power state req, this event handler will be called in Tx
5426 thread context
5427
5428 @ Parameters
5429 void *msgPtr
5430 Event MSG
5431
5432 @ Return
5433 None
5434===========================================================================*/
5435void dxeTxThreadSetPowerStateEventHandler
5436(
5437 wpt_msg *msgPtr
5438)
5439{
5440 wpt_msg *msgContent = (wpt_msg *)msgPtr;
5441 WLANDXE_CtrlBlkType *dxeCtxt;
Mihir Shetea4306052014-03-25 00:02:54 +05305442 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 WLANDXE_PowerStateType reqPowerState;
Mihir Shetea4306052014-03-25 00:02:54 +05305444 wpt_int8 i;
5445 WLANDXE_ChannelCBType *channelEntry;
5446 wpt_log_data_stall_channel_type channelLog;
Jeff Johnson295189b2012-06-20 16:38:30 -07005447
5448 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005449 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005450
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
5452 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
5453 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
5454
5455 switch(reqPowerState)
5456 {
5457 case WLANDXE_POWER_STATE_BMPS:
5458 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5459 {
5460 //don't block MC waiting for num_rsvd to become 0 since it may take a while
5461 //based on amount of TX and RX activity - during this time any received
5462 // management frames will remain un-processed consuming RX buffers
5463 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5464 dxeCtxt->hostPowerState = reqPowerState;
5465 }
5466 else
5467 {
5468 status = eWLAN_PAL_STATUS_E_INVAL;
5469 }
5470 break;
5471 case WLANDXE_POWER_STATE_IMPS:
5472 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
5473 {
Mihir Shetea4306052014-03-25 00:02:54 +05305474
5475 for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++)
5476 {
5477 channelEntry = &dxeCtxt->dxeChannel[i];
5478 if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk)
5479 {
5480 status = eWLAN_PAL_STATUS_E_FAILURE;
5481 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
5482 "%11s : %s :TX Pending frame",
5483 channelType[channelEntry->channelType], __func__);
5484
5485 dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog);
5486 dxeDescriptorDump(channelEntry,
5487 channelEntry->headCtrlBlk->linkedDesc, 0);
5488 dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR",
5489 &channelLog);
5490 dxeChannelAllDescDump(channelEntry,
5491 channelEntry->channelType,
5492 &channelLog);
5493 }
5494 }
5495
5496 if (eWLAN_PAL_STATUS_SUCCESS == status)
5497 {
5498 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
5499 dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5500 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 }
5502 else
5503 {
5504 status = eWLAN_PAL_STATUS_E_INVAL;
5505 }
5506 break;
5507 case WLANDXE_POWER_STATE_FULL:
5508 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
5509 {
5510 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5511 }
5512 dxeCtxt->hostPowerState = reqPowerState;
5513 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5514 break;
5515 case WLANDXE_POWER_STATE_DOWN:
5516 WLANDXE_Stop((void *)dxeCtxt);
5517 break;
5518 default:
5519 //assert
5520 break;
5521 }
5522
Sravan Kumar Kairama8269e72015-11-06 12:13:24 +05305523 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_POWER_STATE, dxeCtxt->hostPowerState));
5524
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
5526 {
5527 dxeCtxt->setPowerStateCb(status,
5528 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
5529 }
Ravali85acf6b2012-12-12 14:01:38 -08005530 else
5531 {
5532 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
5533 "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__);
5534 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 /* Free MSG buffer */
5536 wpalMemoryFree(msgPtr);
5537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005538 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 return;
5540}
5541
5542
5543/*==========================================================================
5544 @ Function Name
5545 dxeRxThreadSetPowerStateEventHandler
5546
5547 @ Description
5548 If WDI sends set power state req, this event handler will be called in Rx
5549 thread context
5550
5551 @ Parameters
5552 void *msgPtr
5553 Event MSG
5554
5555 @ Return
5556 None
5557===========================================================================*/
5558void dxeRxThreadSetPowerStateEventHandler
5559(
5560 wpt_msg *msgPtr
5561)
5562{
5563 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5564
5565 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005566 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005567
5568 /* Now serialise the message through Tx thread also to make sure
5569 * no register access when RIVA is in powersave */
5570 /*Use the same message pointer just change the call back function */
5571 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
5572 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5573 msgPtr);
5574 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5575 {
5576 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5577 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005578 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 }
5580
5581 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005582 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005583}
5584
5585/*==========================================================================
5586 @ Function Name
5587 WLANDXE_SetPowerState
5588
5589 @ Description
5590 From Client let DXE knows what is the WLAN HW(RIVA) power state
5591
5592 @ Parameters
5593 pVoid pDXEContext : DXE Control Block
5594 WLANDXE_PowerStateType powerState
5595
5596 @ Return
5597 wpt_status
5598===========================================================================*/
5599wpt_status WLANDXE_SetPowerState
5600(
5601 void *pDXEContext,
5602 WDTS_PowerStateType powerState,
5603 WDTS_SetPSCbType cBack
5604)
5605{
5606 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5607 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
5608 WLANDXE_PowerStateType hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005609 wpt_msg *rxCompMsg;
5610 wpt_msg *txDescReSyncMsg;
Sravan Kumar Kairam84e995f2016-05-27 16:16:21 +05305611 int state;
Jeff Johnson295189b2012-06-20 16:38:30 -07005612
5613 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005614 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 if(NULL == pDXEContext)
5616 {
5617 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005618 "NULL pDXEContext passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 return eWLAN_PAL_STATUS_E_FAILURE;
5620 }
5621 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
5622
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 switch(powerState)
5624 {
5625 case WDTS_POWER_STATE_FULL:
Sravan Kumar Kairam84e995f2016-05-27 16:16:21 +05305626 dxeEnvBlk.dxe_prev_ps = pDxeCtrlBlk->hostPowerState;
Madan Mohan Koyyalamudi7f1020d2012-09-28 15:29:03 -07005627 if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState)
5628 {
5629 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5630 if(NULL == txDescReSyncMsg)
5631 {
5632 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5633 "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail");
5634 }
5635 else
5636 {
5637 txDescReSyncMsg->callback = dxeTXReSyncDesc;
5638 txDescReSyncMsg->pContext = pDxeCtrlBlk;
5639 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5640 txDescReSyncMsg);
5641 if(eWLAN_PAL_STATUS_SUCCESS != status)
5642 {
5643 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5644 "WLANDXE_SetPowerState, Post TX re-sync MSG fail");
5645 }
5646 }
5647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 hostPowerState = WLANDXE_POWER_STATE_FULL;
5649 break;
5650 case WDTS_POWER_STATE_BMPS:
5651 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
5652 hostPowerState = WLANDXE_POWER_STATE_BMPS;
5653 break;
5654 case WDTS_POWER_STATE_IMPS:
Jeff Johnson295189b2012-06-20 16:38:30 -07005655 hostPowerState = WLANDXE_POWER_STATE_IMPS;
5656 break;
5657 case WDTS_POWER_STATE_DOWN:
5658 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
5659 hostPowerState = WLANDXE_POWER_STATE_DOWN;
5660 break;
5661 default:
5662 hostPowerState = WLANDXE_POWER_STATE_MAX;
5663 }
5664
5665 // A callback i.e. ACK back is needed only when we want to enable BMPS
5666 // and the data/management path is active because we want to ensure
5667 // DXE registers are not accessed when RIVA may be power-collapsed. So
5668 // we need a callback in enter_bmps_req (the request to RIVA is sent
5669 // only after ACK back from TX thread). A callback is not needed in
5670 // finish_scan_req during BMPS since data-path is resumed only in
5671 // finish_scan_rsp and no management frames are sent in between. No
5672 // callback is needed when going from BMPS enabled to BMPS suspended/
5673 // disabled when it is known that RIVA is awake and cannot enter power
5674 // collapse autonomously so no callback is needed in exit_bmps_rsp or
5675 // init_scan_rsp
5676 if ( cBack )
5677 {
5678 //serialize through Rx thread
5679 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5680 if(NULL == rxCompMsg)
5681 {
5682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5683 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
5684 return eWLAN_PAL_STATUS_E_RESOURCES;
5685 }
5686
5687 /* Event type, where it must be defined???? */
5688 /* THIS MUST BE CLEARED ASAP
5689 txCompMsg->type = TX_COMPLETE; */
5690 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
5691 rxCompMsg->pContext = pDxeCtrlBlk;
5692 rxCompMsg->val = hostPowerState;
5693 rxCompMsg->ptr = cBack;
5694 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
5695 rxCompMsg);
5696 if ( eWLAN_PAL_STATUS_SUCCESS != status )
5697 {
5698 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5699 "Rx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005700 status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 }
5702 }
5703 else
5704 {
5705 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
5706 {
5707 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
5708 {
5709 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5710 }
5711 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
5712 {
5713 /* Requested Full power from exit IMPS, reenable the interrupts*/
5714 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
5715 {
5716 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
5717 /* Enable RX interrupt at here, if new PS is not IMPS */
5718 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
5719 if(eWLAN_PAL_STATUS_SUCCESS != status)
5720 {
5721 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005722 "%s Enable RX ready interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 return status;
5724 }
5725 }
5726 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
5727 {
5728 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005729 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 /* Enable RX interrupt at here, if new PS is not IMPS */
5731 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
5732 if(eWLAN_PAL_STATUS_SUCCESS != status)
5733 {
5734 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005735 "%s Enable TX comp interrupt fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 return status;
5737 }
5738 }
5739 }
5740 pDxeCtrlBlk->hostPowerState = hostPowerState;
5741 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
5742 }
5743 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
5744 {
5745 pDxeCtrlBlk->hostPowerState = hostPowerState;
5746 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
5747 }
Mihir Shetea4306052014-03-25 00:02:54 +05305748 else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS )
5749 {
5750 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
5751 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 else
5753 {
5754 HDXE_ASSERT(0);
5755 }
Sravan Kumar Kairam3d22ec02016-08-01 12:58:44 +05305756 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_POWER_STATE,
5757 pDxeCtrlBlk->hostPowerState));
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 }
5759
Sravan Kumar Kairam3d22ec02016-08-01 12:58:44 +05305760 if (WDTS_POWER_STATE_FULL == powerState &&
5761 WLANDXE_POWER_STATE_FULL == pDxeCtrlBlk->hostPowerState) {
Sravan Kumar Kairam84e995f2016-05-27 16:16:21 +05305762 state = wpal_get_int_state(DXE_INTERRUPT_RX_READY);
5763 if (0 == state && eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS) {
5764 dxeEnvBlk.rx_imps_set_fp = 1;
5765 WARN_ON(1);
5766 }
5767 }
5768
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005770 "%s Exit", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005771
5772 return status;
5773}
5774
5775/*==========================================================================
5776 @ Function Name
5777 WLANDXE_GetFreeTxDataResNumber
5778
5779 @ Description
5780 Returns free descriptor numbers for TX data channel (TX high priority)
5781
5782 @ Parameters
5783 pVoid pDXEContext : DXE Control Block
5784
5785 @ Return
5786 wpt_uint32 Free descriptor number of TX high pri ch
5787===========================================================================*/
5788wpt_uint32 WLANDXE_GetFreeTxDataResNumber
5789(
5790 void *pDXEContext
5791)
5792{
5793 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005794 "%s Enter", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005795
5796 if(NULL == pDXEContext)
5797 {
5798 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005799 "NULL parameter passed by caller");
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 return (0);
5801 }
5802
Mihir Shetee6618162015-03-16 14:48:42 +05305803 return ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005804}
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005805
5806/*==========================================================================
5807 @ Function Name
5808 WLANDXE_ChannelDebug
5809
5810 @ Description
5811 Display DXE Channel debugging information
5812 User may request to display DXE channel snapshot
5813 Or if host driver detects any abnormal stcuk may display
5814
5815 @ Parameters
Jeff Johnsonb88db982012-12-10 13:34:59 -08005816 displaySnapshot : Display DXE snapshot option
Mihir Shete40a55652014-03-02 14:14:47 +05305817 debugFlags : Enable stall detect features
5818 defined by WPAL_DeviceDebugFlags
5819 These features may effect
5820 data performance.
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005821
5822 @ Return
5823 NONE
5824
5825===========================================================================*/
5826void WLANDXE_ChannelDebug
5827(
Mihir Shete40a55652014-03-02 14:14:47 +05305828 wpt_boolean displaySnapshot,
5829 wpt_uint8 debugFlags
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005830)
5831{
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005832 wpt_msg *channelDebugMsg;
Mihir Shete40a55652014-03-02 14:14:47 +05305833 wpt_msg *txDescReSyncMsg ;
Mihir Shete41c41bb2014-08-18 17:37:12 +05305834 wpt_uint32 regValue, regValueLocal = 0;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005835 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5836
5837 /* Debug Type 1, Display current snapshot */
5838 if(displaySnapshot)
5839 {
5840 /* Whatever RIVA power condition try to wakeup RIVA through SMSM
5841 * This will not simply wakeup RIVA
5842 * Just incase TX not wanted stuck, Trigger TX again */
Leo Chang345ef992013-07-12 10:17:29 -07005843 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5844 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005845 /* Get free BD count */
Leo Chang345ef992013-07-12 10:17:29 -07005846 wpalSleep(10);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005847 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, &regValue);
Mihir Shete41c41bb2014-08-18 17:37:12 +05305848#ifdef WCN_PRONTO
5849 wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, &regValueLocal);
5850#endif
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005851 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305852 "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====",
Leo Chang345ef992013-07-12 10:17:29 -07005853 tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState,
Mihir Shete41c41bb2014-08-18 17:37:12 +05305854 tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal);
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005855
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005856 wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState,
5857 &regValue,
5858 NULL,
5859 0);
Bansidhar Gopalachari609b79e2013-07-31 17:03:15 -07005860
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005861 channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5862 if(NULL == channelDebugMsg)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005863 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005864 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5865 "WLANDXE_ChannelDebug, MSG MEM alloc Fail");
5866 return ;
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005867 }
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005868
5869 channelDebugMsg->callback = dxeRxThreadChannelDebugHandler;
5870 status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg);
5871 if ( eWLAN_PAL_STATUS_SUCCESS != status )
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005872 {
Madan Mohan Koyyalamudi24a00f92012-10-22 15:21:02 -07005873 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5874 "Tx thread Set power state req serialize fail status=%d",
Jeff Johnson9e237fb2013-10-30 18:46:20 -07005875 status);
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005876 }
5877 }
5878
Mihir Shete40a55652014-03-02 14:14:47 +05305879 if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC)
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005880 {
Mihir Shete40a55652014-03-02 14:14:47 +05305881 txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
5882 if(NULL == txDescReSyncMsg)
5883 {
5884 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5885 "%s: Resync MSG MEM alloc Fail",__func__);
5886 }
5887 else
5888 {
5889 txDescReSyncMsg->callback = dxeDebugTxDescReSync;
5890 txDescReSyncMsg->pContext = tempDxeCtrlBlk;
5891 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
5892 txDescReSyncMsg);
5893 if(eWLAN_PAL_STATUS_SUCCESS != status)
5894 {
5895 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5896 "%s: Post TX re-sync MSG fail",__func__);
5897 }
5898 }
5899 }
5900
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07005901 return;
Madan Mohan Koyyalamudi48139e32012-10-11 14:43:56 -07005902}
Mihir Shete5affadc2015-05-29 20:54:57 +05305903
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05305904/*==========================================================================
5905 @ Function Name
5906 WLANDXE_KickDxe
5907
5908 @ Description
5909 Kick DXE when HDD TX time out happen
5910
5911 @ Parameters
5912 NONE
5913
5914 @ Return
5915 NONE
5916
5917===========================================================================*/
5918void WLANDXE_KickDxe(void)
5919{
Sravan Kumar Kairamcebb2182016-01-25 20:50:11 +05305920 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05305921 "%s: Kick Dxe for HDD TX timeout",__func__);
5922 /* Make wake up HW */
5923 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
5924 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
Sravan Kumar Kairamcebb2182016-01-25 20:50:11 +05305925 DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_SMSM_NOTIFY,
5926 TRACE_WLANDXE_VAR_ENABLE));
Sravan Kumar Kairame9d186c2015-11-27 23:37:02 +05305927}
5928
Mihir Shete5affadc2015-05-29 20:54:57 +05305929wpt_uint32 WLANDXE_SetupLogTransfer(wpt_uint64 bufferAddr, wpt_uint32 bufferLen)
5930{
5931 WLANDXE_ChannelCBType *channelEntry;
5932
5933 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5934
5935
5936 return dxeRXLogRefillRing(tempDxeCtrlBlk, channelEntry, bufferAddr,
5937 bufferLen);
5938}
5939
5940wpt_status WLANDXE_StartLogTransfer(void)
5941{
5942 WLANDXE_ChannelCBType *channelEntry;
5943 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
5944
5945 channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG];
5946
5947 tempDxeCtrlBlk->hostInitiatedH2H = 1;
5948 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
5949 channelEntry->headCtrlBlk->linkedDescPhyAddr);
5950 if(eWLAN_PAL_STATUS_SUCCESS != status)
5951 {
5952 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5953 "%s Write DESC Address register fail", __func__);
5954 return status;
5955 }
5956
Abhishek Singh2b055852015-10-07 14:14:13 +05305957 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
Mihir Shete5affadc2015-05-29 20:54:57 +05305958 channelEntry->extraConfig.chan_mask);
5959 if(eWLAN_PAL_STATUS_SUCCESS != status)
5960 {
5961 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
5962 "dxeChannelInitProgram Write RX Control register fail");
5963 return status;
5964 }
5965 return status;
5966}