blob: b63abb1722d4fc9fb25bc40f8de514e7dbf4826f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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.
20 */
21
22/**=========================================================================
23
24 @file wlan_qct_dxe.c
25
26 @brief
27
28 This file contains the external API exposed by the wlan data transfer abstraction layer module.
29 Copyright (c) 2010-2011 QUALCOMM Incorporated.
30 All Rights Reserved.
31 Qualcomm Confidential and Proprietary
32========================================================================*/
33
34/*===========================================================================
35
36 EDIT HISTORY FOR FILE
37
38
39 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
41
42
43 $Header:$ $DateTime: $ $Author: $
44
45
46when who what, where, why
47-------- --- ----------------------------------------------------------
4808/03/10 schang Created module.
49
50===========================================================================*/
51
52/*===========================================================================
53
54 INCLUDE FILES FOR MODULE
55
56===========================================================================*/
57
58/*----------------------------------------------------------------------------
59 * Include Files
60 * -------------------------------------------------------------------------*/
61#include "wlan_qct_dxe.h"
62#include "wlan_qct_dxe_i.h"
63#include "wlan_qct_pal_device.h"
64#ifdef FEATURE_R33D
65#include "wlan_qct_pal_bus.h"
66#endif /* FEATURE_R33D */
67
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
Jeff Johnsone7245742012-09-05 17:12:55 -070080#define WLANDXE_MAX_REAPED_RX_FRAMES 512
Jeff Johnson295189b2012-06-20 16:38:30 -070081
82/* This is temporary fot the compile
83 * WDI will release official version
84 * This must be removed */
85#define WDI_GET_PAL_CTX() NULL
86
87/*-------------------------------------------------------------------------
88 * Local Varables
89 *-------------------------------------------------------------------------*/
90/* This is temp, someone have to allocate for me, and must be part of global context */
91static WLANDXE_CtrlBlkType *tempDxeCtrlBlk = NULL;
92static char *channelType[WDTS_CHANNEL_MAX] =
93 {
94 "TX_LOW_PRI",
95 "TX_HIGH_PRI",
96 "RX_LOW_PRI",
97#ifndef WLANDXE_TEST_CHANNEL_ENABLE
98 "RX_HIGH_PRI",
99#else
100 "H2H_TEST_TX",
101 "H2H_TEST_RX"
102#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
103 };
Jeff Johnsone7245742012-09-05 17:12:55 -0700104static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES];
Jeff Johnson295189b2012-06-20 16:38:30 -0700105
106/*-------------------------------------------------------------------------
107 * External Function Proto Type
108 *-------------------------------------------------------------------------*/
109
110/*-------------------------------------------------------------------------
111 * Local Function Proto Type
112 *-------------------------------------------------------------------------*/
113static wpt_status dxeRXFrameSingleBufferAlloc
114(
115 WLANDXE_CtrlBlkType *dxeCtxt,
116 WLANDXE_ChannelCBType *channelEntry,
117 WLANDXE_DescCtrlBlkType *currentCtrlBlock
118);
119
120/*-------------------------------------------------------------------------
121 * Local Function
122 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700123/*==========================================================================
124 @ Function Name
125 dxeChannelMonitor
126
127 @ Description
128
129 @ Parameters
130 WLANDXE_ChannelCBType *channelEntry
131 Channel specific control block
132
133 @ Return
134 wpt_status
135
136===========================================================================*/
137static wpt_status dxeChannelMonitor
138(
139 char *monitorDescription,
140 WLANDXE_ChannelCBType *channelEntry
141)
142{
143 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
144
Jeff Johnsone7245742012-09-05 17:12:55 -0700145 if((NULL == monitorDescription) || (NULL == channelEntry))
146 {
147 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
148 "INVALID Input ARG");
149 return eWLAN_PAL_STATUS_E_INVAL;
150 }
151
152 if(channelEntry->channelType > WDTS_CHANNEL_RX_HIGH_PRI)
153 {
154 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
155 "INVALID Channel type");
156 return eWLAN_PAL_STATUS_E_INVAL;
157 }
158
159 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700160 "=== %s Channel Number %d, Channel Type %s",
161 monitorDescription, channelEntry->assignedDMAChannel, channelType[channelEntry->channelType]);
Jeff Johnsone7245742012-09-05 17:12:55 -0700162 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700163 "numDesc %d, numFreeDesc %d, numResvDesc %d",
164 channelEntry->numDesc, channelEntry->numFreeDesc, channelEntry->numRsvdDesc);
Jeff Johnsone7245742012-09-05 17:12:55 -0700165 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700166 "headCB 0x%x, next 0x%x, DESC 0x%x",
167 channelEntry->headCtrlBlk, channelEntry->headCtrlBlk->nextCtrlBlk, channelEntry->headCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700168 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700169 "tailCB 0x%x, next 0x%x, DESC 0x%x",
170 channelEntry->tailCtrlBlk, channelEntry->tailCtrlBlk->nextCtrlBlk, channelEntry->tailCtrlBlk->linkedDescPhyAddr);
Jeff Johnsone7245742012-09-05 17:12:55 -0700171 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700172 "headCB Order %d, tailCB Order %d",
173 channelEntry->headCtrlBlk->ctrlBlkOrder, channelEntry->tailCtrlBlk->ctrlBlkOrder);
Jeff Johnsone7245742012-09-05 17:12:55 -0700174 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700175 "numFragmentCurrentChain %d, numTotalFrame %d ===",
176 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
177
178 return status;
179}
180
Jeff Johnsone7245742012-09-05 17:12:55 -0700181#ifdef WLANDXE_DEBUG_MEMORY_DUMP
Jeff Johnson295189b2012-06-20 16:38:30 -0700182/*==========================================================================
183 @ Function Name
184 dxeMemoryDump
185
186 @ Description
187
188 @ Parameters
189 WLANDXE_ChannelCBType *channelEntry
190 Channel specific control block
191
192 @ Return
193 wpt_status
194
195===========================================================================*/
196static wpt_status dxeMemoryDump
197(
198 wpt_uint8 *dumpPointer,
199 wpt_uint32 dumpSize,
200 char *dumpTarget
201)
202{
203 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
204 wpt_uint32 numBytes = 0;
205 wpt_uint32 idx;
206
Jeff Johnsone7245742012-09-05 17:12:55 -0700207 if((NULL == dumpPointer) ||
208 (NULL == dumpTarget))
209 {
210 return status;
211 }
212
Jeff Johnson295189b2012-06-20 16:38:30 -0700213 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
214 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
215 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
216 "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize);
217
218 numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE;
219 for(idx = 0; idx < dumpSize; idx++)
220 {
221 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
222 "0x%2x ", dumpPointer[idx]);
223 if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE))
224 {
225 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
226 }
227 }
228 if(0 != numBytes)
229 {
230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n");
231 }
232 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
233 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
234
235 return status;
236}
Jeff Johnsone7245742012-09-05 17:12:55 -0700237#endif /* WLANDXE_DEBUG_MEMORY_DUMP */
Jeff Johnson295189b2012-06-20 16:38:30 -0700238
239/*==========================================================================
240 @ Function Name
241 dxeDescriptorDump
242
243 @ Description
244
245 @ Parameters
246 WLANDXE_ChannelCBType *channelEntry
247 Channel specific control block
248
249 @ Return
250 wpt_status
251
252===========================================================================*/
253wpt_status dxeDescriptorDump
254(
255 WLANDXE_ChannelCBType *channelEntry,
256 WLANDXE_DescType *targetDesc,
257 wpt_uint32 fragmentOrder
258)
259{
260 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
261
262
Jeff Johnsone7245742012-09-05 17:12:55 -0700263 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700264 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Jeff Johnsone7245742012-09-05 17:12:55 -0700265 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
266 "Descriptor Dump for channel %s, order %d",
Jeff Johnson295189b2012-06-20 16:38:30 -0700267 channelType[channelEntry->channelType],
Jeff Johnsone7245742012-09-05 17:12:55 -0700268 fragmentOrder);
Jeff Johnson295189b2012-06-20 16:38:30 -0700269
Jeff Johnsone7245742012-09-05 17:12:55 -0700270 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 "CTRL WORD 0x%x, TransferSize %d",
272 WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl),
273 WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize));
Jeff Johnsone7245742012-09-05 17:12:55 -0700274 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x",
276 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL),
277 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL),
278 WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL));
Jeff Johnsone7245742012-09-05 17:12:55 -0700279 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700280 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
281
282 return status;
283}
284
285/*==========================================================================
286 @ Function Name
287 dxeChannelRegisterDump
288
289 @ Description
290
291 @ Parameters
292 WLANDXE_ChannelCBType *channelEntry
293 Channel specific control block
294
295 @ Return
296 wpt_status
297
298===========================================================================*/
299wpt_status dxeChannelRegisterDump
300(
301 WLANDXE_ChannelCBType *channelEntry,
302 char *dumpTarget
303)
304{
305 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
306 wpt_uint32 regValue = 0;
307
Jeff Johnsone7245742012-09-05 17:12:55 -0700308 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 "%s Channel register dump for %s, base address 0x%x",
310 channelType[channelEntry->channelType],
311 dumpTarget,
312 channelEntry->channelRegister.chDXEBaseAddr);
313 regValue = 0;
314 wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700315 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700316 "Control Register 0x%x", regValue);
317
318 regValue = 0;
319 wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &regValue);
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 "Status Register 0x%x", regValue);
322 regValue = 0;
323
324 wpalReadRegister(channelEntry->channelRegister.chDXESadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700325 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 "Source Address Register 0x%x", regValue);
327 regValue = 0;
328
329 wpalReadRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700330 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 "Destination Address Register 0x%x", regValue);
332 regValue = 0;
333
334 wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &regValue);
Jeff Johnsone7245742012-09-05 17:12:55 -0700335 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700336 "Descriptor Address Register 0x%x", regValue);
337
338 return status;
339}
Jeff Johnsone7245742012-09-05 17:12:55 -0700340
341/*==========================================================================
342 @ Function Name
343 dxeChannelAllDescDump
344
345 @ Description
346 Dump all DXE descriptors within assigned channe;
347
348 @ Parameters
349 WLANDXE_ChannelCBType *channelEntry
350
351 @ Return
352 NONE
353
354===========================================================================*/
355void dxeChannelAllDescDump
356(
357 WLANDXE_ChannelCBType *channelEntry
358)
359{
360 wpt_uint32 channelLoop;
361 WLANDXE_DescCtrlBlkType *targetCtrlBlk;
362
363 targetCtrlBlk = channelEntry->headCtrlBlk;
364
365 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
366 "%s %d descriptor chains",
367 channelType[channelEntry->channelType], (int)channelEntry->numDesc);
368 for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++)
369 {
370 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
371 "%5d : 0x%x", (int)targetCtrlBlk->ctrlBlkOrder,
372 (unsigned int)targetCtrlBlk->linkedDesc->descCtrl.ctrl);
373 targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk;
374 }
375
376 return;
377}
Jeff Johnson295189b2012-06-20 16:38:30 -0700378
379/*==========================================================================
380 @ Function Name
381 dxeCtrlBlkAlloc
382
383 @ Description
384 Allocate DXE Control block
385 DXE control block will used by Host DXE driver only, internal structure
386 Will make ring linked list
387
388 @ Parameters
389 WLANDXE_CtrlBlkType *dxeCtrlBlk,
390 DXE host driver main control block
391 WLANDXE_ChannelCBType *channelEntry
392 Channel specific control block
393
394 @ Return
395 wpt_status
396
397===========================================================================*/
398static wpt_status dxeCtrlBlkAlloc
399(
400 WLANDXE_CtrlBlkType *dxeCtrlBlk,
401 WLANDXE_ChannelCBType *channelEntry
402)
403{
404 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
405 unsigned int idx, fIdx;
406 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
407 WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL;
408 WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL;
409 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
410
411 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
412 "%s Enter", __FUNCTION__);
413
414 /* Sanity check */
415 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
416 {
417 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
418 "dxeCtrlBlkAlloc Channel Entry is not valid");
419 return eWLAN_PAL_STATUS_E_INVAL;
420 }
421
422 /* Allocate pre asigned number of control blocks */
423 for(idx = 0; idx < channelEntry->numDesc; idx++)
424 {
425 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType));
426 if(NULL == currentCtrlBlk)
427 {
428 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
429 "dxeCtrlBlkOpen MemAlloc Fail for channel %d",
430 channelEntry->channelType);
431 freeCtrlBlk = channelEntry->headCtrlBlk;
432 for(fIdx = 0; fIdx < idx; fIdx++)
433 {
434 if(NULL == freeCtrlBlk)
435 {
436 break;
437 }
438
439 nextCtrlBlk = freeCtrlBlk->nextCtrlBlk;
440 wpalMemoryFree((void *)freeCtrlBlk);
441 freeCtrlBlk = nextCtrlBlk;
442 }
443 return eWLAN_PAL_STATUS_E_FAULT;
444 }
445
446 memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType));
447 /* Initialize common elements first */
448 currentCtrlBlk->xfrFrame = NULL;
449 currentCtrlBlk->linkedDesc = NULL;
450 currentCtrlBlk->linkedDescPhyAddr = 0;
451 currentCtrlBlk->ctrlBlkOrder = idx;
452
453 /* This is the first control block allocated
454 * Next Control block is not allocated yet
455 * head and tail must be first control block */
456 if(0 == idx)
457 {
458 currentCtrlBlk->nextCtrlBlk = NULL;
459 channelEntry->headCtrlBlk = currentCtrlBlk;
460 channelEntry->tailCtrlBlk = currentCtrlBlk;
461 }
462 /* This is not first, not last control block
463 * previous control block may has next linked block */
464 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
465 {
466 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
467 }
468 /* This is last control blocl
469 * next control block for the last control block is head, first control block
470 * then whole linked list made RING */
471 else if((channelEntry->numDesc - 1) == idx)
472 {
473 prevCtrlBlk->nextCtrlBlk = currentCtrlBlk;
474 currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk;
475 }
476 else
477 {
478 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
479 "dxeCtrlBlkOpen Invalid Ctrl Blk location %d",
480 channelEntry->channelType);
481 wpalMemoryFree(currentCtrlBlk);
482 return eWLAN_PAL_STATUS_E_FAULT;
483 }
484
485 prevCtrlBlk = currentCtrlBlk;
486 channelEntry->numFreeDesc++;
487 }
488
489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __FUNCTION__);
490 return status;
491}
492
493/*==========================================================================
494 @ Function Name
495 dxeDescLinkAlloc
496
497 @ Description
498 Allocate DXE descriptor
499 DXE descriptor will be shared by DXE host driver and RIVA DXE engine
500 Will make RING linked list
501 Will be linked with Descriptor control block one by one
502
503 @ Parameters
504 WLANDXE_CtrlBlkType *dxeCtrlBlk,
505 DXE host driver main control block
506 WLANDXE_ChannelCBType *channelEntry
507 Channel specific control block
508 @ Return
509 wpt_status
510
511===========================================================================*/
512static wpt_status dxeDescAllocAndLink
513(
514 WLANDXE_CtrlBlkType *dxeCtrlBlk,
515 WLANDXE_ChannelCBType *channelEntry
516)
517{
518 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
519 WLANDXE_DescType *currentDesc = NULL;
520 WLANDXE_DescType *prevDesc = NULL;
521 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
522 unsigned int idx;
523 void *physAddress = NULL;
524#ifdef WLANDXE_TEST_CHANNEL_ENABLE
525 WLANDXE_ChannelCBType *testTXChannelCB = &dxeCtrlBlk->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
526 WLANDXE_DescCtrlBlkType *currDescCtrlBlk = testTXChannelCB->headCtrlBlk;
527#endif /* WLANDXE_TEST_CHANNEL_ENABLE*/
528
529 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
530 "%s Enter", __FUNCTION__);
531
532 /* Sanity Check */
533 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
534 {
535 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
536 "dxeDescLinkAlloc Channel Entry is not valid");
537 return eWLAN_PAL_STATUS_E_INVAL;
538 }
539
540 currentCtrlBlk = channelEntry->headCtrlBlk;
541
542#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
543 /* allocate all DXE descriptors for this channel in one chunk */
544 channelEntry->descriptorAllocation = (WLANDXE_DescType *)
545 wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc,
546 &physAddress);
547 if(NULL == channelEntry->descriptorAllocation)
548 {
549 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
550 "dxeDescLinkAlloc Descriptor Alloc Fail");
551 return eWLAN_PAL_STATUS_E_RESOURCES;
552 }
553 currentDesc = channelEntry->descriptorAllocation;
554#endif
555
556 /* Allocate pre asigned number of descriptor */
557 for(idx = 0; idx < channelEntry->numDesc; idx++)
558 {
559#ifndef FEATURE_R33D
560#ifndef WLANDXE_TEST_CHANNEL_ENABLE
561 // descriptors were allocated in a chunk -- use the current one
562 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
563 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
564 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
565#else
566 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
567 {
568 // allocate a descriptor
569 currentDesc = (WLANDXE_DescType *)wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType),
570 &physAddress);
571 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
572 }
573 else
574 {
575 currentDesc = currDescCtrlBlk->linkedDesc;
576 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
577 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
578 }
579#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
580#else
581#ifndef WLANDXE_TEST_CHANNEL_ENABLE
582 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
583 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
585 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
586#else
587 if(WDTS_CHANNEL_H2H_TEST_RX != channelEntry->channelType)
588 {
589 currentDesc = (WLANDXE_DescType *)wpalAcpuDdrDxeDescMemoryAllocate(&physAddress);
590 memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType));
591 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
592 "Allocated Descriptor VA 0x%x, PA 0x%x", currentDesc, physAddress);
593 }
594 else
595 {
596 currentDesc = currDescCtrlBlk->linkedDesc;
597 physAddress = (void *)currDescCtrlBlk->linkedDescPhyAddr;
598 currDescCtrlBlk = (WLANDXE_DescCtrlBlkType *)currDescCtrlBlk->nextCtrlBlk;
599 }
600#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
601#endif /* FEATURE_R33D */
602 if(NULL == currentDesc)
603 {
604 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
605 "dxeDescLinkAlloc MemAlloc Fail for channel %d",
606 channelEntry->channelType);
607 return eWLAN_PAL_STATUS_E_FAULT;
608 }
609
610 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
611 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
612 {
613 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
614 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped;
615 }
616 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
617 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
618 {
619 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
620 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped;
621 }
622 else
623 {
624 /* Just in case. H2H Test RX channel, do nothing
625 * By Definition this must not happen */
626 }
627
628 currentCtrlBlk->linkedDesc = currentDesc;
629 currentCtrlBlk->linkedDescPhyAddr = (unsigned int)physAddress;
630 /* First descriptor, next none
631 * descriptor bottom location is first descriptor address */
632 if(0 == idx)
633 {
634 currentDesc->dxedesc.dxe_short_desc.phyNextL = 0;
635 channelEntry->DescBottomLoc = currentDesc;
636 channelEntry->descBottomLocPhyAddr = (unsigned int)physAddress;
637 }
638 /* Not first, not last descriptor
639 * may make link for previous descriptor with current descriptor
640 * ENDIAN SWAP needed ????? */
641 else if((0 < idx) && (idx < (channelEntry->numDesc - 1)))
642 {
643 prevDesc->dxedesc.dxe_short_desc.phyNextL =
644 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
645 }
646 /* Last descriptor
647 * make a ring by asign next pointer as first descriptor
648 * ENDIAN SWAP NEEDED ??? */
649 else if((channelEntry->numDesc - 1) == idx)
650 {
651 prevDesc->dxedesc.dxe_short_desc.phyNextL =
652 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)physAddress);
653 currentDesc->dxedesc.dxe_short_desc.phyNextL =
654 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)channelEntry->headCtrlBlk->linkedDescPhyAddr);
655 }
656
657 /* If Current Channel is RX channel PAL Packet and OS packet buffer should be
658 * Pre allocated and physical address must be assigned into
659 * Corresponding DXE Descriptor */
660#ifdef WLANDXE_TEST_CHANNEL_ENABLE
661 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
662 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) ||
663 (WDTS_CHANNEL_H2H_TEST_RX == channelEntry->channelType))
664#else
665 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
666 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
667#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
668 {
669 status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk,
670 channelEntry,
671 currentCtrlBlk);
672 if( !WLAN_PAL_IS_STATUS_SUCCESS(status) )
673 {
674 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
675 "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d",
676 channelEntry->channelType);
677 return status;
678 }
679 --channelEntry->numFreeDesc;
680 }
681
682 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
683 prevDesc = currentDesc;
684
685#ifndef FEATURE_R33D
686#ifndef WLANDXE_TEST_CHANNEL_ENABLE
687 // advance to the next pre-allocated descriptor in the chunk
688 currentDesc++;
689 physAddress = ((wpt_int8 *)physAddress) + sizeof(WLANDXE_DescType);
690#endif
691#endif
692 }
693
694 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
695 "%s Exit", __FUNCTION__);
696 return status;
697}
698
699/*==========================================================================
700 @ Function Name
701
702 @ Description
703
704 @ Parameters
705
706 @ Return
707 wpt_status
708
709===========================================================================*/
710static wpt_status dxeSetInterruptPath
711(
712 WLANDXE_CtrlBlkType *dxeCtrlBlk
713)
714{
715 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
716 wpt_uint32 interruptPath = 0;
717 wpt_uint32 idx;
718 WLANDXE_ChannelCBType *channelEntry = NULL;
719
720 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
721 "%s Enter", __FUNCTION__);
722
723 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
724 {
725 channelEntry = &dxeCtrlBlk->dxeChannel[idx];
726#ifdef WLANDXE_TEST_CHANNEL_ENABLE
727 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
728 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) ||
729 (WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType))
730#else
731 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
732 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
733#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
734 {
735 interruptPath |= (1 << channelEntry->assignedDMAChannel);
736 }
737 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
738 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
739 {
740 interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16));
741 }
742 else
743 {
744 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
745 "H2H TEST RX???? %d", channelEntry->channelType);
746 }
747 }
748 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
749 "Interrupt Path Must be 0x%x", interruptPath);
750 dxeCtrlBlk->interruptPath = interruptPath;
751 wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath);
752
753 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
754 "%s Exit", __FUNCTION__);
755 return status;
756}
757
758/*==========================================================================
759 @ Function Name
760 dxeEngineCoreStart
761
762 @ Description
763 Trigger to start RIVA DXE Hardware
764
765 @ Parameters
766 WLANDXE_CtrlBlkType *dxeCtrlBlk,
767 DXE host driver main control block
768
769 @ Return
770 wpt_status
771
772===========================================================================*/
773static wpt_status dxeEngineCoreStart
774(
775 WLANDXE_CtrlBlkType *dxeCtrlBlk
776)
777{
778 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
779 wpt_uint32 registerData = 0;
780
781 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
782 "%s Enter", __FUNCTION__);
783
784 /* START This core init is not needed for the integrated system */
785 /* Reset First */
786 registerData = WLANDXE_DMA_CSR_RESET_MASK;
787 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
788 registerData);
789
790 registerData = WLANDXE_DMA_CSR_EN_MASK;
791 registerData |= WLANDXE_DMA_CSR_ECTR_EN_MASK;
792 registerData |= WLANDXE_DMA_CSR_TSTMP_EN_MASK;
793 registerData |= WLANDXE_DMA_CSR_H2H_SYNC_EN_MASK;
794
795 registerData = 0x00005c89;
796 wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,
797 registerData);
798
799 /* Is This needed?
800 * Not sure, revisit with integrated system */
801 /* END This core init is not needed for the integrated system */
802
803 dxeSetInterruptPath(dxeCtrlBlk);
804 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
805 "%s Exit", __FUNCTION__);
806 return status;
807}
808
809/*==========================================================================
810 @ Function Name
811 dxeChannelInitProgram
812
813 @ Description
814 Program RIVA DXE engine register with initial value
815 What must be programmed
816 - Source Address (SADRL, chDXESadrlRegAddr)
817 - Destination address (DADRL, chDXEDadrlRegAddr)
818 - Next Descriptor address (DESCL, chDXEDesclRegAddr)
819 - current descriptor address (LST_DESCL, chDXELstDesclRegAddr)
820
821 Not need to program now
822 - Channel Control register (CH_CTRL, chDXECtrlRegAddr)
823 TX : Have to program to trigger send out frame
824 RX : programmed by DXE engine
825
826 @ Parameters
827 WLANDXE_CtrlBlkType *dxeCtrlBlk,
828 DXE host driver main control block
829 WLANDXE_ChannelCBType *channelEntry
830 Channel specific control block
831 @ Return
832 wpt_status
833
834===========================================================================*/
835static wpt_status dxeChannelInitProgram
836(
837 WLANDXE_CtrlBlkType *dxeCtrlBlk,
838 WLANDXE_ChannelCBType *channelEntry
839)
840{
841 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
842 wpt_uint32 idx;
843 WLANDXE_DescType *currentDesc = NULL;
844 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
845
846 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
847 "%s Enter", __FUNCTION__);
848
849 /* Sanity Check */
850 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
851 {
852 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
853 "dxeChannelInitProgram Channel Entry is not valid");
854 return eWLAN_PAL_STATUS_E_INVAL;
855 }
856
857 /* Program Source address and destination adderss */
858 if(!channelEntry->channelConfig.useShortDescFmt)
859 {
860 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
861 "dxeChannelInitProgram Long Descriptor not support yet");
862 return eWLAN_PAL_STATUS_E_FAILURE;
863 }
864
865 /* Common register area */
866 /* Next linked list Descriptor pointer */
867 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
868 channelEntry->headCtrlBlk->linkedDescPhyAddr);
869 if(eWLAN_PAL_STATUS_SUCCESS != status)
870 {
871 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
872 "dxeChannelInitProgram Write DESC Address register fail");
873 return status;
874 }
875
876 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
877 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
878 {
879 /* Program default registers */
880 /* TX DMA channel, DMA destination address is work Q */
881 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
882 channelEntry->channelConfig.refWQ);
883 if(eWLAN_PAL_STATUS_SUCCESS != status)
884 {
885 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
886 "dxeChannelInitProgram Write TX DAddress register fail");
887 return status;
888 }
889 }
890 else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
891 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
892 {
893 /* Initialize Descriptor control Word First */
894 currentCtrlBlk = channelEntry->headCtrlBlk;
895 for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++)
896 {
897 currentDesc = currentCtrlBlk->linkedDesc;
898 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
899 }
900
901 /* RX DMA channel, DMA source address is work Q */
902 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
903 channelEntry->channelConfig.refWQ);
904 if(eWLAN_PAL_STATUS_SUCCESS != status)
905 {
906 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
907 "dxeChannelInitProgram Write RX SAddress WQ register fail");
908 return status;
909 }
910
911 /* RX DMA channel, Program pre allocated destination Address */
912 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
913 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
914 if(eWLAN_PAL_STATUS_SUCCESS != status)
915 {
916 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
917 "dxeChannelInitProgram Write RX DAddress register fail");
918 return status;
919 }
920
921 /* RX Channels, default Control registers MUST BE ENABLED */
922 wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
923 channelEntry->extraConfig.chan_mask);
924 if(eWLAN_PAL_STATUS_SUCCESS != status)
925 {
926 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
927 "dxeChannelInitProgram Write RX Control register fail");
928 return status;
929 }
930 }
931 else
932 {
933 /* H2H test channel, not use work Q */
934 /* Program pre allocated destination Address */
935 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
936 WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL));
937 if(eWLAN_PAL_STATUS_SUCCESS != status)
938 {
939 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
940 "dxeChannelInitProgram Write RX DAddress register fail");
941 return status;
942 }
943 }
944
945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
946 "%s Exit", __FUNCTION__);
947 return status;
948}
949
950
951/*==========================================================================
952 @ Function Name
953 dxeChannelStart
954
955 @ Description
956 Start Specific Channel
957
958 @ Parameters
959 WLANDXE_CtrlBlkType *dxeCtrlBlk,
960 DXE host driver main control block
961 WLANDXE_ChannelCBType *channelEntry
962 Channel specific control block
963
964 @ Return
965 wpt_status
966
967===========================================================================*/
968static wpt_status dxeChannelStart
969(
970 WLANDXE_CtrlBlkType *dxeCtrlBlk,
971 WLANDXE_ChannelCBType *channelEntry
972)
973{
974 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
975 wpt_uint32 regValue = 0;
976 wpt_uint32 intMaskVal = 0;
977
978 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
979 "%s Enter", __FUNCTION__);
980
981 channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE;
982 channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE;
983
984 /* Enable individual channel
985 * not to break current channel setup, first read register */
986 status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS,
987 &regValue);
988 if(eWLAN_PAL_STATUS_SUCCESS != status)
989 {
990 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
991 "dxeChannelStart Read Channel Enable register fail");
992 return status;
993 }
994
995 /* Enable Channel specific Interrupt */
996 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
997 &intMaskVal);
998 if(eWLAN_PAL_STATUS_SUCCESS != status)
999 {
1000 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1001 "dxeChannelStart Read INT_MASK register fail");
1002 return status;
1003 }
1004 intMaskVal |= channelEntry->extraConfig.intMask;
1005 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1006 intMaskVal);
1007 if(eWLAN_PAL_STATUS_SUCCESS != status)
1008 {
1009 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1010 "dxeChannelStart Write INT_MASK register fail");
1011 return status;
1012 }
1013
1014 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1015 "%s Exit", __FUNCTION__);
1016 return status;
1017}
1018
1019/*==========================================================================
1020 @ Function Name
1021 dxeChannelStop
1022
1023 @ Description
1024 Stop Specific Channel
1025
1026 @ Parameters
1027 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1028 DXE host driver main control block
1029 WLANDXE_ChannelCBType *channelEntry
1030 Channel specific control block
1031
1032 @ Return
1033 wpt_status
1034
1035===========================================================================*/
1036static wpt_status dxeChannelStop
1037(
1038 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1039 WLANDXE_ChannelCBType *channelEntry
1040)
1041{
1042 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1043 wpt_uint32 intMaskVal = 0;
1044
1045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1046 "%s Enter", __FUNCTION__);
1047
1048 /* Sanity */
1049 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1050 {
1051 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1052 "dxeChannelStop Invalid arg input");
1053 return eWLAN_PAL_STATUS_E_INVAL;
1054 }
1055
1056 /* Maskout interrupt */
1057 status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1058 &intMaskVal);
1059 if(eWLAN_PAL_STATUS_SUCCESS != status)
1060 {
1061 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1062 "dxeChannelStop Read INT_MASK register fail");
1063 return status;
1064 }
1065 intMaskVal ^= channelEntry->extraConfig.intMask;
1066 status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS,
1067 intMaskVal);
1068 if(eWLAN_PAL_STATUS_SUCCESS != status)
1069 {
1070 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1071 "dxeChannelStop Write INT_MASK register fail");
1072 return status;
1073 }
1074
1075 channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE;
1076
1077 /* Stop Channel ??? */
1078 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1079 "%s Exit", __FUNCTION__);
1080 return status;
1081}
1082
1083/*==========================================================================
1084 @ Function Name
1085 dxeChannelClose
1086
1087 @ Description
1088 Close Specific Channel
1089 Free pre allocated RX frame buffer if RX channel
1090 Free DXE descriptor for each channel
1091 Free Descriptor control block for each channel
1092
1093 @ Parameters
1094 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1095 DXE host driver main control block
1096 WLANDXE_ChannelCBType *channelEntry
1097 Channel specific control block
1098
1099 @ Return
1100 wpt_status
1101
1102===========================================================================*/
1103static wpt_status dxeChannelClose
1104(
1105 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1106 WLANDXE_ChannelCBType *channelEntry
1107)
1108{
1109 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1110 wpt_uint32 idx;
1111 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1112 WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL;
1113 WLANDXE_DescType *currentDescriptor = NULL;
1114 WLANDXE_DescType *nextDescriptor = NULL;
1115
1116 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1117 "%s Enter", __FUNCTION__);
1118
1119 /* Sanity */
1120 if((NULL == dxeCtrlBlk) || (NULL == channelEntry))
1121 {
1122 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1123 "dxeChannelStop Invalid arg input");
1124 return eWLAN_PAL_STATUS_E_INVAL;
1125 }
1126
1127 currentCtrlBlk = channelEntry->headCtrlBlk;
1128 if(NULL != currentCtrlBlk)
1129 {
1130 currentDescriptor = currentCtrlBlk->linkedDesc;
1131 for(idx = 0; idx < channelEntry->numDesc; idx++)
1132 {
1133 if (idx + 1 != channelEntry->numDesc)
1134 {
1135 nextCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1136 nextDescriptor = nextCtrlBlk->linkedDesc;
1137 }
1138 else
1139 {
1140 nextCtrlBlk = NULL;
1141 nextDescriptor = NULL;
1142 }
1143 if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) ||
1144 (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType))
1145 {
1146 if (NULL != currentCtrlBlk->xfrFrame)
1147 {
1148 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1149 wpalPacketFree(currentCtrlBlk->xfrFrame);
1150 }
1151 }
1152 /*
1153 * It is the responsibility of DXE to walk through the
1154 * descriptor chain and unlock any pending packets (if
1155 * locked).
1156 */
1157 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
1158 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
1159 {
1160 if((NULL != currentCtrlBlk->xfrFrame) &&
1161 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)))
1162 {
1163 wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1164 wpalPacketFree(currentCtrlBlk->xfrFrame);
1165 }
1166 }
1167#if (defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1168 // descriptors allocated individually so free them individually
1169 wpalDmaMemoryFree(currentDescriptor);
1170#endif
1171 wpalMemoryFree(currentCtrlBlk);
1172
1173 currentCtrlBlk = nextCtrlBlk;
1174 currentDescriptor = nextDescriptor;
1175 }
1176 }
1177
1178#if !(defined(FEATURE_R33D) || defined(WLANDXE_TEST_CHANNEL_ENABLE))
1179 // descriptors were allocated as a single chunk so free the chunk
1180 if(NULL != channelEntry->descriptorAllocation)
1181 {
1182 wpalDmaMemoryFree(channelEntry->descriptorAllocation);
1183 }
1184#endif
1185
1186 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1187 "%s Exit", __FUNCTION__);
1188 return status;
1189}
1190
1191/*==========================================================================
1192 @ Function Name
1193 dxeChannelCleanInt
1194
1195 @ Description
1196 Clean up interrupt from RIVA HW
1197 After Host finish to handle interrupt, interrupt signal must be cleaned up
1198 Otherwise next interrupt will not be generated
1199
1200 @ Parameters
1201 WLANDXE_ChannelCBType *channelEntry
1202 Channel specific control block
1203 wpt_uint32 *chStat
1204 Channel Status register value
1205
1206 @ Return
1207 wpt_status
1208
1209===========================================================================*/
1210static wpt_status dxeChannelCleanInt
1211(
1212 WLANDXE_ChannelCBType *channelEntry,
1213 wpt_uint32 *chStat
1214)
1215{
1216 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1217
1218 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1219 "%s Enter", __FUNCTION__);
1220
1221 /* Read Channel Status Register to know why INT Happen */
1222 status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr,
1223 chStat);
1224 if(eWLAN_PAL_STATUS_SUCCESS != status)
1225 {
1226 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1227 "dxeChannelCleanInt Read CH STAT register fail");
1228 return eWLAN_PAL_STATUS_E_FAULT;
1229 }
1230 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1231 "%s Channel INT Clean, Status 0x%x",
1232 channelType[channelEntry->channelType], *chStat);
1233
1234 /* Clean up all the INT within this channel */
1235 status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS,
1236 (1 << channelEntry->assignedDMAChannel));
1237 if(eWLAN_PAL_STATUS_SUCCESS != status)
1238 {
1239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1240 "dxeChannelCleanInt Write CH Clean register fail");
1241 return eWLAN_PAL_STATUS_E_FAULT;
1242 }
1243
Jeff Johnsone7245742012-09-05 17:12:55 -07001244 /* Clean up Error INT Bit */
1245 if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat)
1246 {
1247 status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS,
1248 (1 << channelEntry->assignedDMAChannel));
1249 if(eWLAN_PAL_STATUS_SUCCESS != status)
1250 {
1251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1252 "dxeChannelCleanInt Read CH STAT register fail");
1253 return eWLAN_PAL_STATUS_E_FAULT;
1254 }
1255 }
1256
1257 /* Clean up DONE INT Bit */
1258 if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat)
1259 {
1260 status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS,
1261 (1 << channelEntry->assignedDMAChannel));
1262 if(eWLAN_PAL_STATUS_SUCCESS != status)
1263 {
1264 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1265 "dxeChannelCleanInt Read CH STAT register fail");
1266 return eWLAN_PAL_STATUS_E_FAULT;
1267 }
1268 }
1269
1270 /* Clean up ED INT Bit */
1271 if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat)
1272 {
1273 status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS,
1274 (1 << channelEntry->assignedDMAChannel));
1275 if(eWLAN_PAL_STATUS_SUCCESS != status)
1276 {
1277 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1278 "dxeChannelCleanInt Read CH STAT register fail");
1279 return eWLAN_PAL_STATUS_E_FAULT;
1280 }
1281 }
1282
Jeff Johnson295189b2012-06-20 16:38:30 -07001283 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1284 "%s Exit", __FUNCTION__);
1285 return status;
1286}
1287
1288/*==========================================================================
1289 @ Function Name
1290 dxeRXPacketAvailableCB
1291
1292 @ Description
1293 If RX frame handler encounts RX buffer pool empty condition,
1294 DXE RX handle loop will be blocked till get available RX buffer pool.
1295 When new RX buffer pool available, Packet available CB function will
1296 be called.
1297
1298 @ Parameters
1299 wpt_packet *freePacket
1300 Newly allocated RX buffer
1301 v_VOID_t *usrData
1302 DXE context
1303
1304 @ Return
1305 NONE
1306
1307===========================================================================*/
1308void dxeRXPacketAvailableCB
1309(
1310 wpt_packet *freePacket,
1311 v_VOID_t *usrData
1312)
1313{
1314 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1315 wpt_status status;
1316
1317 /* Simple Sanity */
1318 if((NULL == freePacket) || (NULL == usrData))
1319 {
1320 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1321 "Get Free RX Buffer fail, Critical Error");
1322 HDXE_ASSERT(0);
1323 return;
1324 }
1325
1326 dxeCtxt = (WLANDXE_CtrlBlkType *)usrData;
1327
1328 if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie)
1329 {
1330 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1331 "DXE Context data corrupted, Critical Error");
1332 HDXE_ASSERT(0);
1333 return;
1334 }
1335
1336 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
1337 "DXE RX packet available, post MSG to RX Thread");
1338
1339 dxeCtxt->freeRXPacket = freePacket;
1340
1341 /* Serialize RX Packet Available message upon RX thread */
1342 HDXE_ASSERT(NULL != dxeCtxt->rxPktAvailMsg);
1343
1344 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
1345 dxeCtxt->rxPktAvailMsg);
1346 if(eWLAN_PAL_STATUS_SUCCESS != status)
1347 {
1348 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
1349 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
1350 "dxeRXPacketAvailableCB serialize fail");
1351 }
1352
1353 return;
1354}
1355
1356/*==========================================================================
1357 @ Function Name
1358 dxeRXFrameSingleBufferAlloc
1359
1360 @ Description
1361 Allocate Platform packet buffer to prepare RX frame
1362 RX frame memory space must be pre allocted and must be asigned to
1363 descriptor
1364 then whenever DMA engine want to tranfer frame from BMU,
1365 buffer must be ready
1366
1367 @ Parameters
1368 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1369 DXE host driver main control block
1370 WLANDXE_ChannelCBType *channelEntry
1371 Channel specific control block
1372 WLANDXE_DescCtrlBlkType currentCtrlBlock
1373 current control block which have to be asigned
1374 frame buffer
1375
1376 @ Return
1377 wpt_status
1378
1379===========================================================================*/
1380static wpt_status dxeRXFrameSingleBufferAlloc
1381(
1382 WLANDXE_CtrlBlkType *dxeCtxt,
1383 WLANDXE_ChannelCBType *channelEntry,
1384 WLANDXE_DescCtrlBlkType *currentCtrlBlock
1385)
1386{
1387 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1388 wpt_packet *currentPalPacketBuffer = NULL;
1389 WLANDXE_DescType *currentDesc = NULL;
1390#ifdef FEATURE_R33D
1391 wpt_uint32 virtualAddressPCIe;
1392 wpt_uint32 physicalAddressPCIe;
1393#else
1394 wpt_iterator iterator;
1395 wpt_uint32 allocatedSize = 0;
1396 void *physAddress = NULL;
1397#endif /* FEATURE_R33D */
1398
Jeff Johnson295189b2012-06-20 16:38:30 -07001399
1400 currentDesc = currentCtrlBlock->linkedDesc;
1401
1402 /* First check if a packet pointer has already been provided by a previously
1403 invoked Rx packet available callback. If so use that packet. */
1404 if(dxeCtxt->rxPalPacketUnavailable && (NULL != dxeCtxt->freeRXPacket))
1405 {
1406 currentPalPacketBuffer = dxeCtxt->freeRXPacket;
1407 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE;
1408 dxeCtxt->freeRXPacket = NULL;
1409 }
1410 else if(!dxeCtxt->rxPalPacketUnavailable)
1411 {
1412 /* Allocate platform Packet buffer and OS Frame Buffer at here */
1413 currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW,
1414 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE,
1415 dxeRXPacketAvailableCB,
1416 (void *)dxeCtxt);
1417
1418 if(NULL == currentPalPacketBuffer)
1419 {
1420 dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE;
1421 }
1422 }
1423
1424 if(NULL == currentPalPacketBuffer)
1425 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 return eWLAN_PAL_STATUS_E_RESOURCES;
1427 }
1428
1429 currentCtrlBlock->xfrFrame = currentPalPacketBuffer;
1430 currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW;
1431 currentPalPacketBuffer->pBD = NULL;
1432 currentPalPacketBuffer->pBDPhys = NULL;
1433 currentPalPacketBuffer->BDLength = 0;
1434#ifdef FEATURE_R33D
1435 status = wpalAllocateShadowRxFrame(currentPalPacketBuffer,
1436 &physicalAddressPCIe,
1437 &virtualAddressPCIe);
1438 HDXE_ASSERT(0 != physicalAddressPCIe);
1439 HDXE_ASSERT(0 != virtualAddressPCIe);
1440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
1441 "RX Shadow Memory Va 0x%x, Pa 0x%x",
1442 virtualAddressPCIe, physicalAddressPCIe);
1443 if(eWLAN_PAL_STATUS_SUCCESS != status)
1444 {
1445 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1446 "dxeRXFrameBufferAlloc Shadow Mem Alloc fail");
1447 return status;
1448 }
1449 currentCtrlBlock->shadowBufferVa = virtualAddressPCIe;
1450 currentPalPacketBuffer->pBDPhys = (void *)physicalAddressPCIe;
1451 memset((wpt_uint8 *)currentCtrlBlock->shadowBufferVa, 0, WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1452#else
1453 status = wpalLockPacketForTransfer(currentPalPacketBuffer);
1454 if(eWLAN_PAL_STATUS_SUCCESS != status)
1455 {
1456 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1457 "dxeRXFrameBufferAlloc unable to lock packet");
1458 return status;
1459 }
1460
1461 /* Init iterator to get physical os buffer address */
1462 status = wpalIteratorInit(&iterator, currentPalPacketBuffer);
1463 if(eWLAN_PAL_STATUS_SUCCESS != status)
1464 {
1465 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1466 "dxeRXFrameBufferAlloc iterator init fail");
1467 return status;
1468 }
1469 status = wpalIteratorNext(&iterator,
1470 currentPalPacketBuffer,
1471 &physAddress,
1472 &allocatedSize);
1473 if(eWLAN_PAL_STATUS_SUCCESS != status)
1474 {
1475 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1476 "dxeRXFrameBufferAlloc iterator Get Next pointer fail");
1477 return status;
1478 }
1479 currentPalPacketBuffer->pBDPhys = physAddress;
1480#endif /* FEATURE_R33D */
1481
1482 /* DXE descriptor must have SWAPPED addres in it's structure
1483 * !!! SWAPPED !!! */
1484 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
1485 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)currentPalPacketBuffer->pBDPhys);
1486
Jeff Johnson295189b2012-06-20 16:38:30 -07001487 return status;
1488}
1489
1490/*==========================================================================
1491 @ Function Name
1492 dxeRXFrameRefillRing
1493
1494 @ Description
1495 Allocate Platform packet buffers to try to fill up the DXE Rx ring
1496
1497 @ Parameters
1498 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1499 DXE host driver main control block
1500 WLANDXE_ChannelCBType *channelEntry
1501 Channel specific control block
1502
1503 @ Return
1504 wpt_status
1505
1506===========================================================================*/
1507static wpt_status dxeRXFrameRefillRing
1508(
1509 WLANDXE_CtrlBlkType *dxeCtxt,
1510 WLANDXE_ChannelCBType *channelEntry
1511)
1512{
1513 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1514 WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk;
1515 WLANDXE_DescType *currentDesc = NULL;
1516
1517 while(channelEntry->numFreeDesc > 0)
1518 {
1519 /* Current Control block is free
1520 * and associated frame buffer is not linked with control block anymore
1521 * allocate new frame buffer for current control block */
1522 status = dxeRXFrameSingleBufferAlloc(dxeCtxt,
1523 channelEntry,
1524 currentCtrlBlk);
1525
1526 if(eWLAN_PAL_STATUS_SUCCESS != status)
1527 {
1528 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1529 "dxeRXFrameRefillRing, out of RX buffer pool, break here");
1530 break;
1531 }
1532
1533 currentDesc = currentCtrlBlk->linkedDesc;
1534 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read;
1535
1536 /* Issue a dummy read from the DXE descriptor DDR location to ensure
1537 that any posted writes are reflected in memory before DXE looks at
1538 the descriptor. */
1539 if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl)
1540 {
1541 //HDXE_ASSERT(0);
1542 }
1543
1544 /* Kick off the DXE ring, if not in any power save mode */
1545 if((WLANDXE_POWER_STATE_IMPS != dxeCtxt->hostPowerState) &&
1546 (WLANDXE_POWER_STATE_DOWN != dxeCtxt->hostPowerState))
1547 {
1548 wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS,
1549 1 << channelEntry->assignedDMAChannel);
1550 }
1551 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
1552 --channelEntry->numFreeDesc;
1553 }
1554
1555 channelEntry->tailCtrlBlk = currentCtrlBlk;
1556
1557 return status;
1558}
1559
1560/*==========================================================================
Jeff Johnsone7245742012-09-05 17:12:55 -07001561 @ Function Name
1562 dxeRXFrameRouteUpperLayer
1563
1564 @ Description
1565 Test DXE descriptors and if any RX frame pending within RING,
1566 Route to upper layer
1567
1568 @ Parameters
1569 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1570 DXE host driver main control block
1571 WLANDXE_ChannelCBType *channelEntry
1572 Channel specific control block
1573 @ Return
1574 -1 Any error happen
1575 0 No frame pulled from RX RING
1576 int number of RX frames pulled from RX ring
1577
1578===========================================================================*/
1579static wpt_int32 dxeRXFrameRouteUpperLayer
1580(
1581 WLANDXE_CtrlBlkType *dxeCtxt,
1582 WLANDXE_ChannelCBType *channelEntry
1583)
1584{
1585 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1586 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1587 WLANDXE_DescType *currentDesc = NULL;
1588 wpt_uint32 descCtrl, frameCount = 0, i;
1589
1590 currentCtrlBlk = channelEntry->headCtrlBlk;
1591 currentDesc = currentCtrlBlk->linkedDesc;
1592
1593 /* Descriptoe should be SWAPPED ???? */
1594 descCtrl = currentDesc->descCtrl.ctrl;
1595
1596 /* Get frames while VALID bit is not set (DMA complete) and a data
1597 * associated with it */
1598 while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) &&
1599 (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) &&
1600 (currentCtrlBlk->xfrFrame->pInternalData != NULL) &&
1601 (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) )
1602 {
1603 channelEntry->numTotalFrame++;
1604 channelEntry->numFreeDesc++;
1605#ifdef FEATURE_R33D
1606 /* Transfer Size should be */
1607 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1608 status = wpalPrepareRxFrame(&currentCtrlBlk->xfrFrame,
1609 (wpt_uint32)currentCtrlBlk->xfrFrame->pBDPhys,
1610 currentCtrlBlk->shadowBufferVa,
1611 WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE);
1612 if(eWLAN_PAL_STATUS_SUCCESS != status)
1613 {
1614 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1615 "dxeRXFrameReady Prepare RX Frame fail");
1616 return -1;
1617 }
1618 status = wpalFreeRxFrame(currentCtrlBlk->shadowBufferVa);
1619 if(eWLAN_PAL_STATUS_SUCCESS != status)
1620 {
1621 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1622 "dxeRXFrameReady Free Shadow RX Frame fail");
1623 return -1;
1624 }
1625
1626#else /* FEATURE_R33D */
1627 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
1628 if (eWLAN_PAL_STATUS_SUCCESS != status)
1629 {
1630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1631 "dxeRXFrameReady unable to unlock packet");
1632 return -1;
1633 }
1634#endif /* FEATURE_R33D */
1635 /* This Descriptor is valid, so linked Control block is also valid
1636 * Linked Control block has pre allocated packet buffer
1637 * So, just let upper layer knows preallocated frame pointer will be OK */
1638 /* Reap Rx frames */
1639 rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame;
1640 frameCount++;
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07001641 currentCtrlBlk->xfrFrame = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07001642
1643 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
1644 dxeRXFrameRefillRing(dxeCtxt,channelEntry);
1645
1646 /* Test next contorl block
1647 * if valid, this control block also has new RX frame must be handled */
1648 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
1649 currentDesc = currentCtrlBlk->linkedDesc;
1650 descCtrl = currentDesc->descCtrl.ctrl;
1651 }
1652
1653 /* Update head control block
1654 * current control block's valid bit was 0
1655 * next trial first control block must be current control block */
1656 channelEntry->headCtrlBlk = currentCtrlBlk;
1657
1658 /* Deliver all the reaped RX frames to upper layers */
1659 i = 0;
1660 while(i < frameCount) {
1661 dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType);
1662 i++;
1663 }
1664
1665 return frameCount;
1666}
1667
1668/*==========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 @ Function Name
1670 dxeRXFrameReady
1671
1672 @ Description
1673 Pop frame from descriptor and route frame to upper transport layer
1674 Assign new platform packet buffer into used descriptor
1675 Actual frame pop and resource realloc
1676
1677 @ Parameters
1678 WLANDXE_CtrlBlkType *dxeCtrlBlk,
1679 DXE host driver main control block
1680 WLANDXE_ChannelCBType *channelEntry
1681 Channel specific control block
1682
1683 @ Return
1684 wpt_status
1685
1686===========================================================================*/
1687static wpt_status dxeRXFrameReady
1688(
1689 WLANDXE_CtrlBlkType *dxeCtxt,
1690 WLANDXE_ChannelCBType *channelEntry
1691)
1692{
1693 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1694 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
1695 WLANDXE_DescType *currentDesc = NULL;
1696 wpt_uint32 descCtrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07001697 wpt_int32 frameCount = 0;
1698
1699 wpt_uint32 descLoop;
1700 wpt_uint32 invalidatedFound = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001701
1702 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1703 "%s Enter", __FUNCTION__);
1704
1705 /* Sanity Check */
1706 if((NULL == dxeCtxt) || (NULL == channelEntry))
1707 {
1708 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1709 "dxeRXFrameReady Channel Entry is not valid");
1710 return eWLAN_PAL_STATUS_E_INVAL;
1711 }
1712
Jeff Johnsone7245742012-09-05 17:12:55 -07001713 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07001714
Jeff Johnsone7245742012-09-05 17:12:55 -07001715 if(0 > frameCount)
Jeff Johnson295189b2012-06-20 16:38:30 -07001716 {
1717 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07001718 "dxeRXFrameReady RX frame route fail");
Jeff Johnson295189b2012-06-20 16:38:30 -07001719 return eWLAN_PAL_STATUS_E_INVAL;
1720 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001721
Jeff Johnsone7245742012-09-05 17:12:55 -07001722 if((0 == frameCount) &&
1723 ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) ||
1724 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
1725 {
1726 currentCtrlBlk = channelEntry->headCtrlBlk;
Jeff Johnson295189b2012-06-20 16:38:30 -07001727 currentDesc = currentCtrlBlk->linkedDesc;
1728 descCtrl = currentDesc->descCtrl.ctrl;
Jeff Johnsone7245742012-09-05 17:12:55 -07001729
1730 if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState)
1731 {
1732 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1733 "RX ISR called but no frame handled PWS %d, channel %s",
1734 (int)dxeCtxt->hostPowerState,
1735 channelType[channelEntry->channelType]);
1736 }
1737
1738 /* Current interupt empty and previous interrupt also empty
1739 * detected successive empty interrupt
1740 * or first interrupt empty, this should not happen */
1741 if(0 == channelEntry->numFragmentCurrentChain)
1742 {
1743 dxeChannelMonitor("RX Ready", channelEntry);
1744 dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0);
1745 dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt");
1746 dxeChannelAllDescDump(channelEntry);
1747
1748 /* Abnormal interrupt detected, try to find not validated descriptor */
1749 for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++)
1750 {
1751 if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID))
1752 {
1753 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1754 "Found Invalidated Descriptor %d", (int)descLoop);
1755 if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))
1756 {
1757 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1758 "Packet locked, Resync Host and HW");
1759 channelEntry->headCtrlBlk = currentCtrlBlk;
1760 invalidatedFound = 1;
1761 break;
1762 }
1763 else
1764 {
1765 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1766 "Packet Not Locked, cannot transfer frame");
1767 }
1768 }
1769 currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk;
1770 currentDesc = currentCtrlBlk->linkedDesc;
1771 descCtrl = currentDesc->descCtrl.ctrl;
1772 }
1773
Jeff Johnson32d95a32012-09-10 13:15:23 -07001774 /* Invalidated descriptor found, and that is not head descriptor
1775 * This means HW/SW descriptor miss match happen, and we may recover with just resync
1776 * Try re-sync here */
1777 if((invalidatedFound) && (0 != descLoop))
Jeff Johnsone7245742012-09-05 17:12:55 -07001778 {
1779 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1780 "Found New Sync location with HW, handle frames from there");
1781 frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry);
1782 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1783 "re-sync routed %d frames to upper layer", (int)frameCount);
Madan Mohan Koyyalamudi0c325532012-09-24 13:24:42 -07001784 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnsone7245742012-09-05 17:12:55 -07001785 frameCount = 0;
1786 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001787 /* Successive Empty interrupt
1788 * But this case, first descriptor also invalidated, then it means head descriptor
1789 * is linked with already handled RX frame, then could not unlock RX frame
1790 * This is just Out of RX buffer pool, not need to anything here */
1791 else if((invalidatedFound) && (0 == descLoop))
1792 {
1793 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1794 "Out of RX Low resource, and INT came in, do nothing till get RX resource");
1795 }
1796 /* Critical error, reload driver */
Jeff Johnsone7245742012-09-05 17:12:55 -07001797 else
1798 {
1799 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1800 "Could not found invalidated descriptor");
1801 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1802 "RX successive empty interrupt, Could not find invalidated DESC reload driver");
1803 dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE;
1804 wpalWlanReload();
1805 }
1806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001807 }
1808
1809 channelEntry->numFragmentCurrentChain = frameCount;
Jeff Johnson295189b2012-06-20 16:38:30 -07001810 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
1811 "%s Exit", __FUNCTION__);
1812 return status;
1813}
1814
1815/*==========================================================================
1816 @ Function Name
1817 dxeNotifySmsm
1818
1819 @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring
1820 buffer
1821
1822 @ Parameters
1823
1824 @ Return
1825 wpt_status
1826
1827===========================================================================*/
1828static wpt_status dxeNotifySmsm
1829(
1830 wpt_boolean kickDxe,
1831 wpt_boolean ringEmpty
1832)
1833{
1834 wpt_uint32 clrSt = 0;
1835 wpt_uint32 setSt = 0;
1836
1837 if(kickDxe)
1838 {
1839 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE");
1840
1841 if(tempDxeCtrlBlk->lastKickOffDxe == 0)
1842 {
1843 setSt |= WPAL_SMSM_WLAN_TX_ENABLE;
1844 tempDxeCtrlBlk->lastKickOffDxe = 1;
1845 }
1846 else if(tempDxeCtrlBlk->lastKickOffDxe == 1)
1847 {
1848 clrSt |= WPAL_SMSM_WLAN_TX_ENABLE;
1849 tempDxeCtrlBlk->lastKickOffDxe = 0;
1850 }
1851 else
1852 {
1853 HDXE_ASSERT(0);
1854 }
1855 }
1856 else
1857 {
1858 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE");
1859 }
1860
1861 if(ringEmpty)
1862 {
1863 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty");
1864 clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
1865 }
1866 else
1867 {
1868 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty");
1869 setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY;
1870 }
1871
1872 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt);
1873
1874 wpalNotifySmsm(clrSt, setSt);
1875
1876 return eWLAN_PAL_STATUS_SUCCESS;
1877}
1878
1879/*==========================================================================
1880 @ Function Name
1881 dxePsComplete
1882
1883 @ Description: Utility function to check the resv desc to deside if we can
1884 get into Power Save mode now
1885
1886 @ Parameters
1887
1888 @ Return
1889 None
1890
1891===========================================================================*/
1892static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based)
1893{
1894 if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL )
1895 {
1896 return;
1897 }
1898
1899 //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts
1900 //must have been consumed by RIVA, OK to get into BMPS
1901 if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
1902 (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
1903 {
1904 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE;
1905 //if host is in BMPS & no pkt to Tx, RIVA can go to power save
1906 if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState)
1907 {
1908 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
1909 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
1910 }
1911 }
1912 else //still more pkts to be served by RIVA
1913 {
1914 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
1915
1916 switch(dxeCtxt->rivaPowerState)
1917 {
1918 case WLANDXE_RIVA_POWER_STATE_ACTIVE:
1919 //NOP
1920 break;
1921 case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN:
1922 if(intr_based)
1923 {
1924 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
1925 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
1926 }
1927 break;
1928 default:
1929 //assert
1930 break;
1931 }
1932 }
1933}
1934
1935/*==========================================================================
1936 @ Function Name
1937 dxeRXEventHandler
1938
1939 @ Description
1940 Handle serailized RX frame ready event
1941 First disable interrupt then pick up frame from pre allocated buffer
1942 Since frame handle is doen, clear interrupt bit to ready next interrupt
1943 Finally re enable interrupt
1944
1945 @ Parameters
1946 wpt_msg *rxReadyMsg
1947 RX frame ready MSG pointer
1948 include DXE control context
1949
1950 @ Return
1951 NONE
1952
1953===========================================================================*/
1954void dxeRXEventHandler
1955(
1956 wpt_msg *rxReadyMsg
1957)
1958{
1959 wpt_msg *msgContent = (wpt_msg *)rxReadyMsg;
1960 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
1961 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
1962 wpt_uint32 intSrc = 0;
1963 WLANDXE_ChannelCBType *channelCb = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07001964 wpt_uint32 chHighStat = 0;
1965 wpt_uint32 chLowStat = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
Jeff Johnsone7245742012-09-05 17:12:55 -07001967 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07001968
Jeff Johnsone7245742012-09-05 17:12:55 -07001969 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 {
1971 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -07001972 "RX Ready WLAN Driver re-loading in progress");
Jeff Johnson32d95a32012-09-10 13:15:23 -07001973 return;
Jeff Johnson295189b2012-06-20 16:38:30 -07001974 }
1975
Jeff Johnsone7245742012-09-05 17:12:55 -07001976 /* Now try to refill the ring with empty Rx buffers to keep DXE busy */
1977 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]);
1978 dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]);
1979
Jeff Johnson295189b2012-06-20 16:38:30 -07001980 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
1981
1982 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) ||
1983 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled))
1984 {
1985 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
1986 "DXE already stopped in RX event handler. Just return");
1987 return;
1988 }
1989
1990 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
1991 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
1992 {
1993 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
1994 "%s Riva is in %d, Just Pull frames without any register touch ",
1995 __FUNCTION__, dxeCtxt->hostPowerState);
1996
1997 /* Not to touch any register, just pull frame directly from chain ring
1998 * First high priority */
1999 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2000 status = dxeRXFrameReady(dxeCtxt,
2001 channelCb);
2002 if(eWLAN_PAL_STATUS_SUCCESS != status)
2003 {
2004 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2005 "dxeRXEventHandler Pull from RX high channel fail");
2006 }
2007
2008 /* Second low priority */
2009 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2010 status = dxeRXFrameReady(dxeCtxt,
2011 channelCb);
2012 if(eWLAN_PAL_STATUS_SUCCESS != status)
2013 {
2014 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2015 "dxeRXEventHandler Pull from RX low channel fail");
2016 }
2017
2018 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2019 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2020
2021 return;
2022 }
2023
2024 /* Disable device interrupt */
2025 /* Read whole interrupt mask register and exclusive only this channel int */
2026 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2027 &intSrc);
2028 if(eWLAN_PAL_STATUS_SUCCESS != status)
2029 {
2030 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2031 "dxeRXEventHandler Read INT_SRC register fail");
2032 return;
2033 }
2034 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2035 "RX Event Handler INT Source 0x%x", intSrc);
2036
2037#ifndef WLANDXE_TEST_CHANNEL_ENABLE
2038 /* Test High Priority Channel interrupt is enabled or not */
2039 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2040 if(intSrc & (1 << channelCb->assignedDMAChannel))
2041 {
2042 status = dxeChannelCleanInt(channelCb, &chHighStat);
2043 if(eWLAN_PAL_STATUS_SUCCESS != status)
2044 {
2045 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2046 "dxeRXEventHandler INT Clean up fail");
2047 return;
2048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat)
2050 {
2051 /* Error Happen during transaction, Handle it */
2052 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002053 else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) ||
2054 (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
Jeff Johnson295189b2012-06-20 16:38:30 -07002055 {
2056 /* Handle RX Ready for high priority channel */
2057 status = dxeRXFrameReady(dxeCtxt,
2058 channelCb);
2059 }
2060 else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat)
2061 {
2062 status = dxeRXFrameReady(dxeCtxt,
2063 channelCb);
2064 }
2065 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2066 "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain);
Jeff Johnsone7245742012-09-05 17:12:55 -07002067 /* Update the Rx DONE histogram */
2068 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2069 if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)
2070 {
2071 channelCb->rxDoneHistogram |= 1;
2072 }
2073 else
2074 {
2075 channelCb->rxDoneHistogram &= ~1;
2076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002077 }
2078#else
2079 /* Test H2H Test interrupt is enabled or not */
2080 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_RX];
2081 if(intSrc & (1 << channelCb->assignedDMAChannel))
2082 {
2083 status = dxeChannelCleanInt(channelCb, &chStat);
2084 if(eWLAN_PAL_STATUS_SUCCESS != status)
2085 {
2086 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2087 "dxeRXEventHandler INT Clean up fail");
2088 return;
2089 }
2090
2091 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
2092 {
2093 /* Error Happen during transaction, Handle it */
2094 }
2095 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
2096 {
2097 /* Handle RX Ready for high priority channel */
2098 status = dxeRXFrameReady(dxeCtxt,
2099 channelCb);
2100 }
2101 /* Update the Rx DONE histogram */
2102 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2103 if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
2104 {
2105 channelCb->rxDoneHistogram |= 1;
2106 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2107 "DXE Channel Number %d, Rx DONE Histogram 0x%016llx",
2108 channelCb->assignedDMAChannel, channelCb->rxDoneHistogram);
2109 }
2110 else
2111 {
2112 channelCb->rxDoneHistogram &= ~1;
2113 }
2114 }
2115#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2116
2117 /* Test Low Priority Channel interrupt is enabled or not */
Jeff Johnsone7245742012-09-05 17:12:55 -07002118 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
Jeff Johnson295189b2012-06-20 16:38:30 -07002119 if(intSrc & (1 << channelCb->assignedDMAChannel))
2120 {
2121 status = dxeChannelCleanInt(channelCb, &chLowStat);
2122 if(eWLAN_PAL_STATUS_SUCCESS != status)
2123 {
2124 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2125 "dxeRXEventHandler INT Clean up fail");
2126 return;
2127 }
2128
2129 if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat)
2130 {
2131 /* Error Happen during transaction, Handle it */
2132 }
2133 else if(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat)
2134 {
2135 /* Handle RX Ready for low priority channel */
2136 status = dxeRXFrameReady(dxeCtxt,
2137 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07002138 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002139
2140 /* Update the Rx DONE histogram */
2141 channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1);
2142 if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)
2143 {
2144 channelCb->rxDoneHistogram |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002145 }
2146 else
2147 {
2148 channelCb->rxDoneHistogram &= ~1;
2149 }
2150 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
2151 "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain);
2152 }
2153 if(eWLAN_PAL_STATUS_SUCCESS != status)
2154 {
2155 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2156 "dxeRXEventHandler Handle Frame Ready Fail");
2157 return;
2158 }
2159
2160 /* Enable system level ISR */
2161 /* Enable RX ready Interrupt at here */
2162 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
2163 if(eWLAN_PAL_STATUS_SUCCESS != status)
2164 {
2165 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2166 "dxeRXEventHandler Enable RX Ready interrupt fail");
2167 return;
2168 }
2169
2170 /* Prepare Control Register EN Channel */
2171 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2172 {
2173 HDXE_ASSERT(0);
2174 }
2175 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chHighStat))
2176 {
2177 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2178 "dxeRXEventHandler RX High, Not yet ED, re-enable CH");
2179 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr,
2180 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask);
2181 }
2182 else
2183 {
2184 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2185 "dxeRXEventHandler RX High, CH STAT = ED_MASK, will RIVA PC");
2186 }
2187
2188 /* Prepare Control Register EN Channel */
2189 if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK))
2190 {
2191 HDXE_ASSERT(0);
2192 }
2193 if(!(WLANDXE_CH_STAT_INT_ED_MASK & chLowStat))
2194 {
2195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2196 "dxeRXEventHandler RX Low, Not yet ED, re-enable CH");
2197 wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr,
2198 dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask);
2199 }
2200 else
2201 {
2202 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2203 "dxeRXEventHandler RX Low, CH STAT = ED_MASK, will RIVA PC");
2204 }
2205
2206 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2207 "%s Exit", __FUNCTION__);
2208 return;
2209}
2210
2211/*==========================================================================
2212 @ Function Name
2213 dxeRXPacketAvailableEventHandler
2214
2215 @ Description
2216 Handle serialized RX Packet Available event when the corresponding callback
2217 is invoked by WPAL.
2218 Try to fill up any completed DXE descriptors with available Rx packet buffer
2219 pointers.
2220
2221 @ Parameters
2222 wpt_msg *rxPktAvailMsg
2223 RX frame ready MSG pointer
2224 include DXE control context
2225
2226 @ Return
2227 NONE
2228
2229===========================================================================*/
2230void dxeRXPacketAvailableEventHandler
2231(
2232 wpt_msg *rxPktAvailMsg
2233)
2234{
2235 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2236 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2237 WLANDXE_ChannelCBType *channelCb = NULL;
2238
2239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2240 "%s Enter", __FUNCTION__);
2241
2242 /* Sanity Check */
2243 if(NULL == rxPktAvailMsg)
2244 {
2245 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2246 "dxeRXPacketAvailableEventHandler Context is not valid");
2247 return;
2248 }
2249
2250 dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext);
2251
2252 do
2253 {
2254 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2255 "dxeRXPacketAvailableEventHandler, start refilling ring");
2256
2257 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI];
2258 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2259
2260 // Wait for another callback to indicate when Rx resources are available
2261 // again.
2262 if(eWLAN_PAL_STATUS_SUCCESS != status)
2263 {
2264 break;
2265 }
2266
2267 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI];
2268 status = dxeRXFrameRefillRing(dxeCtxt,channelCb);
2269 if(eWLAN_PAL_STATUS_SUCCESS != status)
2270 {
2271 break;
2272 }
2273 } while(0);
2274
2275 if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) ||
2276 (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState))
2277 {
2278 /* Interrupt will not enabled at here, it will be enabled at PS mode change */
2279 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE;
2280 }
2281}
2282
2283/*==========================================================================
2284 @ Function Name
2285 dxeRXISR
2286
2287 @ Description
2288 RX frame ready interrupt service routine
2289 interrupt entry function, this function called based on ISR context
2290 Must be serialized
2291
2292 @ Parameters
2293 void *hostCtxt
2294 DXE host driver control context,
2295 pre registerd during interrupt registration
2296
2297 @ Return
2298 NONE
2299
2300===========================================================================*/
2301static void dxeRXISR
2302(
2303 void *hostCtxt
2304)
2305{
2306 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
2307 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2308#ifdef FEATURE_R33D
2309 wpt_uint32 regValue;
2310#endif /* FEATURE_R33D */
2311
Jeff Johnson295189b2012-06-20 16:38:30 -07002312
2313#ifdef FEATURE_R33D
2314 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2315 &regValue);
2316 if(eWLAN_PAL_STATUS_SUCCESS != status)
2317 {
2318 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2319 "dxeTXCompISR Read INT_SRC_RAW fail");
2320 return;
2321 }
2322 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2323 "INT_SRC_RAW 0x%x", regValue);
2324 if(0 == regValue)
2325 {
2326 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2327 "This is not DXE Interrupt, Reject it 0x%x", regValue);
2328 return;
2329 }
2330#endif /* FEATURE_R33D */
2331
2332 /* Disable interrupt at here
2333 * Disable RX Ready system level Interrupt at here
2334 * Otherwise infinite loop might happen */
2335 status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY);
2336 if(eWLAN_PAL_STATUS_SUCCESS != status)
2337 {
2338 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2339 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
2340 return;
2341 }
2342
2343 /* Serialize RX Ready interrupt upon RX thread */
2344 HDXE_ASSERT(NULL != dxeCtxt->rxIsrMsg);
2345 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
2346 dxeCtxt->rxIsrMsg);
2347 if(eWLAN_PAL_STATUS_SUCCESS != status)
2348 {
2349 HDXE_ASSERT(eWLAN_PAL_STATUS_SUCCESS == status);
2350 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
2351 "dxeRXFrameReadyISR interrupt serialize fail");
2352 }
2353
Jeff Johnson295189b2012-06-20 16:38:30 -07002354 return;
2355}
2356
2357/*==========================================================================
2358 @ Function Name
2359 dxeTXPushFrame
2360
2361 @ Description
2362 Push TX frame into DXE descriptor and DXE register
2363 Send notification to DXE register that TX frame is ready to transfer
2364
2365 @ Parameters
2366 WLANDXE_ChannelCBType *channelEntry
2367 Channel specific control block
2368 wpt_packet *palPacket
2369 Packet pointer ready to transfer
2370
2371 @ Return
2372 PAL_STATUS_T
2373===========================================================================*/
2374static wpt_status dxeTXPushFrame
2375(
2376 WLANDXE_ChannelCBType *channelEntry,
2377 wpt_packet *palPacket
2378)
2379{
2380 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2381 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2382 WLANDXE_DescType *currentDesc = NULL;
2383 WLANDXE_DescType *firstDesc = NULL;
2384 WLANDXE_DescType *LastDesc = NULL;
2385 void *sourcePhysicalAddress = NULL;
2386 wpt_uint32 xferSize = 0;
2387#ifdef FEATURE_R33D
2388 tx_frm_pcie_vector_t frameVector;
2389 wpt_uint32 Va;
2390 wpt_uint32 fragCount = 0;
2391#else
2392 wpt_iterator iterator;
2393#endif /* FEATURE_R33D */
Jeff Johnsone7245742012-09-05 17:12:55 -07002394
2395 wpt_uint32 isEmpty = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002396
2397 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2398 "%s Enter", __FUNCTION__);
2399
Jeff Johnsone7245742012-09-05 17:12:55 -07002400 if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) &&
2401 (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc))
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 {
Jeff Johnsone7245742012-09-05 17:12:55 -07002403 isEmpty = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07002404 }
2405
2406 channelEntry->numFragmentCurrentChain = 0;
2407 currentCtrlBlk = channelEntry->headCtrlBlk;
2408
2409 /* Initialize interator, TX is fragmented */
2410#ifdef FEATURE_R33D
2411 memset(&frameVector, 0, sizeof(tx_frm_pcie_vector_t));
2412 status = wpalPrepareTxFrame(palPacket,
2413 &frameVector,
2414 &Va);
2415#else
2416 status = wpalLockPacketForTransfer(palPacket);
2417 if(eWLAN_PAL_STATUS_SUCCESS != status)
2418 {
2419 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2420 "dxeTXPushFrame unable to lock packet");
2421 return status;
2422 }
2423
2424 status = wpalIteratorInit(&iterator, palPacket);
2425#endif /* FEATURE_R33D */
2426 if(eWLAN_PAL_STATUS_SUCCESS != status)
2427 {
2428 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2429 "dxeTXPushFrame iterator init fail");
2430 return status;
2431 }
2432
2433 /* !!!! Revisit break condition !!!!!!! */
2434 while(1)
2435 {
2436 /* Get current descriptor pointer from current control block */
2437 currentDesc = currentCtrlBlk->linkedDesc;
2438 if(NULL == firstDesc)
2439 {
2440 firstDesc = currentCtrlBlk->linkedDesc;
2441 }
2442 /* All control block will have same palPacket Pointer
2443 * to make logic simpler */
2444 currentCtrlBlk->xfrFrame = palPacket;
2445
2446 /* Get next fragment physical address and fragment size
2447 * if this is the first trial, will get first physical address
2448 * if no more fragment, Descriptor src address will be set as NULL, OK??? */
2449#ifdef FEATURE_R33D
2450 if(fragCount == frameVector.num_frg)
2451 {
2452 break;
2453 }
2454 currentCtrlBlk->shadowBufferVa = frameVector.frg[0].va;
2455 sourcePhysicalAddress = (void *)frameVector.frg[fragCount].pa;
2456 xferSize = frameVector.frg[fragCount].size;
2457 fragCount++;
2458 HDXE_ASSERT(0 != xferSize);
2459 HDXE_ASSERT(NULL != sourcePhysicalAddress);
2460#else
2461 status = wpalIteratorNext(&iterator,
2462 palPacket,
2463 &sourcePhysicalAddress,
2464 &xferSize);
2465 if((NULL == sourcePhysicalAddress) ||
2466 (0 == xferSize))
2467 {
2468 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2469 "dxeTXPushFrame end of current frame");
2470 break;
2471 }
2472 if(eWLAN_PAL_STATUS_SUCCESS != status)
2473 {
2474 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2475 "dxeTXPushFrame Get next frame fail");
2476 return status;
2477 }
2478#endif /* FEATURE_R33D */
2479
2480 /* This is the LAST descriptor valid for this transaction */
2481 LastDesc = currentCtrlBlk->linkedDesc;
2482
2483 /* Program DXE descriptor */
2484 currentDesc->dxedesc.dxe_short_desc.srcMemAddrL =
2485 WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)sourcePhysicalAddress);
2486
2487 /* Just normal data transfer from aCPU Flat Memory to BMU Q */
2488 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2489 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2490 {
2491 currentDesc->dxedesc.dxe_short_desc.dstMemAddrL =
2492 WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ);
2493 }
2494 else
2495 {
2496 /* Test specific H2H transfer, destination address already set
2497 * Do Nothing */
2498 }
2499 currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize);
2500
2501 /* Program channel control register */
2502 /* First frame not set VAL bit, why ??? */
2503 if(0 == channelEntry->numFragmentCurrentChain)
2504 {
2505 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write;
2506 }
2507 else
2508 {
2509 currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2510 }
2511
2512 /* Update statistics */
2513 channelEntry->numFragmentCurrentChain++;
2514 channelEntry->numFreeDesc--;
2515 channelEntry->numRsvdDesc++;
2516
2517 /* Get next control block */
2518 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2519 }
2520 channelEntry->numTotalFrame++;
2521 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2522 "NUM TX FRAG %d, Total Frame %d",
2523 channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame);
2524
2525 /* Program Channel control register
2526 * Set as end of packet
2527 * Enable interrupt also for first code lock down
2528 * performace optimization, this will be revisited */
2529 if(NULL == LastDesc)
2530 {
2531 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2532 "dxeTXPushFrame NULL Last Descriptor, broken chain");
2533 return eWLAN_PAL_STATUS_E_FAULT;
2534 }
2535 LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int;
2536 /* Now First one also Valid ????
2537 * this procedure will prevent over handle descriptor from previous
2538 * TX trigger */
2539 firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid;
2540
2541 /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */
2542 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState)
2543 {
2544 /* Update channel head as next avaliable linked slot */
2545 channelEntry->headCtrlBlk = currentCtrlBlk;
Jeff Johnsone7245742012-09-05 17:12:55 -07002546
2547 if( isEmpty )
2548 {
2549 tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE;
2550 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "SMSM_ret LO=%d HI=%d", tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc,
2551 tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc );
2552 dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE);
2553 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 return status;
2555 }
2556
2557 /* If DXE use external descriptor, registers are not needed to be programmed
2558 * Just after finish to program descriptor, tirigger to send */
2559 if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK)
2560 {
2561 /* Issue a dummy read from the DXE descriptor DDR location to
2562 ensure that any previously posted write to the descriptor
2563 completes. */
2564 if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl)
2565 {
2566 //HDXE_ASSERT(0);
2567 }
2568
2569 /* Everything is ready
2570 * Trigger to start DMA */
2571 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
2572 channelEntry->extraConfig.chan_mask);
2573 if(eWLAN_PAL_STATUS_SUCCESS != status)
2574 {
2575 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2576 "dxeTXPushFrame Write Channel Ctrl Register fail");
2577 return status;
2578 }
2579
2580 /* Update channel head as next avaliable linked slot */
2581 channelEntry->headCtrlBlk = currentCtrlBlk;
2582
2583 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2584 "%s Exit", __FUNCTION__);
2585 return status;
2586 }
2587
2588 /* If DXE not use external descriptor, program each registers */
2589 /* Circular buffer handle not need to program DESC register???
2590 * GEN5 code not programed RING buffer case
2591 * REVISIT THIS !!!!!! */
2592 if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) ||
2593 (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType))
2594 {
2595 /* Destination address, assigned Work Q */
2596 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
2597 channelEntry->channelConfig.refWQ);
2598 if(eWLAN_PAL_STATUS_SUCCESS != status)
2599 {
2600 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2601 "dxeTXPushFrame Program dest address register fail");
2602 return status;
2603 }
2604 /* If descriptor format is SHORT */
2605 if(channelEntry->channelConfig.useShortDescFmt)
2606 {
2607 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
2608 0);
2609 if(eWLAN_PAL_STATUS_SUCCESS != status)
2610 {
2611 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2612 "dxeTXPushFrame Program dest address register fail");
2613 return status;
2614 }
2615 }
2616 else
2617 {
2618 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2619 "dxeTXPushFrame LONG Descriptor Format!!!");
2620 }
2621 }
2622#ifdef WLANDXE_TEST_CHANNEL_ENABLE
2623 else if(WDTS_CHANNEL_H2H_TEST_TX == channelEntry->channelType)
2624 {
2625 /* Destination address, Physical memory address */
2626 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr,
2627 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.dstMemAddrL));
2628 if(eWLAN_PAL_STATUS_SUCCESS != status)
2629 {
2630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2631 "dxeTXPushFrame Program dest address register fail");
2632 return status;
2633 }
2634 /* If descriptor format is SHORT */
2635 if(channelEntry->channelConfig.useShortDescFmt)
2636 {
2637 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr,
2638 0);
2639 if(eWLAN_PAL_STATUS_SUCCESS != status)
2640 {
2641 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2642 "dxeTXPushFrame Program dest address register fail");
2643 return status;
2644 }
2645 }
2646 else
2647 {
2648 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2649 "dxeTXPushFrame LONG Descriptor Format!!!");
2650 }
2651 }
2652#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
2653
2654 /* Program Source address register
2655 * This address is already programmed into DXE Descriptor
2656 * But register also upadte */
2657 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr,
2658 WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL));
2659 if(eWLAN_PAL_STATUS_SUCCESS != status)
2660 {
2661 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2662 "dxeTXPushFrame Program src address register fail");
2663 return status;
2664 }
2665 /* If descriptor format is SHORT */
2666 if(channelEntry->channelConfig.useShortDescFmt)
2667 {
2668 status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr,
2669 0);
2670 if(eWLAN_PAL_STATUS_SUCCESS != status)
2671 {
2672 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2673 "dxeTXPushFrame Program dest address register fail");
2674 return status;
2675 }
2676 }
2677 else
2678 {
2679 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2680 "dxeTXPushFrame LONG Descriptor Format!!!");
2681 }
2682
2683 /* Linked list Descriptor pointer */
2684 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr,
2685 channelEntry->headCtrlBlk->linkedDescPhyAddr);
2686 if(eWLAN_PAL_STATUS_SUCCESS != status)
2687 {
2688 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2689 "dxeTXPushFrame Write DESC Address register fail");
2690 return status;
2691 }
2692 /* If descriptor format is SHORT */
2693 if(channelEntry->channelConfig.useShortDescFmt)
2694 {
2695 status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr,
2696 0);
2697 if(eWLAN_PAL_STATUS_SUCCESS != status)
2698 {
2699 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2700 "dxeTXPushFrame Program dest address register fail");
2701 return status;
2702 }
2703 }
2704 else
2705 {
2706 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2707 "dxeTXPushFrame LONG Descriptor Format!!!");
2708 }
2709
2710 /* Transfer Size */
2711 xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize);
2712 status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr,
2713 xferSize);
2714 if(eWLAN_PAL_STATUS_SUCCESS != status)
2715 {
2716 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2717 "dxeTXPushFrame Write DESC Address register fail");
2718 return status;
2719 }
2720
2721 /* Everything is ready
2722 * Trigger to start DMA */
2723 status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr,
2724 channelEntry->extraConfig.chan_mask);
2725 if(eWLAN_PAL_STATUS_SUCCESS != status)
2726 {
2727 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2728 "dxeTXPushFrame Write Channel Ctrl Register fail");
2729 return status;
2730 }
2731
2732 /* Update channel head as next avaliable linked slot */
2733 channelEntry->headCtrlBlk = currentCtrlBlk;
2734
2735 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2736 "%s Exit", __FUNCTION__);
2737 return status;
2738}
2739
2740/*==========================================================================
2741 @ Function Name
2742 dxeTXCompFrame
2743
2744 @ Description
2745 TX Frame transfer complete event handler
2746
2747 @ Parameters
2748 WLANDXE_CtrlBlkType *dxeCtrlBlk,
2749 DXE host driver main control block
2750 WLANDXE_ChannelCBType *channelEntry
2751 Channel specific control block
2752
2753 @ Return
2754 PAL_STATUS_T
2755===========================================================================*/
2756static wpt_status dxeTXCompFrame
2757(
2758 WLANDXE_CtrlBlkType *hostCtxt,
2759 WLANDXE_ChannelCBType *channelEntry
2760)
2761{
2762 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2763 WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL;
2764 WLANDXE_DescType *currentDesc = NULL;
2765 wpt_uint32 descCtrlValue = 0;
2766 unsigned int *lowThreshold = NULL;
2767
2768 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2769 "%s Enter", __FUNCTION__);
2770
2771 /* Sanity */
2772 if((NULL == hostCtxt) || (NULL == channelEntry))
2773 {
2774 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2775 "dxeTXCompFrame Invalid ARG");
2776 return eWLAN_PAL_STATUS_E_INVAL;
2777 }
2778
2779 if(NULL == hostCtxt->txCompCB)
2780 {
2781 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2782 "dxeTXCompFrame TXCompCB is not registered");
Jeff Johnsone7245742012-09-05 17:12:55 -07002783 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002784 }
2785
2786 wpalMutexAcquire(&channelEntry->dxeChannelLock);
2787
2788 currentCtrlBlk = channelEntry->tailCtrlBlk;
2789 currentDesc = currentCtrlBlk->linkedDesc;
2790
2791 if( currentCtrlBlk == channelEntry->headCtrlBlk )
2792 {
2793 wpalMutexRelease(&channelEntry->dxeChannelLock);
Jeff Johnsone7245742012-09-05 17:12:55 -07002794 return eWLAN_PAL_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002795 }
2796
2797 /* */
2798 while(1)
2799 {
2800// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc)));
2801 descCtrlValue = currentDesc->descCtrl.ctrl;
2802 if((descCtrlValue & WLANDXE_DESC_CTRL_VALID))
2803 {
2804 /* caught up with head, bail out */
2805 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2806 "dxeTXCompFrame caught up with head - next DESC has VALID set");
2807 break;
2808 }
2809
2810 HDXE_ASSERT(currentCtrlBlk->xfrFrame != NULL);
2811 channelEntry->numFreeDesc++;
2812 channelEntry->numRsvdDesc--;
2813
2814 /* Send Frame TX Complete notification with frame start fragment location */
2815 if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP)
2816 {
2817 hostCtxt->txCompletedFrames--;
2818#ifdef FEATURE_R33D
2819 wpalFreeTxFrame(currentCtrlBlk->shadowBufferVa);
2820#else
2821 status = wpalUnlockPacket(currentCtrlBlk->xfrFrame);
2822 if (eWLAN_PAL_STATUS_SUCCESS != status)
2823 {
2824 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2825 "dxeRXFrameReady unable to unlock packet");
2826 wpalMutexRelease(&channelEntry->dxeChannelLock);
2827 return status;
2828 }
2829#endif /* FEATURE_R33D */
2830 hostCtxt->txCompCB(hostCtxt->clientCtxt,
2831 currentCtrlBlk->xfrFrame,
2832 eWLAN_PAL_STATUS_SUCCESS);
2833 channelEntry->numFragmentCurrentChain = 0;
2834 }
2835 currentCtrlBlk = currentCtrlBlk->nextCtrlBlk;
2836 currentDesc = currentCtrlBlk->linkedDesc;
2837
2838 /* Break condition
2839 * Head control block is the control block must be programed for the next TX
2840 * so, head control block is not programmed control block yet
2841 * if loop encounte head control block, stop to complete
2842 * in theory, COMP CB must be called already ??? */
2843 if(currentCtrlBlk == channelEntry->headCtrlBlk)
2844 {
2845 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2846 "dxeTXCompFrame caught up with head ptr");
2847 break;
2848 }
2849 /* VALID Bit check ???? */
2850 }
2851
2852 /* Tail and Head Control block must be same */
2853 channelEntry->tailCtrlBlk = currentCtrlBlk;
2854
2855 lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI?
2856 &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
2857 &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
2858
2859 /* If specific channel hit low resource condition send notification to upper layer */
2860 if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) &&
2861 (channelEntry->numFreeDesc > *lowThreshold))
2862 {
2863 /* Change it back if we raised it for fetching a remaining packet from TL */
2864 if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold)
2865 {
2866 *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD;
2867 }
2868
2869 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2870 "DXE TX %d channel recovered from low resource", channelEntry->channelType);
2871 hostCtxt->lowResourceCB(hostCtxt->clientCtxt,
2872 channelEntry->channelType,
2873 eWLAN_PAL_TRUE);
2874 channelEntry->hitLowResource = eWLAN_PAL_FALSE;
2875 }
2876
2877 wpalMutexRelease(&channelEntry->dxeChannelLock);
2878
2879 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2880 "%s Exit", __FUNCTION__);
2881 return status;
2882}
2883
2884/*==========================================================================
2885 @ Function Name
2886 dxeTXEventHandler
2887
2888 @ Description
2889 If DXE HW sends TX related interrupt, this event handler will be called
2890 Handle higher priority channel first
2891 Figureout why interrupt happen and call appropriate final even handler
2892 TX complete or error happen
2893
2894 @ Parameters
2895 void *msgPtr
2896 Even MSG
2897
2898 @ Return
2899 PAL_STATUS_T
2900===========================================================================*/
2901void dxeTXEventHandler
2902(
2903 wpt_msg *msgPtr
2904)
2905{
2906 wpt_msg *msgContent = (wpt_msg *)msgPtr;
2907 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
2908 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
2909 wpt_uint32 intSrc = 0;
2910 wpt_uint32 chStat = 0;
2911 WLANDXE_ChannelCBType *channelCb = NULL;
2912
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002913 wpt_uint8 bEnableISR = 0;
2914 static wpt_uint8 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002915
2916 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
2917 "%s Enter", __FUNCTION__);
2918
2919 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
Jeff Johnsone7245742012-09-05 17:12:55 -07002920 dxeCtxt->ucTxMsgCnt = 0;
2921
2922 if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing)
2923 {
2924 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2925 "wlan: TX COMP WLAN Driver re-loading in progress");
2926 return;
2927 }
2928
Jeff Johnson295189b2012-06-20 16:38:30 -07002929 /* Return from here if the RIVA is in IMPS, to avoid register access */
2930 if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState)
2931 {
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002932 successiveIntWithIMPS++;
Jeff Johnsone7245742012-09-05 17:12:55 -07002933 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002934 "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS);
Jeff Johnsone7245742012-09-05 17:12:55 -07002935 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]);
2936 if(eWLAN_PAL_STATUS_SUCCESS != status)
2937 {
2938 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002939 "dxeTXEventHandler IMPS HC COMP interrupt fail");
Jeff Johnsone7245742012-09-05 17:12:55 -07002940 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002941
2942 status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]);
2943 if(eWLAN_PAL_STATUS_SUCCESS != status)
2944 {
2945 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2946 "dxeTXEventHandler IMPS LC COMP interrupt fail");
2947 }
2948
2949 if(((dxeCtxt->txCompletedFrames) &&
2950 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) &&
2951 (successiveIntWithIMPS == 1))
Jeff Johnsone7245742012-09-05 17:12:55 -07002952 {
2953 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
2954 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
2955 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
2956 "TX COMP INT Enabled, remain TX frame count on ring %d",
2957 dxeCtxt->txCompletedFrames);
2958 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
2959 the posibility of a race*/
2960 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
2961 }
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002962 else
2963 {
2964 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
2965 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2966 "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d",
2967 dxeCtxt->txCompletedFrames, successiveIntWithIMPS);
2968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 return;
2970 }
2971
Madan Mohan Koyyalamudi48e375a2012-09-24 13:19:17 -07002972 successiveIntWithIMPS = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) ||
2974 (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled))
2975 {
2976 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2977 "DXE already stopped in TX event handler. Just return");
2978 return;
2979 }
2980
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 /* Disable device interrupt */
2982 /* Read whole interrupt mask register and exclusive only this channel int */
2983 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
2984 &intSrc);
2985 if(eWLAN_PAL_STATUS_SUCCESS != status)
2986 {
2987 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
2988 "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail");
2989 return;
2990 }
2991 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED,
2992 "TX Event Handler INT Source 0x%x", intSrc);
2993
2994 /* Test High Priority Channel is the INT source or not */
2995 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
2996 if(intSrc & (1 << channelCb->assignedDMAChannel))
2997 {
2998 status = dxeChannelCleanInt(channelCb, &chStat);
2999 if(eWLAN_PAL_STATUS_SUCCESS != status)
3000 {
3001 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3002 "dxeTXEventHandler INT Clean up fail");
3003 return;
3004 }
3005
3006 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3007 {
3008 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3009 "dxeTXEventHandler TX HI status=%x", chStat);
3010 HDXE_ASSERT(0);
3011 }
3012 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3013 {
3014 /* Handle TX complete for high priority channel */
3015 status = dxeTXCompFrame(dxeCtxt,
3016 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003017 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003018 }
3019 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3020 {
3021 /* Handle TX complete for high priority channel */
3022 status = dxeTXCompFrame(dxeCtxt,
3023 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003024 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003025 }
3026 else
3027 {
3028 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3029 "dxeTXEventHandler TX HI status=%x", chStat);
3030 }
3031
3032 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3033 {
3034 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3035 "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!");
3036 }
3037
3038 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3039 "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3040 }
3041
3042 /* Test Low Priority Channel interrupt is enabled or not */
3043 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3044 if(intSrc & (1 << channelCb->assignedDMAChannel))
3045 {
3046 status = dxeChannelCleanInt(channelCb, &chStat);
3047 if(eWLAN_PAL_STATUS_SUCCESS != status)
3048 {
3049 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3050 "dxeTXEventHandler INT Clean up fail");
3051 return;
3052 }
3053
3054 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3055 {
3056 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3057 "dxeTXEventHandler TX LO status=%x", chStat);
3058 HDXE_ASSERT(0);
3059 }
3060 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3061 {
3062 /* Handle TX complete for low priority channel */
3063 status = dxeTXCompFrame(dxeCtxt,
3064 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003065 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003066 }
3067 else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat)
3068 {
3069 /* Handle TX complete for low priority channel */
3070 status = dxeTXCompFrame(dxeCtxt,
3071 channelCb);
Jeff Johnsone7245742012-09-05 17:12:55 -07003072 bEnableISR = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07003073 }
3074 else
3075 {
3076 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3077 "dxeTXEventHandler TX LO status=%x", chStat);
3078 }
3079
3080 if(WLANDXE_CH_STAT_MASKED_MASK & chStat)
3081 {
3082 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,
3083 "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!");
3084 }
3085 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3086 "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc);
3087 }
3088
3089
3090#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3091 /* Test H2H TX Channel interrupt is enabled or not */
3092 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_H2H_TEST_TX];
3093 if(intSrc & (1 << channelCb->assignedDMAChannel))
3094 {
3095 status = wpalReadRegister(channelCb->channelRegister.chDXEStatusRegAddr,
3096 &chStat);
3097 if(eWLAN_PAL_STATUS_SUCCESS != status)
3098 {
3099 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3100 "dxeChannelCleanInt Read CH STAT register fail");
3101 return;
3102 }
3103
3104 if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat)
3105 {
3106 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3107 "WLANDXE_CH_STAT_INT_ERR_MASK occurred");
3108 HDXE_ASSERT(0);
3109 }
3110 else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat)
3111 {
3112 /* Handle TX complete for high priority channel */
3113 status = dxeTXCompFrame(dxeCtxt,
3114 channelCb);
3115 if(eWLAN_PAL_STATUS_SUCCESS != status)
3116 {
3117 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3118 "dxeTXEventHandler INT Clean up fail");
3119 return;
3120 }
3121 }
3122 else
3123 {
3124 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3125 "unexpected channel state %d", chStat);
3126 }
3127 }
3128#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3129
3130 if((bEnableISR || (dxeCtxt->txCompletedFrames)) &&
3131 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3132 {
3133 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3134 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3135 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3136 "TX COMP INT Enabled, remain TX frame count on ring %d",
3137 dxeCtxt->txCompletedFrames);
3138 }
3139
3140 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3141 the posibility of a race*/
3142 dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE);
3143
3144 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3145 "%s Exit", __FUNCTION__);
3146 return;
3147}
3148
3149
3150/*==========================================================================
3151 @ Function Name
3152 dxeTXCompleteProcessing
3153
3154 @ Description
3155 If DXE HW sends TX related interrupt, this event handler will be called
3156 Handle higher priority channel first
3157 Figureout why interrupt happen and call appropriate final even handler
3158 TX complete or error happen
3159
3160 @ Parameters
3161 dxeCtxt DXE context
3162
3163 @ Return
3164 PAL_STATUS_T
3165===========================================================================*/
3166void dxeTXCompleteProcessing
3167(
3168 WLANDXE_CtrlBlkType *dxeCtxt
3169)
3170{
3171 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3172 WLANDXE_ChannelCBType *channelCb = NULL;
3173
3174 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3175 "%s Enter", __FUNCTION__);
3176
3177 /* Test High Priority Channel is the INT source or not */
3178 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI];
3179
3180 /* Handle TX complete for high priority channel */
3181 status = dxeTXCompFrame(dxeCtxt, channelCb);
3182
3183 /* Test Low Priority Channel interrupt is enabled or not */
3184 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3185
3186 /* Handle TX complete for low priority channel */
3187 status = dxeTXCompFrame(dxeCtxt, channelCb);
3188
3189 if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) &&
3190 ((dxeCtxt->txCompletedFrames > 0) ||
3191 (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState)))
3192 {
3193 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3194 wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3195 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3196 "%s %s : %d, %s : %d", __FUNCTION__,
3197 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType],
3198 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc,
3199 channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType],
3200 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc);
3201 }
3202
3203 /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid
3204 the posibility of a race*/
3205 dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE);
3206
3207 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3208 "%s Exit", __FUNCTION__);
3209 return;
3210}
3211/*==========================================================================
3212 @ Function Name
3213 dxeTXISR
3214
3215 @ Description
3216 TX interrupt ISR
3217 Platform will call this function if INT is happen
3218 This function must be registered into platform interrupt module
3219
3220 @ Parameters
3221 void *hostCtxt
3222 DXE host driver control context,
3223 pre registerd during interrupt registration
3224
3225 @ Return
3226 PAL_STATUS_T
3227===========================================================================*/
3228static void dxeTXISR
3229(
3230 void *hostCtxt
3231)
3232{
3233 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt;
3234 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3235#ifdef FEATURE_R33D
3236 wpt_uint32 regValue;
3237#endif /* FEATURE_R33D */
3238
3239 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3240 "%s Enter", __FUNCTION__);
3241
3242 /* Return from here if the RIVA is in IMPS, to avoid register access */
Jeff Johnsone7245742012-09-05 17:12:55 -07003243 if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)
Jeff Johnson295189b2012-06-20 16:38:30 -07003244 {
Jeff Johnsone7245742012-09-05 17:12:55 -07003245 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 /* Disable interrupt at here,
3247 IMPS or IMPS Pending state should not access RIVA register */
3248 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3249 if(eWLAN_PAL_STATUS_SUCCESS != status)
3250 {
3251 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3252 "dxeRXFrameReadyISR Disable RX ready interrupt fail");
3253 return;
3254 }
3255 dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE;
3256 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3257 "%s Riva is in %d, return from here ", __FUNCTION__, dxeCtxt->hostPowerState);
3258 return;
3259 }
3260
3261#ifdef FEATURE_R33D
3262 status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS,
3263 &regValue);
3264 if(eWLAN_PAL_STATUS_SUCCESS != status)
3265 {
3266 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3267 "dxeTXCompISR Read INT_SRC_RAW fail");
3268 return;
3269 }
3270 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3271 "INT_SRC_RAW 0x%x", regValue);
3272 if(0 == regValue)
3273 {
3274 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3275 "This is not DXE Interrupt, Reject it");
3276 return;
3277 }
3278#endif /* FEATURE_R33D */
3279
3280 /* Disable TX Complete Interrupt at here */
3281 status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE);
3282 if(eWLAN_PAL_STATUS_SUCCESS != status)
3283 {
3284 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3285 "dxeTXCompISR Disable TX complete interrupt fail");
3286 return;
3287 }
3288 dxeCtxt->txIntEnable = eWLAN_PAL_FALSE;
3289
3290
3291 if( dxeCtxt->ucTxMsgCnt )
3292 {
3293 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
3294 "Avoiding serializing TX Complete event");
3295 return;
3296 }
3297
3298 dxeCtxt->ucTxMsgCnt = 1;
3299
3300 /* Serialize TX complete interrupt upon TX thread */
3301 HDXE_ASSERT(NULL != dxeCtxt->txIsrMsg);
3302 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
3303 dxeCtxt->txIsrMsg);
3304 if(eWLAN_PAL_STATUS_SUCCESS != status)
3305 {
3306 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
3307 "dxeTXCompISR interrupt serialize fail status=%d", status);
3308 }
3309
3310 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3311 "%s Exit", __FUNCTION__);
3312 return;
3313}
3314
3315/*-------------------------------------------------------------------------
3316 * Global Function
3317 *-------------------------------------------------------------------------*/
3318/*==========================================================================
3319 @ Function Name
3320 WLANDXE_Open
3321
3322 @ Description
3323 Open host DXE driver, allocate DXE resources
3324 Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool
3325
3326 @ Parameters
3327 pVoid pAdaptor : Driver global control block pointer
3328
3329 @ Return
3330 pVoid DXE local module control block pointer
3331===========================================================================*/
3332void *WLANDXE_Open
3333(
3334 void
3335)
3336{
3337 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3338 unsigned int idx;
3339 WLANDXE_ChannelCBType *currentChannel = NULL;
3340 int smsmInitState;
3341#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3342 wpt_uint32 sIdx;
3343 WLANDXE_ChannelCBType *channel = NULL;
3344 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
3345 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
3346#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3347
3348 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3349 "%s Enter", __FUNCTION__);
3350
3351 /* This is temporary allocation */
3352 tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType));
3353 if(NULL == tempDxeCtrlBlk)
3354 {
3355 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3356 "WLANDXE_Open Control Block Alloc Fail");
3357 return NULL;
3358 }
3359 wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType));
3360
3361 status = dxeCommonDefaultConfig(tempDxeCtrlBlk);
3362 if(eWLAN_PAL_STATUS_SUCCESS != status)
3363 {
3364 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3365 "WLANDXE_Open Common Configuration Fail");
3366 WLANDXE_Close(tempDxeCtrlBlk);
3367 return NULL;
3368 }
3369
3370 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3371 {
3372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3373 "WLANDXE_Open Channel %s Open Start", channelType[idx]);
3374 currentChannel = &tempDxeCtrlBlk->dxeChannel[idx];
3375 if(idx == WDTS_CHANNEL_TX_LOW_PRI)
3376 {
3377 currentChannel->channelType = WDTS_CHANNEL_TX_LOW_PRI;
3378 }
3379 else if(idx == WDTS_CHANNEL_TX_HIGH_PRI)
3380 {
3381 currentChannel->channelType = WDTS_CHANNEL_TX_HIGH_PRI;
3382 }
3383 else if(idx == WDTS_CHANNEL_RX_LOW_PRI)
3384 {
3385 currentChannel->channelType = WDTS_CHANNEL_RX_LOW_PRI;
3386 }
3387 else if(idx == WDTS_CHANNEL_RX_HIGH_PRI)
3388 {
3389 currentChannel->channelType = WDTS_CHANNEL_RX_HIGH_PRI;
3390 }
3391#ifdef WLANDXE_TEST_CHANNEL_ENABLE
3392 else if(idx == WDTS_CHANNEL_H2H_TEST_TX)
3393 {
3394 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_TX;
3395 }
3396 else if(idx == WDTS_CHANNEL_H2H_TEST_RX)
3397 {
3398 currentChannel->channelType = WDTS_CHANNEL_H2H_TEST_RX;
3399 }
3400#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
3401
3402 /* Config individual channels from channel default setup table */
3403 status = dxeChannelDefaultConfig(tempDxeCtrlBlk,
3404 currentChannel);
3405 if(eWLAN_PAL_STATUS_SUCCESS != status)
3406 {
3407 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3408 "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx);
3409 WLANDXE_Close(tempDxeCtrlBlk);
3410 return NULL;
3411 }
3412
3413 /* Allocate DXE Control Block will be used by host DXE driver */
3414 status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel);
3415 if(eWLAN_PAL_STATUS_SUCCESS != status)
3416 {
3417 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3418 "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx);
3419
3420 WLANDXE_Close(tempDxeCtrlBlk);
3421 return NULL;
3422 }
3423 status = wpalMutexInit(&currentChannel->dxeChannelLock);
3424 if(eWLAN_PAL_STATUS_SUCCESS != status)
3425 {
3426 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3427 "WLANDXE_Open Lock Init Fail for channel %d", idx);
3428 WLANDXE_Close(tempDxeCtrlBlk);
3429 return NULL;
3430 }
3431
3432 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3433 "WLANDXE_Open Channel %s Open Success", channelType[idx]);
3434 }
3435
3436 /* Allocate and Init RX READY ISR Serialize Buffer */
3437 tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3438 if(NULL == tempDxeCtrlBlk->rxIsrMsg)
3439 {
3440 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3441 "WLANDXE_Open Alloc RX ISR Fail");
3442 WLANDXE_Close(tempDxeCtrlBlk);
3443 return NULL;
3444 }
3445 wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg));
3446 tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler;
3447 tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk;
3448
3449 /* Allocate and Init TX COMP ISR Serialize Buffer */
3450 tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3451 if(NULL == tempDxeCtrlBlk->txIsrMsg)
3452 {
3453 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3454 "WLANDXE_Open Alloc TX ISR Fail");
3455 WLANDXE_Close(tempDxeCtrlBlk);
3456 return NULL;
3457 }
3458 wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg));
3459 tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler;
3460 tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk;
3461
3462 /* Allocate and Init RX Packet Available Serialize Message Buffer */
3463 tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
3464 if(NULL == tempDxeCtrlBlk->rxPktAvailMsg)
3465 {
3466 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3467 "WLANDXE_Open Alloc RX Packet Available Message Fail");
3468 WLANDXE_Close(tempDxeCtrlBlk);
3469 return NULL;
3470 }
3471 wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg));
3472 tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler;
3473 tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk;
3474
3475 tempDxeCtrlBlk->freeRXPacket = NULL;
3476 tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE;
3477 tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
3478 tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07003479 tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07003480
3481 /* Initialize SMSM state
3482 * Init State is
3483 * Clear TX Enable
3484 * RING EMPTY STATE */
3485 smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE,
3486 WPAL_SMSM_WLAN_TX_RINGS_EMPTY);
3487 if(0 != smsmInitState)
3488 {
3489 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3490 "SMSM Channel init fail %d", smsmInitState);
3491 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3492 {
3493 dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]);
3494 }
3495 wpalMemoryFree((void *)&tempDxeCtrlBlk->rxIsrMsg);
3496 wpalMemoryFree((void *)&tempDxeCtrlBlk->txIsrMsg);
3497 wpalMemoryFree(tempDxeCtrlBlk);
3498 return NULL;
3499 }
3500
3501 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3502 "WLANDXE_Open Success");
3503 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3504 "%s Exit", __FUNCTION__);
3505 return (void *)tempDxeCtrlBlk;
3506}
3507
3508/*==========================================================================
3509 @ Function Name
3510 WLANDXE_ClientRegistration
3511
3512 @ Description
3513 Make callback functions registration into DXE driver from DXE driver client
3514
3515 @ Parameters
3516 pVoid pDXEContext : DXE module control block
3517 WDTS_RxFrameReadyCbType rxFrameReadyCB : RX Frame ready CB function pointer
3518 WDTS_TxCompleteCbType txCompleteCB : TX complete CB function pointer
3519 WDTS_LowResourceCbType lowResourceCB : Low DXE resource notification CB function pointer
3520 void *userContext : DXE Cliennt control block
3521
3522 @ Return
3523 wpt_status
3524===========================================================================*/
3525wpt_status WLANDXE_ClientRegistration
3526(
3527 void *pDXEContext,
3528 WLANDXE_RxFrameReadyCbType rxFrameReadyCB,
3529 WLANDXE_TxCompleteCbType txCompleteCB,
3530 WLANDXE_LowResourceCbType lowResourceCB,
3531 void *userContext
3532)
3533{
3534 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3535 WLANDXE_CtrlBlkType *dxeCtxt;
3536
3537 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3538 "%s Enter", __FUNCTION__);
3539
3540 /* Sanity */
3541 if(NULL == pDXEContext)
3542 {
3543 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3544 "WLANDXE_ClientRegistration Invalid DXE CB");
3545 return eWLAN_PAL_STATUS_E_INVAL;
3546 }
3547
3548 if(NULL == rxFrameReadyCB)
3549 {
3550 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3551 "WLANDXE_ClientRegistration Invalid RX READY CB");
3552 return eWLAN_PAL_STATUS_E_INVAL;
3553 }
3554
3555 if(NULL == txCompleteCB)
3556 {
3557 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3558 "WLANDXE_ClientRegistration Invalid txCompleteCB");
3559 return eWLAN_PAL_STATUS_E_INVAL;
3560 }
3561
3562 if(NULL == lowResourceCB)
3563 {
3564 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3565 "WLANDXE_ClientRegistration Invalid lowResourceCB");
3566 return eWLAN_PAL_STATUS_E_INVAL;
3567 }
3568
3569 if(NULL == userContext)
3570 {
3571 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3572 "WLANDXE_ClientRegistration Invalid userContext");
3573 return eWLAN_PAL_STATUS_E_INVAL;
3574 }
3575
3576 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3577
3578 /* Assign */
3579 dxeCtxt->rxReadyCB = rxFrameReadyCB;
3580 dxeCtxt->txCompCB = txCompleteCB;
3581 dxeCtxt->lowResourceCB = lowResourceCB;
3582 dxeCtxt->clientCtxt = userContext;
3583
3584 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3585 "%s Exit", __FUNCTION__);
3586 return status;
3587}
3588
3589/*==========================================================================
3590 @ Function Name
3591 WLANDXE_Start
3592
3593 @ Description
3594 Start Host DXE driver
3595 Initialize DXE channels and start channel
3596
3597 @ Parameters
3598 pVoid pDXEContext : DXE module control block
3599
3600 @ Return
3601 wpt_status
3602===========================================================================*/
3603wpt_status WLANDXE_Start
3604(
3605 void *pDXEContext
3606)
3607{
3608 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3609 wpt_uint32 idx;
3610 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3611
3612 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3613 "%s Enter", __FUNCTION__);
3614
3615 /* Sanity */
3616 if(NULL == pDXEContext)
3617 {
3618 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3619 "WLANDXE_Start Invalid DXE CB");
3620 return eWLAN_PAL_STATUS_E_INVAL;
3621 }
3622 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3623
3624 /* WLANDXE_Start called means DXE engine already initiates
3625 * And DXE HW is reset and init finished
3626 * But here to make sure HW is initialized, reset again */
3627 status = dxeEngineCoreStart(dxeCtxt);
3628 if(eWLAN_PAL_STATUS_SUCCESS != status)
3629 {
3630 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3631 "WLANDXE_Start DXE HW init Fail");
3632 return status;
3633 }
3634
3635 /* Individual Channel Start */
3636 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3637 {
3638 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3639 "WLANDXE_Start Channel %s Start", channelType[idx]);
3640
3641 /* Allocate DXE descriptor will be shared by Host driver and DXE engine */
3642 /* Make connection between DXE descriptor and DXE control block */
3643 status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]);
3644 if(eWLAN_PAL_STATUS_SUCCESS != status)
3645 {
3646 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3647 "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx);
3648 return status;
3649 }
3650
3651 /* Program each channel register with configuration arguments */
3652 status = dxeChannelInitProgram(dxeCtxt,
3653 &dxeCtxt->dxeChannel[idx]);
3654 if(eWLAN_PAL_STATUS_SUCCESS != status)
3655 {
3656 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3657 "WLANDXE_Start %d Program DMA channel Fail", idx);
3658 return status;
3659 }
3660
3661 /* ??? Trigger to start DMA channel
3662 * This must be seperated from ??? */
3663 status = dxeChannelStart(dxeCtxt,
3664 &dxeCtxt->dxeChannel[idx]);
3665 if(eWLAN_PAL_STATUS_SUCCESS != status)
3666 {
3667 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3668 "WLANDXE_Start %d Channel Start Fail", idx);
3669 return status;
3670 }
3671 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN,
3672 "WLANDXE_Start Channel %s Start Success", channelType[idx]);
3673 }
3674
3675 /* Register ISR to OS */
3676 /* Register TX complete interrupt into platform */
3677 status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE,
3678 dxeTXISR,
3679 dxeCtxt);
3680 if(eWLAN_PAL_STATUS_SUCCESS != status)
3681 {
3682 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3683 "WLANDXE_Start TX comp interrupt registration Fail");
3684 return status;
3685 }
3686
3687 /* Register RX ready interrupt into platform */
3688 status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY,
3689 dxeRXISR,
3690 dxeCtxt);
3691 if(eWLAN_PAL_STATUS_SUCCESS != status)
3692 {
3693 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3694 "WLANDXE_Start RX Ready interrupt registration Fail");
3695 return status;
3696 }
3697
3698 /* Enable system level ISR */
3699 /* Enable RX ready Interrupt at here */
3700 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
3701 if(eWLAN_PAL_STATUS_SUCCESS != status)
3702 {
3703 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3704 "dxeTXCompleteEventHandler Enable TX complete interrupt fail");
3705 return status;
3706 }
3707
3708 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3709 "%s Exit", __FUNCTION__);
3710 return status;
3711}
3712
3713/*==========================================================================
3714 @ Function Name
3715 WLANDXE_TXFrame
3716
3717 @ Description
3718 Trigger frame transmit from host to RIVA
3719
3720 @ Parameters
3721 pVoid pDXEContext : DXE Control Block
3722 wpt_packet pPacket : transmit packet structure
3723 WDTS_ChannelType channel : TX channel
3724
3725 @ Return
3726 wpt_status
3727===========================================================================*/
3728wpt_status WLANDXE_TxFrame
3729(
3730 void *pDXEContext,
3731 wpt_packet *pPacket,
3732 WDTS_ChannelType channel
3733)
3734{
3735 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3736 WLANDXE_ChannelCBType *currentChannel = NULL;
3737 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3738 unsigned int *lowThreshold = NULL;
3739
3740 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3741 "%s Enter", __FUNCTION__);
3742
3743 /* Sanity */
3744 if(NULL == pDXEContext)
3745 {
3746 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3747 "WLANDXE_Start Invalid DXE CB");
3748 return eWLAN_PAL_STATUS_E_INVAL;
3749 }
3750
3751 if(NULL == pPacket)
3752 {
3753 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3754 "WLANDXE_Start Invalid pPacket");
3755 return eWLAN_PAL_STATUS_E_INVAL;
3756 }
3757
3758 if((WDTS_CHANNEL_MAX < channel) || (WDTS_CHANNEL_MAX == channel))
3759 {
3760 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3761 "WLANDXE_Start Invalid channel");
3762 return eWLAN_PAL_STATUS_E_INVAL;
3763 }
3764
3765 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3766
3767 currentChannel = &dxeCtxt->dxeChannel[channel];
3768
3769
3770 wpalMutexAcquire(&currentChannel->dxeChannelLock);
3771
3772 lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI?
3773 &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh):
3774 &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh);
3775
3776 /* Decide have to activate TX complete event or not */
3777 switch(dxeCtxt->txCompInt.txIntEnable)
3778 {
3779 /* TX complete interrupt will be activated when low DXE resource */
3780 case WLANDXE_TX_COMP_INT_LR_THRESHOLD:
3781 if((currentChannel->numFreeDesc <= *lowThreshold) &&
3782 (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable))
3783 {
3784 dxeCtxt->txIntEnable = eWLAN_PAL_TRUE;
3785 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
3786 channel,
3787 eWLAN_PAL_FALSE);
3788 }
3789 break;
3790
3791 /* TX complete interrupt will be activated n number of frames transfered */
3792 case WLANDXE_TX_COMP_INT_PER_K_FRAMES:
3793 if(channel == WDTS_CHANNEL_TX_LOW_PRI)
3794 {
3795 currentChannel->numFrameBeforeInt++;
3796 }
3797 break;
3798
3799 /* TX complete interrupt will be activated periodically */
3800 case WLANDXE_TX_COMP_INT_TIMER:
3801 break;
3802 }
3803
3804 dxeCtxt->txCompletedFrames++;
3805
3806 /* Update DXE descriptor, this is frame based
3807 * if a frame consist of N fragments, N Descriptor will be programed */
3808 status = dxeTXPushFrame(currentChannel, pPacket);
3809 if(eWLAN_PAL_STATUS_SUCCESS != status)
3810 {
3811 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3812 "WLANDXE_TxFrame TX Push Frame fail");
3813 wpalMutexRelease(&currentChannel->dxeChannelLock);
3814 return status;
3815 }
3816
3817 /* If specific channel hit low resource condition, send notification to upper layer */
3818 if(currentChannel->numFreeDesc <= *lowThreshold)
3819 {
3820 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
3821 channel,
3822 eWLAN_PAL_FALSE);
3823 currentChannel->hitLowResource = eWLAN_PAL_TRUE;
3824 }
3825 wpalMutexRelease(&currentChannel->dxeChannelLock);
3826
3827 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3828 "%s Exit", __FUNCTION__);
3829 return status;
3830}
3831
3832/*==========================================================================
3833 @ Function Name
3834 WLANDXE_CompleteTX
3835
3836 @ Description
3837 Informs DXE that the current series of Tx packets is complete
3838
3839 @ Parameters
3840 pContext pDXEContext : DXE Control Block
3841 ucTxResReq TX resource number required by TL/WDI
3842
3843 @ Return
3844 wpt_status
3845===========================================================================*/
3846wpt_status
3847WLANDXE_CompleteTX
3848(
3849 void* pContext,
3850 wpt_uint32 ucTxResReq
3851)
3852{
3853 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3854 WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext);
3855 WLANDXE_ChannelCBType *channelCb = NULL;
3856 wpt_boolean inLowRes;
3857
3858 /* Sanity Check */
3859 if( NULL == pContext )
3860 {
3861 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3862 "WLANDXE_CompleteTX invalid param");
3863 return eWLAN_PAL_STATUS_E_INVAL;
3864 }
3865
3866 channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI];
3867 inLowRes = channelCb->hitLowResource;
3868
3869 if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq)
3870 {
3871 /* Raise threshold temporarily if necessary */
3872 dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq;
3873
3874 if(eWLAN_PAL_FALSE == inLowRes)
3875 {
3876 /* Put the channel to low resource condition */
3877 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
3878 WDTS_CHANNEL_TX_LOW_PRI,
3879 eWLAN_PAL_FALSE);
3880 inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE;
3881 }
3882 }
3883
3884 /*Try to reclaim resources*/
3885 dxeTXCompleteProcessing(dxeCtxt);
3886
3887 /* In previous WLANTL_GetFrames call, TL didn't fetch a packet
3888 because its fragment size is larger than DXE free resource. */
3889 if(0 < ucTxResReq)
3890 {
3891 /* DXE successfully claimed enough free DXE resouces for next fetch. */
3892 if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq)
3893 {
3894 /* DXE has not been in low resource condition. DXE forces to kick off
3895 TX tranmit */
3896 if((eWLAN_PAL_FALSE == inLowRes) &&
3897 (eWLAN_PAL_FALSE == channelCb->hitLowResource))
3898 {
3899 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
3900 WDTS_CHANNEL_TX_LOW_PRI,
3901 eWLAN_PAL_FALSE);
3902 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
3903 WDTS_CHANNEL_TX_LOW_PRI,
3904 eWLAN_PAL_TRUE);
3905 channelCb->hitLowResource = eWLAN_PAL_FALSE;
3906 }
3907 }
3908 else
3909 {
3910 /* DXE doesn't have enough free DXE resources. Put the channel
3911 to low resource condition. */
3912 if(eWLAN_PAL_FALSE == channelCb->hitLowResource)
3913 {
3914 /* Put the channel to low resource condition */
3915 dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt,
3916 WDTS_CHANNEL_TX_LOW_PRI,
3917 eWLAN_PAL_FALSE);
3918 channelCb->hitLowResource = eWLAN_PAL_TRUE;
3919 }
3920 }
3921 }
3922
3923 return status;
3924}
3925
3926/*==========================================================================
3927 @ Function Name
3928 WLANDXE_Stop
3929
3930 @ Description
3931 Stop DXE channels and DXE engine operations
3932 Disable all channel interrupt
3933 Stop all channel operation
3934
3935 @ Parameters
3936 pVoid pDXEContext : DXE Control Block
3937
3938 @ Return
3939 wpt_status
3940===========================================================================*/
3941wpt_status WLANDXE_Stop
3942(
3943 void *pDXEContext
3944)
3945{
3946 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
3947 wpt_uint32 idx;
3948 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
3949
3950 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3951 "%s Enter", __FUNCTION__);
3952
3953 /* Sanity */
3954 if(NULL == pDXEContext)
3955 {
3956 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3957 "WLANDXE_Stop Invalid DXE CB");
3958 return eWLAN_PAL_STATUS_E_INVAL;
3959 }
3960
3961 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
3962 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
3963 {
3964 status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
3965 if(eWLAN_PAL_STATUS_SUCCESS != status)
3966 {
3967 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
3968 "WLANDXE_Stop Channel %d Stop Fail", idx);
3969 return status;
3970 }
3971 }
3972
3973 /* During Stop unregister interrupt */
3974 wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE);
3975 wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY);
3976
3977 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
3978 "%s Exit", __FUNCTION__);
3979 return status;
3980}
3981
3982/*==========================================================================
3983 @ Function Name
3984 WLANDXE_Close
3985
3986 @ Description
3987 Close DXE channels
3988 Free DXE related resources
3989 DXE descriptor free
3990 Descriptor control block free
3991 Pre allocated RX buffer free
3992
3993 @ Parameters
3994 pVoid pDXEContext : DXE Control Block
3995
3996 @ Return
3997 wpt_status
3998===========================================================================*/
3999wpt_status WLANDXE_Close
4000(
4001 void *pDXEContext
4002)
4003{
4004 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4005 wpt_uint32 idx;
4006 WLANDXE_CtrlBlkType *dxeCtxt = NULL;
4007#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4008 wpt_uint32 sIdx;
4009 WLANDXE_ChannelCBType *channel = NULL;
4010 WLANDXE_DescCtrlBlkType *crntDescCB = NULL;
4011 WLANDXE_DescCtrlBlkType *nextDescCB = NULL;
4012#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4013
4014 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4015 "%s Enter", __FUNCTION__);
4016
4017 /* Sanity */
4018 if(NULL == pDXEContext)
4019 {
4020 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4021 "WLANDXE_Stop Invalid DXE CB");
4022 return eWLAN_PAL_STATUS_E_INVAL;
4023 }
4024
4025 dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext;
4026 for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++)
4027 {
4028 wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock);
4029 dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]);
4030#ifdef WLANDXE_TEST_CHANNEL_ENABLE
4031 channel = &dxeCtxt->dxeChannel[idx];
4032 crntDescCB = channel->headCtrlBlk;
4033 for(sIdx = 0; sIdx < channel->numDesc; sIdx++)
4034 {
4035 nextDescCB = (WLANDXE_DescCtrlBlkType *)crntDescCB->nextCtrlBlk;
4036 wpalMemoryFree((void *)crntDescCB);
4037 crntDescCB = nextDescCB;
4038 if(NULL == crntDescCB)
4039 {
4040 break;
4041 }
4042 }
4043#endif /* WLANDXE_TEST_CHANNEL_ENABLE */
4044 }
4045
4046 if(NULL != dxeCtxt->rxIsrMsg)
4047 {
4048 wpalMemoryFree(dxeCtxt->rxIsrMsg);
4049 }
4050 if(NULL != dxeCtxt->txIsrMsg)
4051 {
4052 wpalMemoryFree(dxeCtxt->txIsrMsg);
4053 }
4054 if(NULL != dxeCtxt->rxPktAvailMsg)
4055 {
4056 wpalMemoryFree(dxeCtxt->rxPktAvailMsg);
4057 }
4058
4059 wpalMemoryFree(pDXEContext);
4060
4061 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4062 "%s Exit", __FUNCTION__);
4063 return status;
4064}
4065
4066/*==========================================================================
4067 @ Function Name
4068 WLANDXE_TriggerTX
4069
4070 @ Description
4071 TBD
4072
4073 @ Parameters
4074 pVoid pDXEContext : DXE Control Block
4075
4076 @ Return
4077 wpt_status
4078===========================================================================*/
4079wpt_status WLANDXE_TriggerTX
4080(
4081 void *pDXEContext
4082)
4083{
4084 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4085
4086 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4087 "%s Enter", __FUNCTION__);
4088
4089 /* TBD */
4090
4091 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4092 "%s Exit", __FUNCTION__);
4093 return status;
4094}
4095
4096/*==========================================================================
4097 @ Function Name
4098 dxeTxThreadSetPowerStateEventHandler
4099
4100 @ Description
4101 If WDI sends set power state req, this event handler will be called in Tx
4102 thread context
4103
4104 @ Parameters
4105 void *msgPtr
4106 Event MSG
4107
4108 @ Return
4109 None
4110===========================================================================*/
4111void dxeTxThreadSetPowerStateEventHandler
4112(
4113 wpt_msg *msgPtr
4114)
4115{
4116 wpt_msg *msgContent = (wpt_msg *)msgPtr;
4117 WLANDXE_CtrlBlkType *dxeCtxt;
4118 wpt_status status = eWLAN_PAL_STATUS_E_FAILURE;
4119 WLANDXE_PowerStateType reqPowerState;
4120
4121 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4122 "%s Enter", __FUNCTION__);
4123
4124
4125 dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext);
4126 reqPowerState = (WLANDXE_PowerStateType)msgContent->val;
4127 dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr;
4128
4129 switch(reqPowerState)
4130 {
4131 case WLANDXE_POWER_STATE_BMPS:
4132 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4133 {
4134 //don't block MC waiting for num_rsvd to become 0 since it may take a while
4135 //based on amount of TX and RX activity - during this time any received
4136 // management frames will remain un-processed consuming RX buffers
4137 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4138 dxeCtxt->hostPowerState = reqPowerState;
4139 }
4140 else
4141 {
4142 status = eWLAN_PAL_STATUS_E_INVAL;
4143 }
4144 break;
4145 case WLANDXE_POWER_STATE_IMPS:
4146 if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState)
4147 {
4148 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN;
4149 }
4150 else
4151 {
4152 status = eWLAN_PAL_STATUS_E_INVAL;
4153 }
4154 break;
4155 case WLANDXE_POWER_STATE_FULL:
4156 if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState)
4157 {
4158 dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4159 }
4160 dxeCtxt->hostPowerState = reqPowerState;
4161 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4162 break;
4163 case WLANDXE_POWER_STATE_DOWN:
4164 WLANDXE_Stop((void *)dxeCtxt);
4165 break;
4166 default:
4167 //assert
4168 break;
4169 }
4170
4171 if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState)
4172 {
4173 dxeCtxt->setPowerStateCb(status,
4174 dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr);
4175 }
4176 /* Free MSG buffer */
4177 wpalMemoryFree(msgPtr);
4178 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4179 "%s Exit", __FUNCTION__);
4180 return;
4181}
4182
4183
4184/*==========================================================================
4185 @ Function Name
4186 dxeRxThreadSetPowerStateEventHandler
4187
4188 @ Description
4189 If WDI sends set power state req, this event handler will be called in Rx
4190 thread context
4191
4192 @ Parameters
4193 void *msgPtr
4194 Event MSG
4195
4196 @ Return
4197 None
4198===========================================================================*/
4199void dxeRxThreadSetPowerStateEventHandler
4200(
4201 wpt_msg *msgPtr
4202)
4203{
4204 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4205
4206 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4207 "%s Enter", __FUNCTION__);
4208
4209 /* Now serialise the message through Tx thread also to make sure
4210 * no register access when RIVA is in powersave */
4211 /*Use the same message pointer just change the call back function */
4212 msgPtr->callback = dxeTxThreadSetPowerStateEventHandler;
4213 status = wpalPostTxMsg(WDI_GET_PAL_CTX(),
4214 msgPtr);
4215 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4216 {
4217 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4218 "Tx thread Set power state req serialize fail status=%d",
4219 status, 0, 0);
4220 }
4221
4222 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4223 "%s Exit", __FUNCTION__);
4224}
4225
4226/*==========================================================================
4227 @ Function Name
4228 WLANDXE_SetPowerState
4229
4230 @ Description
4231 From Client let DXE knows what is the WLAN HW(RIVA) power state
4232
4233 @ Parameters
4234 pVoid pDXEContext : DXE Control Block
4235 WLANDXE_PowerStateType powerState
4236
4237 @ Return
4238 wpt_status
4239===========================================================================*/
4240wpt_status WLANDXE_SetPowerState
4241(
4242 void *pDXEContext,
4243 WDTS_PowerStateType powerState,
4244 WDTS_SetPSCbType cBack
4245)
4246{
4247 wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
4248 WLANDXE_CtrlBlkType *pDxeCtrlBlk;
4249 WLANDXE_PowerStateType hostPowerState;
4250 wpt_msg *rxCompMsg;
4251
4252 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4253 "%s Enter", __FUNCTION__);
4254 if(NULL == pDXEContext)
4255 {
4256 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4257 "NULL pDXEContext passed by caller", 0, 0, 0);
4258 return eWLAN_PAL_STATUS_E_FAILURE;
4259 }
4260 pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext;
4261
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 switch(powerState)
4263 {
4264 case WDTS_POWER_STATE_FULL:
4265 hostPowerState = WLANDXE_POWER_STATE_FULL;
4266 break;
4267 case WDTS_POWER_STATE_BMPS:
4268 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS;
4269 hostPowerState = WLANDXE_POWER_STATE_BMPS;
4270 break;
4271 case WDTS_POWER_STATE_IMPS:
4272 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS;
4273 hostPowerState = WLANDXE_POWER_STATE_IMPS;
4274 break;
4275 case WDTS_POWER_STATE_DOWN:
4276 pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN;
4277 hostPowerState = WLANDXE_POWER_STATE_DOWN;
4278 break;
4279 default:
4280 hostPowerState = WLANDXE_POWER_STATE_MAX;
4281 }
4282
4283 // A callback i.e. ACK back is needed only when we want to enable BMPS
4284 // and the data/management path is active because we want to ensure
4285 // DXE registers are not accessed when RIVA may be power-collapsed. So
4286 // we need a callback in enter_bmps_req (the request to RIVA is sent
4287 // only after ACK back from TX thread). A callback is not needed in
4288 // finish_scan_req during BMPS since data-path is resumed only in
4289 // finish_scan_rsp and no management frames are sent in between. No
4290 // callback is needed when going from BMPS enabled to BMPS suspended/
4291 // disabled when it is known that RIVA is awake and cannot enter power
4292 // collapse autonomously so no callback is needed in exit_bmps_rsp or
4293 // init_scan_rsp
4294 if ( cBack )
4295 {
4296 //serialize through Rx thread
4297 rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg));
4298 if(NULL == rxCompMsg)
4299 {
4300 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4301 "WLANDXE_SetPowerState, MSG MEM alloc Fail");
4302 return eWLAN_PAL_STATUS_E_RESOURCES;
4303 }
4304
4305 /* Event type, where it must be defined???? */
4306 /* THIS MUST BE CLEARED ASAP
4307 txCompMsg->type = TX_COMPLETE; */
4308 rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler;
4309 rxCompMsg->pContext = pDxeCtrlBlk;
4310 rxCompMsg->val = hostPowerState;
4311 rxCompMsg->ptr = cBack;
4312 status = wpalPostRxMsg(WDI_GET_PAL_CTX(),
4313 rxCompMsg);
4314 if ( eWLAN_PAL_STATUS_SUCCESS != status )
4315 {
4316 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4317 "Rx thread Set power state req serialize fail status=%d",
4318 status, 0, 0);
4319 }
4320 }
4321 else
4322 {
4323 if ( WLANDXE_POWER_STATE_FULL == hostPowerState )
4324 {
4325 if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState )
4326 {
4327 dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE);
4328 }
4329 else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState )
4330 {
4331 /* Requested Full power from exit IMPS, reenable the interrupts*/
4332 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS)
4333 {
4334 pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE;
4335 /* Enable RX interrupt at here, if new PS is not IMPS */
4336 status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY);
4337 if(eWLAN_PAL_STATUS_SUCCESS != status)
4338 {
4339 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4340 "%s Enable RX ready interrupt fail", __FUNCTION__);
4341 return status;
4342 }
4343 }
4344 if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS)
4345 {
4346 pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004347 pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004348 /* Enable RX interrupt at here, if new PS is not IMPS */
4349 status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE);
4350 if(eWLAN_PAL_STATUS_SUCCESS != status)
4351 {
4352 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4353 "%s Enable TX comp interrupt fail", __FUNCTION__);
4354 return status;
4355 }
4356 }
4357 }
4358 pDxeCtrlBlk->hostPowerState = hostPowerState;
4359 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE;
4360 }
4361 else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS )
4362 {
4363 pDxeCtrlBlk->hostPowerState = hostPowerState;
4364 pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN;
4365 }
4366 else
4367 {
4368 HDXE_ASSERT(0);
4369 }
4370 }
4371
4372 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4373 "%s Exit", __FUNCTION__);
4374
4375 return status;
4376}
4377
4378/*==========================================================================
4379 @ Function Name
4380 WLANDXE_GetFreeTxDataResNumber
4381
4382 @ Description
4383 Returns free descriptor numbers for TX data channel (TX high priority)
4384
4385 @ Parameters
4386 pVoid pDXEContext : DXE Control Block
4387
4388 @ Return
4389 wpt_uint32 Free descriptor number of TX high pri ch
4390===========================================================================*/
4391wpt_uint32 WLANDXE_GetFreeTxDataResNumber
4392(
4393 void *pDXEContext
4394)
4395{
4396 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,
4397 "%s Enter", __FUNCTION__);
4398
4399 if(NULL == pDXEContext)
4400 {
4401 HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
4402 "NULL parameter passed by caller", 0, 0, 0);
4403 return (0);
4404 }
4405
4406 return
4407 ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc;
4408}