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