blob: 735e69174cb808727e559eb0dc19aa335ad86656 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Agrawal Ashishaf1de652016-03-02 18:03:43 +05302 * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
Kiet Lam1ed83fc2014-02-19 01:15:45 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
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
Agrawal Ashishaf1de652016-03-02 18:03:43 +0530461 if (ucTxFlag & WDI_USE_FW_IN_TX_PATH ||
462 (pWDICtx->sendMgmtPktViaWQ5 && (ucType == WDI_MAC_MGMT_FRAME)))
Agarwal Ashisha8e81f52014-04-02 01:59:52 +0530463 {
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
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +0530556 if(ucTxFlag & WDI_USE_BD_RATE_1_MASK)
Abhishek Singhfa011222014-04-14 10:57:08 +0530557 {
558 pBd->bdRate = WDI_BDRATE_BCDATA_FRAME;
559 }
Hanumantha Reddy Pothulaee001fc2015-05-26 15:21:53 +0530560 else if(ucTxFlag & WDI_USE_BD_RATE_2_MASK)
561 {
562 pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME;
563 }
564 else if(ucTxFlag & WDI_USE_BD_RATE_3_MASK)
565 {
566 pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
567 }
Abhishek Singhfa011222014-04-14 10:57:08 +0530568
Jeff Johnson295189b2012-06-20 16:38:30 -0700569 pBd->rmf = WDI_RMF_DISABLED;
570
571 /* sanity: Might already be set by caller, but enforce it here again */
572 if( WDI_MAC_DATA_NULL == (ucSubType & ~WDI_MAC_DATA_QOS_DATA))
573 {
574 ucDisableFrmXtl = 1;
575 if (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK)
576 {
577 /*Send to FW to transmit NULL frames.*/
578 pBd->dpuRF = BMUWQ_FW_TRANSMIT;
579 }
580 else
581 {
582#ifdef LIBRA_WAPI_SUPPORT
583 if (ucTxFlag & WDI_WAPI_STA_MASK)
584 {
585 pBd->dpuRF = BMUWQ_WAPI_DPU_TX;
586 /*set NE bit to 1 for the null/qos null frames*/
587 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
588 }
589#endif
590 }
591 }
592#if defined(WLAN_PERF) || defined(FEATURE_WLAN_WAPI) || defined(LIBRA_WAPI_SUPPORT)
593 //For not-NULL data frames
594 else
595 {
596#if defined(FEATURE_WLAN_WAPI)
597 //If caller doesn't want this frame to be encrypted, for example, WAI packets
598 if( (ucTxFlag & WDI_TX_NO_ENCRYPTION_MASK) )
599 {
600 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
601 }
602#endif //defined(FEATURE_WLAN_WAPI)
603#ifdef LIBRA_WAPI_SUPPORT
604 if (ucTxFlag & WDI_WAPI_STA_MASK)
605 {
606 pBd->dpuRF = BMUWQ_WAPI_DPU_TX;
607 }
608#endif //LIBRA_WAPI_SUPPORT
609#if defined(WLAN_PERF)
610 uTxBdSignature = WDI_ComputeTxBdSignature(pWDICtx, pDestMacAddr, ucTid, ucUnicastDst);
611#endif //defined(WLAN_PERF)
612 }
613#endif
614 }
615 else if (ucType == WDI_MAC_MGMT_FRAME)
616 {
617
618 /*--------------------------------------------------------------------
619 * Set common fields for mgmt frames
620 * bd_ssn: Always let DPU auto generate seq # from the nonQos
621 sequence number counter.
622 * bd_rate:unicast mgmt frames will go at lower rate (multicast rate).
623 * multicast mgmt frames will go at the STA rate as in AP mode
624 * buffering has an issue at HW if BD rate is used.
625 * rmf: NOT SET here. would be set later after STA id lookup is done.
626 * Sanity: Force HW frame translation OFF for mgmt frames.
627 --------------------------------------------------------------------*/
628 /* apply to both ucast/mcast mgmt frames */
Madan Mohan Koyyalamudi62799572013-09-24 01:37:27 +0530629 /* Probe requests are sent using BD rate */
630 if( ucSubType == WDI_MAC_MGMT_PROBE_REQ )
Jeff Johnson295189b2012-06-20 16:38:30 -0700631 {
632 pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME;
633 }
Madan Mohan Koyyalamudi62799572013-09-24 01:37:27 +0530634 else
635 {
636 if (useStaRateForBcastFrames)
637 {
638 pBd->bdRate = (ucUnicastDst)? WDI_BDRATE_BCMGMT_FRAME : WDI_TXBD_BDRATE_DEFAULT;
639 }
640 else
641 {
642 pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME;
643 }
644 }
645 if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)
Jeff Johnson295189b2012-06-20 16:38:30 -0700646 {
647 pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
648 }
649
650 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS;
651 if((ucSubType == WDI_MAC_MGMT_ACTION) || (ucSubType == WDI_MAC_MGMT_DEAUTH) ||
652 (ucSubType == WDI_MAC_MGMT_DISASSOC))
653 ucIsRMF = 1;
654 ucDisableFrmXtl = 1;
655 }
656 else
657 { // Control Packet
658 /* We should never get a control packet, asserting here since something
659 is wrong */
660 WDI_ASSERT(0);
661 }
662
663 pBd->ub = !ucUnicastDst;
664
665 /* Fast path: Leverage UMA for BD filling/frame translation.
666 * Must be a data frame to request for FT.
667 * When HW frame translation is enabled, UMA fills in the following fields:
668 * DPU Sig
669 * DPU descriptor index
670 * Updates MPDU header offset, data offset, MPDU length after translation
671 * STA id
672 * BTQM Queue ID
673 */
674
675 pBd->ft = pWDICtx->bFrameTransEnabled & !ucDisableFrmXtl;
676
677 if( !pBd->ft)
678 {
679 /* - Slow path: Frame translation is disabled. Need to set the
680 following fields:
681 * STA id
682 * DPU Sig
683 * DPU descriptor index
684 * BTQM Queue ID
685 * - For mgmt frames, also update rmf bits
686 */
687
688 WDI_StaStruct* pSta = (WDI_StaStruct*) pWDICtx->staTable;
689 wpt_uint8 ucStaId;
690
691 /* Disable frame translation*/
692 pBd->ft = 0;
693#ifdef WLAN_PERF
694 /* Mark the BD could not be reused */
695 uTxBdSignature = WDI_TXBD_SIG_MGMT_MAGIC;
696#endif
Chet Lanctotbd7cdbe2013-08-10 13:13:00 -0700697 if((ucTxFlag & WDI_USE_SELF_STA_REQUESTED_MASK) &&
698 !(ucIsRMF && ucProtMgmtFrame))
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 {
700#ifdef HAL_SELF_STA_PER_BSS
701 // Get the (self) station index from ADDR2, which should be the self MAC addr
702 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
703 *(wpt_macAddr*)pAddr2, &ucStaId );
704 if (WDI_STATUS_SUCCESS != wdiStatus)
705 {
706 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "WDI_STATableFindStaidByAddr failed");
Gopichand Nakkalad786fa32013-03-20 23:48:19 +0530707 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "STA ID = %d " MAC_ADDRESS_STR,
708 ucStaId, MAC_ADDR_ARRAY(*(wpt_macAddr*)pAddr2));
Yue Maf74c9862013-03-21 16:36:15 -0700709 return WDI_STATUS_E_NOT_ALLOWED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 }
711#else
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530712 ucStaId = pWDICtx->ucSelfStaId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700713#endif
714 }
715 else
716 {
717 /*
718 _____________________________________________________________________________________________
719 | | | Data || Mgmt |
720 |____|_______|_______________________________________||_______________________________________|
721 | | Mode | DestAddr | Addr2 (selfMac) || DestAddr | Addr2 (selfMac) |
722 |____|_______|___________________|___________________||___________________|___________________|
723 | | | | || | |
724 | | STA | DestAddr->staIdx | When DestAddr || DestAddr->staIdx | - |
725 | | | | lookup fails, || | |
726 | | | | Addr2->staIdx || | |
727 |U/C | IBSS | DestAddr->staIdx | - || DestAddr->staIdx | - |
728 | | SoftAP| DestAddr->staIdx | - || DestAddr->staIdx | When DestAddr |
729 | | | | || | lookup fails, |
730 | | | | || | Addr2->StaIdx |
731 | | Idle | N/A | N/A || - | Addr2->StaIdx |
732 |____|_______|___________________|___________________||___________________|___________________|
733 | | | | || | |
734 | | STA | N/A | N/A || - | Addr2->staIdx-> |
735 | | | | || | bssIdx->bcasStaIdx|
736 |B/C | IBSS | - | Addr2->staIdx-> || - | Addr2->staIdx-> |
737 | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx|
738 | | SoftAP| - | Addr2->staIdx-> || - | Addr2->staIdx-> |
739 | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx|
740 | | Idle | N/A | N/A || - | Addr2->staIdx-> |
741 | | | | || | bssIdx->bcasStaIdx|
742 |____|_______|___________________|___________________||___________________|___________________|*/
743 // Get the station index based on the above table
744 if( ucUnicastDst )
745 {
746 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700747 *(wpt_macAddr*)pDestMacAddr, &ucStaId );
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700748 // In STA mode the unicast data frame could be
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700749 // transmitted to a DestAddr for which there might not be an entry in
750 // HAL STA table and the lookup would fail. In such cases use the Addr2
751 // (self MAC address) to get the selfStaIdx.
752 // From SelfStaIdx, get BSSIdx and use BSS MacAddr to get the staIdx
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700753 // corresponding to peerSta(AP).
754 // Drop frames only it is a data frame. Management frames can still
755 // go out using selfStaIdx.
Jeff Johnson295189b2012-06-20 16:38:30 -0700756
757
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700758 if (WDI_STATUS_SUCCESS != wdiStatus)
759 {
760 if(ucType == WDI_MAC_MGMT_FRAME)
761 {
762 //For management frames, use self staIdx if peer sta
763 //entry is not found.
764 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
765 *(wpt_macAddr*)pAddr2, &ucStaId );
766 }
767 else
768 {
769 if( !ucDisableFrmXtl )
770 {
771 // FrameTranslation in HW is enanled. This means,
772 // pDestMacaddress may be unknown. Get the station index
773 // for ADDR2, which should be the self MAC addr
774 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
775 *(wpt_macAddr*)pAddr2, &ucStaId );
776 if (WDI_STATUS_SUCCESS == wdiStatus)
777 {
778 //Found self Sta index.
779 WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
780 wpt_uint8 bssIdx = 0;
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700781
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700782 pBSSSes = NULL;
783 //Initialize WDI status to error.
784 wdiStatus = WDI_STATUS_E_NOT_ALLOWED;
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700785
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700786 //Check if its BSSIdx is valid.
787 if (pSTATable[ucStaId].bssIdx != WDI_BSS_INVALID_IDX)
788 {
789 //Use BSSIdx to get the association sequence and use
790 //macBssId to get the peerMac Address(MacBSSID).
791 bssIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
792 pSTATable[ucStaId].bssIdx,
793 &pBSSSes);
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700794
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700795 if ( NULL != pBSSSes )
796 {
797 //Get staId from the peerMac.
798 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
799 pBSSSes->macBSSID, &ucStaId );
800 }
801 }
802 }
803 }
804 }
805 //wdiStatus will be success if it found valid peerStaIdx
806 //Otherwise return failure.
807 if(WDI_STATUS_SUCCESS != wdiStatus )
808 {
809 return WDI_STATUS_E_NOT_ALLOWED;
810 }
811 }
812 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 else
814 {
815 // For bcast frames use the bcast station index
816 wpt_uint8 bssSessIdx;
817
818 // Get the station index for ADDR2, which should be the self MAC addr
819 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
820 *(wpt_macAddr*)pAddr2, &ucStaId );
821 if (WDI_STATUS_SUCCESS != wdiStatus)
822 {
Yue Maf74c9862013-03-21 16:36:15 -0700823 return WDI_STATUS_E_NOT_ALLOWED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700824 }
825
826 // Get the Bss Index related to the staId
827 bssSessIdx = pSta[ucStaId].bssIdx;
828
829 // Get the broadcast station index for this bss
830 (void) WDI_FindAssocSessionByBSSIdx( pWDICtx, bssSessIdx,
831 &pBSSSes );
832 if (NULL == pBSSSes)
833 {
834 // session not found ?!?
835 return WDI_STATUS_E_FAILURE;
836 }
837 ucStaId = pBSSSes->bcastStaIdx;
838 }
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530839 }
840
841 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 -0700842
843 pBd->staIndex = ucStaId;
844
845 *staIndex = ucStaId;
846
847 pSta += ucStaId; // Go to the curresponding station's station table
848
849 if(ucType == WDI_MAC_MGMT_FRAME)
850 {
851 if (ucUnicastDst)
852 {
853 /* If no ack is requested use the bcast queue */
854 if (ucTxFlag & WDI_USE_NO_ACK_REQUESTED_MASK)
855 {
856 pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT;
857 }
858 else
859 {
860 /* Assigning Queue Id configured to Ack */
861 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_MGMT;
862 }
863 }
864 else
865 {
866 /* Assigning to Queue Id configured to No Ack */
867 pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT;
868 }
869
870 if(ucIsRMF && pSta->rmfEnabled)
871 {
Chet Lanctot4b088622013-05-22 16:09:22 -0700872 pBd->dpuNE = !ucProtMgmtFrame;
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 pBd->rmf = 1;
874 if(!ucUnicastDst)
875 pBd->dpuDescIdx = pSta->bcastMgmtDpuIndex; /* IGTK */
876 else
Chet Lanctotbd7cdbe2013-08-10 13:13:00 -0700877 pBd->dpuDescIdx = pSta->dpuIndex; /* PTK */
Jeff Johnson295189b2012-06-20 16:38:30 -0700878 }
879 else
880 {
881 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
882 pBd->rmf = 0;
883 pBd->dpuDescIdx = pSta->dpuIndex; /* PTK for both u/mcast mgmt frames */
884 }
885 }
886 else
887 {
888 /* data frames */
889 /* TID->QID is one-to-one mapping, the same way as followed in H/W */
890 wpt_uint8 queueId = 0;
891
892
893 WDI_STATableGetStaType(pWDICtx, ucStaId, &ucSTAType);
894 if(!ucUnicastDst)
895 pBd->queueId = BTQM_QID0;
896#ifndef HAL_SELF_STA_PER_BSS
897 else if( ucUnicastDst && (ucStaId == pWDICtx->ucSelfStaId))
898 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA;
899#else
900 else if( ucUnicastDst && (ucSTAType == WDI_STA_ENTRY_SELF))
901 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA;
902#endif
903 else if (pSta->qosEnabled)
904 {
905 WDI_BmuGetQidForQOSTid( ucTid, &queueId);
906 pBd->queueId = (wpt_uint32) queueId;
907 }
908 else
909 pBd->queueId = BTQM_QUEUE_TX_nQOS;
910
911 if(ucUnicastDst)
912 {
913 pBd->dpuDescIdx = pSta->dpuIndex; /*unicast data frames: PTK*/
914 }
915 else
916 {
917 pBd->dpuDescIdx = pSta->bcastDpuIndex; /* mcast data frames: GTK*/
918 }
919 }
920
921 pBd->dpuSignature = pSta->dpuSig;
922
923 /* ! Re-analize this assumption
924 - original code from HAL is below - however WDI does not have access to a
925 DPU index table - so it just stores the signature that it receives from HAL upon
926 post assoc
927 if(eHAL_STATUS_SUCCESS == halDpu_GetSignature(pMac, pSta->dpuIndex, &ucDpuSig))
928 pBd->dpuSignature = ucDpuSig;
929 else{
930 WPAL_TRACE( WPT_WDI_CONTROL_MODULE, WPT_MSG_LEVEL_HIGH, "halDpu_GetSignature() failed for dpuId = %d\n", pBd->dpuDescIdx));
931 return VOS_STATUS_E_FAILURE;
932 } */
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800933#ifdef WLAN_SOFTAP_VSTA_FEATURE
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530934 // if this is a Virtual Station or statype is TDLS and trig enabled mask
935 // set then change the DPU Routing Flag so
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800936 // that the frame will be routed to Firmware for queuing & transmit
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530937 if (IS_VSTA_IDX(ucStaId) ||
Ravi Joshiaa81ca22013-06-25 17:20:52 -0700938 (
939#ifdef FEATURE_WLAN_TDLS
940 (ucSTAType == WDI_STA_ENTRY_TDLS_PEER ) &&
941#endif
Kiet Lam9b11b012013-10-24 11:43:30 +0530942 (ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK)) || isEapol)
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800943 {
Agarwal Ashisha8e81f52014-04-02 01:59:52 +0530944 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,
945 "Sending EAPOL pakcet over WQ5 MAC S: %08x. MAC D: %08x.",
946 *((wpt_uint32 *) pAddr2),
947 *((wpt_uint32 *) pDestMacAddr));
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800948 pBd->dpuRF = BMUWQ_FW_DPU_TX;
949 }
950#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700951
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530952 }
953
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 /*------------------------------------------------------------------------
955 Over SDIO bus, SIF won't swap data bytes to/from data FIFO.
956 In order for MAC modules to recognize BD in Riva's default endian
957 format (Big endian)
958 * All BD fields need to be swaped here
959 ------------------------------------------------------------------------*/
960 WDI_SwapTxBd((wpt_uint8 *)pBd);
961
962#ifdef WLAN_PERF
963 /* Save the BD signature. This field won't be swapped and remains in host
964 byte order */
965 pBd->txBdSignature = uTxBdSignature ;
966#endif
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530967
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 return wdiStatus;
969}/*WDI_FillTxBd*/
970
971
972/**
973 @brief WDI_RxBD_GetFrameTypeSubType - Called by the data path
974 to retrieve the type/subtype of the received frame.
975
976 @param pvBDHeader: Void pointer to the RxBD buffer.
977 usFrmCtrl: the frame ctrl of the 802.11 header
978
979 @return A byte which contains both type and subtype info. LSB four bytes
980 (b0 to b3)is subtype and b5-b6 is type info.
981*/
982
983wpt_uint8
984WDI_RxBD_GetFrameTypeSubType
985(
986 void* _pvBDHeader,
987 wpt_uint16 usFrmCtrl
988)
989{
990 WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader;
991 wpt_uint8 typeSubType;
992 WDI_MacFrameCtl wdiFrmCtl;
993
994 if (pRxBd->ft != WDI_RX_BD_FT_DONE)
995 {
996 if (pRxBd->asf)
997 {
998 typeSubType = (WDI_MAC_DATA_FRAME << WDI_FRAME_TYPE_OFFSET) |
999 WDI_MAC_DATA_QOS_DATA;
1000 } else {
1001 wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl));
1002 typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) |
1003 wdiFrmCtl.subType;
1004 }
1005 }
1006 else
1007 {
1008 wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl));
1009 typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) |
1010 wdiFrmCtl.subType;
1011 }
1012
1013 return typeSubType;
1014}/*WDI_RxBD_GetFrameTypeSubType*/
1015
1016/**
1017 @brief WDI_SwapRxBd swaps the RX BD.
1018
1019
1020 @param pBd - pointer to the BD (in/out)
1021
1022 @return None
1023*/
1024void
1025WDI_SwapRxBd(wpt_uint8 *pBd)
1026{
1027#ifndef WDI_BIG_BYTE_ENDIAN
1028 WDI_SwapBytes(pBd , WDI_RX_BD_HEADER_SIZE);
1029#endif
1030}/*WDI_SwapRxBd*/
1031
1032
1033/**
1034 @brief WDI_SwapTxBd - Swaps the TX BD
1035
1036 @param pBd - pointer to the BD (in/out)
1037
1038 @return none
1039*/
1040void
1041WDI_SwapTxBd(wpt_uint8 *pBd)
1042{
1043#ifndef WDI_BIG_BYTE_ENDIAN
1044 WDI_SwapBytes(pBd , WDI_TX_BD_HEADER_SIZE);
1045#endif
1046}/*WDI_SwapTxBd*/
1047
1048/*! TO DO: - check if we still need this for RIVA*/
1049/**
1050 @brief WDI_RxAmsduBdFix - fix for HW issue for AMSDU
1051
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301052
Jeff Johnson295189b2012-06-20 16:38:30 -07001053 @param pWDICtx: Context to the WDI
1054 pBDHeader - pointer to the BD header
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301055
Jeff Johnson295189b2012-06-20 16:38:30 -07001056 @return None
1057*/
1058void
1059WDI_RxAmsduBdFix
1060(
1061 WDI_ControlBlockType* pWDICtx,
1062 void* _pvBDHeader
1063)
1064{
1065 WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader;
1066 wpt_uint32 *pModBd, *pMaskBd, *pFirstBd, i;
1067 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
1068
1069 if (pRxBd->asf)
1070 {
1071 if (pRxBd->sybFrameIdx == 0)
1072 {
1073 //copy the BD of first AMSDU
1074 pWDICtx->wdiRxAmsduFirstBdCache = *pRxBd;
1075 }
1076 else
1077 {
1078 pModBd = (wpt_uint32*)pRxBd;
1079 pMaskBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduBdFixMask;
1080 pFirstBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduFirstBdCache;
1081
1082 for (i = 0; i < sizeof(WDI_RxBdType)/sizeof(wpt_uint32 *); i++)
1083 {
1084 //modified BD = zero out non AMSDU related fields in this BD |
1085 // non AMSDU related fields from the first BD.
1086 pModBd[i] = (pModBd[i] & ~pMaskBd[i]) |
1087 (pFirstBd[i] & pMaskBd[i]);
1088 }
1089 }
1090 }
1091 return;
1092}/*WDI_RxAmsduBdFix*/
1093