blob: 73d3729504a2a61fbd70add4ed3adc3a0a6222c0 [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
350static void
351__limProcessAddTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
352{
353#if (WNI_POLARIS_FW_PRODUCT == AP)
354
355 tSirAddtsReqInfo addts;
356 tSirRetStatus retval;
357 tpSirMacMgmtHdr pHdr;
358 tSirMacScheduleIE schedule;
359 tpDphHashNode pSta;
360 tANI_U16 status;
361 tANI_U16 aid;
362 tANI_U32 frameLen;
363 tANI_U8 *pBody;
364 tANI_U8 tspecIdx = 0; //index in the sch tspec table.
365
366 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
367 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
368 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
369
370
371 if ((psessionEntry->limSystemRole != eLIM_AP_ROLE)||(psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE))
372 {
373 PELOGW(limLog(pMac, LOGW, FL("AddTs request at non-AP: ignoring\n"));)
374 return;
375 }
376
377 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
378 if (pSta == NULL)
379 {
380 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTs\n"));)
381 return;
382 }
383
384 PELOGW(limLog(pMac, LOGW, "AddTs Request from STA %d\n", aid);)
385 retval = sirConvertAddtsReq2Struct(pMac, pBody, frameLen, &addts);
386 if (retval != eSIR_SUCCESS)
387 {
388 PELOGW(limLog(pMac, LOGW, FL("AddTs parsing failed (error %d)\n"), retval);)
389 return;
390 }
391
392 status = eSIR_MAC_SUCCESS_STATUS;
393
394
395 if (addts.wmeTspecPresent)
396 {
397 if ((! psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled))
398 {
399 PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: wme not enabled/capable\n"));)
400 status = eSIR_MAC_WME_REFUSED_STATUS;
401 }
402 else
403 {
404 PELOG2(limLog(pMac, LOG2, FL("WME Addts received\n"));)
405 }
406 }
407 else if (addts.wsmTspecPresent)
408 {
409 if ((! psessionEntry->limWsmEnabled) || (! pSta->wsmEnabled))
410 {
411 PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: wsm not enabled/capable\n"));)
412 status = eSIR_MAC_REQ_DECLINED_STATUS;
413 }
414 else
415 {
416 PELOG2(limLog(pMac, LOG2, FL("WSM Addts received\n"));)
417 }
418 }
419 else if ((! psessionEntry->limQosEnabled) || (! pSta->lleEnabled))
420 {
421 PELOGW(limLog(pMac, LOGW, FL("Ignoring addts request: qos not enabled/capable\n"));)
422 status = eSIR_MAC_REQ_DECLINED_STATUS;
423 }
424 else
425 {
426 PELOG2(limLog(pMac, LOG2, FL("11e QoS Addts received\n"));)
427 }
428
429 // for edca, if no Admit Control, ignore the request
430 if ((status == eSIR_MAC_SUCCESS_STATUS) &&
431 (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) &&
432 (! psessionEntry->gLimEdcaParamsBC[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm))
433 {
434 limLog(pMac, LOGW, FL("AddTs with UP %d has no ACM - ignoring request\n"),
435 addts.tspec.tsinfo.traffic.userPrio);
436 status = (addts.wmeTspecPresent) ?
437 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
438 }
439
440 if (status != eSIR_MAC_SUCCESS_STATUS)
441 {
442 limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, NULL,psessionEntry);
443 return;
444 }
445
446 // try to admit the STA and send the appropriate response
447 retval = limAdmitControlAddTS(pMac, &pSta->staAddr[0], &addts, NULL, pSta->assocId, true, &schedule, &tspecIdx, psessionEntry);
448 if (retval != eSIR_SUCCESS)
449 {
450 PELOGW(limLog(pMac, LOGW, FL("Unable to admit TS\n"));)
451 status = (addts.wmeTspecPresent) ?
452 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
453 }
454 else if (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)
455 {
456 if(eSIR_SUCCESS != limSendHalMsgAddTs(pMac, pSta->staIndex, tspecIdx, addts.tspec, psessionEntry->peSessionId))
457 {
458 limLog(pMac, LOGW, FL("AddTs with UP %d failed in limSendHalMsgAddTs - ignoring request\n"),
459 addts.tspec.tsinfo.traffic.userPrio);
460 status = (addts.wmeTspecPresent) ?
461 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
462
463 limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecIdx);
464 }
465 if (status != eSIR_MAC_SUCCESS_STATUS)
466 {
467 limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, NULL,psessionEntry);
468 return;
469 }
470 }
471#if 0 //only EDCA is supported now.
472 else if (addts.numTclas > 1)
473 {
474 limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported\n"),
475 aid, addts.numTclas);
476 status = (addts.wmeTspecPresent) ?
477 eSIR_MAC_WME_REFUSED_STATUS : eSIR_MAC_UNSPEC_FAILURE_STATUS;
478 }
479 else if (addts.numTclas == 1)
480 {
481 limLog(pMac, LOGW, "AddTs Request from STA %d: tsid %d, UP %d, OK!\n", aid,
482 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio);
483 status = eSIR_MAC_SUCCESS_STATUS;
484 }
485#endif
486
487 limLog(pMac, LOGW, "AddTs Request from STA %d: Sending AddTs Response with status %d\n",
488 aid, status);
489
490 limSendAddtsRspActionFrame(pMac, pHdr->sa, status, &addts, &schedule,psessionEntry);
491#endif
492}
493
494
495static void
496__limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
497{
498 tSirAddtsRspInfo addts;
499 tSirRetStatus retval;
500 tpSirMacMgmtHdr pHdr;
501 tpDphHashNode pSta;
502 tANI_U16 aid;
503 tANI_U32 frameLen;
504 tANI_U8 *pBody;
505 tpLimTspecInfo tspecInfo;
506 tANI_U8 ac;
507 tpDphHashNode pStaDs = NULL;
508 tANI_U8 rspReqd = 1;
509 tANI_U32 cfgLen;
510 tSirMacAddr peerMacAddr;
511
512
513 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
514 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
515 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
516
517
518 PELOGW(limLog(pMac, LOGW, "Recv AddTs Response\n");)
519 if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))
520 {
521 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp recvd at AP: ignoring\n"));)
522 return;
523 }
524
525 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
526 if (pSta == NULL)
527 {
528 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp\n"));)
529 return;
530 }
531
532 retval = sirConvertAddtsRsp2Struct(pMac, pBody, frameLen, &addts);
533 if (retval != eSIR_SUCCESS)
534 {
535 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp parsing failed (error %d)\n"), retval);)
536 return;
537 }
538
539 // don't have to check for qos/wme capabilities since we wouldn't have this
540 // flag set otherwise
541 if (! pMac->lim.gLimAddtsSent)
542 {
543 // we never sent an addts request!
544 PELOGW(limLog(pMac, LOGW, "Recvd AddTsRsp but no request was ever sent - ignoring\n");)
545 return;
546 }
547
548 if (pMac->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken)
549 {
550 limLog(pMac, LOGW, "AddTsRsp: token mismatch (got %d, exp %d) - ignoring\n",
551 addts.dialogToken, pMac->lim.gLimAddtsReq.req.dialogToken);
552 return;
553 }
554
555 /*
556 * for successful addts reponse, try to add the classifier.
557 * if this fails for any reason, we should send a delts request to the ap
558 * for now, its ok not to send a delts since we are going to add support for
559 * multiple tclas soon and until then we won't send any addts requests with
560 * multiple tclas elements anyway.
561 * In case of addClassifier failure, we just let the addts timer run out
562 */
563 if (((addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
564 (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) &&
565 (addts.status == eSIR_MAC_SUCCESS_STATUS))
566 {
567 // add the classifier - this should always succeed
568 if (addts.numTclas > 1) // currently no support for multiple tclas elements
569 {
570 limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported\n"),
571 aid, addts.numTclas);
572 return;
573 }
574 else if (addts.numTclas == 1)
575 {
576 limLog(pMac, LOGW, "AddTs Response from STA %d: tsid %d, UP %d, OK!\n", aid,
577 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio);
578 }
579 }
580 limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d \n",
581 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio,
582 addts.status);
583
584 // deactivate the response timer
585 limDeactivateAndChangeTimer(pMac, eLIM_ADDTS_RSP_TIMER);
586
587 if (addts.status != eSIR_MAC_SUCCESS_STATUS)
588 {
589 limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d \n",
590 addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio,
591 addts.status);
592 limSendSmeAddtsRsp(pMac, true, addts.status, psessionEntry, addts.tspec,
593 psessionEntry->smeSessionId, psessionEntry->transactionId);
594
595 // clear the addts flag
596 pMac->lim.gLimAddtsSent = false;
597
598 return;
599 }
600#ifdef FEATURE_WLAN_CCX
601 if (addts.tsmPresent)
602 {
603 limLog(pMac, LOGW, "TSM IE Present\n");
604 psessionEntry->ccxContext.tsm.tid = addts.tspec.tsinfo.traffic.userPrio;
605 vos_mem_copy(&psessionEntry->ccxContext.tsm.tsmInfo,
606 &addts.tsmIE,sizeof(tSirMacCCXTSMIE));
607 limActivateTSMStatsTimer(pMac, psessionEntry);
608 }
609#endif
610 /* Since AddTS response was successful, check for the PSB flag
611 * and directional flag inside the TS Info field.
612 * An AC is trigger enabled AC if the PSB subfield is set to 1
613 * in the uplink direction.
614 * An AC is delivery enabled AC if the PSB subfield is set to 1
615 * in the downlink direction.
616 * An AC is trigger and delivery enabled AC if the PSB subfield
617 * is set to 1 in the bi-direction field.
618 */
619 if (addts.tspec.tsinfo.traffic.psb == 1)
620 limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, SET_UAPSD_MASK);
621 else
622 limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, CLEAR_UAPSD_MASK);
623
624
625 /* ADDTS success, so AC is now admitted. We shall now use the default
626 * EDCA parameters as advertised by AP and send the updated EDCA params
627 * to HAL.
628 */
629 ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
630 if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK)
631 {
632 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
633 }
634 else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK)
635 {
636 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
637 }
638 else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)
639 {
640 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac);
641 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac);
642 }
643
644 limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
645
646 pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
647 if (pStaDs != NULL)
648 {
649 if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
650 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
651 else
652 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
653 }
654 else
655 limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
656
657
658 sirCopyMacAddr(peerMacAddr,psessionEntry->bssId);
659
660 //if schedule is not present then add TSPEC with svcInterval as 0.
661 if(!addts.schedulePresent)
662 addts.schedule.svcInterval = 0;
663 if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, &addts.tspec, addts.schedule.svcInterval, &tspecInfo))
664 {
665 PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed \n"));)
666 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec,
667 psessionEntry);
668 pMac->lim.gLimAddtsSent = false;
669 return; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status.
670 }
671 if((addts.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA) ||
672 ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC) &&
673 (psessionEntry->gLimEdcaParams[upToAc(addts.tspec.tsinfo.traffic.userPrio)].aci.acm)))
674 {
675 retval = limSendHalMsgAddTs(pMac, pSta->staIndex, tspecInfo->idx, addts.tspec, psessionEntry->peSessionId);
676 if(eSIR_SUCCESS != retval)
677 {
678 limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecInfo->idx);
679
680 // Send DELTS action frame to AP
681 cfgLen = sizeof(tSirMacAddr);
682 limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec,
683 psessionEntry);
684 limSendSmeAddtsRsp(pMac, true, retval, psessionEntry, addts.tspec,
685 psessionEntry->smeSessionId, psessionEntry->transactionId);
686 pMac->lim.gLimAddtsSent = false;
687 return;
688 }
689 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)\n"),
690 addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);)
691 }
692 else
693 {
694 PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)\n"),
695 addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);)
696 PELOGW(limLog(pMac, LOGW, FL("no ACM: Bypass sending WDA_ADD_TS_REQ to HAL \n"));)
697 // Use the smesessionId and smetransactionId from the PE session context
698 limSendSmeAddtsRsp(pMac, true, eSIR_SME_SUCCESS, psessionEntry, addts.tspec,
699 psessionEntry->smeSessionId, psessionEntry->transactionId);
700 }
701
702 // clear the addts flag
703 pMac->lim.gLimAddtsSent = false;
704 return;
705}
706
707
708static void
709__limProcessDelTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
710{
711 tSirRetStatus retval;
712 tSirDeltsReqInfo delts;
713 tpSirMacMgmtHdr pHdr;
714 tpDphHashNode pSta;
715 tANI_U32 frameLen;
716 tANI_U16 aid;
717 tANI_U8 *pBody;
718 tANI_U8 tsStatus;
719 tSirMacTSInfo *tsinfo;
720 tANI_U8 tspecIdx;
721 tANI_U8 ac;
722 tpDphHashNode pStaDs = NULL;
723
724
725 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
726 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
727 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
728
729 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
730 if (pSta == NULL)
731 {
732 PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring DelTs\n"));)
733 return;
734 }
735
736 // parse the delts request
737 retval = sirConvertDeltsReq2Struct(pMac, pBody, frameLen, &delts);
738 if (retval != eSIR_SUCCESS)
739 {
740 PELOGW(limLog(pMac, LOGW, FL("DelTs parsing failed (error %d)\n"), retval);)
741 return;
742 }
743
744 if (delts.wmeTspecPresent)
745 {
746 if ((!psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled))
747 {
748 PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: wme not enabled/capable\n"));)
749 return;
750 }
751 PELOG2(limLog(pMac, LOG2, FL("WME Delts received\n"));)
752 }
753 else if ((psessionEntry->limQosEnabled) && pSta->lleEnabled)
754 {
755 PELOG2(limLog(pMac, LOG2, FL("11e QoS Delts received\n"));)
756 }
757 else if ((psessionEntry->limWsmEnabled) && pSta->wsmEnabled)
758 {
759 PELOG2(limLog(pMac, LOG2, FL("WSM Delts received\n"));)
760 }
761 else
762 {
763 PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: qos not enabled/capable\n"));)
764 return;
765 }
766
767 tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;
768
769 // if no Admit Control, ignore the request
770 if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA))
771 {
772
773#if(defined(ANI_PRODUCT_TYPE_AP) || defined(ANI_PRODUCT_TYPE_AP_SDK))
774 if ((psessionEntry->limSystemRole == eLIM_AP_ROLE &&
775 (! psessionEntry->gLimEdcaParamsBC[upToAc(tsinfo->traffic.userPrio)].aci.acm)) ||
776 (psessionEntry->limSystemRole != eLIM_AP_ROLE &&
777 (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm)))
778#else
779 if ((upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) || (! psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm))
780#endif
781 {
782 limLog(pMac, LOGW, FL("DelTs with UP %d has no AC - ignoring request\n"),
783 tsinfo->traffic.userPrio);
784 return;
785 }
786 }
787
788 // try to delete the TS
789 if (eSIR_SUCCESS != limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx))
790 {
791 PELOGW(limLog(pMac, LOGW, FL("Unable to Delete TS\n"));)
792 return;
793 }
794
795 else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) ||
796 (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH))
797 {
798 //Edca only for now.
799 }
800 else
801 {
802 //send message to HAL to delete TS
Jeff Johnsone7245742012-09-05 17:12:55 -0700803 if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, pSta->staIndex, tspecIdx, delts, psessionEntry->peSessionId))
Jeff Johnson295189b2012-06-20 16:38:30 -0700804 {
805 limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request\n"),
806 tsinfo->traffic.userPrio);
807 return;
808 }
809 }
810
811 /* We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
812 * The AC for this TSPEC is no longer trigger enabled if this Tspec
813 * was set-up in uplink direction only.
814 * The AC for this TSPEC is no longer delivery enabled if this Tspec
815 * was set-up in downlink direction only.
816 * The AC for this TSPEC is no longer triiger enabled and delivery
817 * enabled if this Tspec was a bidirectional TSPEC.
818 */
819 limSetTspecUapsdMask(pMac, tsinfo, CLEAR_UAPSD_MASK);
820
821
822 /* We're deleting the TSPEC.
823 * The AC for this TSPEC is no longer admitted in uplink/downlink direction
824 * if this TSPEC was set-up in uplink/downlink direction only.
825 * The AC for this TSPEC is no longer admitted in both uplink and downlink
826 * directions if this TSPEC was a bi-directional TSPEC.
827 * If ACM is set for this AC and this AC is admitted only in downlink
828 * direction, PE needs to downgrade the EDCA parameter
829 * (for the AC for which TS is being deleted) to the
830 * next best AC for which ACM is not enabled, and send the
831 * updated values to HAL.
832 */
833 ac = upToAc(tsinfo->traffic.userPrio);
834
835 if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK)
836 {
837 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
838 }
839 else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK)
840 {
841 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
842 }
843 else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR)
844 {
845 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac);
846 pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac);
847 }
848
849 limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry);
850
851 pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable);
852 if (pStaDs != NULL)
853 {
854 if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE)
855 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE);
856 else
857 limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE);
858 }
859 else
860 limLog(pMac, LOGE, FL("Self entry missing in Hash Table \n"));
861
862 PELOG1(limLog(pMac, LOG1, FL("DeleteTS succeeded\n"));)
863 if((psessionEntry->limSystemRole != eLIM_AP_ROLE)&&(psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE))
864 limSendSmeDeltsInd(pMac, &delts, aid,psessionEntry);
865
866#ifdef FEATURE_WLAN_CCX
867 limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER);
868#endif
869
870}
871
872
873#ifdef ANI_SUPPORT_11H
874/**
875 * limProcessBasicMeasReq
876 *
877 *FUNCTION:
878 * This function is called by limProcessMeasurementRequestFrame()
879 * when it received a Basic measurement Request action frame.
880 * Station/BP receiving this should perform basic measurements
881 * and then send Basic Measurement Report. AP should not perform
882 * any measurements, and send report indicating refusal.
883 *
884 *LOGIC:
885 *
886 *ASSUMPTIONS:
887 *
888 *NOTE:
889 *
890 * @param pMac - Pointer to Global MAC structure
891 * @param pMeasReqFrame - A pointer to Basic Meas. Req structure
892 * @return None
893 */
894static void
895__limProcessBasicMeasReq(tpAniSirGlobal pMac,
896 tpSirMacMeasReqActionFrame pMeasReqFrame,
897 tSirMacAddr peerMacAddr)
898{
899 // TBD - Station shall perform basic measurements
900
901 if (limSendMeasReportFrame(pMac,
902 pMeasReqFrame,
903 peerMacAddr) != eSIR_SUCCESS)
904 {
905 PELOGE(limLog(pMac, LOGE, FL("fail to send Basic Meas report \n"));)
906 return;
907 }
908}
909
910
911/**
912 * limProcessCcaMeasReq
913 *
914 *FUNCTION:
915 * This function is called by limProcessMeasurementRequestFrame()
916 * when it received a CCA measurement Request action frame.
917 * Station/BP receiving this should perform CCA measurements
918 * and then send CCA Measurement Report. AP should not perform
919 * any measurements, and send report indicating refusal.
920 *
921 *LOGIC:
922 *
923 *ASSUMPTIONS:
924 *
925 *NOTE:
926 *
927 * @param pMac - Pointer to Global MAC structure
928 * @param pMeasReqFrame - A pointer to CCA Meas. Req structure
929 * @return None
930 */
931static void
932__limProcessCcaMeasReq(tpAniSirGlobal pMac,
933 tpSirMacMeasReqActionFrame pMeasReqFrame,
934 tSirMacAddr peerMacAddr)
935{
936 // TBD - Station shall perform cca measurements
937
938 if (limSendMeasReportFrame(pMac,
939 pMeasReqFrame,
940 peerMacAddr) != eSIR_SUCCESS)
941 {
942 PELOGE(limLog(pMac, LOGE, FL("fail to send CCA Meas report \n"));)
943 return;
944 }
945}
946
947
948/**
949 * __limProcessRpiMeasReq
950 *
951 *FUNCTION:
952 * This function is called by limProcessMeasurementRequestFrame()
953 * when it received a RPI measurement Request action frame.
954 * Station/BP/AP receiving this shall not perform any measurements,
955 * and send report indicating refusal.
956 *
957 *LOGIC:
958 *
959 *ASSUMPTIONS:
960 *
961 *NOTE:
962 *
963 * @param pMac - Pointer to Global MAC structure
964 * @param pMeasReqFrame - A pointer to RPI Meas. Req structure
965 * @return None
966 */
967static void
968__limProcessRpiMeasReq(tpAniSirGlobal pMac,
969 tpSirMacMeasReqActionFrame pMeasReqFrame,
970 tSirMacAddr peerMacAddr)
971{
972 if (limSendMeasReportFrame(pMac,
973 pMeasReqFrame,
974 peerMacAddr) != eSIR_SUCCESS)
975 {
976 PELOGE(limLog(pMac, LOGE, FL("fail to send RPI Meas report \n"));)
977 return;
978 }
979}
980
981
982/**
983 * __limProcessMeasurementRequestFrame
984 *
985 *FUNCTION:
986 *
987 *LOGIC:
988 *
989 *ASSUMPTIONS:
990 *
991 *NOTE:
992 *
993 * @param pMac - Pointer to Global MAC structure
994 * @param *pRxPacketInfo - A pointer to packet info structure
995 * @return None
996 */
997
998static void
999__limProcessMeasurementRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
1000{
1001 tpSirMacMgmtHdr pHdr;
1002 tANI_U8 *pBody;
1003 tpSirMacMeasReqActionFrame pMeasReqFrame;
1004 tANI_U32 frameLen;
1005
1006 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1007 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1008 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1009
1010 if ( eHAL_STATUS_SUCCESS !=
1011 palAllocateMemory( pMac->hHdd, (void **)&pMeasReqFrame, sizeof( tSirMacMeasReqActionFrame ) ) )
1012 {
1013 limLog(pMac, LOGE,
1014 FL("limProcessMeasurementRequestFrame: palAllocateMemory failed \n"));
1015 return;
1016 }
1017
1018 if (sirConvertMeasReqFrame2Struct(pMac, pBody, pMeasReqFrame, frameLen) !=
1019 eSIR_SUCCESS)
1020 {
1021 PELOGW(limLog(pMac, LOGW, FL("Rcv invalid Measurement Request Action Frame \n"));)
1022 return;
1023 }
1024
1025
1026 switch(pMeasReqFrame->measReqIE.measType)
1027 {
1028 case SIR_MAC_BASIC_MEASUREMENT_TYPE:
1029 __limProcessBasicMeasReq(pMac, pMeasReqFrame, pHdr->sa);
1030 break;
1031
1032 case SIR_MAC_CCA_MEASUREMENT_TYPE:
1033 __limProcessCcaMeasReq(pMac, pMeasReqFrame, pHdr->sa);
1034 break;
1035
1036 case SIR_MAC_RPI_MEASUREMENT_TYPE:
1037 __limProcessRpiMeasReq(pMac, pMeasReqFrame, pHdr->sa);
1038 break;
1039
1040 default:
1041 PELOG1(limLog(pMac, LOG1, FL("Unknown Measurement Type %d \n"),
1042 pMeasReqFrame->measReqIE.measType);)
1043 break;
1044 }
1045
1046} /*** end limProcessMeasurementRequestFrame ***/
1047
1048
1049/**
1050 * limProcessTpcRequestFrame
1051 *
1052 *FUNCTION:
1053 * This function is called upon receiving Tpc Request frame.
1054 *
1055 *NOTE:
1056 *
1057 * @param pMac - Pointer to Global MAC structure
1058 * @param *pRxPacketInfo - A pointer to packet info structure
1059 * @return None
1060 */
1061
1062static void
1063__limProcessTpcRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo)
1064{
1065 tpSirMacMgmtHdr pHdr;
1066 tANI_U8 *pBody;
1067 tpSirMacTpcReqActionFrame pTpcReqFrame;
1068 tANI_U32 frameLen;
1069
1070 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1071 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1072 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
1073
1074 PELOG1(limLog(pMac, LOG1, FL("****LIM: Processing TPC Request from peer ****"));)
1075
1076 if ( eHAL_STATUS_SUCCESS !=
1077 palAllocateMemory( pMac->hHdd, (void **)&pTpcReqFrame, sizeof( tSirMacTpcReqActionFrame ) ) )
1078 {
1079 PELOGE(limLog(pMac, LOGE, FL("palAllocateMemory failed \n"));)
1080 return;
1081 }
1082
1083 if (sirConvertTpcReqFrame2Struct(pMac, pBody, pTpcReqFrame, frameLen) !=
1084 eSIR_SUCCESS)
1085 {
1086 PELOGW(limLog(pMac, LOGW, FL("Rcv invalid TPC Req Action Frame \n"));)
1087 return;
1088 }
1089
1090 if (limSendTpcReportFrame(pMac,
1091 pTpcReqFrame,
1092 pHdr->sa) != eSIR_SUCCESS)
1093 {
1094 PELOGE(limLog(pMac, LOGE, FL("fail to send TPC Report Frame. \n"));)
1095 return;
1096 }
1097}
1098#endif
1099
1100
1101/**
1102 * \brief Validate an ADDBA Req from peer with respect
1103 * to our own BA configuration
1104 *
1105 * \sa __limValidateAddBAParameterSet
1106 *
1107 * \param pMac The global tpAniSirGlobal object
1108 *
1109 * \param baParameterSet The ADDBA Parameter Set.
1110 *
1111 * \param pDelBAFlag this parameter is NULL except for call from processAddBAReq
1112 * delBAFlag is set when entry already exists.
1113 *
1114 * \param reqType ADDBA Req v/s ADDBA Rsp
1115 * 1 - ADDBA Req
1116 * 0 - ADDBA Rsp
1117 *
1118 * \return eSIR_SUCCESS if setup completes successfully
1119 * eSIR_FAILURE is some problem is encountered
1120 */
1121
1122static tSirMacStatusCodes
1123__limValidateAddBAParameterSet( tpAniSirGlobal pMac,
1124 tpDphHashNode pSta,
1125 tDot11fFfAddBAParameterSet baParameterSet,
1126 tANI_U8 dialogueToken,
1127 tLimAddBaValidationReqType reqType ,
1128 tANI_U8* pDelBAFlag /*this parameter is NULL except for call from processAddBAReq*/)
1129{
1130 if(baParameterSet.tid >= STACFG_MAX_TC)
1131 {
1132 return eSIR_MAC_WME_INVALID_PARAMS_STATUS;
1133 }
1134
1135 //check if there is already a BA session setup with this STA/TID while processing AddBaReq
1136 if((true == pSta->tcCfg[baParameterSet.tid].fUseBARx) &&
1137 (LIM_ADDBA_REQ == reqType))
1138 {
1139 //There is already BA session setup for STA/TID.
1140 limLog( pMac, LOGW,
1141 FL( "AddBAReq rcvd when there is already a session for this StaId = %d, tid = %d\n " ),
1142 pSta->staIndex, baParameterSet.tid);
1143 limPrintMacAddr( pMac, pSta->staAddr, LOGW );
1144
1145 if(pDelBAFlag)
1146 *pDelBAFlag = true;
1147 }
1148 return eSIR_MAC_SUCCESS_STATUS;
1149}
1150
1151/**
1152 * \brief Validate a DELBA Ind from peer with respect
1153 * to our own BA configuration
1154 *
1155 * \sa __limValidateDelBAParameterSet
1156 *
1157 * \param pMac The global tpAniSirGlobal object
1158 *
1159 * \param baParameterSet The DELBA Parameter Set.
1160 *
1161 * \param pSta Runtime, STA-related configuration cached
1162 * in the HashNode object
1163 *
1164 * \return eSIR_SUCCESS if setup completes successfully
1165 * eSIR_FAILURE is some problem is encountered
1166 */
1167static tSirMacStatusCodes
1168__limValidateDelBAParameterSet( tpAniSirGlobal pMac,
1169 tDot11fFfDelBAParameterSet baParameterSet,
1170 tpDphHashNode pSta )
1171{
1172tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS;
1173
1174 // Validate if a BA is active for the requested TID
1175 if( pSta->tcCfg[baParameterSet.tid].fUseBATx ||
1176 pSta->tcCfg[baParameterSet.tid].fUseBARx )
1177 {
1178 statusCode = eSIR_MAC_SUCCESS_STATUS;
1179
1180 limLog( pMac, LOGW,
1181 FL("Valid DELBA Ind received. Time to send WDA_DELBA_IND to HAL...\n"));
1182 }
1183 else
1184 limLog( pMac, LOGW,
1185 FL("Received an INVALID DELBA Ind for TID %d...\n"),
1186 baParameterSet.tid );
1187
1188 return statusCode;
1189}
1190
1191/**
1192 * \brief Process an ADDBA REQ
1193 *
1194 * \sa limProcessAddBAReq
1195 *
1196 * \param pMac The global tpAniSirGlobal object
1197 *
1198 * \param pRxPacketInfo Handle to the Rx packet info from HDD
1199 *
1200 * \return none
1201 *
1202 */
1203static void
1204__limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1205{
1206 tDot11fAddBAReq frmAddBAReq;
1207 tpSirMacMgmtHdr pHdr;
1208 tpDphHashNode pSta;
1209 tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS;
1210 tANI_U16 aid;
1211 tANI_U32 frameLen, nStatus;
1212 tANI_U8 *pBody;
1213 tANI_U8 delBAFlag =0;
1214
1215 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1216 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1217 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1218
1219 // Unpack the received frame
1220 nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq );
1221 if( DOT11F_FAILED( nStatus ))
1222 {
1223 limLog( pMac, LOGE,
1224 FL("Failed to unpack and parse an ADDBA Request (0x%08x, %d bytes):\n"),
1225 nStatus,
1226 frameLen );
1227
1228 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1229
1230 // Without an unpacked request we cannot respond, so silently ignore the request
1231 return;
1232 }
1233 else if ( DOT11F_WARNED( nStatus ) )
1234 {
1235 limLog( pMac, LOGW,
1236 FL( "There were warnings while unpacking an ADDBA Request (0x%08x, %d bytes):\n"),
1237 nStatus,
1238 frameLen );
1239
1240 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1241 }
1242
1243 pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1244 if( pSta == NULL )
1245 {
1246 limLog( pMac, LOGE,
1247 FL( "STA context not found - ignoring ADDBA from \n" ));
1248 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1249
1250 // FIXME - Should we do this?
1251 status = eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS;
1252 goto returnAfterError;
1253 }
1254
1255 limLog( pMac, LOGW,
1256 FL( "ADDBA Req from STA with AID %d, tid = %d\n" ),
1257 aid, frmAddBAReq.AddBAParameterSet.tid);
1258
1259#ifdef WLAN_SOFTAP_VSTA_FEATURE
1260 // we can only do BA on "hard" STAs
1261 if (!(IS_HWSTA_IDX(pSta->staIndex)))
1262 {
1263 status = eSIR_MAC_REQ_DECLINED_STATUS;
1264 goto returnAfterError;
1265 }
1266#endif //WLAN_SOFTAP_VSTA_FEATURE
1267
1268
1269 // Now, validate the ADDBA Req
1270 if( eSIR_MAC_SUCCESS_STATUS !=
1271 (status = __limValidateAddBAParameterSet( pMac, pSta,
1272 frmAddBAReq.AddBAParameterSet,
1273 0, //dialogue token is don't care in request validation.
1274 LIM_ADDBA_REQ, &delBAFlag)))
1275 goto returnAfterError;
1276
1277 //BA already set, so we need to delete it before adding new one.
1278 if(delBAFlag)
1279 {
1280 if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac,
1281 pSta,
1282 (tANI_U8)frmAddBAReq.AddBAParameterSet.tid,
1283 eBA_RECIPIENT,psessionEntry))
1284 {
1285 status = eSIR_MAC_UNSPEC_FAILURE_STATUS;
1286 goto returnAfterError;
1287 }
1288 }
1289
1290 // Check if the ADD BA Declined configuration is Disabled
1291 if ((pMac->lim.gAddBA_Declined & ( 1 << frmAddBAReq.AddBAParameterSet.tid ) )) {
1292 limLog( pMac, LOGE, FL( "Declined the ADDBA Req for the TID %d \n" ),
1293 frmAddBAReq.AddBAParameterSet.tid);
1294 status = eSIR_MAC_REQ_DECLINED_STATUS;
1295 goto returnAfterError;
1296 }
1297
1298 //
1299 // Post WDA_ADDBA_REQ to HAL.
1300 // If HAL/HDD decide to allow this ADDBA Req session,
1301 // then this BA session is termed active
1302 //
1303
1304 // Change the Block Ack state of this STA to wait for
1305 // ADDBA Rsp from HAL
1306 LIM_SET_STA_BA_STATE(pSta, frmAddBAReq.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP);
1307
1308 if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac,
1309 pSta,
1310 (tANI_U8) frmAddBAReq.DialogToken.token,
1311 (tANI_U8) frmAddBAReq.AddBAParameterSet.tid,
1312 (tANI_U8) frmAddBAReq.AddBAParameterSet.policy,
1313 frmAddBAReq.AddBAParameterSet.bufferSize,
1314 frmAddBAReq.BATimeout.timeout,
1315 (tANI_U16) frmAddBAReq.BAStartingSequenceControl.ssn,
1316 eBA_RECIPIENT,psessionEntry))
1317 status = eSIR_MAC_UNSPEC_FAILURE_STATUS;
1318 else
1319 return;
1320
1321returnAfterError:
1322
1323 //
1324 // Package LIM_MLM_ADDBA_RSP to MLME, with proper
1325 // status code. MLME will then send an ADDBA RSP
1326 // over the air to the peer MAC entity
1327 //
1328 if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac,
1329 pHdr->sa,
1330 status,
1331 frmAddBAReq.DialogToken.token,
1332 (tANI_U8) frmAddBAReq.AddBAParameterSet.tid,
1333 (tANI_U8) frmAddBAReq.AddBAParameterSet.policy,
1334 frmAddBAReq.AddBAParameterSet.bufferSize,
1335 frmAddBAReq.BATimeout.timeout,psessionEntry))
1336 {
1337 limLog( pMac, LOGW,
1338 FL( "Failed to post LIM_MLM_ADDBA_RSP to " ));
1339 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1340 }
1341
1342}
1343
1344/**
1345 * \brief Process an ADDBA RSP
1346 *
1347 * \sa limProcessAddBARsp
1348 *
1349 * \param pMac The global tpAniSirGlobal object
1350 *
1351 * \param pRxPacketInfo Handle to the packet info structure from HDD
1352 *
1353 * \return none
1354 *
1355 */
1356static void
1357__limProcessAddBARsp( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1358{
1359tDot11fAddBARsp frmAddBARsp;
1360tpSirMacMgmtHdr pHdr;
1361tpDphHashNode pSta;
1362tSirMacReasonCodes reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
1363tANI_U16 aid;
1364tANI_U32 frameLen, nStatus;
1365tANI_U8 *pBody;
1366
1367 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1368 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1369 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1370
1371 pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1372 if( pSta == NULL )
1373 {
1374 limLog( pMac, LOGE,
1375 FL( "STA context not found - ignoring ADDBA from \n" ));
1376 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1377 return;
1378 }
1379
1380#ifdef WLAN_SOFTAP_VSTA_FEATURE
1381 // We can only do BA on "hard" STAs. We should not have issued an ADDBA
1382 // Request, so we should never be processing a ADDBA Response
1383 if (!(IS_HWSTA_IDX(pSta->staIndex)))
1384 {
1385 return;
1386 }
1387#endif //WLAN_SOFTAP_VSTA_FEATURE
1388
1389 // Unpack the received frame
1390 nStatus = dot11fUnpackAddBARsp( pMac, pBody, frameLen, &frmAddBARsp );
1391 if( DOT11F_FAILED( nStatus ))
1392 {
1393 limLog( pMac, LOGE,
1394 FL( "Failed to unpack and parse an ADDBA Response (0x%08x, %d bytes):\n"),
1395 nStatus,
1396 frameLen );
1397
1398 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1399 goto returnAfterError;
1400 }
1401 else if ( DOT11F_WARNED( nStatus ) )
1402 {
1403 limLog( pMac, LOGW,
1404 FL( "There were warnings while unpacking an ADDBA Response (0x%08x, %d bytes):\n"),
1405 nStatus,
1406 frameLen );
1407
1408 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1409 }
1410
1411 limLog( pMac, LOGW,
1412 FL( "ADDBA Rsp from STA with AID %d, tid = %d, status = %d\n" ),
1413 aid, frmAddBARsp.AddBAParameterSet.tid, frmAddBARsp.Status.status);
1414
1415 //if there is no matchin dialougue token then ignore the response.
1416
1417 if(eSIR_SUCCESS != limSearchAndDeleteDialogueToken(pMac, frmAddBARsp.DialogToken.token,
1418 pSta->assocId, frmAddBARsp.AddBAParameterSet.tid))
1419 {
1420 PELOGW(limLog(pMac, LOGW, FL("dialogueToken in received addBARsp did not match with outstanding requests\n"));)
1421 return;
1422 }
1423
1424 // Check first if the peer accepted the ADDBA Req
1425 if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status )
1426 {
1427 //if peer responded with buffer size 0 then we should pick the default.
1428 if(0 == frmAddBARsp.AddBAParameterSet.bufferSize)
1429 frmAddBARsp.AddBAParameterSet.bufferSize = BA_DEFAULT_TX_BUFFER_SIZE;
1430
1431 // Now, validate the ADDBA Rsp
1432 if( eSIR_MAC_SUCCESS_STATUS !=
1433 __limValidateAddBAParameterSet( pMac, pSta,
1434 frmAddBARsp.AddBAParameterSet,
1435 (tANI_U8)frmAddBARsp.DialogToken.token,
1436 LIM_ADDBA_RSP, NULL))
1437 goto returnAfterError;
1438 }
1439 else
1440 goto returnAfterError;
1441
1442 // Change STA state to wait for ADDBA Rsp from HAL
1443 LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP);
1444
1445 //
1446 // Post WDA_ADDBA_REQ to HAL.
1447 // If HAL/HDD decide to allow this ADDBA Rsp session,
1448 // then this BA session is termed active
1449 //
1450
1451 if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac,
1452 pSta,
1453 (tANI_U8) frmAddBARsp.DialogToken.token,
1454 (tANI_U8) frmAddBARsp.AddBAParameterSet.tid,
1455 (tANI_U8) frmAddBARsp.AddBAParameterSet.policy,
1456 frmAddBARsp.AddBAParameterSet.bufferSize,
1457 frmAddBARsp.BATimeout.timeout,
1458 0,
1459 eBA_INITIATOR,psessionEntry))
1460 reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
1461 else
1462 return;
1463
1464returnAfterError:
1465
1466 // TODO: Do we need to signal an error status to SME,
1467 // if status != eSIR_MAC_SUCCESS_STATUS
1468
1469 // Restore STA "BA" State
1470 LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_IDLE);
1471 //
1472 // Need to send a DELBA IND to peer, who
1473 // would have setup a BA session with this STA
1474 //
1475 if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status )
1476 {
1477 //
1478 // Package LIM_MLM_DELBA_REQ to MLME, with proper
1479 // status code. MLME will then send a DELBA IND
1480 // over the air to the peer MAC entity
1481 //
1482 if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac,
1483 pSta,
1484 eBA_INITIATOR,
1485 (tANI_U8) frmAddBARsp.AddBAParameterSet.tid,
1486 reasonCode, psessionEntry))
1487 {
1488 limLog( pMac, LOGW,
1489 FL( "Failed to post LIM_MLM_DELBA_REQ to " ));
1490 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1491 }
1492 }
1493}
1494
1495/**
1496 * \brief Process a DELBA Indication
1497 *
1498 * \sa limProcessDelBAInd
1499 *
1500 * \param pMac The global tpAniSirGlobal object
1501 *
1502 * \param pRxPacketInfo Handle to the Rx packet info from HDD
1503 *
1504 * \return none
1505 *
1506 */
1507static void
1508__limProcessDelBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1509{
1510tDot11fDelBAInd frmDelBAInd;
1511tpSirMacMgmtHdr pHdr;
1512tpDphHashNode pSta;
1513tANI_U16 aid;
1514tANI_U32 frameLen, nStatus;
1515tANI_U8 *pBody;
1516
1517 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1518 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1519 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1520
1521 pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1522 if( pSta == NULL )
1523 {
1524 limLog( pMac, LOGE, FL( "STA context not found - ignoring DELBA from \n"));
1525 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1526 return;
1527 }
1528
1529 limLog( pMac, LOG1, FL( "DELBA Ind from STA with AID %d\n" ), aid );
1530
1531 // Unpack the received frame
1532 nStatus = dot11fUnpackDelBAInd( pMac, pBody, frameLen, &frmDelBAInd );
1533 if( DOT11F_FAILED( nStatus ))
1534 {
1535 limLog( pMac, LOGE,
1536 FL( "Failed to unpack and parse a DELBA Indication (0x%08x, %d bytes):\n"),
1537 nStatus,
1538 frameLen );
1539
1540 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1541 return;
1542 }
1543 else if ( DOT11F_WARNED( nStatus ) )
1544 {
1545 limLog( pMac, LOGW,
1546 FL( "There were warnings while unpacking a DELBA Indication (0x%08x, %d bytes):\n"),
1547 nStatus,
1548 frameLen );
1549
1550 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1551 }
1552
1553 limLog( pMac, LOGW,
1554 FL( "Received DELBA for TID %d, Reason code %d\n" ),
1555 frmDelBAInd.DelBAParameterSet.tid,
1556 frmDelBAInd.Reason.code );
1557
1558 // Now, validate the DELBA Ind
1559 if( eSIR_MAC_SUCCESS_STATUS != __limValidateDelBAParameterSet( pMac,
1560 frmDelBAInd.DelBAParameterSet,
1561 pSta ))
1562 return;
1563
1564 //
1565 // Post WDA_DELBA_IND to HAL and delete the
1566 // existing BA session
1567 //
1568 // NOTE - IEEE 802.11-REVma-D8.0, Section 7.3.1.16
1569 // is kind of confusing...
1570 //
1571 if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac,
1572 pSta,
1573 (tANI_U8) frmDelBAInd.DelBAParameterSet.tid,
1574 (eBA_RECIPIENT == frmDelBAInd.DelBAParameterSet.initiator)?
1575 eBA_INITIATOR: eBA_RECIPIENT,psessionEntry))
1576 limLog( pMac, LOGE, FL( "Posting WDA_DELBA_IND to HAL failed \n"));
1577
1578 return;
1579
1580}
1581
1582static void
1583__limProcessSMPowerSaveUpdate(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry)
1584{
1585
1586#if 0
1587 tpSirMacMgmtHdr pHdr;
1588 tDot11fSMPowerSave frmSMPower;
1589 tSirMacHTMIMOPowerSaveState state;
1590 tpDphHashNode pSta;
1591 tANI_U16 aid;
1592 tANI_U32 frameLen, nStatus;
1593 tANI_U8 *pBody;
1594
1595 pHdr = SIR_MAC_BD_TO_MPDUHEADER( pBd );
1596 pBody = SIR_MAC_BD_TO_MPDUDATA( pBd );
1597 frameLen = SIR_MAC_BD_TO_PAYLOAD_LEN( pBd );
1598
1599 pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable );
1600 if( pSta == NULL ) {
1601 limLog( pMac, LOGE,FL( "STA context not found - ignoring UpdateSM PSave Mode from \n" ));
1602 limPrintMacAddr( pMac, pHdr->sa, LOGW );
1603 return;
1604 }
1605
1606 /**Unpack the received frame */
1607 nStatus = dot11fUnpackSMPowerSave( pMac, pBody, frameLen, &frmSMPower);
1608
1609 if( DOT11F_FAILED( nStatus )) {
1610 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):\n"),
1611 nStatus, frameLen );
1612 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1613 return;
1614 }else if ( DOT11F_WARNED( nStatus ) ) {
1615 limLog(pMac, LOGW, FL( "There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):\n"),
1616 nStatus, frameLen );
1617 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1618 }
1619
1620 limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with PS_Enable:%d"
1621 "PS Mode: %d"), frmSMPower.SMPowerModeSet.PowerSave_En,
1622 frmSMPower.SMPowerModeSet.Mode);
1623
1624 /** Update in the DPH Table about the Update in the SM Power Save mode*/
1625 if (frmSMPower.SMPowerModeSet.PowerSave_En && frmSMPower.SMPowerModeSet.Mode)
1626 state = eSIR_HT_MIMO_PS_DYNAMIC;
1627 else if ((frmSMPower.SMPowerModeSet.PowerSave_En) && (frmSMPower.SMPowerModeSet.Mode ==0))
1628 state = eSIR_HT_MIMO_PS_STATIC;
1629 else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0) && (frmSMPower.SMPowerModeSet.Mode == 0))
1630 state = eSIR_HT_MIMO_PS_NO_LIMIT;
1631 else {
1632 PELOGW(limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with invalid mode"));)
1633 return;
1634 }
1635
1636 if (state == pSta->htMIMOPSState) {
1637 PELOGE(limLog(pMac, LOGE, FL("The PEER is already set in the same mode"));)
1638 return;
1639 }
1640
1641 /** Update in the HAL Station Table for the Update of the Protection Mode */
1642 pSta->htMIMOPSState = state;
1643 limPostSMStateUpdate(pMac,pSta->staIndex, pSta->htMIMOPSState);
1644
1645#endif
1646
1647}
1648
1649#if defined WLAN_FEATURE_VOWIFI
1650
1651static void
1652__limProcessRadioMeasureRequest( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
1653{
1654 tpSirMacMgmtHdr pHdr;
1655 tDot11fRadioMeasurementRequest frm;
1656 tANI_U32 frameLen, nStatus;
1657 tANI_U8 *pBody;
1658
1659 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1660 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1661 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1662
1663 if( psessionEntry == NULL )
1664 {
1665 return;
1666 }
1667
1668 /**Unpack the received frame */
1669 nStatus = dot11fUnpackRadioMeasurementRequest( pMac, pBody, frameLen, &frm );
1670
1671 if( DOT11F_FAILED( nStatus )) {
1672 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):\n"),
1673 nStatus, frameLen );
1674 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1675 return;
1676 }else if ( DOT11F_WARNED( nStatus ) ) {
1677 limLog(pMac, LOGW, FL( "There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):\n"),
1678 nStatus, frameLen );
1679 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1680 }
1681
1682 // Call rrm function to handle the request.
1683
1684 rrmProcessRadioMeasurementRequest( pMac, pHdr->sa, &frm, psessionEntry );
1685}
1686
1687static void
1688__limProcessLinkMeasurementReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
1689{
1690 tpSirMacMgmtHdr pHdr;
1691 tDot11fLinkMeasurementRequest frm;
1692 tANI_U32 frameLen, nStatus;
1693 tANI_U8 *pBody;
1694
1695 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1696 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1697 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1698
1699 if( psessionEntry == NULL )
1700 {
1701 return;
1702 }
1703
1704 /**Unpack the received frame */
1705 nStatus = dot11fUnpackLinkMeasurementRequest( pMac, pBody, frameLen, &frm );
1706
1707 if( DOT11F_FAILED( nStatus )) {
1708 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):\n"),
1709 nStatus, frameLen );
1710 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1711 return;
1712 }else if ( DOT11F_WARNED( nStatus ) ) {
1713 limLog(pMac, LOGW, FL( "There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):\n"),
1714 nStatus, frameLen );
1715 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1716 }
1717
1718 // Call rrm function to handle the request.
1719
1720 rrmProcessLinkMeasurementRequest( pMac, pRxPacketInfo, &frm, psessionEntry );
1721
1722}
1723
1724static void
1725__limProcessNeighborReport( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry )
1726{
1727 tpSirMacMgmtHdr pHdr;
1728 tDot11fNeighborReportResponse frm;
1729 tANI_U32 frameLen, nStatus;
1730 tANI_U8 *pBody;
1731
1732 pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo );
1733 pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo );
1734 frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo );
1735
1736 if( psessionEntry == NULL )
1737 {
1738 return;
1739 }
1740
1741 /**Unpack the received frame */
1742 nStatus = dot11fUnpackNeighborReportResponse( pMac, pBody, frameLen, &frm );
1743
1744 if( DOT11F_FAILED( nStatus )) {
1745 limLog( pMac, LOGE, FL( "Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):\n"),
1746 nStatus, frameLen );
1747 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1748 return;
1749 }else if ( DOT11F_WARNED( nStatus ) ) {
1750 limLog(pMac, LOGW, FL( "There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):\n"),
1751 nStatus, frameLen );
1752 PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );)
1753 }
1754
1755 //Call rrm function to handle the request.
1756 rrmProcessNeighborReportResponse( pMac, &frm, psessionEntry );
1757
1758}
1759
1760#endif
1761
1762#ifdef WLAN_FEATURE_11W
1763/**
1764 * limProcessActionFrame
1765 *
1766 *FUNCTION:
1767 * This function is called by limProcessActionFrame() upon
1768 * SA query request Action frame reception.
1769 *
1770 *LOGIC:
1771 *
1772 *ASSUMPTIONS:
1773 *
1774 *NOTE:
1775 *
1776 * @param pMac - Pointer to Global MAC structure
1777 * @param *pBd - A pointer to Buffer descriptor + associated PDUs
1778 * @return None
1779 */
1780static void __limProcessSAQueryRequestActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1781{
1782 tpSirMacMgmtHdr pHdr;
1783 tANI_U8 *pBody;
1784 tANI_U16 transId = 0;
1785
1786 /* Prima --- Below Macro not available in prima
1787 pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
1788 pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */
1789
1790 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
1791 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1792
1793 /*Extract 11w trsansId from SA query request action frame
1794 In SA query response action frame we will send same transId
1795 In SA query request action frame:
1796 Category : 1 byte
1797 Action : 1 byte
1798 Transaction ID : 2 bbytes */
1799
1800 transId = pBody[2];
1801 transId = transId << 8;
1802 transId |= pBody[3];
1803
1804 //Send 11w SA query response action frame
1805 if (limSendSaQueryResponseFrame(pMac,
1806 transId,
1807 pHdr->sa,psessionEntry) != eSIR_SUCCESS)
1808 {
1809 PELOGE(limLog(pMac, LOGE, FL("fail to send SA query response action frame. \n"));)
1810 return;
1811 }
1812}
1813
1814#endif
1815
1816/**
1817 * limProcessActionFrame
1818 *
1819 *FUNCTION:
1820 * This function is called by limProcessMessageQueue() upon
1821 * Action frame reception.
1822 *
1823 *LOGIC:
1824 *
1825 *ASSUMPTIONS:
1826 *
1827 *NOTE:
1828 *
1829 * @param pMac - Pointer to Global MAC structure
1830 * @param *pRxPacketInfo - A pointer to packet info structure
1831 * @return None
1832 */
1833
1834void
1835limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry)
1836{
1837 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
1838 tpSirMacActionFrameHdr pActionHdr = (tpSirMacActionFrameHdr) pBody;
1839
1840
1841 switch (pActionHdr->category)
1842 {
1843 case SIR_MAC_ACTION_QOS_MGMT:
1844 if (psessionEntry->limQosEnabled)
1845 {
1846 switch (pActionHdr->actionID)
1847 {
1848 case SIR_MAC_QOS_ADD_TS_REQ:
1849 __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1850 break;
1851
1852 case SIR_MAC_QOS_ADD_TS_RSP:
1853 __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1854 break;
1855
1856 case SIR_MAC_QOS_DEL_TS_REQ:
1857 __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1858 break;
1859
1860 default:
1861 PELOGE(limLog(pMac, LOGE, FL("Qos action %d not handled\n"), pActionHdr->actionID);)
1862 break;
1863 }
1864 break ;
1865 }
1866
1867 break;
1868
1869 case SIR_MAC_ACTION_SPECTRUM_MGMT:
1870 switch (pActionHdr->actionID)
1871 {
1872#ifdef ANI_SUPPORT_11H
1873 case SIR_MAC_ACTION_MEASURE_REQUEST_ID:
1874 if(psessionEntry->lim11hEnable)
1875 {
1876 __limProcessMeasurementRequestFrame(pMac, pRxPacketInfo);
1877 }
1878 break;
1879
1880 case SIR_MAC_ACTION_TPC_REQUEST_ID:
1881 if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
1882 (pessionEntry->limSystemRole == eLIM_AP_ROLE))
1883 {
1884 if(psessionEntry->lim11hEnable)
1885 {
1886 __limProcessTpcRequestFrame(pMac, pRxPacketInfo);
1887 }
1888 }
1889 break;
1890
1891#endif
1892 case SIR_MAC_ACTION_CHANNEL_SWITCH_ID:
1893 if (psessionEntry->limSystemRole == eLIM_STA_ROLE)
1894 {
1895 __limProcessChannelSwitchActionFrame(pMac, pRxPacketInfo,psessionEntry);
1896 }
1897 break;
1898 default:
1899 PELOGE(limLog(pMac, LOGE, FL("Spectrum mgmt action id %d not handled\n"), pActionHdr->actionID);)
1900 break;
1901 }
1902 break;
1903
1904 case SIR_MAC_ACTION_WME:
1905 if (! psessionEntry->limWmeEnabled)
1906 {
1907 limLog(pMac, LOGW, FL("WME mode disabled - dropping action frame %d\n"),
1908 pActionHdr->actionID);
1909 break;
1910 }
1911 switch(pActionHdr->actionID)
1912 {
1913 case SIR_MAC_QOS_ADD_TS_REQ:
1914 __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1915 break;
1916
1917 case SIR_MAC_QOS_ADD_TS_RSP:
1918 __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1919 break;
1920
1921 case SIR_MAC_QOS_DEL_TS_REQ:
1922 __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1923 break;
1924
1925 default:
1926 PELOGE(limLog(pMac, LOGE, FL("WME action %d not handled\n"), pActionHdr->actionID);)
1927 break;
1928 }
1929 break;
1930
1931 case SIR_MAC_ACTION_BLKACK:
1932 // Determine the "type" of BA Action Frame
1933 switch(pActionHdr->actionID)
1934 {
1935 case SIR_MAC_BLKACK_ADD_REQ:
1936 __limProcessAddBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1937 break;
1938
1939 case SIR_MAC_BLKACK_ADD_RSP:
1940 __limProcessAddBARsp( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1941 break;
1942
1943 case SIR_MAC_BLKACK_DEL:
1944 __limProcessDelBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1945 break;
1946
1947 default:
1948 break;
1949 }
1950
1951 break;
1952 case SIR_MAC_ACTION_HT:
1953 /** Type of HT Action to be performed*/
1954 switch(pActionHdr->actionID) {
1955 case SIR_MAC_SM_POWER_SAVE:
1956 __limProcessSMPowerSaveUpdate(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry);
1957 break;
1958 default:
1959 PELOGE(limLog(pMac, LOGE, FL("Action ID %d not handled in HT Action category\n"), pActionHdr->actionID);)
1960 break;
1961 }
1962 break;
1963
1964#if defined WLAN_FEATURE_VOWIFI
1965 case SIR_MAC_ACTION_RRM:
1966 if( pMac->rrm.rrmPEContext.rrmEnable )
1967 {
1968 switch(pActionHdr->actionID) {
1969 case SIR_MAC_RRM_RADIO_MEASURE_REQ:
1970 __limProcessRadioMeasureRequest( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry );
1971 break;
1972 case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
1973 __limProcessLinkMeasurementReq( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry );
1974 break;
1975 case SIR_MAC_RRM_NEIGHBOR_RPT:
1976 __limProcessNeighborReport( pMac, (tANI_U8*) pRxPacketInfo, psessionEntry );
1977 break;
1978 default:
1979 PELOGE( limLog( pMac, LOGE, FL("Action ID %d not handled in RRM\n"), pActionHdr->actionID);)
1980 break;
1981
1982 }
1983 }
1984 else
1985 {
1986 // Else we will just ignore the RRM messages.
1987 PELOGE( limLog( pMac, LOGE, FL("RRM Action frame ignored as RRM is disabled in cfg\n"));)
1988 }
1989 break;
1990#endif
1991#if defined WLAN_FEATURE_P2P
1992 case SIR_MAC_ACTION_PUBLIC_USAGE:
1993 switch(pActionHdr->actionID) {
1994 case SIR_MAC_ACTION_VENDOR_SPECIFIC:
1995 {
1996 tpSirMacVendorSpecificPublicActionFrameHdr pPubAction = (tpSirMacVendorSpecificPublicActionFrameHdr) pActionHdr;
1997 tpSirMacMgmtHdr pHdr;
1998 tANI_U32 frameLen;
1999 tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
2000
2001 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
2002 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
2003
2004 //Check if it is a P2P public action frame.
2005 if( palEqualMemory( pMac->hHdd, pPubAction->Oui, P2POui, 4 ) )
2006 {
2007 /* Forward to the SME to HDD to wpa_supplicant */
2008 // type is ACTION
2009 limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
2010 (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
Jeff Johnsone7245742012-09-05 17:12:55 -07002011 WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry);
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 }
2013 else
2014 {
2015 limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x\n"),
2016 pPubAction->Oui[0], pPubAction->Oui[1], pPubAction->Oui[2], pPubAction->Oui[3] );
2017 }
2018 }
2019 break;
2020
2021 default:
2022 PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x \n"), pActionHdr->actionID);)
2023 break;
2024 }
2025 break;
2026#endif
2027
2028#ifdef WLAN_FEATURE_11W
2029 case SIR_MAC_ACTION_SA_QUERY:
2030 {
2031 /**11w SA query request action frame received**/
2032 __limProcessSAQueryRequestActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry );
2033 break;
2034 }
2035#endif
2036
2037 default:
2038 PELOGE(limLog(pMac, LOGE, FL("Action category %d not handled\n"), pActionHdr->category);)
2039 break;
2040 }
2041}
2042
2043#if defined WLAN_FEATURE_P2P
2044/**
2045 * limProcessActionFrameNoSession
2046 *
2047 *FUNCTION:
2048 * This function is called by limProcessMessageQueue() upon
2049 * Action frame reception and no session.
2050 * Currently only public action frames can be received from
2051 * a non-associated station.
2052 *
2053 *LOGIC:
2054 *
2055 *ASSUMPTIONS:
2056 *
2057 *NOTE:
2058 *
2059 * @param pMac - Pointer to Global MAC structure
2060 * @param *pBd - A pointer to Buffer descriptor + associated PDUs
2061 * @return None
2062 */
2063
2064void
2065limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd)
2066{
2067 tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd);
2068 tpSirMacVendorSpecificPublicActionFrameHdr pActionHdr = (tpSirMacVendorSpecificPublicActionFrameHdr) pBody;
2069
2070 limLog( pMac, LOGE, "Received a Action frame -- no session");
2071
2072 switch ( pActionHdr->category )
2073 {
2074 case SIR_MAC_ACTION_PUBLIC_USAGE:
2075 switch(pActionHdr->actionID) {
2076 case SIR_MAC_ACTION_VENDOR_SPECIFIC:
2077 {
2078 tpSirMacMgmtHdr pHdr;
2079 tANI_U32 frameLen;
2080 tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
2081
2082 pHdr = WDA_GET_RX_MAC_HEADER(pBd);
2083 frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
2084
2085 //Check if it is a P2P public action frame.
2086 if( palEqualMemory( pMac->hHdd, pActionHdr->Oui, P2POui, 4 ) )
2087 {
2088 /* Forward to the SME to HDD to wpa_supplicant */
2089 // type is ACTION
2090 limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
2091 (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
Jeff Johnsone7245742012-09-05 17:12:55 -07002092 WDA_GET_RX_CH( pBd ), NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 }
2094 else
2095 {
2096 limLog( pMac, LOGE, FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x\n"),
2097 pActionHdr->Oui[0], pActionHdr->Oui[1], pActionHdr->Oui[2], pActionHdr->Oui[3] );
2098 }
2099 }
2100 break;
2101 default:
2102 PELOGE(limLog(pMac, LOGE, FL("Unhandled public action frame -- %x \n"), pActionHdr->actionID);)
2103 break;
2104 }
2105 break;
2106 default:
2107 PELOGE(limLog(pMac, LOGE, FL("Unhandled action frame without session -- %x \n"), pActionHdr->category);)
2108 break;
2109
2110 }
2111}
2112#endif