blob: 00ab8118ef5d3a2f7876c592ff5c60317840fb4f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam1ed83fc2014-02-19 01:15:45 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
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/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam1ed83fc2014-02-19 01:15:45 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*===========================================================================
32
33 W L A N _ Q C T _ W D I _ D P. C
34
35 OVERVIEW:
36
37 This software unit holds the implementation of the WLAN Device Abstraction
38 Layer Internal Utility routines to be used by the Data Path.
39
40 The functions externalized by this module are to be only by the WDI data
41 path.
42
43 The module leveraged as much as functionality as was possible from the HAL
44 in Libra/Volans.
45
46 DEPENDENCIES:
47
48 Are listed for each API below.
49
50
Kiet Lamaa8e15a2014-02-11 23:30:06 -080051 Copyright (c) 2010 QUALCOMM Incorporated.
52 All Rights Reserved.
53 Qualcomm Confidential and Proprietary
Jeff Johnson295189b2012-06-20 16:38:30 -070054===========================================================================*/
55
56/*===========================================================================
57
58 EDIT HISTORY FOR FILE
59
60
61 This section contains comments describing changes made to the module.
62 Notice that changes are listed in reverse chronological order.
63
64
65 $Header$$DateTime$$Author$
66
67
68 when who what, where, why
69---------- --- --------------------------------------------------------
702010-08-19 lti Created module
71
72===========================================================================*/
73
74#include "wlan_qct_pal_api.h"
75#include "wlan_qct_pal_type.h"
76#include "wlan_qct_wdi.h"
77#include "wlan_qct_wdi_i.h"
78#include "wlan_qct_wdi_sta.h"
79#include "wlan_qct_wdi_dp.h"
80#include "wlan_qct_wdi_bd.h"
81#include "wlan_qct_pal_trace.h"
82
83#include "wlan_qct_dev_defs.h"
Gopichand Nakkalad786fa32013-03-20 23:48:19 +053084#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
85#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
Jeff Johnson295189b2012-06-20 16:38:30 -070086
87extern uint8 WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision);
88extern uint8 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision);
89
90
91/*----------------------------------------------------------------------------
92 * Preprocessor Definitions and Constants
93 * -------------------------------------------------------------------------*/
94
95/*--------------------------------------------------------------------------
96 TID->QueueID mapping
97 --------------------------------------------------------------------------*/
98static wpt_uint8 btqmQosTid2QidMapping[] =
99{
100 BTQM_QID0,
101 BTQM_QID1,
102 BTQM_QID2,
103 BTQM_QID3,
104 BTQM_QID4,
105 BTQM_QID5,
106 BTQM_QID6,
107 BTQM_QID7
108};
109/*===========================================================================
110 Helper Internal API
111 ===========================================================================*/
112
113/**
114 @brief WDI_DP_UtilsInit - Intializes the parameters required to
115 interact with the data path
116
117 @param pWDICtx: pointer to the main WDI Ctrl Block
118
119 @return success always
120*/
121WDI_Status
122WDI_DP_UtilsInit
123(
124 WDI_ControlBlockType* pWDICtx
125)
126{
127 WDI_RxBdType* pAmsduRxBdFixMask;
128
Jeff Johnson295189b2012-06-20 16:38:30 -0700129 // WQ to be used for filling the TxBD
130 pWDICtx->ucDpuRF = BMUWQ_BTQM_TX_MGMT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700131
132#ifdef WLAN_PERF
133 pWDICtx->uBdSigSerialNum = 0;
134#endif
135
136 pAmsduRxBdFixMask = &pWDICtx->wdiRxAmsduBdFixMask;
137
138 wpalMemoryFill(pAmsduRxBdFixMask,sizeof(WDI_RxBdType), 0xff);
139
140 pAmsduRxBdFixMask->penultimatePduIdx = 0;
141 pAmsduRxBdFixMask->headPduIdx = 0;
142 pAmsduRxBdFixMask->tailPduIdx = 0;
143 pAmsduRxBdFixMask->mpduHeaderLength = 0;
144 pAmsduRxBdFixMask->mpduHeaderOffset = 0;
145 pAmsduRxBdFixMask->mpduDataOffset = 0;
146 pAmsduRxBdFixMask->pduCount = 0;
147 pAmsduRxBdFixMask->mpduLength = 0;
148 pAmsduRxBdFixMask->asf = 0;
149 pAmsduRxBdFixMask->esf = 0;
150 pAmsduRxBdFixMask->lsf = 0;
151 pAmsduRxBdFixMask->processOrder = 0;
152 pAmsduRxBdFixMask->sybFrameIdx = 0;
153 pAmsduRxBdFixMask->totalMsduSize = 0;
154 pAmsduRxBdFixMask->aduFeedback = 0;
155
156 return WDI_STATUS_SUCCESS;
157}/*WDI_DP_UtilsInit*/
158
159
160/**
161 @brief WDI_DP_UtilsExit - Clears the parameters required to
162 interact with the data path
163
164 @param pWDICtx: pointer to the main WDI Ctrl Block
165
166 @return success always
167*/
168WDI_Status
169WDI_DP_UtilsExit
170(
171 WDI_ControlBlockType* pWDICtx
172)
173{
174 return WDI_STATUS_SUCCESS;
175}/*WDI_DP_UtilsExit*/
176
177/**
178 @brief WDI_SwapBytes - Swap Bytes of a given buffer
179
180 @param pBd: buffer to be swapped
181 nbSwap: number of bytes to swap
182
183 @return none
184*/
185WPT_STATIC WPT_INLINE void
186WDI_SwapBytes
187(
188 wpt_uint8 *pBd,
189 wpt_uint32 nbSwap
190)
191{
192 wpt_uint32 *pU32;
193 wpt_uint32 nU32;
194 wpt_uint32 wc;
195
196 nU32 = (((nbSwap) + 3)>>2);
197
198 pU32 = (wpt_uint32 *)pBd;
199 for ( wc = 0; wc < nU32; wc++ )
200 {
201 pU32[ wc ] = WPAL_BE32_TO_CPU( pU32[ wc ] );
202 }
203}/*WDI_SwapBytes*/
204
205/**
206 @brief WDI_BmuGetQidForQOSTid - returns the BMU QID for a given
207 TID
208
209 @param ucTid: TID
210 pQid: out QID
211
212 @see
213 @return Result of the function call
214*/
215WDI_Status
216WDI_BmuGetQidForQOSTid
217(
218 wpt_uint8 ucTid,
219 wpt_uint8* pQid
220)
221{
222 if (ucTid > BTQM_QUEUE_TX_TID_7 )
223 return WDI_STATUS_E_FAILURE;
224
225 *pQid = btqmQosTid2QidMapping[ucTid];
226 return WDI_STATUS_SUCCESS;
227}/*WDI_BmuGetQidForQOSTid*/
228
229#ifdef WLAN_PERF
230
231/**
232 @brief WDI_ComputeTxBdSignature - computes the BD signature
233
234 @param pWDICtx: pointer to the global WDI context;
235
236 pDestMacAddr: destination MAC address
237
238 ucTid: TID of the frame
239
240 ucDisableFrmXtl: Unicast destination
241
242 @return the signature
243*/
244static wpt_uint32
245WDI_ComputeTxBdSignature
246(
247 WDI_ControlBlockType* pWDICtx,
248 wpt_uint8* pDestMac,
249 wpt_uint8 ucTid,
250 wpt_uint8 ucUnicastDst
251)
252{
253 wpt_uint16 *pMacU16 = (wpt_uint16 *) pDestMac;
254
255 return ((pMacU16[0] ^ pMacU16[1] ^ pMacU16[2])<< WDI_TXBD_SIG_MACADDR_HASH_OFFSET |
256 pWDICtx->uBdSigSerialNum << WDI_TXBD_SIG_SERIAL_OFFSET |
257 ucTid << WDI_TXBD_SIG_TID_OFFSET |
258 ucUnicastDst << WDI_TXBD_SIG_UCAST_DATA_OFFSET);
259}/*WDI_ComputeTxBdSignature*/
260
261
262/**
263 @brief WDI_TxBdFastFwd - evaluates if a frame can be fast
264 forwarded
265
266 @param pWDICtx: Context to the WDI
267 pDestMac: Destination MAC
268 ucTid: packet TID pBDHeader
269 ucUnicastDst: is packet unicast
270 pTxBd: pointer to the BD header
271 usMpduLength: len
272
273 @return 1 - if the frame can be fast fwd-ed ; 0 if not
274*/
275wpt_uint32
276WDI_TxBdFastFwd
277(
278 WDI_ControlBlockType* pWDICtx,
279 wpt_uint8* pDestMac,
280 wpt_uint8 ucTid,
281 wpt_uint8 ucUnicastDst,
282 void* pTxBd,
283 wpt_uint16 usMpduLength
284 )
285{
286 WDI_TxBdType* pBd = (WDI_TxBdType*) pTxBd;
287 wpt_uint32 uRetval = 0;
288#ifdef WPT_LITTLE_BYTE_ENDIAN
289 wpt_uint16 usSwapped;
290 wpt_uint16* pU16 = (wpt_uint16 *) pTxBd;
291#endif
292
293 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
294
295 if( pBd->txBdSignature ==
296 WDI_ComputeTxBdSignature(pWDICtx, pDestMac, ucTid, ucUnicastDst))
297 {
298
299#ifdef WPT_LITTLE_BYTE_ENDIAN
300 /* When swap to BE format, mpduLength field is at 8th WORD location(16th byte) */
301 usSwapped = wpt_cpu_to_be16(usMpduLength);
302 pU16[8] = usSwapped;
303#else
304 /* Remove the #error when ported to a real BIG ENDIAN machine */
305 // #error "Is host byte order really BIG endian?"
306 /* When host is already in BE format, no swapping needed.*/
307 pBd->mpduLength = usMpduLength;
308#endif
309 uRetval = 1;
310 }
311 return uRetval ;
312}/*WDI_TxBdFastFwd*/
313
314#endif /*WLAN_PERF*/
315
316/*===========================================================================
317 External API
318 ===========================================================================*/
319
320/**
321 @brief WLANHAL_FillTxBd - Called by TL to fill in TxBD.
322
323 Following are the highlights of the function
324
325 1. All unicast data packets are sent by data rate decided by TPE.
326 (i.e BD rates are disabled).
327
328 2. All u/mcast management packets would go in Broadcast
329 Management Rates
330
331 3. dpuNE would be disabled for all data packets
332
333 4. dpuNE would be enabled for all management packets
334 excluding packets when RMF is enabled
335
336 5. QID8 at self STA is for broadcast data which uses no ACK
337 policy.
338
339 6. QID9 at self STA, we use it for unicast mgmt and set ACK
340 policy to normal ACK.
341
342 7. QID10 at self STA, we use it for b/mcast mgmt and set ACK
343 policy to NO ACK.
344
345 WDI DP Utilities modules must be initiatilized before this
346 API can be called.
347
348 @param
349
350 IN
351 pWDICtx: pointer to the global WDI context;
352
353 ucTypeSubtype: 802.11 [5:4] ucType [3:0] subtype
354
355 pDestMacAddr: destination MAC address
356
357 pTid: ptr to TID of the frame
358
359 ucDisableFrmXtl: When set, disables UMA HW frame
360 translation and WDI needs to fill in all BD
361 fields. When not set, UMA performs BD
362 filling and frame translation
363
364 pTxBd: ptr to the TxBD
365
366 ucTxFlag: different option setting for TX.
367
Chet Lanctot4b088622013-05-22 16:09:22 -0700368 ucProtMgmtFrame: for management frames, whether the frame is
369 protected (protect bit is set in FC)
370
Jeff Johnson295189b2012-06-20 16:38:30 -0700371 uTimeStamp: Timestamp when the frame was received from HDD. (usec)
372
373 @return
374 The result code associated with performing the operation
375
376*/
377
378WDI_Status
379WDI_FillTxBd
380(
381 WDI_ControlBlockType* pWDICtx,
382 wpt_uint8 ucTypeSubtype,
383 void* pDestMacAddr,
384 void* pAddr2,
385 wpt_uint8* pTid,
386 wpt_uint8 ucDisableFrmXtl,
387 void* pTxBd,
Chandrasekaran Manishekar7218fa22014-06-26 10:34:25 +0530388 wpt_uint32 ucTxFlag,
Chet Lanctot4b088622013-05-22 16:09:22 -0700389 wpt_uint8 ucProtMgmtFrame,
Jeff Johnson295189b2012-06-20 16:38:30 -0700390 wpt_uint32 uTimeStamp,
Kiet Lam9b11b012013-10-24 11:43:30 +0530391 wpt_uint8 isEapol,
Jeff Johnson295189b2012-06-20 16:38:30 -0700392 wpt_uint8* staIndex
393)
394{
395 wpt_uint8 ucTid = *pTid;
396 WDI_TxBdType* pBd = (WDI_TxBdType*) pTxBd;
397 WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
398 wpt_uint8 ucUnicastDst = 0;
399 wpt_uint8 ucType = 0;
400 wpt_uint8 ucSubType = 0;
401 wpt_uint8 ucIsRMF = 0;
402 WDI_BSSSessionType* pBSSSes;
403 wpt_uint8 ucSTAType = 0;
404#ifdef WLAN_PERF
405 wpt_uint32 uTxBdSignature = pBd->txBdSignature;
406#endif
407 tANI_U8 useStaRateForBcastFrames = 0;
408 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
409
410 /*------------------------------------------------------------------------
411 Get type and subtype of the frame first
412 ------------------------------------------------------------------------*/
413 ucType = (ucTypeSubtype & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET;
414 ucSubType = (ucTypeSubtype & WDI_FRAME_SUBTYPE_MASK);
415
416 WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
Arif Hussain9a5d5382013-11-17 22:05:35 -0800417 "Type: %d/%d, MAC S: %08x. MAC D: %08x., Tid=%d, frmXlat=%d, pTxBD=%p ucTxFlag 0x%X",
Jeff Johnson295189b2012-06-20 16:38:30 -0700418 ucType, ucSubType,
419 *((wpt_uint32 *) pAddr2),
420 *((wpt_uint32 *) pDestMacAddr),
421 ucTid,
422 !ucDisableFrmXtl, pTxBd, ucTxFlag );
423
424
425 //logic to determine the version match between host and riva to find out when to enable using STA rate for bcast frames.
426 //determine if Riva vsersion and host version both are greater than or equal to 0.0.2 (major, minor, version). if yes then use STA rate
427 // instead of BD rate for BC/MC frames. Otherwise use old code to use BD rate instead.
428 {
429 if (WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(0, 0, 2, 0) &&
430 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(0, 0, 2, 0))
431 useStaRateForBcastFrames = 1;
432 }
433
434
435 /*-----------------------------------------------------------------------
436 * Set common fields in TxBD
437 * bdt: always HWBD_TYPE_GENERIC
438 dpuRF: This is not used in Gen6 since all WQs are explicitly
439 programmed to each HW module
440 * ucTid: from caller, ignored if frame is MGMT frame
441 * fwTxComplete0: always set to 0
442 * txComplete1: If TxComp inrs is requested, enable TxComplete interrupt
443 * dpuFeedback/aduFeedback/reserved2: Always set to 0
444 ap: ACK policy to be placed in Qos ctrl field. Ignored by HW if non
445 Qos ucType frames.
446 u/b: If Addr1 of this frame in its 802.11 form is unicast, set to 0.
447 Otherwise set to 1.
448 dpuNE: always set to 0. DPU also uses the privacy bit in 802.11 hdr
449 for encryption decision
450 -----------------------------------------------------------------------*/
451 pBd->bdt = HWBD_TYPE_GENERIC;
452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453 // Route all trigger enabled frames to FW WQ, for FW to suspend trigger frame generation
454 // when no traffic is exists on trigger enabled ACs
455 if(ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK) {
456 pBd->dpuRF = pWDICtx->ucDpuRF;
457 } else
Jeff Johnson295189b2012-06-20 16:38:30 -0700458 {
459 pBd->dpuRF = BMUWQ_BTQM_TX_MGMT;
460 }
461
Agarwal Ashisha8e81f52014-04-02 01:59:52 +0530462 if (ucTxFlag & WDI_USE_FW_IN_TX_PATH)
463 {
464 WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
465 "iType: %d SubType %d, MAC S: %08x. MAC D: %08x., Tid=%d",
466 ucType, ucSubType,
467 *((wpt_uint32 *) pAddr2),
468 *((wpt_uint32 *) pDestMacAddr),
469 ucTid);
470
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530471 pBd->dpuRF = BMUWQ_FW_DPU_TX;
Agarwal Ashisha8e81f52014-04-02 01:59:52 +0530472 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700473
474 pBd->tid = ucTid;
475 // Clear the reserved field as this field is used for defining special
476 // flow control BD.
477 pBd->reserved4 = 0;
478 pBd->fwTxComplete0 = 0;
479
480 /* This bit is for host to register TxComplete Interrupt */
481 pBd->txComplete1 = (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK) ? 1 : 0;
482
483 pBd->ap = WDI_ACKPOLICY_ACK_REQUIRED;
484 pBd->dpuNE = WDI_NO_ENCRYPTION_DISABLED;
485
486 ucUnicastDst = !(((wpt_uint8 *)pDestMacAddr)[0] & 0x01);
487 *((wpt_uint32 *)pBd + WDI_DPU_FEEDBACK_OFFSET) = 0;
488
489 if(!ucUnicastDst)
490 {
491 pBd->ap = WDI_ACKPOLICY_ACK_NOTREQUIRED;
492 }
493
494 if (ucType == WDI_MAC_DATA_FRAME)
495 {
496
497 /* Set common fields for data frames (regardless FT enable/disable)
498 * bd_ssn: Let DPU auto generate seq # if QosData frame. All other
499 frames DPU generates seq using nonQos counter.
500 For QosNull, don't occupy one Qos seq # to avoid a potential
501 hole seen in reorder buffer when BA is enabled.
502
503 * bd_rate:HW default or broadcast data rate
504 * rmf: RMF doesn't apply for data frames. Always set to 0
505 * u/b: If Addr1 of this frame in its 802.11 form is unicast,
506 set to 0. Otherwise set to 1.
507 * Sanity: Force disable HW frame translation if incoming frame is
508 NULL data frame
509 */
510
511 if ((ucSubType & WDI_MAC_DATA_QOS_DATA)&&
512 (ucSubType != WDI_MAC_DATA_QOS_NULL))
513 {
514 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_QOS;
515 }
516 else
517 {
518 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS;
519 }
520
521 /* Unicast/Mcast decision:
522 * In Infra STA role, all frames to AP are unicast frames.
523 * For IBSS, then check the actual DA MAC address
524 This implementation doesn't support multi BSS and AP case.
525 if(eSYSTEM_STA_IN_IBSS_ROLE == systemRole)
526 ucUnicastDst = !(((wpt_uint8 *)pDestMacAddr)[0] & 0x01);
527 else
528 ucUnicastDst = WDI_DEFAULT_UNICAST_ENABLED;
529
530 The above is original HAL code - however to make implementation
531 more elastic and supportive of concurrency scenarios we shall just
532 assume that bcast bit of MAC adddress cannot be set if addr is not
533 bcast: (!! may want to revisit this during testing)
534 */
535
536 //Broadcast frames buffering don't work well if BD rate is used in AP mode.
537 //always use STA rate for data frames.
538 //never use BD rate for BC/MC frames in AP mode.
539
540
541 if (useStaRateForBcastFrames)
542 {
543 pBd->bdRate = WDI_TXBD_BDRATE_DEFAULT;
544 }
545 else
546 {
547 pBd->bdRate = (ucUnicastDst)? WDI_TXBD_BDRATE_DEFAULT : WDI_BDRATE_BCDATA_FRAME;
548 }
Gopichand Nakkalad75b1532013-02-15 13:33:42 -0800549#ifdef FEATURE_WLAN_TDLS
550 if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)
551 {
552 pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
553 }
554#endif
Abhishek Singhfa011222014-04-14 10:57:08 +0530555
556 if(ucTxFlag & WDI_USE_BD_RATE_MASK)
557 {
558 pBd->bdRate = WDI_BDRATE_BCDATA_FRAME;
559 }
560
Jeff Johnson295189b2012-06-20 16:38:30 -0700561 pBd->rmf = WDI_RMF_DISABLED;
562
563 /* sanity: Might already be set by caller, but enforce it here again */
564 if( WDI_MAC_DATA_NULL == (ucSubType & ~WDI_MAC_DATA_QOS_DATA))
565 {
566 ucDisableFrmXtl = 1;
567 if (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK)
568 {
569 /*Send to FW to transmit NULL frames.*/
570 pBd->dpuRF = BMUWQ_FW_TRANSMIT;
571 }
572 else
573 {
574#ifdef LIBRA_WAPI_SUPPORT
575 if (ucTxFlag & WDI_WAPI_STA_MASK)
576 {
577 pBd->dpuRF = BMUWQ_WAPI_DPU_TX;
578 /*set NE bit to 1 for the null/qos null frames*/
579 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
580 }
581#endif
582 }
583 }
584#if defined(WLAN_PERF) || defined(FEATURE_WLAN_WAPI) || defined(LIBRA_WAPI_SUPPORT)
585 //For not-NULL data frames
586 else
587 {
588#if defined(FEATURE_WLAN_WAPI)
589 //If caller doesn't want this frame to be encrypted, for example, WAI packets
590 if( (ucTxFlag & WDI_TX_NO_ENCRYPTION_MASK) )
591 {
592 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
593 }
594#endif //defined(FEATURE_WLAN_WAPI)
595#ifdef LIBRA_WAPI_SUPPORT
596 if (ucTxFlag & WDI_WAPI_STA_MASK)
597 {
598 pBd->dpuRF = BMUWQ_WAPI_DPU_TX;
599 }
600#endif //LIBRA_WAPI_SUPPORT
601#if defined(WLAN_PERF)
602 uTxBdSignature = WDI_ComputeTxBdSignature(pWDICtx, pDestMacAddr, ucTid, ucUnicastDst);
603#endif //defined(WLAN_PERF)
604 }
605#endif
606 }
607 else if (ucType == WDI_MAC_MGMT_FRAME)
608 {
609
610 /*--------------------------------------------------------------------
611 * Set common fields for mgmt frames
612 * bd_ssn: Always let DPU auto generate seq # from the nonQos
613 sequence number counter.
614 * bd_rate:unicast mgmt frames will go at lower rate (multicast rate).
615 * multicast mgmt frames will go at the STA rate as in AP mode
616 * buffering has an issue at HW if BD rate is used.
617 * rmf: NOT SET here. would be set later after STA id lookup is done.
618 * Sanity: Force HW frame translation OFF for mgmt frames.
619 --------------------------------------------------------------------*/
620 /* apply to both ucast/mcast mgmt frames */
Madan Mohan Koyyalamudi62799572013-09-24 01:37:27 +0530621 /* Probe requests are sent using BD rate */
622 if( ucSubType == WDI_MAC_MGMT_PROBE_REQ )
Jeff Johnson295189b2012-06-20 16:38:30 -0700623 {
624 pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME;
625 }
Madan Mohan Koyyalamudi62799572013-09-24 01:37:27 +0530626 else
627 {
628 if (useStaRateForBcastFrames)
629 {
630 pBd->bdRate = (ucUnicastDst)? WDI_BDRATE_BCMGMT_FRAME : WDI_TXBD_BDRATE_DEFAULT;
631 }
632 else
633 {
634 pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME;
635 }
636 }
637 if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)
Jeff Johnson295189b2012-06-20 16:38:30 -0700638 {
639 pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
640 }
641
642 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS;
643 if((ucSubType == WDI_MAC_MGMT_ACTION) || (ucSubType == WDI_MAC_MGMT_DEAUTH) ||
644 (ucSubType == WDI_MAC_MGMT_DISASSOC))
645 ucIsRMF = 1;
646 ucDisableFrmXtl = 1;
647 }
648 else
649 { // Control Packet
650 /* We should never get a control packet, asserting here since something
651 is wrong */
652 WDI_ASSERT(0);
653 }
654
655 pBd->ub = !ucUnicastDst;
656
657 /* Fast path: Leverage UMA for BD filling/frame translation.
658 * Must be a data frame to request for FT.
659 * When HW frame translation is enabled, UMA fills in the following fields:
660 * DPU Sig
661 * DPU descriptor index
662 * Updates MPDU header offset, data offset, MPDU length after translation
663 * STA id
664 * BTQM Queue ID
665 */
666
667 pBd->ft = pWDICtx->bFrameTransEnabled & !ucDisableFrmXtl;
668
669 if( !pBd->ft)
670 {
671 /* - Slow path: Frame translation is disabled. Need to set the
672 following fields:
673 * STA id
674 * DPU Sig
675 * DPU descriptor index
676 * BTQM Queue ID
677 * - For mgmt frames, also update rmf bits
678 */
679
680 WDI_StaStruct* pSta = (WDI_StaStruct*) pWDICtx->staTable;
681 wpt_uint8 ucStaId;
682
683 /* Disable frame translation*/
684 pBd->ft = 0;
685#ifdef WLAN_PERF
686 /* Mark the BD could not be reused */
687 uTxBdSignature = WDI_TXBD_SIG_MGMT_MAGIC;
688#endif
Chet Lanctotbd7cdbe2013-08-10 13:13:00 -0700689 if((ucTxFlag & WDI_USE_SELF_STA_REQUESTED_MASK) &&
690 !(ucIsRMF && ucProtMgmtFrame))
Jeff Johnson295189b2012-06-20 16:38:30 -0700691 {
692#ifdef HAL_SELF_STA_PER_BSS
693 // Get the (self) station index from ADDR2, which should be the self MAC addr
694 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
695 *(wpt_macAddr*)pAddr2, &ucStaId );
696 if (WDI_STATUS_SUCCESS != wdiStatus)
697 {
698 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "WDI_STATableFindStaidByAddr failed");
Gopichand Nakkalad786fa32013-03-20 23:48:19 +0530699 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "STA ID = %d " MAC_ADDRESS_STR,
700 ucStaId, MAC_ADDR_ARRAY(*(wpt_macAddr*)pAddr2));
Yue Maf74c9862013-03-21 16:36:15 -0700701 return WDI_STATUS_E_NOT_ALLOWED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 }
703#else
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530704 ucStaId = pWDICtx->ucSelfStaId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700705#endif
706 }
707 else
708 {
709 /*
710 _____________________________________________________________________________________________
711 | | | Data || Mgmt |
712 |____|_______|_______________________________________||_______________________________________|
713 | | Mode | DestAddr | Addr2 (selfMac) || DestAddr | Addr2 (selfMac) |
714 |____|_______|___________________|___________________||___________________|___________________|
715 | | | | || | |
716 | | STA | DestAddr->staIdx | When DestAddr || DestAddr->staIdx | - |
717 | | | | lookup fails, || | |
718 | | | | Addr2->staIdx || | |
719 |U/C | IBSS | DestAddr->staIdx | - || DestAddr->staIdx | - |
720 | | SoftAP| DestAddr->staIdx | - || DestAddr->staIdx | When DestAddr |
721 | | | | || | lookup fails, |
722 | | | | || | Addr2->StaIdx |
723 | | Idle | N/A | N/A || - | Addr2->StaIdx |
724 |____|_______|___________________|___________________||___________________|___________________|
725 | | | | || | |
726 | | STA | N/A | N/A || - | Addr2->staIdx-> |
727 | | | | || | bssIdx->bcasStaIdx|
728 |B/C | IBSS | - | Addr2->staIdx-> || - | Addr2->staIdx-> |
729 | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx|
730 | | SoftAP| - | Addr2->staIdx-> || - | Addr2->staIdx-> |
731 | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx|
732 | | Idle | N/A | N/A || - | Addr2->staIdx-> |
733 | | | | || | bssIdx->bcasStaIdx|
734 |____|_______|___________________|___________________||___________________|___________________|*/
735 // Get the station index based on the above table
736 if( ucUnicastDst )
737 {
738 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700739 *(wpt_macAddr*)pDestMacAddr, &ucStaId );
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700740 // In STA mode the unicast data frame could be
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700741 // transmitted to a DestAddr for which there might not be an entry in
742 // HAL STA table and the lookup would fail. In such cases use the Addr2
743 // (self MAC address) to get the selfStaIdx.
744 // From SelfStaIdx, get BSSIdx and use BSS MacAddr to get the staIdx
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700745 // corresponding to peerSta(AP).
746 // Drop frames only it is a data frame. Management frames can still
747 // go out using selfStaIdx.
Jeff Johnson295189b2012-06-20 16:38:30 -0700748
749
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700750 if (WDI_STATUS_SUCCESS != wdiStatus)
751 {
752 if(ucType == WDI_MAC_MGMT_FRAME)
753 {
754 //For management frames, use self staIdx if peer sta
755 //entry is not found.
756 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
757 *(wpt_macAddr*)pAddr2, &ucStaId );
758 }
759 else
760 {
761 if( !ucDisableFrmXtl )
762 {
763 // FrameTranslation in HW is enanled. This means,
764 // pDestMacaddress may be unknown. Get the station index
765 // for ADDR2, which should be the self MAC addr
766 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
767 *(wpt_macAddr*)pAddr2, &ucStaId );
768 if (WDI_STATUS_SUCCESS == wdiStatus)
769 {
770 //Found self Sta index.
771 WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
772 wpt_uint8 bssIdx = 0;
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700773
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700774 pBSSSes = NULL;
775 //Initialize WDI status to error.
776 wdiStatus = WDI_STATUS_E_NOT_ALLOWED;
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700777
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700778 //Check if its BSSIdx is valid.
779 if (pSTATable[ucStaId].bssIdx != WDI_BSS_INVALID_IDX)
780 {
781 //Use BSSIdx to get the association sequence and use
782 //macBssId to get the peerMac Address(MacBSSID).
783 bssIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
784 pSTATable[ucStaId].bssIdx,
785 &pBSSSes);
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700786
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700787 if ( NULL != pBSSSes )
788 {
789 //Get staId from the peerMac.
790 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
791 pBSSSes->macBSSID, &ucStaId );
792 }
793 }
794 }
795 }
796 }
797 //wdiStatus will be success if it found valid peerStaIdx
798 //Otherwise return failure.
799 if(WDI_STATUS_SUCCESS != wdiStatus )
800 {
801 return WDI_STATUS_E_NOT_ALLOWED;
802 }
803 }
804 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 else
806 {
807 // For bcast frames use the bcast station index
808 wpt_uint8 bssSessIdx;
809
810 // Get the station index for ADDR2, which should be the self MAC addr
811 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
812 *(wpt_macAddr*)pAddr2, &ucStaId );
813 if (WDI_STATUS_SUCCESS != wdiStatus)
814 {
Yue Maf74c9862013-03-21 16:36:15 -0700815 return WDI_STATUS_E_NOT_ALLOWED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700816 }
817
818 // Get the Bss Index related to the staId
819 bssSessIdx = pSta[ucStaId].bssIdx;
820
821 // Get the broadcast station index for this bss
822 (void) WDI_FindAssocSessionByBSSIdx( pWDICtx, bssSessIdx,
823 &pBSSSes );
824 if (NULL == pBSSSes)
825 {
826 // session not found ?!?
827 return WDI_STATUS_E_FAILURE;
828 }
829 ucStaId = pBSSSes->bcastStaIdx;
830 }
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530831 }
832
833 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,"StaId:%d and ucTxFlag:%02x", ucStaId, ucTxFlag);
Jeff Johnson295189b2012-06-20 16:38:30 -0700834
835 pBd->staIndex = ucStaId;
836
837 *staIndex = ucStaId;
838
839 pSta += ucStaId; // Go to the curresponding station's station table
840
841 if(ucType == WDI_MAC_MGMT_FRAME)
842 {
843 if (ucUnicastDst)
844 {
845 /* If no ack is requested use the bcast queue */
846 if (ucTxFlag & WDI_USE_NO_ACK_REQUESTED_MASK)
847 {
848 pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT;
849 }
850 else
851 {
852 /* Assigning Queue Id configured to Ack */
853 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_MGMT;
854 }
855 }
856 else
857 {
858 /* Assigning to Queue Id configured to No Ack */
859 pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT;
860 }
861
862 if(ucIsRMF && pSta->rmfEnabled)
863 {
Chet Lanctot4b088622013-05-22 16:09:22 -0700864 pBd->dpuNE = !ucProtMgmtFrame;
Jeff Johnson295189b2012-06-20 16:38:30 -0700865 pBd->rmf = 1;
866 if(!ucUnicastDst)
867 pBd->dpuDescIdx = pSta->bcastMgmtDpuIndex; /* IGTK */
868 else
Chet Lanctotbd7cdbe2013-08-10 13:13:00 -0700869 pBd->dpuDescIdx = pSta->dpuIndex; /* PTK */
Jeff Johnson295189b2012-06-20 16:38:30 -0700870 }
871 else
872 {
873 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
874 pBd->rmf = 0;
875 pBd->dpuDescIdx = pSta->dpuIndex; /* PTK for both u/mcast mgmt frames */
876 }
877 }
878 else
879 {
880 /* data frames */
881 /* TID->QID is one-to-one mapping, the same way as followed in H/W */
882 wpt_uint8 queueId = 0;
883
884
885 WDI_STATableGetStaType(pWDICtx, ucStaId, &ucSTAType);
886 if(!ucUnicastDst)
887 pBd->queueId = BTQM_QID0;
888#ifndef HAL_SELF_STA_PER_BSS
889 else if( ucUnicastDst && (ucStaId == pWDICtx->ucSelfStaId))
890 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA;
891#else
892 else if( ucUnicastDst && (ucSTAType == WDI_STA_ENTRY_SELF))
893 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA;
894#endif
895 else if (pSta->qosEnabled)
896 {
897 WDI_BmuGetQidForQOSTid( ucTid, &queueId);
898 pBd->queueId = (wpt_uint32) queueId;
899 }
900 else
901 pBd->queueId = BTQM_QUEUE_TX_nQOS;
902
903 if(ucUnicastDst)
904 {
905 pBd->dpuDescIdx = pSta->dpuIndex; /*unicast data frames: PTK*/
906 }
907 else
908 {
909 pBd->dpuDescIdx = pSta->bcastDpuIndex; /* mcast data frames: GTK*/
910 }
911 }
912
913 pBd->dpuSignature = pSta->dpuSig;
914
915 /* ! Re-analize this assumption
916 - original code from HAL is below - however WDI does not have access to a
917 DPU index table - so it just stores the signature that it receives from HAL upon
918 post assoc
919 if(eHAL_STATUS_SUCCESS == halDpu_GetSignature(pMac, pSta->dpuIndex, &ucDpuSig))
920 pBd->dpuSignature = ucDpuSig;
921 else{
922 WPAL_TRACE( WPT_WDI_CONTROL_MODULE, WPT_MSG_LEVEL_HIGH, "halDpu_GetSignature() failed for dpuId = %d\n", pBd->dpuDescIdx));
923 return VOS_STATUS_E_FAILURE;
924 } */
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800925#ifdef WLAN_SOFTAP_VSTA_FEATURE
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530926 // if this is a Virtual Station or statype is TDLS and trig enabled mask
927 // set then change the DPU Routing Flag so
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800928 // that the frame will be routed to Firmware for queuing & transmit
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530929 if (IS_VSTA_IDX(ucStaId) ||
Ravi Joshiaa81ca22013-06-25 17:20:52 -0700930 (
931#ifdef FEATURE_WLAN_TDLS
932 (ucSTAType == WDI_STA_ENTRY_TDLS_PEER ) &&
933#endif
Kiet Lam9b11b012013-10-24 11:43:30 +0530934 (ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK)) || isEapol)
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800935 {
Agarwal Ashisha8e81f52014-04-02 01:59:52 +0530936 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
937 "Sending EAPOL pakcet over WQ5 MAC S: %08x. MAC D: %08x.",
938 *((wpt_uint32 *) pAddr2),
939 *((wpt_uint32 *) pDestMacAddr));
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800940 pBd->dpuRF = BMUWQ_FW_DPU_TX;
941 }
942#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700943
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530944 }
945
Jeff Johnson295189b2012-06-20 16:38:30 -0700946 /*------------------------------------------------------------------------
947 Over SDIO bus, SIF won't swap data bytes to/from data FIFO.
948 In order for MAC modules to recognize BD in Riva's default endian
949 format (Big endian)
950 * All BD fields need to be swaped here
951 ------------------------------------------------------------------------*/
952 WDI_SwapTxBd((wpt_uint8 *)pBd);
953
954#ifdef WLAN_PERF
955 /* Save the BD signature. This field won't be swapped and remains in host
956 byte order */
957 pBd->txBdSignature = uTxBdSignature ;
958#endif
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530959
Jeff Johnson295189b2012-06-20 16:38:30 -0700960 return wdiStatus;
961}/*WDI_FillTxBd*/
962
963
964/**
965 @brief WDI_RxBD_GetFrameTypeSubType - Called by the data path
966 to retrieve the type/subtype of the received frame.
967
968 @param pvBDHeader: Void pointer to the RxBD buffer.
969 usFrmCtrl: the frame ctrl of the 802.11 header
970
971 @return A byte which contains both type and subtype info. LSB four bytes
972 (b0 to b3)is subtype and b5-b6 is type info.
973*/
974
975wpt_uint8
976WDI_RxBD_GetFrameTypeSubType
977(
978 void* _pvBDHeader,
979 wpt_uint16 usFrmCtrl
980)
981{
982 WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader;
983 wpt_uint8 typeSubType;
984 WDI_MacFrameCtl wdiFrmCtl;
985
986 if (pRxBd->ft != WDI_RX_BD_FT_DONE)
987 {
988 if (pRxBd->asf)
989 {
990 typeSubType = (WDI_MAC_DATA_FRAME << WDI_FRAME_TYPE_OFFSET) |
991 WDI_MAC_DATA_QOS_DATA;
992 } else {
993 wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl));
994 typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) |
995 wdiFrmCtl.subType;
996 }
997 }
998 else
999 {
1000 wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl));
1001 typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) |
1002 wdiFrmCtl.subType;
1003 }
1004
1005 return typeSubType;
1006}/*WDI_RxBD_GetFrameTypeSubType*/
1007
1008/**
1009 @brief WDI_SwapRxBd swaps the RX BD.
1010
1011
1012 @param pBd - pointer to the BD (in/out)
1013
1014 @return None
1015*/
1016void
1017WDI_SwapRxBd(wpt_uint8 *pBd)
1018{
1019#ifndef WDI_BIG_BYTE_ENDIAN
1020 WDI_SwapBytes(pBd , WDI_RX_BD_HEADER_SIZE);
1021#endif
1022}/*WDI_SwapRxBd*/
1023
1024
1025/**
1026 @brief WDI_SwapTxBd - Swaps the TX BD
1027
1028 @param pBd - pointer to the BD (in/out)
1029
1030 @return none
1031*/
1032void
1033WDI_SwapTxBd(wpt_uint8 *pBd)
1034{
1035#ifndef WDI_BIG_BYTE_ENDIAN
1036 WDI_SwapBytes(pBd , WDI_TX_BD_HEADER_SIZE);
1037#endif
1038}/*WDI_SwapTxBd*/
1039
1040/*! TO DO: - check if we still need this for RIVA*/
1041/**
1042 @brief WDI_RxAmsduBdFix - fix for HW issue for AMSDU
1043
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301044
Jeff Johnson295189b2012-06-20 16:38:30 -07001045 @param pWDICtx: Context to the WDI
1046 pBDHeader - pointer to the BD header
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301047
Jeff Johnson295189b2012-06-20 16:38:30 -07001048 @return None
1049*/
1050void
1051WDI_RxAmsduBdFix
1052(
1053 WDI_ControlBlockType* pWDICtx,
1054 void* _pvBDHeader
1055)
1056{
1057 WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader;
1058 wpt_uint32 *pModBd, *pMaskBd, *pFirstBd, i;
1059 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
1060
1061 if (pRxBd->asf)
1062 {
1063 if (pRxBd->sybFrameIdx == 0)
1064 {
1065 //copy the BD of first AMSDU
1066 pWDICtx->wdiRxAmsduFirstBdCache = *pRxBd;
1067 }
1068 else
1069 {
1070 pModBd = (wpt_uint32*)pRxBd;
1071 pMaskBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduBdFixMask;
1072 pFirstBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduFirstBdCache;
1073
1074 for (i = 0; i < sizeof(WDI_RxBdType)/sizeof(wpt_uint32 *); i++)
1075 {
1076 //modified BD = zero out non AMSDU related fields in this BD |
1077 // non AMSDU related fields from the first BD.
1078 pModBd[i] = (pModBd[i] & ~pMaskBd[i]) |
1079 (pFirstBd[i] & pMaskBd[i]);
1080 }
1081 }
1082 }
1083 return;
1084}/*WDI_RxAmsduBdFix*/
1085