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