blob: 540d7a32e08c20d9cf8549f5344f95cf27c8f04a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * Airgo Networks, Inc proprietary. All rights reserved.
24 * This file limProcessActionFrame.cc contains the code
25 * for processing Action Frame.
26 * Author: Michael Lui
27 * Date: 05/23/03
28 * History:-
29 * Date Modified by Modification Information
30 * --------------------------------------------------------------------
31 *
32 */
33#include "palTypes.h"
34#include "wniApi.h"
35#include "sirApi.h"
36#include "aniGlobal.h"
37#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
38#include "halDataStruct.h"
39#endif
40#if (WNI_POLARIS_FW_PRODUCT == AP)
41#include "wniCfgAp.h"
42#else
43#include "wniCfgSta.h"
44#endif
45#include "schApi.h"
46#include "utilsApi.h"
47#include "limTypes.h"
48#include "limUtils.h"
49#include "limAssocUtils.h"
50#include "limSecurityUtils.h"
51#include "limSerDesUtils.h"
52#include "limSendSmeRspMessages.h"
53#include "parserApi.h"
54#include "limAdmitControl.h"
55#include "wmmApsd.h"
56#include "limSendMessages.h"
57#if defined WLAN_FEATURE_VOWIFI
58#include "rrmApi.h"
59#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070060#include "limSessionUtils.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070061
62#if defined FEATURE_WLAN_CCX
63#include "ccxApi.h"
64#endif
65#include "wlan_qct_wda.h"
66
67
68#define BA_DEFAULT_TX_BUFFER_SIZE 64
69
70typedef enum
71{
72 LIM_ADDBA_RSP = 0,
73 LIM_ADDBA_REQ = 1
74}tLimAddBaValidationReqType;
75
76/* Note: The test passes if the STAUT stops sending any frames, and no further
77 frames are transmitted on this channel by the station when the AP has sent
78 the last 6 beacons, with the channel switch information elements as seen
79 with the sniffer.*/
80#define SIR_CHANSW_TX_STOP_MAX_COUNT 6
81/**-----------------------------------------------------------------
82\fn limStopTxAndSwitchChannel
83\brief Stops the transmission if channel switch mode is silent and
84 starts the channel switch timer.
85
86\param pMac
87\return NONE
88-----------------------------------------------------------------*/
89void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId)
90{
91 tANI_U8 isFullPowerRequested = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070092 tpPESession psessionEntry;
93
94 psessionEntry = peFindSessionBySessionId( pMac , sessionId );
95
96 if( NULL == psessionEntry )
97 {
98 limLog(pMac, LOGE, FL("Session %d not active\n "), sessionId);
99 return;
100 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102 PELOG1(limLog(pMac, LOG1, FL("Channel switch Mode == %d\n"),
Jeff Johnsone7245742012-09-05 17:12:55 -0700103 psessionEntry->gLimChannelSwitch.switchMode);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700104
Jeff Johnsone7245742012-09-05 17:12:55 -0700105 if (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT ||
106 psessionEntry->gLimChannelSwitch.switchCount <= SIR_CHANSW_TX_STOP_MAX_COUNT)
Jeff Johnson295189b2012-06-20 16:38:30 -0700107 {
108 /* Freeze the transmission */
109 limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX);
110
111 /*Request for Full power only if the device is in powersave*/
112 if(!limIsSystemInActiveState(pMac))
113 {
114 /* Request Full Power */
115 limSendSmePreChannelSwitchInd(pMac);
116 isFullPowerRequested = 1;
117 }
118 }
119 else
120 {
121 /* Resume the transmission */
122 limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
123 }
124
Jeff Johnsone7245742012-09-05 17:12:55 -0700125 pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -0700126 /* change the channel immediatly only if the channel switch count is 0 and the
127 * device is not in powersave
128 * If the device is in powersave channel switch should happen only after the
129 * device comes out of the powersave */
Jeff Johnsone7245742012-09-05 17:12:55 -0700130 if (psessionEntry->gLimChannelSwitch.switchCount == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -0700131 {
132 if(limIsSystemInActiveState(pMac))
133 {
134 limProcessChannelSwitchTimeout(pMac);
135 }
136 else if(!isFullPowerRequested)
137 {
138 /* If the Full power is already not requested
139 * Request Full Power so the channel switch happens
140 * after device comes to full power */
141 limSendSmePreChannelSwitchInd(pMac);
142 }
143 return;
144 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700145 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_CHANNEL_SWITCH_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700146
Jeff Johnson295189b2012-06-20 16:38:30 -0700147
148 if (tx_timer_activate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != TX_SUCCESS)
149 {
150 limLog(pMac, LOGP, FL("tx_timer_activate failed\n"));
151 }
152 return;
153}
154
155/**------------------------------------------------------------
156\fn limStartChannelSwitch
157\brief Switches the channel if switch count == 0, otherwise
158 starts the timer for channel switch and stops BG scan
159 and heartbeat timer tempororily.
160
161\param pMac
162\param psessionEntry
163\return NONE
164------------------------------------------------------------*/
165tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry)
166{
167 PELOG1(limLog(pMac, LOG1, FL("Starting the channel switch\n"));)
Jeff Johnsone7245742012-09-05 17:12:55 -0700168
169 /*If channel switch is already running and it is on a different session, just return*/
170 /*This need to be removed for MCC */
171 if( limIsChanSwitchRunning (pMac) &&
172 psessionEntry->gLimSpecMgmt.dot11hChanSwState != eLIM_11H_CHANSW_RUNNING )
173 {
174 limLog(pMac, LOGW, FL("Ignoring channel switch on session %d\n"), psessionEntry->peSessionId);
175 return eSIR_SUCCESS;
176 }
177
Jeff Johnson295189b2012-06-20 16:38:30 -0700178 /* Deactivate and change reconfigure the timeout value */
Jeff Johnsone7245742012-09-05 17:12:55 -0700179 //limDeactivateAndChangeTimer(pMac, eLIM_CHANNEL_SWITCH_TIMER);
180 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS)
181 {
182 limLog(pMac, LOGP, FL("tx_timer_deactivate failed!\n"));
183 return eSIR_FAILURE;
184 }
185
186 if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer,
187 psessionEntry->gLimChannelSwitch.switchTimeoutValue,
188 0) != TX_SUCCESS)
189 {
190 limLog(pMac, LOGP, FL("tx_timer_change failed \n"));
191 return eSIR_FAILURE;
192 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700193
194 /* Follow the channel switch, forget about the previous quiet. */
195 //If quiet is running, chance is there to resume tx on its timeout.
196 //so stop timer for a safer side.
Jeff Johnsone7245742012-09-05 17:12:55 -0700197 if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN)
Jeff Johnson295189b2012-06-20 16:38:30 -0700198 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700199 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700200 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS)
201 {
202 limLog(pMac, LOGP, FL("tx_timer_deactivate failed\n"));
203 return eSIR_FAILURE;
204 }
205 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700206 else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
Jeff Johnson295189b2012-06-20 16:38:30 -0700207 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700208 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -0700209 if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS)
210 {
211 limLog(pMac, LOGP, FL("tx_timer_deactivate failed\n"));
212 return eSIR_FAILURE;
213 }
214 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700215 psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
Jeff Johnson295189b2012-06-20 16:38:30 -0700216
217 /* Prepare for 11h channel switch */
218 limPrepareFor11hChannelSwitch(pMac, psessionEntry);
219
220 /** Dont add any more statements here as we posted finish scan request
221 * to HAL, wait till we get the response
222 */
223 return eSIR_SUCCESS;
224}
225
226
227/**
228 * __limProcessChannelSwitchActionFrame
229 *
230 *FUNCTION:
231 *
232 *LOGIC:
233 *
234 *ASSUMPTIONS:
235 *
236 *NOTE:
237 *
238 * @param pMac - Pointer to Global MAC structure
239 * @param *pRxPacketInfo - A pointer to packet info structure
240 * @return None
241 */
242
243static void
244
245__limProcessChannelSwitchActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
246{
247
248 tpSirMacMgmtHdr pHdr;
249 tANI_U8 *pBody;
250 tDot11fChannelSwitch *pChannelSwitchFrame;
251 tANI_U16 beaconPeriod;
252 tANI_U32 val;
253 tANI_U32 frameLen;
254 tANI_U32 nStatus;
255 eHalStatus status;
256
257 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
258 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
259 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
260
261 PELOG3(limLog(pMac, LOG3, FL("Received Channel switch action frame\n"));)
262 if (!psessionEntry->lim11hEnable)
263 return;
264
265 status = palAllocateMemory( pMac->hHdd, (void **)&pChannelSwitchFrame, sizeof(*pChannelSwitchFrame));
266 if (eHAL_STATUS_SUCCESS != status)
267 {
268 limLog(pMac, LOGE,
269 FL("palAllocateMemory failed, status = %d \n"), status);
270 return;
271 }
272
273 /* Unpack channel switch frame */
274 nStatus = dot11fUnpackChannelSwitch(pMac, pBody, frameLen, pChannelSwitchFrame);
275
276 if( DOT11F_FAILED( nStatus ))
277 {
278 limLog( pMac, LOGE,
279 FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):\n"),
280 nStatus,
281 frameLen);
282 palFreeMemory(pMac->hHdd, pChannelSwitchFrame);
283 return;
284 }
285 else if(DOT11F_WARNED( nStatus ))
286 {
287 limLog( pMac, LOGW,
288 FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):\n"),
289 nStatus,
290 frameLen);
291 }
292
293 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) &psessionEntry->bssId,
294 (tANI_U8 *) &pHdr->sa,
295 sizeof(tSirMacAddr)))
296 {
297 #if 0
298 if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &val) != eSIR_SUCCESS)
299 {
300 palFreeMemory(pMac->hHdd, pChannelSwitchFrame);
301 limLog(pMac, LOGP, FL("could not retrieve Beacon interval\n"));
302 return;
303 }
304 #endif// TO SUPPORT BT-AMP
305
306 /* copy the beacon interval from psessionEntry*/
307 val = psessionEntry->beaconParams.beaconInterval;
308
309 beaconPeriod = (tANI_U16) val;
310
Jeff Johnsone7245742012-09-05 17:12:55 -0700311 psessionEntry->gLimChannelSwitch.primaryChannel = pChannelSwitchFrame->ChanSwitchAnn.newChannel;
312 psessionEntry->gLimChannelSwitch.switchCount = pChannelSwitchFrame->ChanSwitchAnn.switchCount;
313 psessionEntry->gLimChannelSwitch.switchTimeoutValue = SYS_MS_TO_TICKS(beaconPeriod) *
314 psessionEntry->gLimChannelSwitch.switchCount;
315 psessionEntry->gLimChannelSwitch.switchMode = pChannelSwitchFrame->ChanSwitchAnn.switchMode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700316
317 PELOG3(limLog(pMac, LOG3, FL("Rcv Chnl Swtch Frame: Timeout in %d ticks\n"),
Jeff Johnsone7245742012-09-05 17:12:55 -0700318 psessionEntry->gLimChannelSwitch.switchTimeoutValue);)
Jeff Johnson295189b2012-06-20 16:38:30 -0700319
320 /* Only primary channel switch element is present */
Jeff Johnsone7245742012-09-05 17:12:55 -0700321 psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
322 psessionEntry->gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
Jeff Johnsone7245742012-09-05 17:12:55 -0700324 if (psessionEntry->htSupportedChannelWidthSet)
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700326 if ((pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) ||
327 (pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY))
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700329 psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
330 psessionEntry->gLimChannelSwitch.secondarySubBand = pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset;
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 }
332 }
333
334 }
335 else
336 {
337 PELOG1(limLog(pMac, LOG1, FL("LIM: Received action frame not from our BSS, dropping..."));)
338 }
339
340 if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry))
341 {
342 PELOG1(limLog(pMac, LOG1, FL("Could not start channel switch\n"));)
343 }
344
345 palFreeMemory(pMac->hHdd, pChannelSwitchFrame);
346 return;
347} /*** end limProcessChannelSwitchActionFrame() ***/
348
349
Mohit Khanna4a70d262012-09-11 16:30:12 -0700350#ifdef WLAN_FEATURE_11AC
351static void
352__limProcessOperatingModeActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
353{
354
355 tpSirMacMgmtHdr pHdr;
356 tANI_U8 *pBody;
357 tDot11fOperatingMode *pOperatingModeframe;
358 tANI_U32 frameLen;
359 tANI_U32 nStatus;
360 eHalStatus status;
361 tpDphHashNode pSta;
362 tANI_U16 aid;
363 tANI_U8 operMode;
364
365 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
366 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
367 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
368
369 PELOG3(limLog(pMac, LOG3, FL("Received Operating Mode action frame\n"));)
370 status = palAllocateMemory( pMac->hHdd, (void **)&pOperatingModeframe, sizeof(*pOperatingModeframe));
371 if (eHAL_STATUS_SUCCESS != status)
372 {
373 limLog(pMac, LOGE,
374 FL("palAllocateMemory failed, status = %d \n"), status);
375 return;
376 }
377
378 /* Unpack channel switch frame */
379 nStatus = dot11fUnpackOperatingMode(pMac, pBody, frameLen, pOperatingModeframe);
380
381 if( DOT11F_FAILED( nStatus ))
382 {
383 limLog( pMac, LOGE,
384 FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):\n"),
385 nStatus,
386 frameLen);
387 palFreeMemory(pMac->hHdd, pOperatingModeframe);
388 return;
389 }
390 else if(DOT11F_WARNED( nStatus ))
391 {
392 limLog( pMac, LOGW,
393 FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):\n"),
394 nStatus,
395 frameLen);
396 }
397 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
398
399 operMode = pSta->vhtSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_80MHZ : pSta->htSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_40MHZ: eHT_CHANNEL_WIDTH_20MHZ;
400 if( operMode != pOperatingModeframe->OperatingMode.chanWidth)
401 {
402 limLog(pMac, LOGE,
403 FL(" recevied Chanwidth %d, staIdx = %d\n"),
404 (pOperatingModeframe->OperatingMode.chanWidth ),
405 pSta->staIndex);
406
407 limLog(pMac, LOGE,
408 FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x\n"),
409 pHdr->sa[0],
410 pHdr->sa[1],
411 pHdr->sa[2],
412 pHdr->sa[3],
413 pHdr->sa[4],
414 pHdr->sa[5]);
415
416 if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ)
417 {
418 pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
419 pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
420 }
421 else if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_40MHZ)
422 {
423 pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
424 pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
425 }
426 else if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_20MHZ)
427 {
428 pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
429 pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
430 }
431 limCheckVHTOpModeChange( pMac, psessionEntry,
432 (pOperatingModeframe->OperatingMode.chanWidth), pSta->staIndex);\
433 }
434 palFreeMemory(pMac->hHdd, pOperatingModeframe);
435 return;
436}
437#endif
438
Jeff Johnson295189b2012-06-20 16:38:30 -0700439static void
440__limProcessAddTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
441{
442#if (WNI_POLARIS_FW_PRODUCT == AP)
443
444 tSirAddtsReqInfo addts;
445 tSirRetStatus retval;
446 tpSirMacMgmtHdr pHdr;
447 tSirMacScheduleIE schedule;
448 tpDphHashNode pSta;
449 tANI_U16 status;
450 tANI_U16 aid;
451 tANI_U32 frameLen;
452 tANI_U8 *pBody;
453 tANI_U8 tspecIdx = 0; //index in the sch tspec table.
454
455 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
456 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
457 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
458
459
460 if ((psessionEntry->limSystemRole != eLIM_AP_ROLE)||(psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE))
461 {
462 PELOGW(limLog(pMac, LOGW, FL("AddTs request at non-AP: ignoring\n"));)
463 return;
464 }
465
466 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
467 if (pSta == NULL)
468 {
469 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTs\n"));)
470 return;
471 }
472
473 PELOGW(limLog(pMac, LOGW, "AddTs Request from STA %d\n", aid);)
474 retval = sirConvertAddtsReq2Struct(pMac, pBody, frameLen, &addts);
475 if (retval != eSIR_SUCCESS)
476 {
477 PELOGW(limLog(pMac, LOGW, FL("AddTs parsing failed (error %d)\n"), retval);)
478 return;
479 }
480
481 status = eSIR_MAC_SUCCESS_STATUS;
482
483
484 if (addts.wmeTspecPresent)
485 {
486 if ((! psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled))
487 {
488 PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: wme not enabled/capable\n"));)
489 status = eSIR_MAC_WME_REFUSED_STATUS;
490 }
491 else
492 {
493 PELOG2(limLog(pMac, LOG2, FL("WME Addts received\n"));)
494 }
495 }
496 else if (addts.wsmTspecPresent)
497 {
498 if ((! psessionEntry->limWsmEnabled) || (! pSta->wsmEnabled))
499 {
500 PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: wsm not enabled/capable\n"));)
501 status = eSIR_MAC_REQ_DECLINED_STATUS;
502 }
503 else
504 {
505 PELOG2(limLog(pMac, LOG2, FL("WSM Addts received\n"));)
506 }
507 }
508 else if ((! psessionEntry->limQosEnabled) || (! pSta->lleEnabled))
509 {
510 PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: qos not enabled/capable\n"));)
511 status = eSIR_MAC_REQ_DECLINED_STATUS;
512 }
513 else
514 {
515 PELOG2(limLog(pMac, LOG2, FL("11e QoS Addts received\n"));)
516 }
517
518 // for edca, if no Admit Control, ignore the request
519 if ((status == eSIR_MAC_SUCCESS_STATUS) &&
520 (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) &&
521 (! psessionEntry->gLimEdcaParamsBC[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm))
522 {
523 limLog(pMac, LOGW, FL("AddTs with UP %d has no ACM - ignoring request\n"),
524 addts.tspec.tsinfo.traffic.userPrio);
525 status = (addts.wmeTspecPresent) ?
526 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
527 }
528
529 if (status != eSIR_MAC_SUCCESS_STATUS)
530 {
531 limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, NULL,psessionEntry);
532 return;
533 }
534
535 // try to admit the STA and send the appropriate response
536 retval = limAdmitControlAddTS(pMac, &pSta->staAddr[0], &addts, NULL, pSta->assocId, true, &schedule, &tspecIdx, psessionEntry);
537 if (retval != eSIR_SUCCESS)
538 {
539 PELOGW(limLog(pMac, LOGW, FL("Unable to admit TS\n"));)
540 status = (addts.wmeTspecPresent) ?
541 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
542 }
543 else if (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)
544 {
545 if(eSIR_SUCCESS != limSendHalMsgAddTs(pMac, pSta->staIndex, tspecIdx, addts.tspec, psessionEntry->peSessionId))
546 {
547 limLog(pMac, LOGW, FL("AddTs with UP %d failed in limSendHalMsgAddTs - ignoring request\n"),
548 addts.tspec.tsinfo.traffic.userPrio);
549 status = (addts.wmeTspecPresent) ?
550 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
551
552 limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecIdx);
553 }
554 if (status != eSIR_MAC_SUCCESS_STATUS)
555 {
556 limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, NULL,psessionEntry);
557 return;
558 }
559 }
560#if 0 //only EDCA is supported now.
561 else if (addts.numTclas > 1)
562 {
563 limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported\n"),
564 aid, addts.numTclas);
565 status = (addts.wmeTspecPresent) ?
566 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
567 }
568 else if (addts.numTclas == 1)
569 {
570 limLog(pMac, LOGW, "AddTs Request from STA %d: tsid %d, UP %d, OK!\n", aid,
571 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio);
572 status = eSIR_MAC_SUCCESS_STATUS;
573 }
574#endif
575
576 limLog(pMac, LOGW, "AddTs Request from STA %d: Sending AddTs Response with status %d\n",
577 aid, status);
578
579 limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, &schedule,psessionEntry);
580#endif
581}
582
583
584static void
585__limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
586{
587 tSirAddtsRspInfo addts;
588 tSirRetStatus retval;
589 tpSirMacMgmtHdr pHdr;
590 tpDphHashNode pSta;
591 tANI_U16 aid;
592 tANI_U32 frameLen;
593 tANI_U8 *pBody;
594 tpLimTspecInfo tspecInfo;
595 tANI_U8 ac;
596 tpDphHashNode pStaDs = NULL;
597 tANI_U8 rspReqd = 1;
598 tANI_U32 cfgLen;
599 tSirMacAddr peerMacAddr;
600
601
602 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
603 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
604 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
605
606
607 PELOGW(limLog(pMac, LOGW, "Recv AddTs Response\n");)
608 if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
609 {
610 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp recvd at AP: ignoring\n"));)
611 return;
612 }
613
614 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
615 if (pSta == NULL)
616 {
617 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp\n"));)
618 return;
619 }
620
621 retval = sirConvertAddtsRsp2Struct(pMac, pBody, frameLen, &addts);
622 if (retval != eSIR_SUCCESS)
623 {
624 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp parsing failed (error %d)\n"), retval);)
625 return;
626 }
627
628 // don't have to check for qos/wme capabilities since we wouldn't have this
629 // flag set otherwise
630 if (! pMac->lim.gLimAddtsSent)
631 {
632 // we never sent an addts request!
633 PELOGW(limLog(pMac, LOGW, "Recvd AddTsRsp but no request was ever sent - ignoring\n");)
634 return;
635 }
636
637 if (pMac->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken)
638 {
639 limLog(pMac, LOGW, "AddTsRsp: token mismatch (got %d, exp %d) - ignoring\n",
640 addts.dialogToken, pMac->lim.gLimAddtsReq.req.dialogToken);
641 return;
642 }
643
644 /*
645 * for successful addts reponse, try to add the classifier.
646 * if this fails for any reason, we should send a delts request to the ap
647 * for now, its ok not to send a delts since we are going to add support for
648 * multiple tclas soon and until then we won't send any addts requests with
649 * multiple tclas elements anyway.
650 * In case of addClassifier failure, we just let the addts timer run out
651 */
652 if (((addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
653 (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) &&
654 (addts.status == eSIR_MAC_SUCCESS_STATUS))
655 {
656 // add the classifier - this should always succeed
657 if (addts.numTclas > 1) // currently no support for multiple tclas elements
658 {
659 limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported\n"),
660 aid, addts.numTclas);
661 return;
662 }
663 else if (addts.numTclas == 1)
664 {
665 limLog(pMac, LOGW, "AddTs Response from STA %d: tsid %d, UP %d, OK!\n", aid,
666 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio);
667 }
668 }
669 limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d \n",
670 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio,
671 addts.status);
672
673 // deactivate the response timer
674 limDeactivateAndChangeTimer(pMac, eLIM_ADDTS_RSP_TIMER);
675
676 if (addts.status != eSIR_MAC_SUCCESS_STATUS)
677 {
678 limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d \n",
679 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio,
680 addts.status);
681 limSendSmeAddtsRsp(pMac, true, addts.status, psessionEntry, addts.tspec,
682 psessionEntry->smeSessionId, psessionEntry->transactionId);
683
684 // clear the addts flag
685 pMac->lim.gLimAddtsSent = false;
686
687 return;
688 }
689#ifdef FEATURE_WLAN_CCX
690 if (addts.tsmPresent)
691 {
692 limLog(pMac, LOGW, "TSM IE Present\n");
693 psessionEntry->ccxContext.tsm.tid = addts.tspec.tsinfo.traffic.userPrio;
694 vos_mem_copy(&psessionEntry->ccxContext.tsm.tsmInfo,
695 &addts.tsmIE,sizeof(tSirMacCCXTSMIE));
696 limActivateTSMStatsTimer(pMac, psessionEntry);
697 }
698#endif
699 /* Since AddTS response was successful, check for the PSB flag
700 * and directional flag inside the TS Info field.
701 * An AC is trigger enabled AC if the PSB subfield is set to 1
702 * in the uplink direction.
703 * An AC is delivery enabled AC if the PSB subfield is set to 1
704 * in the downlink direction.
705 * An AC is trigger and delivery enabled AC if the PSB subfield
706 * is set to 1 in the bi-direction field.
707 */
708 if (addts.tspec.tsinfo.traffic.psb == 1)
709 limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, SET_UAPSD_MASK);
710 else
711 limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, CLEAR_UAPSD_MASK);
712
713
714 /* ADDTS success, so AC is now admitted. We shall now use the default
715 * EDCA parameters as advertised by AP and send the updated EDCA params
716 * to HAL.
717 */
718 ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
719 if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK)
720 {
721 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
722 }
723 else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK)
724 {
725 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
726 }
727 else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)
728 {
729 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
730 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
731 }
732
733 limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
734
735 pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
736 if (pStaDs != NULL)
737 {
738 if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
739 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
740 else
741 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
742 }
743 else
744 limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
745
746
747 sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
748
749 //if schedule is not present then add TSPEC with svcInterval as 0.
750 if(!addts.schedulePresent)
751 addts.schedule.svcInterval = 0;
752 if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, &addts.tspec, addts.schedule.svcInterval, &tspecInfo))
753 {
754 PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed \n"));)
755 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec,
756 psessionEntry);
757 pMac->lim.gLimAddtsSent = false;
758 return; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status.
759 }
760 if((addts.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA) ||
761 ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC) &&
762 (psessionEntry->gLimEdcaParams[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm)))
763 {
764 retval = limSendHalMsgAddTs(pMac, pSta->staIndex, tspecInfo->idx, addts.tspec, psessionEntry->peSessionId);
765 if(eSIR_SUCCESS != retval)
766 {
767 limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecInfo->idx);
768
769 // Send DELTS action frame to AP
770 cfgLen = sizeof(tSirMacAddr);
771 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec,
772 psessionEntry);
773 limSendSmeAddtsRsp(pMac, true, retval, psessionEntry, addts.tspec,
774 psessionEntry->smeSessionId, psessionEntry->transactionId);
775 pMac->lim.gLimAddtsSent = false;
776 return;
777 }
778 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)\n"),
779 addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);)
780 }
781 else
782 {
783 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)\n"),
784 addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);)
785 PELOGW(limLog(pMac, LOGW, FL("no ACM: Bypass sending WDA_ADD_TS_REQ to HAL \n"));)
786 // Use the smesessionId and smetransactionId from the PE session context
787 limSendSmeAddtsRsp(pMac, true, eSIR_SME_SUCCESS, psessionEntry, addts.tspec,
788 psessionEntry->smeSessionId, psessionEntry->transactionId);
789 }
790
791 // clear the addts flag
792 pMac->lim.gLimAddtsSent = false;
793 return;
794}
795
796
797static void
798__limProcessDelTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
799{
800 tSirRetStatus retval;
801 tSirDeltsReqInfo delts;
802 tpSirMacMgmtHdr pHdr;
803 tpDphHashNode pSta;
804 tANI_U32 frameLen;
805 tANI_U16 aid;
806 tANI_U8 *pBody;
807 tANI_U8 tsStatus;
808 tSirMacTSInfo *tsinfo;
809 tANI_U8 tspecIdx;
810 tANI_U8 ac;
811 tpDphHashNode pStaDs = NULL;
812
813
814 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
815 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
816 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
817
818 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
819 if (pSta == NULL)
820 {
821 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring DelTs\n"));)
822 return;
823 }
824
825 // parse the delts request
826 retval = sirConvertDeltsReq2Struct(pMac, pBody, frameLen, &delts);
827 if (retval != eSIR_SUCCESS)
828 {
829 PELOGW(limLog(pMac, LOGW, FL("DelTs parsing failed (error %d)\n"), retval);)
830 return;
831 }
832
833 if (delts.wmeTspecPresent)
834 {
835 if ((!psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled))
836 {
837 PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: wme not enabled/capable\n"));)
838 return;
839 }
840 PELOG2(limLog(pMac, LOG2, FL("WME Delts received\n"));)
841 }
842 else if ((psessionEntry->limQosEnabled) && pSta->lleEnabled)
843 {
844 PELOG2(limLog(pMac, LOG2, FL("11e QoS Delts received\n"));)
845 }
846 else if ((psessionEntry->limWsmEnabled) && pSta->wsmEnabled)
847 {
848 PELOG2(limLog(pMac, LOG2, FL("WSM Delts received\n"));)
849 }
850 else
851 {
852 PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: qos not enabled/capable\n"));)
853 return;
854 }
855
856 tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;
857
858 // if no Admit Control, ignore the request
859 if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA))
860 {
861
862#if(defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
863 if ((psessionEntry->limSystemRole == eLIM_AP_ROLE &&
864 (! psessionEntry->gLimEdcaParamsBC[upToAc(tsinfo->traffic.userPrio)].aci.acm)) ||
865 (psessionEntry->limSystemRole != eLIM_AP_ROLE &&
866 (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm)))
867#else
868 if ((upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) || (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm))
869#endif
870 {
871 limLog(pMac, LOGW, FL("DelTs with UP %d has no AC - ignoring request\n"),
872 tsinfo->traffic.userPrio);
873 return;
874 }
875 }
876
877 // try to delete the TS
878 if (eSIR_SUCCESS != limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx))
879 {
880 PELOGW(limLog(pMac, LOGW, FL("Unable to Delete TS\n"));)
881 return;
882 }
883
884 else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
885 (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH))
886 {
887 //Edca only for now.
888 }
889 else
890 {
891 //send message to HAL to delete TS
Jeff Johnsone7245742012-09-05 17:12:55 -0700892 if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, pSta->staIndex, tspecIdx, delts, psessionEntry->peSessionId))
Jeff Johnson295189b2012-06-20 16:38:30 -0700893 {
894 limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request\n"),
895 tsinfo->traffic.userPrio);
896 return;
897 }
898 }
899
900 /* We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
901 * The AC for this TSPEC is no longer trigger enabled if this Tspec
902 * was set-up in uplink direction only.
903 * The AC for this TSPEC is no longer delivery enabled if this Tspec
904 * was set-up in downlink direction only.
905 * The AC for this TSPEC is no longer triiger enabled and delivery
906 * enabled if this Tspec was a bidirectional TSPEC.
907 */
908 limSetTspecUapsdMask(pMac, tsinfo, CLEAR_UAPSD_MASK);
909
910
911 /* We're deleting the TSPEC.
912 * The AC for this TSPEC is no longer admitted in uplink/downlink direction
913 * if this TSPEC was set-up in uplink/downlink direction only.
914 * The AC for this TSPEC is no longer admitted in both uplink and downlink
915 * directions if this TSPEC was a bi-directional TSPEC.
916 * If ACM is set for this AC and this AC is admitted only in downlink
917 * direction, PE needs to downgrade the EDCA parameter
918 * (for the AC for which TS is being deleted) to the
919 * next best AC for which ACM is not enabled, and send the
920 * updated values to HAL.
921 */
922 ac = upToAc(tsinfo->traffic.userPrio);
923
924 if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK)
925 {
926 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
927 }
928 else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK)
929 {
930 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
931 }
932 else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR)
933 {
934 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
935 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
936 }
937
938 limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
939
940 pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
941 if (pStaDs != NULL)
942 {
943 if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
944 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
945 else
946 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
947 }
948 else
949 limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
950
951 PELOG1(limLog(pMac, LOG1, FL("DeleteTS succeeded\n"));)
952 if((psessionEntry->limSystemRole != eLIM_AP_ROLE)&&(psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE))
953 limSendSmeDeltsInd(pMac, &delts, aid,psessionEntry);
954
955#ifdef FEATURE_WLAN_CCX
956 limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER);
957#endif
958
959}
960
961
962#ifdef ANI_SUPPORT_11H
963/**
964 * limProcessBasicMeasReq
965 *
966 *FUNCTION:
967 * This function is called by limProcessMeasurementRequestFrame()
968 * when it received a Basic measurement Request action frame.
969 * Station/BP receiving this should perform basic measurements
970 * and then send Basic Measurement Report. AP should not perform
971 * any measurements, and send report indicating refusal.
972 *
973 *LOGIC:
974 *
975 *ASSUMPTIONS:
976 *
977 *NOTE:
978 *
979 * @param pMac - Pointer to Global MAC structure
980 * @param pMeasReqFrame - A pointer to Basic Meas. Req structure
981 * @return None
982 */
983static void
984__limProcessBasicMeasReq(tpAniSirGlobal pMac,
985 tpSirMacMeasReqActionFrame pMeasReqFrame,
986 tSirMacAddr peerMacAddr)
987{
988 // TBD - Station shall perform basic measurements
989
990 if (limSendMeasReportFrame(pMac,
991 pMeasReqFrame,
992 peerMacAddr) != eSIR_SUCCESS)
993 {
994 PELOGE(limLog(pMac, LOGE, FL("fail to send Basic Meas report \n"));)
995 return;
996 }
997}
998
999
1000/**
1001 * limProcessCcaMeasReq
1002 *
1003 *FUNCTION:
1004 * This function is called by limProcessMeasurementRequestFrame()
1005 * when it received a CCA measurement Request action frame.
1006 * Station/BP receiving this should perform CCA measurements
1007 * and then send CCA Measurement Report. AP should not perform
1008 * any measurements, and send report indicating refusal.
1009 *
1010 *LOGIC:
1011 *
1012 *ASSUMPTIONS:
1013 *
1014 *NOTE:
1015 *
1016 * @param pMac - Pointer to Global MAC structure
1017 * @param pMeasReqFrame - A pointer to CCA Meas. Req structure
1018 * @return None
1019 */
1020static void
1021__limProcessCcaMeasReq(tpAniSirGlobal pMac,
1022 tpSirMacMeasReqActionFrame pMeasReqFrame,
1023 tSirMacAddr peerMacAddr)
1024{
1025 // TBD - Station shall perform cca measurements
1026
1027 if (limSendMeasReportFrame(pMac,
1028 pMeasReqFrame,
1029 peerMacAddr) != eSIR_SUCCESS)
1030 {
1031 PELOGE(limLog(pMac, LOGE, FL("fail to send CCA Meas report \n"));)
1032 return;
1033 }
1034}
1035
1036
1037/**
1038 * __limProcessRpiMeasReq
1039 *
1040 *FUNCTION:
1041 * This function is called by limProcessMeasurementRequestFrame()
1042 * when it received a RPI measurement Request action frame.
1043 * Station/BP/AP receiving this shall not perform any measurements,
1044 * and send report indicating refusal.
1045 *
1046 *LOGIC:
1047 *
1048 *ASSUMPTIONS:
1049 *
1050 *NOTE:
1051 *
1052 * @param pMac - Pointer to Global MAC structure
1053 * @param pMeasReqFrame - A pointer to RPI Meas. Req structure
1054 * @return None
1055 */
1056static void
1057__limProcessRpiMeasReq(tpAniSirGlobal pMac,
1058 tpSirMacMeasReqActionFrame pMeasReqFrame,
1059 tSirMacAddr peerMacAddr)
1060{
1061 if (limSendMeasReportFrame(pMac,
1062 pMeasReqFrame,
1063 peerMacAddr) != eSIR_SUCCESS)
1064 {
1065 PELOGE(limLog(pMac, LOGE, FL("fail to send RPI Meas report \n"));)
1066 return;
1067 }
1068}
1069
1070
1071/**
1072 * __limProcessMeasurementRequestFrame
1073 *
1074 *FUNCTION:
1075 *
1076 *LOGIC:
1077 *
1078 *ASSUMPTIONS:
1079 *
1080 *NOTE:
1081 *
1082 * @param pMac - Pointer to Global MAC structure
1083 * @param *pRxPacketInfo - A pointer to packet info structure
1084 * @return None
1085 */
1086
1087static void
1088__limProcessMeasurementRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
1089{
1090 tpSirMacMgmtHdr pHdr;
1091 tANI_U8 *pBody;
1092 tpSirMacMeasReqActionFrame pMeasReqFrame;
1093 tANI_U32 frameLen;
1094
1095 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1096 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1097 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1098
1099 if ( eHAL_STATUS_SUCCESS !=
1100 palAllocateMemory( pMac->hHdd, (void **)&pMeasReqFrame, sizeof( tSirMacMeasReqActionFrame ) ) )
1101 {
1102 limLog(pMac, LOGE,
1103 FL("limProcessMeasurementRequestFrame: palAllocateMemory failed \n"));
1104 return;
1105 }
1106
1107 if (sirConvertMeasReqFrame2Struct(pMac, pBody, pMeasReqFrame, frameLen) !=
1108 eSIR_SUCCESS)
1109 {
1110 PELOGW(limLog(pMac, LOGW, FL("Rcv invalid Measurement Request Action Frame \n"));)
1111 return;
1112 }
1113
1114
1115 switch(pMeasReqFrame->measReqIE.measType)
1116 {
1117 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
1118 __limProcessBasicMeasReq(pMac, pMeasReqFrame, pHdr->sa);
1119 break;
1120
1121 case SIR_MAC_CCA_MEASUREMENT_TYPE:
1122 __limProcessCcaMeasReq(pMac, pMeasReqFrame, pHdr->sa);
1123 break;
1124
1125 case SIR_MAC_RPI_MEASUREMENT_TYPE:
1126 __limProcessRpiMeasReq(pMac, pMeasReqFrame, pHdr->sa);
1127 break;
1128
1129 default:
1130 PELOG1(limLog(pMac, LOG1, FL("Unknown Measurement Type %d \n"),
1131 pMeasReqFrame->measReqIE.measType);)
1132 break;
1133 }
1134
1135} /*** end limProcessMeasurementRequestFrame ***/
1136
1137
1138/**
1139 * limProcessTpcRequestFrame
1140 *
1141 *FUNCTION:
1142 * This function is called upon receiving Tpc Request frame.
1143 *
1144 *NOTE:
1145 *
1146 * @param pMac - Pointer to Global MAC structure
1147 * @param *pRxPacketInfo - A pointer to packet info structure
1148 * @return None
1149 */
1150
1151static void
1152__limProcessTpcRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
1153{
1154 tpSirMacMgmtHdr pHdr;
1155 tANI_U8 *pBody;
1156 tpSirMacTpcReqActionFrame pTpcReqFrame;
1157 tANI_U32 frameLen;
1158
1159 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1160 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1161 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1162
1163 PELOG1(limLog(pMac, LOG1, FL("****LIM: Processing TPC Request from peer ****"));)
1164
1165 if ( eHAL_STATUS_SUCCESS !=
1166 palAllocateMemory( pMac->hHdd, (void **)&pTpcReqFrame, sizeof( tSirMacTpcReqActionFrame ) ) )
1167 {
1168 PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed \n"));)
1169 return;
1170 }
1171
1172 if (sirConvertTpcReqFrame2Struct(pMac, pBody, pTpcReqFrame, frameLen) !=
1173 eSIR_SUCCESS)
1174 {
1175 PELOGW(limLog(pMac, LOGW, FL("Rcv invalid TPC Req Action Frame \n"));)
1176 return;
1177 }
1178
1179 if (limSendTpcReportFrame(pMac,
1180 pTpcReqFrame,
1181 pHdr->sa) != eSIR_SUCCESS)
1182 {
1183 PELOGE(limLog(pMac, LOGE, FL("fail to send TPC Report Frame. \n"));)
1184 return;
1185 }
1186}
1187#endif
1188
1189
1190/**
1191 * \brief Validate an ADDBA Req from peer with respect
1192 * to our own BA configuration
1193 *
1194 * \sa __limValidateAddBAParameterSet
1195 *
1196 * \param pMac The global tpAniSirGlobal object
1197 *
1198 * \param baParameterSet The ADDBA Parameter Set.
1199 *
1200 * \param pDelBAFlag this parameter is NULL except for call from processAddBAReq
1201 * delBAFlag is set when entry already exists.
1202 *
1203 * \param reqType ADDBA Req v/s ADDBA Rsp
1204 * 1 - ADDBA Req
1205 * 0 - ADDBA Rsp
1206 *
1207 * \return eSIR_SUCCESS if setup completes successfully
1208 * eSIR_FAILURE is some problem is encountered
1209 */
1210
1211static tSirMacStatusCodes
1212__limValidateAddBAParameterSet( tpAniSirGlobal pMac,
1213 tpDphHashNode pSta,
1214 tDot11fFfAddBAParameterSet baParameterSet,
1215 tANI_U8 dialogueToken,
1216 tLimAddBaValidationReqType reqType ,
1217 tANI_U8* pDelBAFlag /*this parameter is NULL except for call from processAddBAReq*/)
1218{
1219 if(baParameterSet.tid >= STACFG_MAX_TC)
1220 {
1221 return eSIR_MAC_WME_INVALID_PARAMS_STATUS;
1222 }
1223
1224 //check if there is already a BA session setup with this STA/TID while processing AddBaReq
1225 if((true == pSta->tcCfg[baParameterSet.tid].fUseBARx) &&
1226 (LIM_ADDBA_REQ == reqType))
1227 {
1228 //There is already BA session setup for STA/TID.
1229 limLog( pMac, LOGW,
1230 FL( "AddBAReq rcvd when there is already a session for this StaId = %d, tid = %d\n " ),
1231 pSta->staIndex, baParameterSet.tid);
1232 limPrintMacAddr( pMac, pSta->staAddr, LOGW );
1233
1234 if(pDelBAFlag)
1235 *pDelBAFlag = true;
1236 }
1237 return eSIR_MAC_SUCCESS_STATUS;
1238}
1239
1240/**
1241 * \brief Validate a DELBA Ind from peer with respect
1242 * to our own BA configuration
1243 *
1244 * \sa __limValidateDelBAParameterSet
1245 *
1246 * \param pMac The global tpAniSirGlobal object
1247 *
1248 * \param baParameterSet The DELBA Parameter Set.
1249 *
1250 * \param pSta Runtime, STA-related configuration cached
1251 * in the HashNode object
1252 *
1253 * \return eSIR_SUCCESS if setup completes successfully
1254 * eSIR_FAILURE is some problem is encountered
1255 */
1256static tSirMacStatusCodes
1257__limValidateDelBAParameterSet( tpAniSirGlobal pMac,
1258 tDot11fFfDelBAParameterSet baParameterSet,
1259 tpDphHashNode pSta )
1260{
1261tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS;
1262
1263 // Validate if a BA is active for the requested TID
1264 if( pSta->tcCfg[baParameterSet.tid].fUseBATx ||
1265 pSta->tcCfg[baParameterSet.tid].fUseBARx )
1266 {
1267 statusCode = eSIR_MAC_SUCCESS_STATUS;
1268
1269 limLog( pMac, LOGW,
1270 FL("Valid DELBA Ind received. Time to send WDA_DELBA_IND to HAL...\n"));
1271 }
1272 else
1273 limLog( pMac, LOGW,
1274 FL("Received an INVALID DELBA Ind for TID %d...\n"),
1275 baParameterSet.tid );
1276
1277 return statusCode;
1278}
1279
1280/**
1281 * \brief Process an ADDBA REQ
1282 *
1283 * \sa limProcessAddBAReq
1284 *
1285 * \param pMac The global tpAniSirGlobal object
1286 *
1287 * \param pRxPacketInfo Handle to the Rx packet info from HDD
1288 *
1289 * \return none
1290 *
1291 */
1292static void
1293__limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1294{
1295 tDot11fAddBAReq frmAddBAReq;
1296 tpSirMacMgmtHdr pHdr;
1297 tpDphHashNode pSta;
1298 tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS;
1299 tANI_U16 aid;
1300 tANI_U32 frameLen, nStatus;
1301 tANI_U8 *pBody;
1302 tANI_U8 delBAFlag =0;
1303
1304 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1305 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1306 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1307
1308 // Unpack the received frame
1309 nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq );
1310 if( DOT11F_FAILED( nStatus ))
1311 {
1312 limLog( pMac, LOGE,
1313 FL("Failed to unpack and parse an ADDBA Request (0x%08x, %d bytes):\n"),
1314 nStatus,
1315 frameLen );
1316
1317 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1318
1319 // Without an unpacked request we cannot respond, so silently ignore the request
1320 return;
1321 }
1322 else if ( DOT11F_WARNED( nStatus ) )
1323 {
1324 limLog( pMac, LOGW,
1325 FL( "There were warnings while unpacking an ADDBA Request (0x%08x, %d bytes):\n"),
1326 nStatus,
1327 frameLen );
1328
1329 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1330 }
1331
1332 pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1333 if( pSta == NULL )
1334 {
1335 limLog( pMac, LOGE,
1336 FL( "STA context not found - ignoring ADDBA from \n" ));
1337 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1338
1339 // FIXME - Should we do this?
1340 status = eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS;
1341 goto returnAfterError;
1342 }
1343
1344 limLog( pMac, LOGW,
1345 FL( "ADDBA Req from STA with AID %d, tid = %d\n" ),
1346 aid, frmAddBAReq.AddBAParameterSet.tid);
1347
1348#ifdef WLAN_SOFTAP_VSTA_FEATURE
1349 // we can only do BA on "hard" STAs
1350 if (!(IS_HWSTA_IDX(pSta->staIndex)))
1351 {
1352 status = eSIR_MAC_REQ_DECLINED_STATUS;
1353 goto returnAfterError;
1354 }
1355#endif //WLAN_SOFTAP_VSTA_FEATURE
1356
1357
1358 // Now, validate the ADDBA Req
1359 if( eSIR_MAC_SUCCESS_STATUS !=
1360 (status = __limValidateAddBAParameterSet( pMac, pSta,
1361 frmAddBAReq.AddBAParameterSet,
1362 0, //dialogue token is don't care in request validation.
1363 LIM_ADDBA_REQ, &delBAFlag)))
1364 goto returnAfterError;
1365
1366 //BA already set, so we need to delete it before adding new one.
1367 if(delBAFlag)
1368 {
1369 if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac,
1370 pSta,
1371 (tANI_U8)frmAddBAReq.AddBAParameterSet.tid,
1372 eBA_RECIPIENT,psessionEntry))
1373 {
1374 status = eSIR_MAC_UNSPEC_FAILURE_STATUS;
1375 goto returnAfterError;
1376 }
1377 }
1378
1379 // Check if the ADD BA Declined configuration is Disabled
1380 if ((pMac->lim.gAddBA_Declined & ( 1 << frmAddBAReq.AddBAParameterSet.tid ) )) {
1381 limLog( pMac, LOGE, FL( "Declined the ADDBA Req for the TID %d \n" ),
1382 frmAddBAReq.AddBAParameterSet.tid);
1383 status = eSIR_MAC_REQ_DECLINED_STATUS;
1384 goto returnAfterError;
1385 }
1386
1387 //
1388 // Post WDA_ADDBA_REQ to HAL.
1389 // If HAL/HDD decide to allow this ADDBA Req session,
1390 // then this BA session is termed active
1391 //
1392
1393 // Change the Block Ack state of this STA to wait for
1394 // ADDBA Rsp from HAL
1395 LIM_SET_STA_BA_STATE(pSta, frmAddBAReq.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP);
1396
1397 if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac,
1398 pSta,
1399 (tANI_U8) frmAddBAReq.DialogToken.token,
1400 (tANI_U8) frmAddBAReq.AddBAParameterSet.tid,
1401 (tANI_U8) frmAddBAReq.AddBAParameterSet.policy,
1402 frmAddBAReq.AddBAParameterSet.bufferSize,
1403 frmAddBAReq.BATimeout.timeout,
1404 (tANI_U16) frmAddBAReq.BAStartingSequenceControl.ssn,
1405 eBA_RECIPIENT,psessionEntry))
1406 status = eSIR_MAC_UNSPEC_FAILURE_STATUS;
1407 else
1408 return;
1409
1410returnAfterError:
1411
1412 //
1413 // Package LIM_MLM_ADDBA_RSP to MLME, with proper
1414 // status code. MLME will then send an ADDBA RSP
1415 // over the air to the peer MAC entity
1416 //
1417 if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac,
1418 pHdr->sa,
1419 status,
1420 frmAddBAReq.DialogToken.token,
1421 (tANI_U8) frmAddBAReq.AddBAParameterSet.tid,
1422 (tANI_U8) frmAddBAReq.AddBAParameterSet.policy,
1423 frmAddBAReq.AddBAParameterSet.bufferSize,
1424 frmAddBAReq.BATimeout.timeout,psessionEntry))
1425 {
1426 limLog( pMac, LOGW,
1427 FL( "Failed to post LIM_MLM_ADDBA_RSP to " ));
1428 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1429 }
1430
1431}
1432
1433/**
1434 * \brief Process an ADDBA RSP
1435 *
1436 * \sa limProcessAddBARsp
1437 *
1438 * \param pMac The global tpAniSirGlobal object
1439 *
1440 * \param pRxPacketInfo Handle to the packet info structure from HDD
1441 *
1442 * \return none
1443 *
1444 */
1445static void
1446__limProcessAddBARsp( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1447{
1448tDot11fAddBARsp frmAddBARsp;
1449tpSirMacMgmtHdr pHdr;
1450tpDphHashNode pSta;
1451tSirMacReasonCodes reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
1452tANI_U16 aid;
1453tANI_U32 frameLen, nStatus;
1454tANI_U8 *pBody;
1455
1456 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1457 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1458 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1459
1460 pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1461 if( pSta == NULL )
1462 {
1463 limLog( pMac, LOGE,
1464 FL( "STA context not found - ignoring ADDBA from \n" ));
1465 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1466 return;
1467 }
1468
1469#ifdef WLAN_SOFTAP_VSTA_FEATURE
1470 // We can only do BA on "hard" STAs. We should not have issued an ADDBA
1471 // Request, so we should never be processing a ADDBA Response
1472 if (!(IS_HWSTA_IDX(pSta->staIndex)))
1473 {
1474 return;
1475 }
1476#endif //WLAN_SOFTAP_VSTA_FEATURE
1477
1478 // Unpack the received frame
1479 nStatus = dot11fUnpackAddBARsp( pMac, pBody, frameLen, &frmAddBARsp );
1480 if( DOT11F_FAILED( nStatus ))
1481 {
1482 limLog( pMac, LOGE,
1483 FL( "Failed to unpack and parse an ADDBA Response (0x%08x, %d bytes):\n"),
1484 nStatus,
1485 frameLen );
1486
1487 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1488 goto returnAfterError;
1489 }
1490 else if ( DOT11F_WARNED( nStatus ) )
1491 {
1492 limLog( pMac, LOGW,
1493 FL( "There were warnings while unpacking an ADDBA Response (0x%08x, %d bytes):\n"),
1494 nStatus,
1495 frameLen );
1496
1497 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1498 }
1499
1500 limLog( pMac, LOGW,
1501 FL( "ADDBA Rsp from STA with AID %d, tid = %d, status = %d\n" ),
1502 aid, frmAddBARsp.AddBAParameterSet.tid, frmAddBARsp.Status.status);
1503
1504 //if there is no matchin dialougue token then ignore the response.
1505
1506 if(eSIR_SUCCESS != limSearchAndDeleteDialogueToken(pMac, frmAddBARsp.DialogToken.token,
1507 pSta->assocId, frmAddBARsp.AddBAParameterSet.tid))
1508 {
1509 PELOGW(limLog(pMac, LOGW, FL("dialogueToken in received addBARsp did not match with outstanding requests\n"));)
1510 return;
1511 }
1512
1513 // Check first if the peer accepted the ADDBA Req
1514 if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status )
1515 {
1516 //if peer responded with buffer size 0 then we should pick the default.
1517 if(0 == frmAddBARsp.AddBAParameterSet.bufferSize)
1518 frmAddBARsp.AddBAParameterSet.bufferSize = BA_DEFAULT_TX_BUFFER_SIZE;
1519
1520 // Now, validate the ADDBA Rsp
1521 if( eSIR_MAC_SUCCESS_STATUS !=
1522 __limValidateAddBAParameterSet( pMac, pSta,
1523 frmAddBARsp.AddBAParameterSet,
1524 (tANI_U8)frmAddBARsp.DialogToken.token,
1525 LIM_ADDBA_RSP, NULL))
1526 goto returnAfterError;
1527 }
1528 else
1529 goto returnAfterError;
1530
1531 // Change STA state to wait for ADDBA Rsp from HAL
1532 LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP);
1533
1534 //
1535 // Post WDA_ADDBA_REQ to HAL.
1536 // If HAL/HDD decide to allow this ADDBA Rsp session,
1537 // then this BA session is termed active
1538 //
1539
1540 if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac,
1541 pSta,
1542 (tANI_U8) frmAddBARsp.DialogToken.token,
1543 (tANI_U8) frmAddBARsp.AddBAParameterSet.tid,
1544 (tANI_U8) frmAddBARsp.AddBAParameterSet.policy,
1545 frmAddBARsp.AddBAParameterSet.bufferSize,
1546 frmAddBARsp.BATimeout.timeout,
1547 0,
1548 eBA_INITIATOR,psessionEntry))
1549 reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
1550 else
1551 return;
1552
1553returnAfterError:
1554
1555 // TODO: Do we need to signal an error status to SME,
1556 // if status != eSIR_MAC_SUCCESS_STATUS
1557
1558 // Restore STA "BA" State
1559 LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_IDLE);
1560 //
1561 // Need to send a DELBA IND to peer, who
1562 // would have setup a BA session with this STA
1563 //
1564 if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status )
1565 {
1566 //
1567 // Package LIM_MLM_DELBA_REQ to MLME, with proper
1568 // status code. MLME will then send a DELBA IND
1569 // over the air to the peer MAC entity
1570 //
1571 if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac,
1572 pSta,
1573 eBA_INITIATOR,
1574 (tANI_U8) frmAddBARsp.AddBAParameterSet.tid,
1575 reasonCode, psessionEntry))
1576 {
1577 limLog( pMac, LOGW,
1578 FL( "Failed to post LIM_MLM_DELBA_REQ to " ));
1579 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1580 }
1581 }
1582}
1583
1584/**
1585 * \brief Process a DELBA Indication
1586 *
1587 * \sa limProcessDelBAInd
1588 *
1589 * \param pMac The global tpAniSirGlobal object
1590 *
1591 * \param pRxPacketInfo Handle to the Rx packet info from HDD
1592 *
1593 * \return none
1594 *
1595 */
1596static void
1597__limProcessDelBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1598{
1599tDot11fDelBAInd frmDelBAInd;
1600tpSirMacMgmtHdr pHdr;
1601tpDphHashNode pSta;
1602tANI_U16 aid;
1603tANI_U32 frameLen, nStatus;
1604tANI_U8 *pBody;
1605
1606 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1607 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1608 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1609
1610 pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1611 if( pSta == NULL )
1612 {
1613 limLog( pMac, LOGE, FL( "STA context not found - ignoring DELBA from \n"));
1614 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1615 return;
1616 }
1617
1618 limLog( pMac, LOG1, FL( "DELBA Ind from STA with AID %d\n" ), aid );
1619
1620 // Unpack the received frame
1621 nStatus = dot11fUnpackDelBAInd( pMac, pBody, frameLen, &frmDelBAInd );
1622 if( DOT11F_FAILED( nStatus ))
1623 {
1624 limLog( pMac, LOGE,
1625 FL( "Failed to unpack and parse a DELBA Indication (0x%08x, %d bytes):\n"),
1626 nStatus,
1627 frameLen );
1628
1629 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1630 return;
1631 }
1632 else if ( DOT11F_WARNED( nStatus ) )
1633 {
1634 limLog( pMac, LOGW,
1635 FL( "There were warnings while unpacking a DELBA Indication (0x%08x, %d bytes):\n"),
1636 nStatus,
1637 frameLen );
1638
1639 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1640 }
1641
1642 limLog( pMac, LOGW,
1643 FL( "Received DELBA for TID %d, Reason code %d\n" ),
1644 frmDelBAInd.DelBAParameterSet.tid,
1645 frmDelBAInd.Reason.code );
1646
1647 // Now, validate the DELBA Ind
1648 if( eSIR_MAC_SUCCESS_STATUS != __limValidateDelBAParameterSet( pMac,
1649 frmDelBAInd.DelBAParameterSet,
1650 pSta ))
1651 return;
1652
1653 //
1654 // Post WDA_DELBA_IND to HAL and delete the
1655 // existing BA session
1656 //
1657 // NOTE - IEEE 802.11-REVma-D8.0, Section 7.3.1.16
1658 // is kind of confusing...
1659 //
1660 if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac,
1661 pSta,
1662 (tANI_U8) frmDelBAInd.DelBAParameterSet.tid,
1663 (eBA_RECIPIENT == frmDelBAInd.DelBAParameterSet.initiator)?
1664 eBA_INITIATOR: eBA_RECIPIENT,psessionEntry))
1665 limLog( pMac, LOGE, FL( "Posting WDA_DELBA_IND to HAL failed \n"));
1666
1667 return;
1668
1669}
1670
1671static void
1672__limProcessSMPowerSaveUpdate(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry)
1673{
1674
1675#if 0
1676 tpSirMacMgmtHdr pHdr;
1677 tDot11fSMPowerSave frmSMPower;
1678 tSirMacHTMIMOPowerSaveState state;
1679 tpDphHashNode pSta;
1680 tANI_U16 aid;
1681 tANI_U32 frameLen, nStatus;
1682 tANI_U8 *pBody;
1683
1684 pHdr = SIR_MAC_BD_TO_MPDUHEADER( pBd );
1685 pBody = SIR_MAC_BD_TO_MPDUDATA( pBd );
1686 frameLen = SIR_MAC_BD_TO_PAYLOAD_LEN( pBd );
1687
1688 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1689 if( pSta == NULL ) {
1690 limLog( pMac, LOGE,FL( "STA context not found - ignoring UpdateSM PSave Mode from \n" ));
1691 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1692 return;
1693 }
1694
1695 /**Unpack the received frame */
1696 nStatus = dot11fUnpackSMPowerSave( pMac, pBody, frameLen, &frmSMPower);
1697
1698 if( DOT11F_FAILED( nStatus )) {
1699 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):\n"),
1700 nStatus, frameLen );
1701 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1702 return;
1703 }else if ( DOT11F_WARNED( nStatus ) ) {
1704 limLog(pMac, LOGW, FL( "There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):\n"),
1705 nStatus, frameLen );
1706 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1707 }
1708
1709 limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with PS_Enable:%d"
1710 "PS Mode: %d"), frmSMPower.SMPowerModeSet.PowerSave_En,
1711 frmSMPower.SMPowerModeSet.Mode);
1712
1713 /** Update in the DPH Table about the Update in the SM Power Save mode*/
1714 if (frmSMPower.SMPowerModeSet.PowerSave_En && frmSMPower.SMPowerModeSet.Mode)
1715 state = eSIR_HT_MIMO_PS_DYNAMIC;
1716 else if ((frmSMPower.SMPowerModeSet.PowerSave_En) && (frmSMPower.SMPowerModeSet.Mode ==0))
1717 state = eSIR_HT_MIMO_PS_STATIC;
1718 else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0) && (frmSMPower.SMPowerModeSet.Mode == 0))
1719 state = eSIR_HT_MIMO_PS_NO_LIMIT;
1720 else {
1721 PELOGW(limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with invalid mode"));)
1722 return;
1723 }
1724
1725 if (state == pSta->htMIMOPSState) {
1726 PELOGE(limLog(pMac, LOGE, FL("The PEER is already set in the same mode"));)
1727 return;
1728 }
1729
1730 /** Update in the HAL Station Table for the Update of the Protection Mode */
1731 pSta->htMIMOPSState = state;
1732 limPostSMStateUpdate(pMac,pSta->staIndex, pSta->htMIMOPSState);
1733
1734#endif
1735
1736}
1737
1738#if defined WLAN_FEATURE_VOWIFI
1739
1740static void
1741__limProcessRadioMeasureRequest( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
1742{
1743 tpSirMacMgmtHdr pHdr;
1744 tDot11fRadioMeasurementRequest frm;
1745 tANI_U32 frameLen, nStatus;
1746 tANI_U8 *pBody;
1747
1748 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1749 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1750 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1751
1752 if( psessionEntry == NULL )
1753 {
1754 return;
1755 }
1756
1757 /**Unpack the received frame */
1758 nStatus = dot11fUnpackRadioMeasurementRequest( pMac, pBody, frameLen, &frm );
1759
1760 if( DOT11F_FAILED( nStatus )) {
1761 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):\n"),
1762 nStatus, frameLen );
1763 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1764 return;
1765 }else if ( DOT11F_WARNED( nStatus ) ) {
1766 limLog(pMac, LOGW, FL( "There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):\n"),
1767 nStatus, frameLen );
1768 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1769 }
1770
1771 // Call rrm function to handle the request.
1772
1773 rrmProcessRadioMeasurementRequest( pMac, pHdr->sa, &frm, psessionEntry );
1774}
1775
1776static void
1777__limProcessLinkMeasurementReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
1778{
1779 tpSirMacMgmtHdr pHdr;
1780 tDot11fLinkMeasurementRequest frm;
1781 tANI_U32 frameLen, nStatus;
1782 tANI_U8 *pBody;
1783
1784 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1785 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1786 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1787
1788 if( psessionEntry == NULL )
1789 {
1790 return;
1791 }
1792
1793 /**Unpack the received frame */
1794 nStatus = dot11fUnpackLinkMeasurementRequest( pMac, pBody, frameLen, &frm );
1795
1796 if( DOT11F_FAILED( nStatus )) {
1797 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):\n"),
1798 nStatus, frameLen );
1799 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1800 return;
1801 }else if ( DOT11F_WARNED( nStatus ) ) {
1802 limLog(pMac, LOGW, FL( "There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):\n"),
1803 nStatus, frameLen );
1804 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1805 }
1806
1807 // Call rrm function to handle the request.
1808
1809 rrmProcessLinkMeasurementRequest( pMac, pRxPacketInfo, &frm, psessionEntry );
1810
1811}
1812
1813static void
1814__limProcessNeighborReport( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
1815{
1816 tpSirMacMgmtHdr pHdr;
1817 tDot11fNeighborReportResponse frm;
1818 tANI_U32 frameLen, nStatus;
1819 tANI_U8 *pBody;
1820
1821 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1822 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1823 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1824
1825 if( psessionEntry == NULL )
1826 {
1827 return;
1828 }
1829
1830 /**Unpack the received frame */
1831 nStatus = dot11fUnpackNeighborReportResponse( pMac, pBody, frameLen, &frm );
1832
1833 if( DOT11F_FAILED( nStatus )) {
1834 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):\n"),
1835 nStatus, frameLen );
1836 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1837 return;
1838 }else if ( DOT11F_WARNED( nStatus ) ) {
1839 limLog(pMac, LOGW, FL( "There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):\n"),
1840 nStatus, frameLen );
1841 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1842 }
1843
1844 //Call rrm function to handle the request.
1845 rrmProcessNeighborReportResponse( pMac, &frm, psessionEntry );
1846
1847}
1848
1849#endif
1850
1851#ifdef WLAN_FEATURE_11W
1852/**
1853 * limProcessActionFrame
1854 *
1855 *FUNCTION:
1856 * This function is called by limProcessActionFrame() upon
1857 * SA query request Action frame reception.
1858 *
1859 *LOGIC:
1860 *
1861 *ASSUMPTIONS:
1862 *
1863 *NOTE:
1864 *
1865 * @param pMac - Pointer to Global MAC structure
1866 * @param *pBd - A pointer to Buffer descriptor + associated PDUs
1867 * @return None
1868 */
1869static void __limProcessSAQueryRequestActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1870{
1871 tpSirMacMgmtHdr pHdr;
1872 tANI_U8 *pBody;
1873 tANI_U16 transId = 0;
1874
1875 /* Prima --- Below Macro not available in prima
1876 pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
1877 pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */
1878
1879 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1880 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1881
1882 /*Extract 11w trsansId from SA query request action frame
1883 In SA query response action frame we will send same transId
1884 In SA query request action frame:
1885 Category : 1 byte
1886 Action : 1 byte
1887 Transaction ID : 2 bbytes */
1888
1889 transId = pBody[2];
1890 transId = transId << 8;
1891 transId |= pBody[3];
1892
1893 //Send 11w SA query response action frame
1894 if (limSendSaQueryResponseFrame(pMac,
1895 transId,
1896 pHdr->sa,psessionEntry) != eSIR_SUCCESS)
1897 {
1898 PELOGE(limLog(pMac, LOGE, FL("fail to send SA query response action frame. \n"));)
1899 return;
1900 }
1901}
1902
1903#endif
1904
1905/**
1906 * limProcessActionFrame
1907 *
1908 *FUNCTION:
1909 * This function is called by limProcessMessageQueue() upon
1910 * Action frame reception.
1911 *
1912 *LOGIC:
1913 *
1914 *ASSUMPTIONS:
1915 *
1916 *NOTE:
1917 *
1918 * @param pMac - Pointer to Global MAC structure
1919 * @param *pRxPacketInfo - A pointer to packet info structure
1920 * @return None
1921 */
1922
1923void
1924limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1925{
1926 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1927 tpSirMacActionFrameHdr pActionHdr = (tpSirMacActionFrameHdr) pBody;
1928
1929
1930 switch (pActionHdr->category)
1931 {
1932 case SIR_MAC_ACTION_QOS_MGMT:
1933 if (psessionEntry->limQosEnabled)
1934 {
1935 switch (pActionHdr->actionID)
1936 {
1937 case SIR_MAC_QOS_ADD_TS_REQ:
1938 __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1939 break;
1940
1941 case SIR_MAC_QOS_ADD_TS_RSP:
1942 __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1943 break;
1944
1945 case SIR_MAC_QOS_DEL_TS_REQ:
1946 __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1947 break;
1948
1949 default:
1950 PELOGE(limLog(pMac, LOGE, FL("Qos action %d not handled\n"), pActionHdr->actionID);)
1951 break;
1952 }
1953 break ;
1954 }
1955
1956 break;
1957
1958 case SIR_MAC_ACTION_SPECTRUM_MGMT:
1959 switch (pActionHdr->actionID)
1960 {
1961#ifdef ANI_SUPPORT_11H
1962 case SIR_MAC_ACTION_MEASURE_REQUEST_ID:
1963 if(psessionEntry->lim11hEnable)
1964 {
1965 __limProcessMeasurementRequestFrame(pMac, pRxPacketInfo);
1966 }
1967 break;
1968
1969 case SIR_MAC_ACTION_TPC_REQUEST_ID:
1970 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
1971 (pessionEntry->limSystemRole == eLIM_AP_ROLE))
1972 {
1973 if(psessionEntry->lim11hEnable)
1974 {
1975 __limProcessTpcRequestFrame(pMac, pRxPacketInfo);
1976 }
1977 }
1978 break;
1979
1980#endif
1981 case SIR_MAC_ACTION_CHANNEL_SWITCH_ID:
1982 if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
1983 {
1984 __limProcessChannelSwitchActionFrame(pMac, pRxPacketInfo,psessionEntry);
1985 }
1986 break;
1987 default:
1988 PELOGE(limLog(pMac, LOGE, FL("Spectrum mgmt action id %d not handled\n"), pActionHdr->actionID);)
1989 break;
1990 }
1991 break;
1992
1993 case SIR_MAC_ACTION_WME:
1994 if (! psessionEntry->limWmeEnabled)
1995 {
1996 limLog(pMac, LOGW, FL("WME mode disabled - dropping action frame %d\n"),
1997 pActionHdr->actionID);
1998 break;
1999 }
2000 switch(pActionHdr->actionID)
2001 {
2002 case SIR_MAC_QOS_ADD_TS_REQ:
2003 __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2004 break;
2005
2006 case SIR_MAC_QOS_ADD_TS_RSP:
2007 __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2008 break;
2009
2010 case SIR_MAC_QOS_DEL_TS_REQ:
2011 __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2012 break;
2013
2014 default:
2015 PELOGE(limLog(pMac, LOGE, FL("WME action %d not handled\n"), pActionHdr->actionID);)
2016 break;
2017 }
2018 break;
2019
2020 case SIR_MAC_ACTION_BLKACK:
2021 // Determine the "type" of BA Action Frame
2022 switch(pActionHdr->actionID)
2023 {
2024 case SIR_MAC_BLKACK_ADD_REQ:
2025 __limProcessAddBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2026 break;
2027
2028 case SIR_MAC_BLKACK_ADD_RSP:
2029 __limProcessAddBARsp( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2030 break;
2031
2032 case SIR_MAC_BLKACK_DEL:
2033 __limProcessDelBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2034 break;
2035
2036 default:
2037 break;
2038 }
2039
2040 break;
2041 case SIR_MAC_ACTION_HT:
2042 /** Type of HT Action to be performed*/
2043 switch(pActionHdr->actionID) {
2044 case SIR_MAC_SM_POWER_SAVE:
2045 __limProcessSMPowerSaveUpdate(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
2046 break;
2047 default:
2048 PELOGE(limLog(pMac, LOGE, FL("Action ID %d not handled in HT Action category\n"), pActionHdr->actionID);)
2049 break;
2050 }
2051 break;
2052
2053#if defined WLAN_FEATURE_VOWIFI
2054 case SIR_MAC_ACTION_RRM:
2055 if( pMac->rrm.rrmPEContext.rrmEnable )
2056 {
2057 switch(pActionHdr->actionID) {
2058 case SIR_MAC_RRM_RADIO_MEASURE_REQ:
2059 __limProcessRadioMeasureRequest( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry );
2060 break;
2061 case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
2062 __limProcessLinkMeasurementReq( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry );
2063 break;
2064 case SIR_MAC_RRM_NEIGHBOR_RPT:
2065 __limProcessNeighborReport( pMac, (tANI_U8*) pRxPacketInfo, psessionEntry );
2066 break;
2067 default:
2068 PELOGE( limLog( pMac, LOGE, FL("Action ID %d not handled in RRM\n"), pActionHdr->actionID);)
2069 break;
2070
2071 }
2072 }
2073 else
2074 {
2075 // Else we will just ignore the RRM messages.
2076 PELOGE( limLog( pMac, LOGE, FL("RRM Action frame ignored as RRM is disabled in cfg\n"));)
2077 }
2078 break;
2079#endif
2080#if defined WLAN_FEATURE_P2P
2081 case SIR_MAC_ACTION_PUBLIC_USAGE:
2082 switch(pActionHdr->actionID) {
2083 case SIR_MAC_ACTION_VENDOR_SPECIFIC:
2084 {
2085 tpSirMacVendorSpecificPublicActionFrameHdr pPubAction = (tpSirMacVendorSpecificPublicActionFrameHdr) pActionHdr;
2086 tpSirMacMgmtHdr pHdr;
2087 tANI_U32 frameLen;
2088 tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
2089
2090 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
2091 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
2092
2093 //Check if it is a P2P public action frame.
2094 if( palEqualMemory( pMac->hHdd, pPubAction->Oui, P2POui, 4 ) )
2095 {
2096 /* Forward to the SME to HDD to wpa_supplicant */
2097 // type is ACTION
2098 limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
2099 (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
Jeff Johnsone7245742012-09-05 17:12:55 -07002100 WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 }
2102 else
2103 {
2104 limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x\n"),
2105 pPubAction->Oui[0], pPubAction->Oui[1], pPubAction->Oui[2], pPubAction->Oui[3] );
2106 }
2107 }
2108 break;
2109
2110 default:
2111 PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x \n"), pActionHdr->actionID);)
2112 break;
2113 }
2114 break;
2115#endif
2116
2117#ifdef WLAN_FEATURE_11W
2118 case SIR_MAC_ACTION_SA_QUERY:
2119 {
2120 /**11w SA query request action frame received**/
2121 __limProcessSAQueryRequestActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry );
2122 break;
2123 }
2124#endif
Mohit Khanna4a70d262012-09-11 16:30:12 -07002125#ifdef WLAN_FEATURE_11AC
2126 case SIR_MAC_ACTION_VHT:
2127 {
2128 if (psessionEntry->vhtCapability)
2129 {
2130 switch (pActionHdr->actionID)
2131 {
2132 case SIR_MAC_VHT_OPMODE_NOTIFICATION:
2133 __limProcessOperatingModeActionFrame(pMac,pRxPacketInfo,psessionEntry);
2134 break;
2135 default:
2136 break;
2137 }
2138 }
2139 }
2140#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002141 default:
2142 PELOGE(limLog(pMac, LOGE, FL("Action category %d not handled\n"), pActionHdr->category);)
2143 break;
2144 }
2145}
2146
2147#if defined WLAN_FEATURE_P2P
2148/**
2149 * limProcessActionFrameNoSession
2150 *
2151 *FUNCTION:
2152 * This function is called by limProcessMessageQueue() upon
2153 * Action frame reception and no session.
2154 * Currently only public action frames can be received from
2155 * a non-associated station.
2156 *
2157 *LOGIC:
2158 *
2159 *ASSUMPTIONS:
2160 *
2161 *NOTE:
2162 *
2163 * @param pMac - Pointer to Global MAC structure
2164 * @param *pBd - A pointer to Buffer descriptor + associated PDUs
2165 * @return None
2166 */
2167
2168void
2169limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd)
2170{
2171 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd);
2172 tpSirMacVendorSpecificPublicActionFrameHdr pActionHdr = (tpSirMacVendorSpecificPublicActionFrameHdr) pBody;
2173
Mohit Khanna23863762012-09-11 17:40:09 -07002174 limLog( pMac, LOG1, "Received a Action frame -- no session");
Jeff Johnson295189b2012-06-20 16:38:30 -07002175
2176 switch ( pActionHdr->category )
2177 {
2178 case SIR_MAC_ACTION_PUBLIC_USAGE:
2179 switch(pActionHdr->actionID) {
2180 case SIR_MAC_ACTION_VENDOR_SPECIFIC:
2181 {
2182 tpSirMacMgmtHdr pHdr;
2183 tANI_U32 frameLen;
2184 tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
2185
2186 pHdr = WDA_GET_RX_MAC_HEADER(pBd);
2187 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
2188
2189 //Check if it is a P2P public action frame.
2190 if( palEqualMemory( pMac->hHdd, pActionHdr->Oui, P2POui, 4 ) )
2191 {
2192 /* Forward to the SME to HDD to wpa_supplicant */
2193 // type is ACTION
2194 limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
2195 (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
Jeff Johnsone7245742012-09-05 17:12:55 -07002196 WDA_GET_RX_CH( pBd ), NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 }
2198 else
2199 {
2200 limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x\n"),
2201 pActionHdr->Oui[0], pActionHdr->Oui[1], pActionHdr->Oui[2], pActionHdr->Oui[3] );
2202 }
2203 }
2204 break;
2205 default:
2206 PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x \n"), pActionHdr->actionID);)
2207 break;
2208 }
2209 break;
2210 default:
Mohit Khanna23863762012-09-11 17:40:09 -07002211 PELOGE(limLog(pMac, LOG1, FL("Unhandled action frame without session -- %x \n"), pActionHdr->category);)
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 break;
2213
2214 }
2215}
2216#endif