blob: 3a53c485ce44afa1590de40cc2e54c7864f87eaa [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"
Gopichand Nakkalad786fa32013-03-20 23:48:19 +053095#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
96#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
Jeff Johnson295189b2012-06-20 16:38:30 -070097
98extern uint8 WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision);
99extern uint8 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision);
100
101
102/*----------------------------------------------------------------------------
103 * Preprocessor Definitions and Constants
104 * -------------------------------------------------------------------------*/
105
106/*--------------------------------------------------------------------------
107 TID->QueueID mapping
108 --------------------------------------------------------------------------*/
109static wpt_uint8 btqmQosTid2QidMapping[] =
110{
111 BTQM_QID0,
112 BTQM_QID1,
113 BTQM_QID2,
114 BTQM_QID3,
115 BTQM_QID4,
116 BTQM_QID5,
117 BTQM_QID6,
118 BTQM_QID7
119};
120/*===========================================================================
121 Helper Internal API
122 ===========================================================================*/
123
124/**
125 @brief WDI_DP_UtilsInit - Intializes the parameters required to
126 interact with the data path
127
128 @param pWDICtx: pointer to the main WDI Ctrl Block
129
130 @return success always
131*/
132WDI_Status
133WDI_DP_UtilsInit
134(
135 WDI_ControlBlockType* pWDICtx
136)
137{
138 WDI_RxBdType* pAmsduRxBdFixMask;
139
Jeff Johnson295189b2012-06-20 16:38:30 -0700140 // WQ to be used for filling the TxBD
141 pWDICtx->ucDpuRF = BMUWQ_BTQM_TX_MGMT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700142
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
Chet Lanctot4b088622013-05-22 16:09:22 -0700379 ucProtMgmtFrame: for management frames, whether the frame is
380 protected (protect bit is set in FC)
381
Jeff Johnson295189b2012-06-20 16:38:30 -0700382 uTimeStamp: Timestamp when the frame was received from HDD. (usec)
383
384 @return
385 The result code associated with performing the operation
386
387*/
388
389WDI_Status
390WDI_FillTxBd
391(
392 WDI_ControlBlockType* pWDICtx,
393 wpt_uint8 ucTypeSubtype,
394 void* pDestMacAddr,
395 void* pAddr2,
396 wpt_uint8* pTid,
397 wpt_uint8 ucDisableFrmXtl,
398 void* pTxBd,
399 wpt_uint8 ucTxFlag,
Chet Lanctot4b088622013-05-22 16:09:22 -0700400 wpt_uint8 ucProtMgmtFrame,
Jeff Johnson295189b2012-06-20 16:38:30 -0700401 wpt_uint32 uTimeStamp,
402 wpt_uint8* staIndex
403)
404{
405 wpt_uint8 ucTid = *pTid;
406 WDI_TxBdType* pBd = (WDI_TxBdType*) pTxBd;
407 WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
408 wpt_uint8 ucUnicastDst = 0;
409 wpt_uint8 ucType = 0;
410 wpt_uint8 ucSubType = 0;
411 wpt_uint8 ucIsRMF = 0;
412 WDI_BSSSessionType* pBSSSes;
413 wpt_uint8 ucSTAType = 0;
414#ifdef WLAN_PERF
415 wpt_uint32 uTxBdSignature = pBd->txBdSignature;
416#endif
417 tANI_U8 useStaRateForBcastFrames = 0;
418 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
419
420 /*------------------------------------------------------------------------
421 Get type and subtype of the frame first
422 ------------------------------------------------------------------------*/
423 ucType = (ucTypeSubtype & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET;
424 ucSubType = (ucTypeSubtype & WDI_FRAME_SUBTYPE_MASK);
425
426 WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
427 "Type: %d/%d, MAC S: %08x. MAC D: %08x., Tid=%d, frmXlat=%d, pTxBD=%08x ucTxFlag 0x%X\n",
428 ucType, ucSubType,
429 *((wpt_uint32 *) pAddr2),
430 *((wpt_uint32 *) pDestMacAddr),
431 ucTid,
432 !ucDisableFrmXtl, pTxBd, ucTxFlag );
433
434
435 //logic to determine the version match between host and riva to find out when to enable using STA rate for bcast frames.
436 //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
437 // instead of BD rate for BC/MC frames. Otherwise use old code to use BD rate instead.
438 {
439 if (WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(0, 0, 2, 0) &&
440 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(0, 0, 2, 0))
441 useStaRateForBcastFrames = 1;
442 }
443
444
445 /*-----------------------------------------------------------------------
446 * Set common fields in TxBD
447 * bdt: always HWBD_TYPE_GENERIC
448 dpuRF: This is not used in Gen6 since all WQs are explicitly
449 programmed to each HW module
450 * ucTid: from caller, ignored if frame is MGMT frame
451 * fwTxComplete0: always set to 0
452 * txComplete1: If TxComp inrs is requested, enable TxComplete interrupt
453 * dpuFeedback/aduFeedback/reserved2: Always set to 0
454 ap: ACK policy to be placed in Qos ctrl field. Ignored by HW if non
455 Qos ucType frames.
456 u/b: If Addr1 of this frame in its 802.11 form is unicast, set to 0.
457 Otherwise set to 1.
458 dpuNE: always set to 0. DPU also uses the privacy bit in 802.11 hdr
459 for encryption decision
460 -----------------------------------------------------------------------*/
461 pBd->bdt = HWBD_TYPE_GENERIC;
462
Jeff Johnson295189b2012-06-20 16:38:30 -0700463 // Route all trigger enabled frames to FW WQ, for FW to suspend trigger frame generation
464 // when no traffic is exists on trigger enabled ACs
465 if(ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK) {
466 pBd->dpuRF = pWDICtx->ucDpuRF;
467 } else
Jeff Johnson295189b2012-06-20 16:38:30 -0700468 {
469 pBd->dpuRF = BMUWQ_BTQM_TX_MGMT;
470 }
471
472
473 pBd->tid = ucTid;
474 // Clear the reserved field as this field is used for defining special
475 // flow control BD.
476 pBd->reserved4 = 0;
477 pBd->fwTxComplete0 = 0;
478
479 /* This bit is for host to register TxComplete Interrupt */
480 pBd->txComplete1 = (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK) ? 1 : 0;
481
482 pBd->ap = WDI_ACKPOLICY_ACK_REQUIRED;
483 pBd->dpuNE = WDI_NO_ENCRYPTION_DISABLED;
484
485 ucUnicastDst = !(((wpt_uint8 *)pDestMacAddr)[0] & 0x01);
486 *((wpt_uint32 *)pBd + WDI_DPU_FEEDBACK_OFFSET) = 0;
487
488 if(!ucUnicastDst)
489 {
490 pBd->ap = WDI_ACKPOLICY_ACK_NOTREQUIRED;
491 }
492
493 if (ucType == WDI_MAC_DATA_FRAME)
494 {
495
496 /* Set common fields for data frames (regardless FT enable/disable)
497 * bd_ssn: Let DPU auto generate seq # if QosData frame. All other
498 frames DPU generates seq using nonQos counter.
499 For QosNull, don't occupy one Qos seq # to avoid a potential
500 hole seen in reorder buffer when BA is enabled.
501
502 * bd_rate:HW default or broadcast data rate
503 * rmf: RMF doesn't apply for data frames. Always set to 0
504 * u/b: If Addr1 of this frame in its 802.11 form is unicast,
505 set to 0. Otherwise set to 1.
506 * Sanity: Force disable HW frame translation if incoming frame is
507 NULL data frame
508 */
509
510 if ((ucSubType & WDI_MAC_DATA_QOS_DATA)&&
511 (ucSubType != WDI_MAC_DATA_QOS_NULL))
512 {
513 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_QOS;
514 }
515 else
516 {
517 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS;
518 }
519
520 /* Unicast/Mcast decision:
521 * In Infra STA role, all frames to AP are unicast frames.
522 * For IBSS, then check the actual DA MAC address
523 This implementation doesn't support multi BSS and AP case.
524 if(eSYSTEM_STA_IN_IBSS_ROLE == systemRole)
525 ucUnicastDst = !(((wpt_uint8 *)pDestMacAddr)[0] & 0x01);
526 else
527 ucUnicastDst = WDI_DEFAULT_UNICAST_ENABLED;
528
529 The above is original HAL code - however to make implementation
530 more elastic and supportive of concurrency scenarios we shall just
531 assume that bcast bit of MAC adddress cannot be set if addr is not
532 bcast: (!! may want to revisit this during testing)
533 */
534
535 //Broadcast frames buffering don't work well if BD rate is used in AP mode.
536 //always use STA rate for data frames.
537 //never use BD rate for BC/MC frames in AP mode.
538
539
540 if (useStaRateForBcastFrames)
541 {
542 pBd->bdRate = WDI_TXBD_BDRATE_DEFAULT;
543 }
544 else
545 {
546 pBd->bdRate = (ucUnicastDst)? WDI_TXBD_BDRATE_DEFAULT : WDI_BDRATE_BCDATA_FRAME;
547 }
Gopichand Nakkalad75b1532013-02-15 13:33:42 -0800548#ifdef FEATURE_WLAN_TDLS
549 if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)
550 {
551 pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
552 }
553#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700554 pBd->rmf = WDI_RMF_DISABLED;
555
556 /* sanity: Might already be set by caller, but enforce it here again */
557 if( WDI_MAC_DATA_NULL == (ucSubType & ~WDI_MAC_DATA_QOS_DATA))
558 {
559 ucDisableFrmXtl = 1;
560 if (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK)
561 {
562 /*Send to FW to transmit NULL frames.*/
563 pBd->dpuRF = BMUWQ_FW_TRANSMIT;
564 }
565 else
566 {
567#ifdef LIBRA_WAPI_SUPPORT
568 if (ucTxFlag & WDI_WAPI_STA_MASK)
569 {
570 pBd->dpuRF = BMUWQ_WAPI_DPU_TX;
571 /*set NE bit to 1 for the null/qos null frames*/
572 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
573 }
574#endif
575 }
576 }
577#if defined(WLAN_PERF) || defined(FEATURE_WLAN_WAPI) || defined(LIBRA_WAPI_SUPPORT)
578 //For not-NULL data frames
579 else
580 {
581#if defined(FEATURE_WLAN_WAPI)
582 //If caller doesn't want this frame to be encrypted, for example, WAI packets
583 if( (ucTxFlag & WDI_TX_NO_ENCRYPTION_MASK) )
584 {
585 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
586 }
587#endif //defined(FEATURE_WLAN_WAPI)
588#ifdef LIBRA_WAPI_SUPPORT
589 if (ucTxFlag & WDI_WAPI_STA_MASK)
590 {
591 pBd->dpuRF = BMUWQ_WAPI_DPU_TX;
592 }
593#endif //LIBRA_WAPI_SUPPORT
594#if defined(WLAN_PERF)
595 uTxBdSignature = WDI_ComputeTxBdSignature(pWDICtx, pDestMacAddr, ucTid, ucUnicastDst);
596#endif //defined(WLAN_PERF)
597 }
598#endif
599 }
600 else if (ucType == WDI_MAC_MGMT_FRAME)
601 {
602
603 /*--------------------------------------------------------------------
604 * Set common fields for mgmt frames
605 * bd_ssn: Always let DPU auto generate seq # from the nonQos
606 sequence number counter.
607 * bd_rate:unicast mgmt frames will go at lower rate (multicast rate).
608 * multicast mgmt frames will go at the STA rate as in AP mode
609 * buffering has an issue at HW if BD rate is used.
610 * rmf: NOT SET here. would be set later after STA id lookup is done.
611 * Sanity: Force HW frame translation OFF for mgmt frames.
612 --------------------------------------------------------------------*/
613 /* apply to both ucast/mcast mgmt frames */
614 if (useStaRateForBcastFrames)
615 {
616 pBd->bdRate = (ucUnicastDst)? WDI_BDRATE_BCMGMT_FRAME : WDI_TXBD_BDRATE_DEFAULT;
617 }
618 else
619 {
620 pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME;
621 }
622
623 if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)
624 {
625 pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
626 }
627
628 pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS;
629 if((ucSubType == WDI_MAC_MGMT_ACTION) || (ucSubType == WDI_MAC_MGMT_DEAUTH) ||
630 (ucSubType == WDI_MAC_MGMT_DISASSOC))
631 ucIsRMF = 1;
632 ucDisableFrmXtl = 1;
633 }
634 else
635 { // Control Packet
636 /* We should never get a control packet, asserting here since something
637 is wrong */
638 WDI_ASSERT(0);
639 }
640
641 pBd->ub = !ucUnicastDst;
642
643 /* Fast path: Leverage UMA for BD filling/frame translation.
644 * Must be a data frame to request for FT.
645 * When HW frame translation is enabled, UMA fills in the following fields:
646 * DPU Sig
647 * DPU descriptor index
648 * Updates MPDU header offset, data offset, MPDU length after translation
649 * STA id
650 * BTQM Queue ID
651 */
652
653 pBd->ft = pWDICtx->bFrameTransEnabled & !ucDisableFrmXtl;
654
655 if( !pBd->ft)
656 {
657 /* - Slow path: Frame translation is disabled. Need to set the
658 following fields:
659 * STA id
660 * DPU Sig
661 * DPU descriptor index
662 * BTQM Queue ID
663 * - For mgmt frames, also update rmf bits
664 */
665
666 WDI_StaStruct* pSta = (WDI_StaStruct*) pWDICtx->staTable;
667 wpt_uint8 ucStaId;
668
669 /* Disable frame translation*/
670 pBd->ft = 0;
671#ifdef WLAN_PERF
672 /* Mark the BD could not be reused */
673 uTxBdSignature = WDI_TXBD_SIG_MGMT_MAGIC;
674#endif
675 if(ucTxFlag & WDI_USE_SELF_STA_REQUESTED_MASK)
676 {
677#ifdef HAL_SELF_STA_PER_BSS
678 // Get the (self) station index from ADDR2, which should be the self MAC addr
679 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
680 *(wpt_macAddr*)pAddr2, &ucStaId );
681 if (WDI_STATUS_SUCCESS != wdiStatus)
682 {
683 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "WDI_STATableFindStaidByAddr failed");
Gopichand Nakkalad786fa32013-03-20 23:48:19 +0530684 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "STA ID = %d " MAC_ADDRESS_STR,
685 ucStaId, MAC_ADDR_ARRAY(*(wpt_macAddr*)pAddr2));
Yue Maf74c9862013-03-21 16:36:15 -0700686 return WDI_STATUS_E_NOT_ALLOWED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700687 }
688#else
689 ucStaId = pWDICtx->ucSelfStaId;
690#endif
691 }
692 else
693 {
694 /*
695 _____________________________________________________________________________________________
696 | | | Data || Mgmt |
697 |____|_______|_______________________________________||_______________________________________|
698 | | Mode | DestAddr | Addr2 (selfMac) || DestAddr | Addr2 (selfMac) |
699 |____|_______|___________________|___________________||___________________|___________________|
700 | | | | || | |
701 | | STA | DestAddr->staIdx | When DestAddr || DestAddr->staIdx | - |
702 | | | | lookup fails, || | |
703 | | | | Addr2->staIdx || | |
704 |U/C | IBSS | DestAddr->staIdx | - || DestAddr->staIdx | - |
705 | | SoftAP| DestAddr->staIdx | - || DestAddr->staIdx | When DestAddr |
706 | | | | || | lookup fails, |
707 | | | | || | Addr2->StaIdx |
708 | | Idle | N/A | N/A || - | Addr2->StaIdx |
709 |____|_______|___________________|___________________||___________________|___________________|
710 | | | | || | |
711 | | STA | N/A | N/A || - | Addr2->staIdx-> |
712 | | | | || | bssIdx->bcasStaIdx|
713 |B/C | IBSS | - | Addr2->staIdx-> || - | Addr2->staIdx-> |
714 | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx|
715 | | SoftAP| - | Addr2->staIdx-> || - | Addr2->staIdx-> |
716 | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx|
717 | | Idle | N/A | N/A || - | Addr2->staIdx-> |
718 | | | | || | bssIdx->bcasStaIdx|
719 |____|_______|___________________|___________________||___________________|___________________|*/
720 // Get the station index based on the above table
721 if( ucUnicastDst )
722 {
723 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700724 *(wpt_macAddr*)pDestMacAddr, &ucStaId );
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700725 // In STA mode the unicast data frame could be
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700726 // transmitted to a DestAddr for which there might not be an entry in
727 // HAL STA table and the lookup would fail. In such cases use the Addr2
728 // (self MAC address) to get the selfStaIdx.
729 // From SelfStaIdx, get BSSIdx and use BSS MacAddr to get the staIdx
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700730 // corresponding to peerSta(AP).
731 // Drop frames only it is a data frame. Management frames can still
732 // go out using selfStaIdx.
Jeff Johnson295189b2012-06-20 16:38:30 -0700733
734
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700735 if (WDI_STATUS_SUCCESS != wdiStatus)
736 {
737 if(ucType == WDI_MAC_MGMT_FRAME)
738 {
739 //For management frames, use self staIdx if peer sta
740 //entry is not found.
741 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
742 *(wpt_macAddr*)pAddr2, &ucStaId );
743 }
744 else
745 {
746 if( !ucDisableFrmXtl )
747 {
748 // FrameTranslation in HW is enanled. This means,
749 // pDestMacaddress may be unknown. Get the station index
750 // for ADDR2, which should be the self MAC addr
751 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
752 *(wpt_macAddr*)pAddr2, &ucStaId );
753 if (WDI_STATUS_SUCCESS == wdiStatus)
754 {
755 //Found self Sta index.
756 WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable;
757 wpt_uint8 bssIdx = 0;
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700758
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700759 pBSSSes = NULL;
760 //Initialize WDI status to error.
761 wdiStatus = WDI_STATUS_E_NOT_ALLOWED;
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700762
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700763 //Check if its BSSIdx is valid.
764 if (pSTATable[ucStaId].bssIdx != WDI_BSS_INVALID_IDX)
765 {
766 //Use BSSIdx to get the association sequence and use
767 //macBssId to get the peerMac Address(MacBSSID).
768 bssIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx,
769 pSTATable[ucStaId].bssIdx,
770 &pBSSSes);
Madan Mohan Koyyalamudi15a48f02012-10-05 17:13:53 -0700771
Madan Mohan Koyyalamudia9adc1c2012-10-05 17:18:39 -0700772 if ( NULL != pBSSSes )
773 {
774 //Get staId from the peerMac.
775 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
776 pBSSSes->macBSSID, &ucStaId );
777 }
778 }
779 }
780 }
781 }
782 //wdiStatus will be success if it found valid peerStaIdx
783 //Otherwise return failure.
784 if(WDI_STATUS_SUCCESS != wdiStatus )
785 {
786 return WDI_STATUS_E_NOT_ALLOWED;
787 }
788 }
789 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700790 else
791 {
792 // For bcast frames use the bcast station index
793 wpt_uint8 bssSessIdx;
794
795 // Get the station index for ADDR2, which should be the self MAC addr
796 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
797 *(wpt_macAddr*)pAddr2, &ucStaId );
798 if (WDI_STATUS_SUCCESS != wdiStatus)
799 {
Yue Maf74c9862013-03-21 16:36:15 -0700800 return WDI_STATUS_E_NOT_ALLOWED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700801 }
802
803 // Get the Bss Index related to the staId
804 bssSessIdx = pSta[ucStaId].bssIdx;
805
806 // Get the broadcast station index for this bss
807 (void) WDI_FindAssocSessionByBSSIdx( pWDICtx, bssSessIdx,
808 &pBSSSes );
809 if (NULL == pBSSSes)
810 {
811 // session not found ?!?
812 return WDI_STATUS_E_FAILURE;
813 }
814 ucStaId = pBSSSes->bcastStaIdx;
815 }
816 }
817
818 pBd->staIndex = ucStaId;
819
820 *staIndex = ucStaId;
821
822 pSta += ucStaId; // Go to the curresponding station's station table
823
824 if(ucType == WDI_MAC_MGMT_FRAME)
825 {
826 if (ucUnicastDst)
827 {
828 /* If no ack is requested use the bcast queue */
829 if (ucTxFlag & WDI_USE_NO_ACK_REQUESTED_MASK)
830 {
831 pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT;
832 }
833 else
834 {
835 /* Assigning Queue Id configured to Ack */
836 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_MGMT;
837 }
838 }
839 else
840 {
841 /* Assigning to Queue Id configured to No Ack */
842 pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT;
843 }
844
845 if(ucIsRMF && pSta->rmfEnabled)
846 {
Chet Lanctot4b088622013-05-22 16:09:22 -0700847 pBd->dpuNE = !ucProtMgmtFrame;
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 pBd->rmf = 1;
849 if(!ucUnicastDst)
850 pBd->dpuDescIdx = pSta->bcastMgmtDpuIndex; /* IGTK */
851 else
Chet Lanctot186b5732013-03-18 10:26:30 -0700852 {
853 wpt_uint8 peerStaId;
854
855 //We need to find the peer's station's DPU index to send this
856 //frame using PTK
857 wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx,
858 *(wpt_macAddr*)pDestMacAddr, &peerStaId );
859 if (WDI_STATUS_SUCCESS != wdiStatus)
860 {
861 WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR,
862 "%s failed to find peer sta %02X-%02X-%02X-%02X-%02X-%02X",
863 __FUNCTION__, ((wpt_uint8 *)pDestMacAddr)[0],
864 ((wpt_uint8 *)pDestMacAddr)[1], ((wpt_uint8 *)pDestMacAddr)[5],
865 ((wpt_uint8 *)pDestMacAddr)[3], ((wpt_uint8 *)pDestMacAddr)[4],
866 ((wpt_uint8 *)pDestMacAddr)[5]);
867 return WDI_STATUS_E_FAILURE;
868 }
869 pBd->dpuDescIdx = ((WDI_StaStruct*)pWDICtx->staTable)[peerStaId].dpuIndex; /* PTK */
870 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700871 }
872 else
873 {
874 pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED;
875 pBd->rmf = 0;
876 pBd->dpuDescIdx = pSta->dpuIndex; /* PTK for both u/mcast mgmt frames */
877 }
878 }
879 else
880 {
881 /* data frames */
882 /* TID->QID is one-to-one mapping, the same way as followed in H/W */
883 wpt_uint8 queueId = 0;
884
885
886 WDI_STATableGetStaType(pWDICtx, ucStaId, &ucSTAType);
887 if(!ucUnicastDst)
888 pBd->queueId = BTQM_QID0;
889#ifndef HAL_SELF_STA_PER_BSS
890 else if( ucUnicastDst && (ucStaId == pWDICtx->ucSelfStaId))
891 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA;
892#else
893 else if( ucUnicastDst && (ucSTAType == WDI_STA_ENTRY_SELF))
894 pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA;
895#endif
896 else if (pSta->qosEnabled)
897 {
898 WDI_BmuGetQidForQOSTid( ucTid, &queueId);
899 pBd->queueId = (wpt_uint32) queueId;
900 }
901 else
902 pBd->queueId = BTQM_QUEUE_TX_nQOS;
903
904 if(ucUnicastDst)
905 {
906 pBd->dpuDescIdx = pSta->dpuIndex; /*unicast data frames: PTK*/
907 }
908 else
909 {
910 pBd->dpuDescIdx = pSta->bcastDpuIndex; /* mcast data frames: GTK*/
911 }
912 }
913
914 pBd->dpuSignature = pSta->dpuSig;
915
916 /* ! Re-analize this assumption
917 - original code from HAL is below - however WDI does not have access to a
918 DPU index table - so it just stores the signature that it receives from HAL upon
919 post assoc
920 if(eHAL_STATUS_SUCCESS == halDpu_GetSignature(pMac, pSta->dpuIndex, &ucDpuSig))
921 pBd->dpuSignature = ucDpuSig;
922 else{
923 WPAL_TRACE( WPT_WDI_CONTROL_MODULE, WPT_MSG_LEVEL_HIGH, "halDpu_GetSignature() failed for dpuId = %d\n", pBd->dpuDescIdx));
924 return VOS_STATUS_E_FAILURE;
925 } */
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800926#ifdef WLAN_SOFTAP_VSTA_FEATURE
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530927 // if this is a Virtual Station or statype is TDLS and trig enabled mask
928 // set then change the DPU Routing Flag so
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800929 // that the frame will be routed to Firmware for queuing & transmit
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530930 if (IS_VSTA_IDX(ucStaId) ||
931 ((ucSTAType == WDI_STA_ENTRY_TDLS_PEER ) &&
932 (ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK)))
Gopichand Nakkala976e3252013-01-03 15:45:56 -0800933 {
934 pBd->dpuRF = BMUWQ_FW_DPU_TX;
935 }
936#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700937
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530938 }
939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /*------------------------------------------------------------------------
941 Over SDIO bus, SIF won't swap data bytes to/from data FIFO.
942 In order for MAC modules to recognize BD in Riva's default endian
943 format (Big endian)
944 * All BD fields need to be swaped here
945 ------------------------------------------------------------------------*/
946 WDI_SwapTxBd((wpt_uint8 *)pBd);
947
948#ifdef WLAN_PERF
949 /* Save the BD signature. This field won't be swapped and remains in host
950 byte order */
951 pBd->txBdSignature = uTxBdSignature ;
952#endif
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530953
Jeff Johnson295189b2012-06-20 16:38:30 -0700954 return wdiStatus;
955}/*WDI_FillTxBd*/
956
957
958/**
959 @brief WDI_RxBD_GetFrameTypeSubType - Called by the data path
960 to retrieve the type/subtype of the received frame.
961
962 @param pvBDHeader: Void pointer to the RxBD buffer.
963 usFrmCtrl: the frame ctrl of the 802.11 header
964
965 @return A byte which contains both type and subtype info. LSB four bytes
966 (b0 to b3)is subtype and b5-b6 is type info.
967*/
968
969wpt_uint8
970WDI_RxBD_GetFrameTypeSubType
971(
972 void* _pvBDHeader,
973 wpt_uint16 usFrmCtrl
974)
975{
976 WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader;
977 wpt_uint8 typeSubType;
978 WDI_MacFrameCtl wdiFrmCtl;
979
980 if (pRxBd->ft != WDI_RX_BD_FT_DONE)
981 {
982 if (pRxBd->asf)
983 {
984 typeSubType = (WDI_MAC_DATA_FRAME << WDI_FRAME_TYPE_OFFSET) |
985 WDI_MAC_DATA_QOS_DATA;
986 } else {
987 wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl));
988 typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) |
989 wdiFrmCtl.subType;
990 }
991 }
992 else
993 {
994 wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl));
995 typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) |
996 wdiFrmCtl.subType;
997 }
998
999 return typeSubType;
1000}/*WDI_RxBD_GetFrameTypeSubType*/
1001
1002/**
1003 @brief WDI_SwapRxBd swaps the RX BD.
1004
1005
1006 @param pBd - pointer to the BD (in/out)
1007
1008 @return None
1009*/
1010void
1011WDI_SwapRxBd(wpt_uint8 *pBd)
1012{
1013#ifndef WDI_BIG_BYTE_ENDIAN
1014 WDI_SwapBytes(pBd , WDI_RX_BD_HEADER_SIZE);
1015#endif
1016}/*WDI_SwapRxBd*/
1017
1018
1019/**
1020 @brief WDI_SwapTxBd - Swaps the TX BD
1021
1022 @param pBd - pointer to the BD (in/out)
1023
1024 @return none
1025*/
1026void
1027WDI_SwapTxBd(wpt_uint8 *pBd)
1028{
1029#ifndef WDI_BIG_BYTE_ENDIAN
1030 WDI_SwapBytes(pBd , WDI_TX_BD_HEADER_SIZE);
1031#endif
1032}/*WDI_SwapTxBd*/
1033
1034/*! TO DO: - check if we still need this for RIVA*/
1035/**
1036 @brief WDI_RxAmsduBdFix - fix for HW issue for AMSDU
1037
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301038
Jeff Johnson295189b2012-06-20 16:38:30 -07001039 @param pWDICtx: Context to the WDI
1040 pBDHeader - pointer to the BD header
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301041
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 @return None
1043*/
1044void
1045WDI_RxAmsduBdFix
1046(
1047 WDI_ControlBlockType* pWDICtx,
1048 void* _pvBDHeader
1049)
1050{
1051 WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader;
1052 wpt_uint32 *pModBd, *pMaskBd, *pFirstBd, i;
1053 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
1054
1055 if (pRxBd->asf)
1056 {
1057 if (pRxBd->sybFrameIdx == 0)
1058 {
1059 //copy the BD of first AMSDU
1060 pWDICtx->wdiRxAmsduFirstBdCache = *pRxBd;
1061 }
1062 else
1063 {
1064 pModBd = (wpt_uint32*)pRxBd;
1065 pMaskBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduBdFixMask;
1066 pFirstBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduFirstBdCache;
1067
1068 for (i = 0; i < sizeof(WDI_RxBdType)/sizeof(wpt_uint32 *); i++)
1069 {
1070 //modified BD = zero out non AMSDU related fields in this BD |
1071 // non AMSDU related fields from the first BD.
1072 pModBd[i] = (pModBd[i] & ~pMaskBd[i]) |
1073 (pFirstBd[i] & pMaskBd[i]);
1074 }
1075 }
1076 }
1077 return;
1078}/*WDI_RxAmsduBdFix*/
1079