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