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