qcacld-3.0: Initial snapshot of ihelium wlan driver
qcacld-3.0: Initial snapshot of ihelium wlan driver
to match code-scanned SU Release 5.0.0.139. This is
open-source version of wlan for next Android release.
Change-Id: Icf598ca97da74f84bea607e4e902d1889806f507
diff --git a/core/mac/src/cfg/cfgUtil/cfg.txt b/core/mac/src/cfg/cfgUtil/cfg.txt
new file mode 100644
index 0000000..85071b9
--- /dev/null
+++ b/core/mac/src/cfg/cfgUtil/cfg.txt
@@ -0,0 +1,4474 @@
+* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+*
+* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+*
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+
+* This file was originally distributed by Qualcomm Atheros, Inc.
+* under proprietary terms before Copyright ownership was assigned
+* to the Linux Foundation.
+
+*
+* This is the data definition file for the CFG module.
+* Author: Kevin Nguyen
+* Date: 03/18/02
+* History:-
+* 03/18/02 Created.
+* 08/10/05 ww: add maoe channels to have a complete channel listing: (see WNI_CFG_VALID_CHANNEL_LIST)
+* 08/10/05 ww: WNI_CFG_SCAN_CONTROL_LIST has a new contents
+* --------------------------------------------------------------------
+
+**********************************************************************
+*
+* This file contains the descriptions of all configuration parameters
+* for both STA and AP.
+*
+* OUTPUT:
+* -------
+* The output files are:
+* wniCfgSta.h - C header file for STA mode only
+* wniCfgAp.h - C header file for both STA and AP
+* wniCfgSta.bin - Control and default values for STA system
+* wniCfgAp.bin - Control and default values for AP system
+*
+* PARAMETER DESCRIPTION:
+* ----------------------
+* For each parameter, the description must be on separate lines and
+* exactly as specified below. [] are comments and should not be included.
+*
+* [Common info] parameter_name type maxLen semIndx
+* [STA flags] valid RW P/NP RESTART/RELOAD
+* [STA_NTF] notification_mask
+* [STA values] min max value [for integer]
+* length byte1 byte2 ... [for string]
+* [AP flags] valid RW/RO/WO P/NP RESTART/RELOAD
+* [AP_NTF] notification_mask
+* [AP values] min max value [for integer]
+* length byte1 byte2 ... [for string]
+*
+* parameter_name:
+* This will be used as the base name for C macro definition.
+* Therefore, C syntax rule must be observed.
+*
+* type:
+* Specifies parameter type
+* S - variable-length string
+* I - integer
+*
+* maxLen:
+* Specifies maximum parameter length in bytes.
+*
+* semIndx:
+* Specifies semaphore index to use for locking this parameter.
+* More than one parameters (those belonging to the same group)
+* can share the same semaphore index.
+*
+* valid:
+* Specifies if this parameter will be valid in current mode.
+* V - Valid
+* NV - Not valid
+*
+* RW:
+* Specifies Read/Write mode.
+* RO - Read only
+* RW - Read/Write
+* WO - Write only
+* XX - Not accessible from host
+*
+* P:
+* Specifies persistent memory option
+* P - Save to persistent memory
+* NP - No save
+*
+* RELOAD:
+* Specifies whether setting this requires reloading the MAC module
+* This attribute can be changed only when SME is in OFFLINE or SUSPEND(OFFLINE) state
+*
+* RESTART:
+* Specifies whether setting this requires (re)assoc at STA and restart at AP
+* This attribute can be changed only when SME is in OFFLINE, SUSPEND(OFFLINE),
+* IDLE or SUSPEND(IDLE) states
+*
+* STA_notification:
+* Lists modules to be notified in STA mode. Valid modules are:
+* HDD, LIM, SCH, ARQ, DPH, NIM, SP, RFP, RHP, TFP. More than one
+* modules can be listed on the same line using space or tab as the
+* separator. If no notification is required, 'NONE' must be specified.
+*
+* AP_notification:
+* Lists module to be notified in AP mode. Valid modules are:
+* HDD, LIM, SCH, ARQ, DPH, NIM, SP, RFP, RHP, TFP. More than one
+* modules can be listed on the same line using space or tab as the
+* separator. If no notification is required, 'NONE' must be specified.
+*
+* STA/AP integer values:
+* min:
+* Specifies minimum value for an integer parameter. This field is
+* ignored if the parameter type is string. However, this field must
+* not be omitted.
+*
+* max:
+* Specifies maximum value for an integer parameter. This field is
+* ignored if the parameter type is string. However, this field must
+* not be omitted.
+*
+* default:
+* Specifies default value for an integer parameter. This field is
+* ignored if the parameter type is string. However, this field must
+* not be omitted.
+*
+* STA/AP string values:
+* len:
+* The actual length of the string
+*
+* bytei:
+* byte i of the string where i varies from 1 to len
+*
+* TABLE GENERATION:
+* -----------------
+* Table can be generated using keywords '#TABLE' and '#END' as below:
+*
+* #TABLE table_name number_of_row
+* WNI_CFG_xxxx
+* .......
+* .......
+* #END
+*
+* The CFG utility will generate the following output:
+* WNI_CFG_table_xxx_ID xxx
+* WNI_CFG_table_xxx_ROW number_of_rows
+* WNI_CFG_table_xxx_COL number_of_columns
+*
+* These will be followed by the parameter definition for each entry in
+* the table. Table is organized in column-major order.
+*
+* #ENTRY_VALUES 1
+* 0 4 1
+* 0 0 0
+* #ENTRY_VALUES 2
+* 0 4 2
+* 0 0 0
+* #ENTRY_VALUES 3
+* 0 4 3
+* 0 0 0
+* #ENTRY_VALUES 4
+* 0 4 4
+* 0 0 0
+*
+*
+* ENUMERATION
+* -----------
+* Enumerations can be define using keyword '#ENUM'
+*
+* #ENUM xxx val
+*
+* The cfg utility will generate the following output in the header file
+* #define paramname_xxx val
+*
+
+
+*
+* Station ID (changing requires restart)
+*
+
+WNI_CFG_STA_ID S 6 1
+V RW NP RELOAD
+HAL
+6 0x22 0x22 0x44 0x44 0x33 0x33
+V RW NP RELOAD
+HAL
+6 0x22 0x22 0x11 0x11 0x33 0x33
+
+*
+* CF Pollable
+*
+
+WNI_CFG_CF_POLLABLE I 4 1
+NV RO NP RESTART
+NONE
+0 0 0
+V RO NP RESTART
+NONE
+0 1 0
+
+*
+* CFP Period
+*
+
+WNI_CFG_CFP_PERIOD I 4 1
+V RO NP
+NONE
+0 255 1
+V RW NP
+SCH
+0 255 1
+
+*
+* CFP Max Duration
+*
+
+WNI_CFG_CFP_MAX_DURATION I 4 1
+V RO NP
+NONE
+0 65535 30000
+V RW NP
+HAL
+0 65535 30000
+
+*
+* SSID (changing requires restart)
+*
+
+WNI_CFG_SSID S 32 1
+V RW NP RESTART
+NONE
+10 1 2 3 4 5 6 7 8 9 0
+V RW NP RESTART
+NONE
+10 1 2 3 4 5 6 7 8 9 0
+
+*
+* Beacon Period
+* Can't be changed on STA in infrastructure, ignore notification at SCH
+*
+
+WNI_CFG_BEACON_INTERVAL I 4 2
+V RW NP
+SCH
+0 65535 100
+V RW NP
+SCH
+0 65535 100
+
+*
+* DTIM Period
+*
+
+WNI_CFG_DTIM_PERIOD I 4 2
+V RO NP
+NONE
+0 65535 1
+V RW NP
+SCH
+0 65535 1
+
+
+*
+* WEP Key Length (5 or 13 bytes)
+*
+
+WNI_CFG_WEP_KEY_LENGTH I 4 5
+V RW NP RESTART
+NONE
+5 13 5
+V RW NP RESTART
+NONE
+5 13 5
+
+#ENUM 5 5
+#ENUM 13 13
+
+*
+* Default Key Table
+*
+
+#TABLE WNI_CFG_WEP_DEFAULT_KEY_TABLE 4
+
+WNI_CFG_WEP_DEFAULT_KEY S 13 4
+V WO NP RESTART
+NONE
+0
+V WO NP RESTART
+NONE
+0
+
+#END
+
+*
+* WEP Default Key id
+*
+
+WNI_CFG_WEP_DEFAULT_KEYID I 4 5
+V RW NP
+LIM
+0 3 0
+V RW NP
+LIM
+0 3 0
+
+#ENUM 0 0
+#ENUM 1 1
+#ENUM 2 2
+#ENUM 3 3
+
+*
+* Exclude unencrypted frames (WEP)
+*
+
+WNI_CFG_EXCLUDE_UNENCRYPTED I 4 5
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* RTS Threshold
+*
+
+WNI_CFG_RTS_THRESHOLD I 4 6
+V RW NP
+HAL
+0 1048576 2347
+V RW NP
+HAL
+0 1048576 2347
+
+*
+* Short Retry Limit
+*
+
+WNI_CFG_SHORT_RETRY_LIMIT I 4 6
+V RW NP
+HAL
+0 255 6
+V RW NP
+HAL
+0 255 6
+
+*
+* Long Retry Limit
+*
+
+WNI_CFG_LONG_RETRY_LIMIT I 4 6
+V RW NP
+HAL
+0 255 6
+V RW NP
+HAL
+0 255 6
+
+
+*
+* Fragmentation Threshold
+*
+
+WNI_CFG_FRAGMENTATION_THRESHOLD I 4 6
+V RW NP
+HAL
+256 8000 8000
+V RW NP
+HAL
+256 8000 8000
+
+
+*
+* Minimum Channel Time (TU)
+*
+
+WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME I 4 9
+V RW NP
+NONE
+0 65535 20
+V RW NP
+NONE
+0 65535 20
+
+*
+* Maximum Channel Time (TU)
+*
+
+WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME I 4 9
+V RW NP
+NONE
+0 65535 40
+V RW NP
+NONE
+0 65535 40
+*
+* Minimum Channel Time (TU)
+*
+
+WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME I 4 9
+V RW NP
+NONE
+0 65535 60
+V RW NP
+NONE
+0 65535 60
+
+*
+* Maximum Channel Time (TU)
+*
+
+WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME I 4 9
+V RW NP
+NONE
+0 65535 110
+V RW NP
+NONE
+0 65535 110
+
+*
+* Join Failure Timeout (TU)
+*
+
+WNI_CFG_JOIN_FAILURE_TIMEOUT I 4 7
+V RW NP
+NONE
+0 65535 3000
+V RW NP
+NONE
+0 65535 3000
+
+*
+* Authenticate Failure Timeout (TU)
+*
+
+WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT I 4 7
+V RW NP
+NONE
+0 65535 1000
+V RW NP
+NONE
+0 65535 1000
+
+*
+* Authenticate Response Timeout (TU)
+*
+
+WNI_CFG_AUTHENTICATE_RSP_TIMEOUT I 4 7
+V RW NP
+NONE
+0 65535 1000
+V RW NP
+NONE
+0 65535 1000
+
+*
+* Assocation Failure Timeout (TU)
+*
+
+WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT I 4 8
+V RW NP
+LIM
+0 65535 2000
+V RW NP
+LIM
+0 65535 3000
+
+*
+* Reassociation Failure Timeout (TU)
+*
+
+WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT I 4 7
+V RW NP
+NONE
+0 65535 1000
+V RW NP
+NONE
+0 65535 3000
+
+
+*
+* RA periodicity Timeout (TU)
+*
+
+WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS I 4 7
+V RW NP
+HAL
+0 65535 1000
+NV RW NP
+NONE
+0 0 0
+
+*
+* Beacon Filter Enable/Disable (TU)
+*
+
+WNI_CFG_PS_ENABLE_BCN_FILTER I 4 7
+V RW NP
+HAL
+0 1 1
+NV RW NP
+NONE
+0 1 1
+
+*
+* Heart Beat Enable/Disable (TU)
+*
+
+WNI_CFG_PS_ENABLE_HEART_BEAT I 4 7
+V RW NP
+HAL
+0 1 1
+NV RW NP
+NONE
+0 1 1
+
+*
+* RSSI Monitor Enable/Disable (TU)
+*
+
+WNI_CFG_PS_ENABLE_RSSI_MONITOR I 4 7
+V RW NP
+HAL
+0 1 0
+NV RW NP
+NONE
+0 1 0
+
+
+*
+* PS Data InActivity Timeout (TU)
+*
+
+WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT I 4 7
+V RW NP
+HAL
+1 255 20
+NV RW NP
+NONE
+1 255 20
+
+
+*
+* RF Settling Time Clk (In US)
+*
+
+WNI_CFG_RF_SETTLING_TIME_CLK I 4 7
+V RW NP
+HAL
+0 60000 1500
+NV RW NP
+NONE
+0 60000 1500
+
+*
+* Supported Rate Set for 11b
+*
+
+WNI_CFG_SUPPORTED_RATES_11B S 4 2
+V RO NP
+NONE
+4 2 4 11 22
+V RO NP
+NONE
+4 2 4 11 22
+
+*
+* Supported Rate Set for 11a
+*
+
+WNI_CFG_SUPPORTED_RATES_11A S 8 7
+V RO NP
+NONE
+8 12 18 24 36 48 72 96 108
+V RO NP
+NONE
+8 12 18 24 36 48 72 96 108
+
+
+*
+* PHY Mode
+*
+
+WNI_CFG_PHY_MODE I 4 9
+V RW NP RESTART
+NONE
+0 3 0
+V RW NP RESTART
+NONE
+0 3 0
+
+#ENUM 11A 0
+#ENUM 11B 1
+#ENUM 11G 2
+#ENUM NONE 3
+
+
+*
+*The Dot11 mode can change dynamically on STA
+*
+WNI_CFG_DOT11_MODE I 4 9
+V RW NP RESTART
+LIM
+0 11 0
+V RW NP RESTART
+LIM
+0 11 0
+
+#ENUM ALL 0
+#ENUM 11A 1
+#ENUM 11B 2
+#ENUM 11G 3
+#ENUM 11N 4
+#ENUM 11G_ONLY 5
+#ENUM 11N_ONLY 6
+#ENUM 11AC 7
+#ENUM 11AC_ONLY 8
+
+
+
+
+
+
+*
+* Operational Rate Set (goes in beacon, probe rsp and assoc req)
+*
+
+WNI_CFG_OPERATIONAL_RATE_SET S 12 2
+V RW NP RESTART
+NONE
+0
+V RW NP RESTART
+NONE
+4 0x82 0x84 11 22
+* 8 0x8c 18 24 36 48 72 96 108
+
+*
+* Extended Operational Rate Set (goes in beacon, assoc req)
+* required for 11g
+*
+
+WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET S 8 7
+V RW NP RESTART
+NONE
+0
+V RW NP RESTART
+NONE
+0
+
+*
+* Proprietary Operational Rate Set
+*
+
+WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET S 4 7
+V RW NP RESTART
+NONE
+4 1 3 5 7
+V RW NP RESTART
+NONE
+4 1 3 5 7
+
+*
+* BSSID
+* In IBSS, this can be changed for coalescing, should SME go into IDLE state?
+*
+
+*
+* Listen Interval
+*
+
+WNI_CFG_LISTEN_INTERVAL I 4 7
+V RW NP RESTART
+NONE
+0 65535 1
+V RO NP
+NONE
+0 65535 1
+
+*
+* Valid Channel List
+*
+
+WNI_CFG_VALID_CHANNEL_LIST S 100 8
+V RW NP RESTART
+LIM
+55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252
+V RW NP RESTART
+LIM
+55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252
+
+*
+* Current Channel
+*
+
+WNI_CFG_CURRENT_CHANNEL I 4 9
+V RO NP
+NONE
+0 165 1
+V RO NP
+NONE
+0 165 1
+
+
+*
+* For 11a or pure 11g, use 6Mbps(rateindex 11)
+* as the default beaconRateIndex and
+* nonBeaconRateIndex.
+*
+WNI_CFG_DEFAULT_RATE_INDEX_5GHZ I 4 9
+V RW NP
+NONE
+0 11 5
+V RW NP
+NONE
+0 11 5
+
+*
+* For 11b/g, use 1Mbps
+* as the default beaconRateIndex and
+* nonBeaconRateIndex.
+*
+WNI_CFG_DEFAULT_RATE_INDEX_24GHZ I 4 9
+V RW NP
+NONE
+0 31 1
+V RW NP
+NONE
+0 31 1
+
+
+* *********************************************************
+*
+* Rate adaptation type
+*
+
+WNI_CFG_RATE_ADAPTATION_TYPE I 4 0
+V RW NP
+SCH
+0 2 1
+V RW NP
+SCH
+0 2 1
+
+#ENUM FIXED 0
+#ENUM AUTO 1
+#ENUM SNR_BASED 2
+
+*
+* Rate adaptation fixed rate
+* Used to determine the rate for all peer stations
+*
+*
+
+WNI_CFG_FIXED_RATE I 4 0
+V RW NP
+HAL
+0 44 0
+V RW NP
+HAL
+0 44 0
+
+#ENUM AUTO 0
+
+#ENUM 1MBPS 1
+#ENUM 2MBPS 2
+#ENUM 5_5MBPS 3
+#ENUM 11MBPS 4
+
+#ENUM 6MBPS 5
+#ENUM 9MBPS 6
+#ENUM 12MBPS 7
+#ENUM 18MBPS 8
+#ENUM 24MBPS 9
+#ENUM 36MBPS 10
+#ENUM 48MBPS 11
+#ENUM 54MBPS 12
+
+#ENUM 6_5MBPS_MCS0_20MHZ_SIMO 13
+#ENUM 13MBPS_MCS1_20MHZ_SIMO 14
+#ENUM 19_5MBPS_MCS2_20MHZ_SIMO 15
+#ENUM 26MBPS_MCS3_20MHZ_SIMO 16
+#ENUM 39MBPS_MCS4_20MHZ_SIMO 17
+#ENUM 52MBPS_MCS5_20MHZ_SIMO 18
+#ENUM 58_5MBPS_MCS6_20MHZ_SIMO 19
+#ENUM 65MBPS_MCS7_20MHZ_SIMO 20
+
+#ENUM 7_2MBPS_MCS0_20MHZ_SIMO_SGI 21
+#ENUM 14_4MBPS_MCS1_20MHZ_SIMO_SGI 22
+#ENUM 21_7MBPS_MCS2_20MHZ_SIMO_SGI 23
+#ENUM 28_9MBPS_MCS3_20MHZ_SIMO_SGI 24
+#ENUM 43_3MBPS_MCS4_20MHZ_SIMO_SGI 25
+#ENUM 57_8MBPS_MCS5_20MHZ_SIMO_SGI 26
+#ENUM 65MBPS_MCS6_20MHZ_SIMO_SGI 27
+#ENUM 72_2MBPS_MCS7_20MHZ_SIMO_SGI 28
+
+#ENUM 0_25MBPS_SLR_20MHZ_SIMO 29
+#ENUM 0_5MBPS_SLR_20MHZ_SIMO 30
+
+#ENUM 68_25MBPS_QC_PROP_20MHZ_SIMO 31
+#ENUM 54MBPS_MCS3_40MHZ_SIMO 32
+#ENUM 81MBPS_MCS4_40MHZ_SIMO 33
+#ENUM 108MBPS_MCS5_40MHZ_SIMO 34
+#ENUM 121_5MBPS_MCS6_40MHZ_SIMO 35
+#ENUM 135MBPS_MCS7_40MHZ_SIMO 36
+#ENUM 15MBPS_MCS0_40MHZ_SIMO_SGI 37
+#ENUM 30MBPS_MCS1_40MHZ_SIMO_SGI 38
+#ENUM 45MBPS_MCS2_40MHZ_SIMO_SGI 39
+#ENUM 60MBPS_MCS3_40MHZ_SIMO_SGI 40
+#ENUM 90MBPS_MCS4_40MHZ_SIMO_SGI 41
+#ENUM 120MBPS_MCS5_40MHZ_SIMO_SGI 42
+#ENUM 135MBPS_MCS6_40MHZ_SIMO_SGI 43
+#ENUM 150MBPS_MCS7_40MHZ_SIMO_SGI 44
+
+* *********************************************************
+*
+* Broadcast/mutlicast rates for 2.4GHZ
+* uses the same rate indices definition as WNI_CFG_FIXED_RATE
+* default value corresponds to 1M
+
+WNI_CFG_FIXED_RATE_MULTICAST_24GHZ I 4 8
+V RW NP
+HAL
+0 31 1
+V RW NP
+HAL
+0 31 1
+
+* *********************************************************
+*
+* Broadcast/mutlicast rates for 5 GHZ
+* uses the same rate indices definition as WNI_CFG_FIXED_RATE
+* default value corresponds to 6M
+
+WNI_CFG_FIXED_RATE_MULTICAST_5GHZ I 4 8
+V RW NP
+HAL
+0 31 5
+V RW NP
+HAL
+0 31 5
+
+*
+* retry rate selection policy
+* 0 => use the minimum supported rate
+* 1 => use the same rate as the chosen primary rate
+* 2 => use the rate specified in RETRYRATE_SECONDARY
+* 3 => use the rate closest to the primary
+* 4 => autoselect the retry rate based on RA algorithm
+*
+
+WNI_CFG_RETRYRATE_POLICY I 4 0
+V RW NP
+HAL
+0 255 4
+V RW NP
+HAL
+0 255 4
+
+#ENUM MIN_SUPPORTED 0
+#ENUM PRIMARY 1
+#ENUM RESERVED 2
+#ENUM CLOSEST 3
+#ENUM AUTOSELECT 4
+#ENUM MAX 5
+
+*
+* the following two CFG's are
+* used only if the retryrate policy == 2
+* These should be set to one of the values used
+* for configuring fixed rates (see enumerated rates)
+*
+
+WNI_CFG_RETRYRATE_SECONDARY I 4 0
+V RW NP
+HAL
+0 255 0
+V RW NP
+HAL
+0 255 0
+
+WNI_CFG_RETRYRATE_TERTIARY I 4 0
+V RW NP
+HAL
+0 255 0
+V RW NP
+HAL
+0 255 0
+
+* *********************************************************
+*
+* Automatic Power Save Delivery capability
+*
+
+WNI_CFG_APSD_ENABLED I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* Shared key authentication supported
+*
+
+WNI_CFG_SHARED_KEY_AUTH_ENABLE I 4 8
+V RW NP
+NONE
+0 1 1
+V RW NP
+NONE
+0 1 1
+
+*
+* Open system authentication supported
+*
+
+WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE I 4 8
+V RW NP
+NONE
+0 1 1
+V RW NP
+NONE
+0 1 1
+
+*
+* Authentication Type (change requires restart)
+*
+
+WNI_CFG_AUTHENTICATION_TYPE I 4 8
+V RW NP RESTART
+NONE
+0 65535 0
+V RW NP RESTART
+NONE
+0 65535 0
+
+*
+* CF Poll Request (change requires restart)
+*
+
+WNI_CFG_CF_POLL_REQUEST I 4 8
+NV RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* Privacy Enabled (change requires restart)
+*
+
+WNI_CFG_PRIVACY_ENABLED I 4 8
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* Short Preamble (change requires restart)
+*
+
+WNI_CFG_SHORT_PREAMBLE I 4 8
+V RW NP RESTART
+NONE
+0 1 1
+V RW NP RESTART
+NONE
+0 1 1
+
+*
+* Short Slot time
+* This is the operational state of the BSS
+
+WNI_CFG_SHORT_SLOT_TIME I 4 8
+V RW NP
+NONE
+0 1 1
+V RW NP
+NONE
+0 1 0
+
+
+*
+* ACCEPT Short Slot Association only
+*
+* 1: If AP supports shortSlot, then AP will accept
+* association only from stations that supports
+* supports short slot
+* 0: AP supports shortSlot, but AP will accept association
+* from stations regardless of whether station supports
+* short slot or long slot
+*
+WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY I 4 9
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+
+*
+* QOS Enabled (change requires restart)
+*
+
+WNI_CFG_QOS_ENABLED I 4 8
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* HCF Enabled (change requires restart)
+*
+
+WNI_CFG_HCF_ENABLED I 4 8
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* RSN (11i/WPA) Enabled
+*
+
+WNI_CFG_RSN_ENABLED I 4 8
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* Background scanning periodicity (kilo usec)
+*
+
+WNI_CFG_BACKGROUND_SCAN_PERIOD I 4 8
+V RW NP
+LIM
+0 180000 5000
+V RW NP
+LIM
+0 18000 5000
+
+*
+* Max number of Preauthentication
+*
+
+WNI_CFG_MAX_NUM_PRE_AUTH I 4 8
+V RW NP RESTART
+NONE
+0 256 64
+V RW NP RESTART
+NONE
+0 256 64
+
+*
+* Preauthentication Cleanup Timeout (kilo usec)
+*
+
+WNI_CFG_PREAUTH_CLNUP_TIMEOUT I 4 8
+NV XX NP
+NONE
+0 0 0
+V RW NP
+LIM
+0 120000 30000
+
+*
+* Release AID Timeout
+*
+
+WNI_CFG_RELEASE_AID_TIMEOUT I 4 8
+NV XX NP
+NONE
+0 0 0
+V RW NP
+LIM
+0 100000 1000
+*
+* Heartbeat Threshold
+*
+
+WNI_CFG_HEART_BEAT_THRESHOLD I 4 8
+V RW NP
+LIM
+0 65535 40
+NV RW NP
+NONE
+0 65535 40
+
+*
+* Probe response wait time out after heartbeat failure
+*
+
+WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT I 4 8
+V RW NP
+NONE
+10 10000 40
+V RW NP
+NONE
+10 10000 40
+
+*
+* Manufacturer OUI (from eeprom)
+*
+
+WNI_CFG_MANUFACTURER_OUI S 3 8
+V RO NP
+NONE
+3 0x0 0xa 0xf5
+V RO NP
+NONE
+3 0x0 0xa 0xf5
+
+*
+* Manufacture Name (from eeprom)
+*
+
+WNI_CFG_MANUFACTURER_NAME S 65 8
+V RO NP
+NONE
+8 0x51 0x75 0x61 0x6c 0x63 0x6f 0x6D 0x6D
+V RO NP
+NONE
+8 0x51 0x75 0x61 0x6c 0x63 0x6f 0x6D 0x6D
+
+*
+* Model Number (from eeprom)
+*
+
+WNI_CFG_MODEL_NUMBER S 33 8
+V RO NP
+NONE
+6 0x4d 0x4e 0x31 0x32 0x33 0x34
+V RO NP
+NONE
+6 0x4d 0x4e 0x31 0x32 0x33 0x34
+
+
+
+*
+* Model Name (from eeprom)
+* WFR4031
+*
+
+WNI_CFG_MODEL_NAME S 33 8
+V RO NP
+NONE
+7 0x57 0x46 0x52 0x34 0x30 0x33 0x31
+V RO NP
+NONE
+7 0x57 0x46 0x52 0x34 0x30 0x33 0x31
+
+
+
+
+*
+* Manufacture Product Name (from eeprom)
+*
+
+WNI_CFG_MANUFACTURER_PRODUCT_NAME S 33 8
+V RO NP
+NONE
+6 0x31 0x31 0x6e 0x2D 0x41 0x50
+V RO NP
+NONE
+6 0x31 0x31 0x6e 0x2D 0x41 0x50
+
+
+*
+* Manufacture Product Version (from eeprom)
+*
+
+WNI_CFG_MANUFACTURER_PRODUCT_VERSION S 33 8
+V RO NP
+NONE
+6 0x53 0x4e 0x31 0x32 0x33 0x34
+V RO NP
+NONE
+6 0x53 0x4e 0x31 0x32 0x33 0x34
+
+*
+* Multi Domain Capability (11d) Enable
+*
+
+WNI_CFG_11D_ENABLED I 4 9
+V RW NP RESTART
+NONE
+0 1 1
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* per channel Max power transmit (in dBm)
+* this parameter correspond to the MAX_COUNTRY_EID
+* table of (Channel Number/num channel/max tx power)
+*
+* There is one table for 5GHz channels and one table for 2.4GHz channels
+*
+
+WNI_CFG_MAX_TX_POWER_2_4 S 128 8
+V RW NP
+NONE
+3 1 14 20
+V RW NP
+NONE
+3 1 14 20
+
+WNI_CFG_MAX_TX_POWER_5 S 128 8
+V RW NP
+NONE
+3 36 126 20
+V RW NP
+NONE
+3 36 126 20
+
+*
+* Cell size configurations. These are canned configurations for a specified
+* cell size.
+*
+WNI_CFG_NETWORK_DENSITY I 4 9
+V RW NP
+HAL
+0 3 3
+V RW NP
+HAL
+0 3 0
+
+#ENUM LOW 0
+#ENUM MEDIUM 1
+#ENUM HIGH 2
+#ENUM ADAPTIVE 3
+
+
+*
+* Adaptive Threshold Algorithm
+*
+WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM I 4 9
+V RW NP
+HAL
+1 2 2
+V RW NP
+HAL
+1 2 2
+
+#ENUM CARRIER 1
+#ENUM CORRELATION 2
+
+
+
+*
+* Current TX Antenna
+*
+
+WNI_CFG_CURRENT_TX_ANTENNA I 4 9
+V RW NP
+HAL
+1 1 1
+V RW NP
+HAL
+1 2 2
+
+*
+* Current RX Antenna
+*
+
+WNI_CFG_CURRENT_RX_ANTENNA I 4 9
+V RW NP
+HAL
+1 2 2
+V RW NP
+HAL
+1 3 3
+
+*
+* Current TX Power Level
+*
+
+WNI_CFG_CURRENT_TX_POWER_LEVEL I 4 9
+V RW NP
+NONE
+0 128 27
+V RW NP
+NONE
+0 128 27
+
+
+*
+
+
+
+
+* Parameter to indicate or not new BSS found
+*
+
+WNI_CFG_NEW_BSS_FOUND_IND I 4 9
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+
+*
+* Qualcomm Prop Rates are disabled by default
+*
+WNI_CFG_PROPRIETARY_RATES_ENABLED I 4 12
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+
+*
+* AP node Name
+*
+
+WNI_CFG_AP_NODE_NAME S 32 8
+NV RO NP
+NONE
+0
+V RW NP RESTART
+NONE
+0
+
+*
+* Country code (from EEPROM)
+*
+
+WNI_CFG_COUNTRY_CODE S 3 8
+V RW NP
+NONE
+0
+V RW NP
+NONE
+3 0x11 0x22 0x33
+
+*
+* Spectrum Management (11h) enable/disable
+*
+
+WNI_CFG_11H_ENABLED I 4 12
+V RW NP RESTART
+NONE
+0 1 1
+V RW NP RESTART
+NONE
+0 1 1
+
+*
+* Wait for CNF Timeout. CNF include (RE)ASSOC, DISASSOC, AUTH, DEAUTH,
+* DUMMY packet
+*
+
+WNI_CFG_WT_CNF_TIMEOUT I 4 12
+V RW NP
+NONE
+10 3000 1000
+V RW NP
+NONE
+10 3000 1000
+
+*
+* Proximity, set it for very short distances
+* Proxmity setting is applied via halPhySetNwDensity()
+*
+* close proximity off = densityOn is true. network density config applies.
+* close proximity on = densityOn is false. Don't care about network density config.
+*
+
+WNI_CFG_PROXIMITY I 4 12
+V RW NP
+HAL
+0 1 0
+V RW NP
+HAL
+0 1 0
+
+#ENUM OFF 0
+#ENUM ON 1
+
+*
+* Default LOG level
+*
+
+WNI_CFG_LOG_LEVEL I 4 12
+V RW NP
+NONE
+0 7 4
+V RW NP
+NONE
+0 7 4
+
+*
+* OLBC detection timeout
+*
+
+WNI_CFG_OLBC_DETECT_TIMEOUT I 4 12
+V RW NP
+NONE
+1000 30000 10000
+V RW NP
+NONE
+1000 30000 10000
+
+**********************************
+* Protection Enable
+*
+*LOWER byte for associated stations
+*UPPER byte for overlapping stations.
+*11g ==> protection from 11g
+*11b ==> protection from 11b
+*each byte will have the following info
+*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+*reserved reserved RIFS Lsig n-GF ht20 11g 11b
+**********************************
+WNI_CFG_PROTECTION_ENABLED I 4 9
+V RW NP RESTART
+LIM
+0 0xffff 0xffff
+V RW NP RESTART
+LIM
+0 0xffff 0xffff
+
+#ENUM FROM_llA 0
+#ENUM FROM_llB 1
+#ENUM FROM_llG 2
+#ENUM HT_20 3
+#ENUM NON_GF 4
+#ENUM LSIG_TXOP 5
+#ENUM RIFS 6
+#ENUM OBSS 7
+#ENUM OLBC_FROM_llA 8
+#ENUM OLBC_FROM_llB 9
+#ENUM OLBC_FROM_llG 10
+#ENUM OLBC_HT20 11
+#ENUM OLBC_NON_GF 12
+#ENUM OLBC_LSIG_TXOP 13
+#ENUM OLBC_RIFS 14
+#ENUM OLBC_OBSS 15
+
+
+* ****************************************
+*
+* 11G Protection Enable Always
+* Valid only if protection is enabled
+* forces uses of protection regardless of legacy stations
+*
+
+WNI_CFG_11G_PROTECTION_ALWAYS I 4 9
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*********************************************
+* Force protection
+* 0 : disable protection
+* 1 : CTS
+* 2 : RTS by threshold (threshold nonzero)
+* 3 : dual CTS (not supported right now)
+* 4 : RTS (threshold 0)
+* 5 : auto
+
+WNI_CFG_FORCE_POLICY_PROTECTION I 4 9
+V RW NP RESTART
+HAL
+0 5 5
+V RW NP RESTART
+HAL
+0 5 5
+
+#ENUM DISABLE 0
+#ENUM CTS 1
+#ENUM RTS 2
+#ENUM DUAL_CTS 3
+#ENUM RTS_ALWAYS 4
+#ENUM AUTO 5
+
+
+
+
+
+
+********************************************
+* 11G Short Preamble Enable
+*
+
+WNI_CFG_11G_SHORT_PREAMBLE_ENABLED I 4 9
+V RW NP RESTART
+NONE
+0 1 0
+V RW NP RESTART
+NONE
+0 1 0
+
+*
+* 11G Short Slot Time Enable (change requires restart)
+* This is the admin state of short slot support.
+
+WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED I 4 9
+V RW NP RESTART
+NONE
+0 1 1
+V RW NP RESTART
+NONE
+0 1 1
+
+*
+* Calibration periodicity (minutes)
+*
+
+WNI_CFG_CAL_PERIOD I 4 12
+V RW NP
+HAL
+2 10 5
+V RW NP
+HAL
+2 10 5
+
+*
+* Statistics collection periodicity (seconds)
+*
+
+WNI_CFG_STATS_PERIOD I 4 12
+V RW NP
+HAL
+1 10 10
+V RW NP
+HAL
+1 10 10
+
+*
+* Calibration on/off control
+*
+
+WNI_CFG_CAL_CONTROL I 4 12
+V RW NP
+HAL
+0 1 0
+V RW NP
+HAL
+0 1 0
+
+#ENUM CAL_ON 0
+#ENUM CAL_OFF 1
+
+
+*
+* Parameter to allow 11g only STAs while operating in 11g mode
+*
+
+WNI_CFG_11G_ONLY_POLICY I 4 12
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* Packet Classification
+* This flag is a bitmask used to indicate which
+* frame classifier to be enabled:
+* b0: DSCP
+* b1: 802.1P
+*
+
+WNI_CFG_PACKET_CLASSIFICATION I 4 12
+V RW NP
+HAL
+0 3 0
+V RW NP
+HAL
+0 3 0
+
+#ENUM DISABLED 0
+#ENUM DSCP 1
+#ENUM 8021P 2
+#ENUM ALL 3
+
+*
+* WME Enabled (change requires restart)
+*
+
+WNI_CFG_WME_ENABLED I 4 8
+V RW NP RESTART
+NONE
+0 1 1
+V RW NP RESTART
+NONE
+0 1 1
+
+*
+* ADDTS response timeout (in ms)
+*
+
+WNI_CFG_ADDTS_RSP_TIMEOUT I 4 8
+V RW NP
+NONE
+0 65535 1000
+V RW NP
+NONE
+0 65535 1000
+
+
+ * Max SP Length indicates the max number of
+ * total buffered MSDUs and MMPDUs the WMM AP
+ * may deliver to WMM STA during any service period
+ * triggered by WMM STA.
+ * 1) If AP sends WMM IE with the UAPSD bit 0, max_sp_length=0
+ * 2) If WMM STA's all 4 UAPSD flag are set to 0, max_sp_length=0
+ * 3) If AP sends WMM IE with UAPSD=1, and at least one of stations
+ * UAPSD flag is set to 1, then max_sp_length can be set to:
+ * [b5:b6]=0x00: WMM AP may deliver all buffered frames
+ * [b5:b6]=0x10: WMM AP may deliver max 2 buffered frames
+ * [b5:b6]=0x01: WMM AP may deliver max 4 buffered frames
+ * [b5:b6]=0x11: WMM AP may deliver max 6 buffered frames
+
+WNI_CFG_MAX_SP_LENGTH I 4 8
+V RW NP
+NONE
+0 3 0
+V RW NP
+NONE
+0 3 0
+
+
+*
+* KEEP ALIVE STA Limit Threshold , used in AP to delete the STA
+* from Station Table which didn't respond to Probe Response Messages
+*
+
+WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD I 4 8
+NV RW NP
+NONE
+0 32 0
+V RW NP
+NONE
+0 32 0
+
+*
+* Parameter that specifies whether to send SSID
+* in Probe Response when SSID is suppressed
+*
+
+WNI_CFG_SEND_SINGLE_SSID_ALWAYS I 4 12
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* WSM Enabled (change requires restart)
+* Takes effect only if WME is also enabled
+*
+
+WNI_CFG_WSM_ENABLED I 4 8
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+* ****************************************
+*
+
+
+
+* Background Channel List
+* Contains pairs of {channelNumber, scanType}
+* where scanType = 0 indicates active scan and
+* = 1 indicates passive scan
+*
+*
+*WNI_CFG_BACKGROUND_SCAN_LIST S 128 8
+*V RW NP RESTART
+*LIM
+*60 36 0 40 0 44 0 48 0 52 0 56 0 60 0 64 0 1 0 6 0 11 0 34 0 38 0 42 0 46 0 2 0 3 0 4 0 5 0 7 0 8 0 9 0 10 0 12 0 13 0 14 0 149 0 153 0 157 0 161 0
+*V RW NP RESTART
+*LIM
+*60 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 34 0 36 0 38 0 40 0 42 0 44 0 46 0 48 0 52 0 56 0 60 0 64 0 149 0 153 0 157 0 161 0
+*
+
+* ****************************************
+* EDCA paramters are contained in profiles - each profile contains
+* the parameters [ACM, AIFSN, CWmin, CWmax, TxOp] for four
+* access categories (i.e., four sets). Two such sets of four parameters
+* make a single profile: One set is used locally by the AP, the other set
+* is broadcast for use by stations.
+*
+* Cwmin and Cwmax are two bytes each, MSB first. So Cwmin of [3 255] is
+* equivalent to 0x3ff, i.e. 3*256+255=1023
+*
+* The profile to use is selected based on the valus of the profile select param
+* See ENUMs below for definitions of profile values
+*
+
+WNI_CFG_EDCA_PROFILE I 4 8
+V RW NP
+SCH
+0 255 1
+V RW NP
+SCH
+0 255 1
+
+#ENUM ANI 0
+#ENUM WMM 1
+#ENUM TIT_DEMO 2
+#ENUM MAX 3
+
+#ENUM ACM_IDX 0
+#ENUM AIFSN_IDX 1
+#ENUM CWMINA_IDX 2
+#ENUM CWMAXA_IDX 4
+#ENUM TXOPA_IDX 6
+#ENUM CWMINB_IDX 7
+#ENUM CWMAXB_IDX 9
+#ENUM TXOPB_IDX 11
+#ENUM CWMING_IDX 12
+#ENUM CWMAXG_IDX 14
+#ENUM TXOPG_IDX 16
+
+
+* ****************************************
+* Profile 0 (Airgo) parameters - AC_BK Local
+* ACM, AIFSN, [CWminH, CWminL, CWmaxH, CWmaxL, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACBK_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0
+
+*
+* Profile 0 (Airgo) parameters AC_BE Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACBE_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100
+V RW NP RESTART
+NONE
+17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100
+
+*
+* Profile 0 (Airgo) parameters AC_VI Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACVI_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200
+V RW NP RESTART
+NONE
+17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200
+
+*
+* Profile 0 (Airgo) parameters AC_VO Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACVO_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100
+V RW NP RESTART
+NONE
+17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100
+
+*
+* Profile 0 (Airgo) parameters - AC_BK Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACBK S 20 8
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0
+
+*
+* Profile 0 (Airgo) parameters AC_BE Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACBE S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100
+V RW NP RESTART
+NONE
+17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100
+
+*
+* Profile 0 (Airgo) parameters AC_VI Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACVI S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200
+V RW NP RESTART
+NONE
+17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200
+
+*
+* Profile 0 (Airgo) parameters AC_VO Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_ANI_ACVO S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100
+V RW NP RESTART
+NONE
+17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100
+
+
+* ****************************************
+* Profile 1 (WME) parameters - AC_BK Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACBK_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0
+
+
+*
+* Profile 1 (WME) parameters AC_BE Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACBE_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 3 0 15 0 63 0 0 31 3 255 0 0 15 0 63 0
+V RW NP RESTART
+NONE
+17 0 3 0 15 0 63 0 0 15 0 63 0 0 15 0 63 0
+
+*
+* Profile 1 (WME) parameters AC_VI Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACVI_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 1 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94
+V RW NP RESTART
+NONE
+17 0 1 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94
+
+*
+* Profile 1 (WME) parameters AC_VO Local
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACVO_LOCAL S 20 8
+V RW NP RESTART
+NONE
+17 0 1 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47
+V RW NP RESTART
+NONE
+17 0 1 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47
+
+*
+* Profile 1 (WME) parameters - AC_BK Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACBK S 20 8
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0
+V RW NP RESTART
+NONE
+17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0
+
+*
+* Profile 1 (WME) parameters AC_BE Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACBE S 20 8
+V RW NP RESTART
+NONE
+17 0 3 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0
+V RW NP RESTART
+NONE
+17 0 3 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0
+
+*
+* Profile 1 (WME) parameters AC_VI Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACVI S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94
+V RW NP RESTART
+NONE
+17 0 2 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94
+
+*
+* Profile 1 (WME) parameters AC_VO Broadcast
+* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G
+*
+
+WNI_CFG_EDCA_WME_ACVO S 20 8
+V RW NP RESTART
+NONE
+17 0 2 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47
+V RW NP RESTART
+NONE
+17 0 2 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47
+
+*
+* Radar detector flag enable/disable
+*
+
+WNI_CFG_RDET_FLAG I 4 9
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+WNI_CFG_RADAR_CHANNEL_LIST S 20 8
+V RW NP RESTART
+NONE
+15 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140
+V RW NP RESTART
+NONE
+15 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140
+
+*
+* Local Power Constraint (dBm)
+*
+
+WNI_CFG_LOCAL_POWER_CONSTRAINT I 4 12
+V RW NP RESTART
+NONE
+0 255 0
+V RW NP RESTART
+NONE
+0 255 0
+
+* *********************************************************
+*
+* Admission Control Policy
+* used for admitting tspec's when either edca or hcca are in use
+*
+
+WNI_CFG_ADMIT_POLICY I 4 8
+V RW NP RESTART
+NONE
+0 2 0
+V RW NP
+SCH
+0 2 0
+
+#ENUM ADMIT_ALL 0
+#ENUM REJECT_ALL 1
+#ENUM BW_FACTOR 2
+
+*
+* Oversubscription factor for admission control
+* valid only when admit policy is set to BW_FACTOR
+* units are in terms of 1/10th of available bandwidth
+*
+
+WNI_CFG_ADMIT_BWFACTOR I 4 8
+V RW NP RESTART
+NONE
+0 100 20
+V RW NP
+SCH
+0 100 20
+
+* *********************************************************
+*
+* Number of "consecutive" Background Scan Failure needed
+* before LIM is forced to perform 1 aggressive background scan
+*
+WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE I 4 8
+V RW NP RESTART
+NONE
+0 256 60
+V RW NP RESTART
+NONE
+0 256 60
+
+
+*************************************
+* Feature: Channel Bonding
+*************************************
+*
+* Global flag to enable/disable Channel Bonding
+* 0 - Disable: Force disable channel bonding for all TC-ids
+* 1 - Enable: Force enable channel bonding for all TC-ids
+* 2 - no legacy bss: Enable channel bonding if no legacy BSS are present
+* 3 - no legacy all: Enable channel bonding if no legacy BSS or devices are present
+* 4 - intelligent: Enable channel bonding depending on load level on secondary channel
+*
+WNI_CFG_CHANNEL_BONDING_MODE I 4 12
+V RW NP RESTART
+LIM
+0 10 0
+V RW NP RESTART
+LIM
+0 10 0
+
+#ENUM DISABLE 0
+#ENUM ENABLE 1
+#ENUM IF_NO_LEGACY_BSS 2
+#ENUM IF_NO_LEGACY_ALL 3
+#ENUM INTELLIGENT 4
+
+
+*
+* When the channel is 40MHz wide, this CFG indicates
+* if the secondary channel is located above (at
+* a higher frequency), or located below (at a
+* lower frequency).
+*
+* 0 - There is no secondary channel. The channel is 20Mhz
+* 1 - LOWER: Secondary channel 40MHZ is located below the primary channel
+* 2 - CENTERED:Secondary channel and primary located at centered
+* 3 - HIGHER: Secondary channel 40 MHZ is located above the primary channel
+* 4 - 80MHZ_LOW_CENTERED : 20/40MHZ offset LOW 40/80MHZ offset CENTERED
+* 5 - 80MHZ_CENTERED_CENTERED : 20/40MHZ offset CENTERED 40/80MHZ offset CENTERED
+* 6 - 80MHZ_HIGH_CENTERED : 20/40MHZ offset HIGH 40/80MHZ offset CENTERED
+* 7 - 80MHZ_LOW_LOW: 20/40MHZ offset LOW 40/80MHZ offset LOW
+* 8 - 80MHZ_HIGH_LOW: 20/40MHZ offset HIGH 40/80MHZ offset LOW
+* 9 - 80MHZ_LOW_HIGH: 20/40MHZ offset LOW 40/80MHZ offset HIGH
+* 10 - 80MHZ_HIGH_HIGH: 20/40MHZ offset HIGH 40/80MHZ offset HIGH
+*
+WNI_CFG_CB_SECONDARY_CHANNEL_STATE I 4 12
+V RW NP
+NONE
+0 10 0
+V RW NP
+NONE
+0 10 0
+
+#ENUM NONE 0
+#ENUM LOWER 1
+#ENUM HIGHER 2
+#ENUM 11AC_20MHZ_LOW_40MHZ_CENTERED 3
+#ENUM 11AC_20MHZ_CENTERED_40MHZ_CENTERED 4
+#ENUM 11AC_20MHZ_HIGH_40MHZ_CENTERED 5
+#ENUM 11AC_20MHZ_LOW_40MHZ_LOW 6
+#ENUM 11AC_20MHZ_HIGH_40MHZ_LOW 7
+#ENUM 11AC_20MHZ_LOW_40MHZ_HIGH 8
+#ENUM 11AC_20MHZ_HIGH_40MHZ_HIGH 9
+
+*************************************
+* Feature: Dynamic Retry Rates
+*************************************
+*
+* When the short/long retry count reach the
+* adaptive_retry_threshold(0), then the retry0
+* template shall be used
+*
+WNI_CFG_DYNAMIC_THRESHOLD_ZERO I 4 12
+V RW NP
+HAL
+0 255 2
+V RW NP
+HAL
+0 255 2
+
+*
+* When the short/long retry count reach the
+* adaptive_retry_threshold(1), then the retry1
+* template shall be used
+*
+WNI_CFG_DYNAMIC_THRESHOLD_ONE I 4 12
+V RW NP
+HAL
+0 255 4
+V RW NP
+HAL
+0 255 4
+
+*
+* When the short/long retry count reach the
+* adaptive_retry_threshold(2), then the retry2
+* template shall be used
+*
+WNI_CFG_DYNAMIC_THRESHOLD_TWO I 4 12
+V RW NP
+HAL
+0 255 6
+V RW NP
+HAL
+0 255 6
+
+
+*
+* Trigger Station Background Scan Flag
+*
+WNI_CFG_TRIG_STA_BK_SCAN I 4 12
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 1
+
+* *********************************************************
+* control of dynamic EDCA parameter profile switching
+*
+* OOB, we would like to support WMM standard edca profile
+* However, when Airgo STA's join the BSS, we would like
+* to switch the profile to Airgo high-performance edca parameters
+*
+* This cfg supports that behaviour. It is used only if 11e qos
+* has been enabled and is ignored otherwise.
+*
+* When set to any value (other than unused), it determines the
+* edca profile to switch to when an Airgo STA joins the BSS.
+*
+* By default, we choose to switch to Airgo profile.
+*
+* NOTE: This parameter applies only to an AP
+*
+
+WNI_CFG_DYNAMIC_PROFILE_SWITCHING I 4 8
+V RW NP RESTART
+NONE
+0 255 255
+V RW NP RESTART
+NONE
+0 255 1
+
+#ENUM UNUSED 255
+
+* *********************************************************
+*
+* Scan control list
+* Contains pairs of {channelNumber, activeScanAllowedFlag}
+* where scanType = 1 indicates active scan is allowed, and
+* = 0 indicates passive scan is used
+* If a channel is not on this list, active scan is NOT allowed. So it is
+* sufficient to inlude only those channels where active scan is allowed
+* on this list.
+*
+* The list determines only whether active scan is allowed or not; it does not
+* determine which type of scan is actually performed.
+*
+
+WNI_CFG_SCAN_CONTROL_LIST S 128 8
+V RW NP RESTART
+LIM
+112 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 0 54 0 56 0 58 0 60 0 62 0 64 0 100 0 104 0 108 0 112 0 116 0 120 0 124 0 128 0 132 0 136 0 140 0 149 1 151 1 153 1 155 1 157 1 159 1 161 1 165 1 240 1 242 1 244 1 246 1 248 1 250 1 252 1
+V RW NP RESTART
+LIM
+112 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 0 54 0 56 0 58 0 60 0 62 0 64 0 100 0 104 0 108 0 112 0 116 0 120 0 124 0 128 0 132 0 136 0 140 0 149 1 151 1 153 1 155 1 157 1 159 1 161 1 165 1 240 1 242 1 244 1 246 1 248 1 250 1 252 1
+
+
+* ****************************************
+*
+* MIMO rates enabled (for rate adaptation, to start)
+*
+
+WNI_CFG_MIMO_ENABLED I 4 9
+V RW NP RELOAD
+NONE
+0 1 1
+V RW NP RELOAD
+NIM
+0 1 1
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+
+
+*
+* BLOCK ACK Enabled (change requires restart)
+* change default to ON
+* bit 0 ==> delayed BA
+* bit 1 ==> immediate BA
+WNI_CFG_BLOCK_ACK_ENABLED I 4 8
+V RW NP RESTART
+LIM
+0 3 0
+V RW NP RESTART
+LIM
+0 3 0
+
+#ENUM DELAYED 0
+#ENUM IMMEDIATE 1
+
+
+*
+*BA Activity check global timer
+*
+WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT I 4 7
+V RW NP
+HAL
+0 65535 1000
+V RW NP
+HAL
+0 65535 1000
+
+
+*
+* Rx STBC support
+*
+WNI_CFG_HT_RX_STBC I 4 7
+V RW NP RESTART
+LIM
+0 3 1
+V RW NP RESTART
+LIM
+0 3 1
+
+
+*
+* 1. HT capabilities Info: 2 bytes size
+*
+* Supported channel Width is set to 1 (40 Mhz)
+* SM Power Save is disabled.
+* GreenField support is enabled.
+* Short GI for 20 and 40Mhz is enabled.
+* Max AMSDU Size is set to 0(3839 Octets)
+* DSSS-CCK Mode is enabled.
+* LSIG TXOP Protection is disabled
+* Rest of the features are not supported at this moment.
+*
+* fedc ba98 7654 3210
+* 0000 0001 0010 0000
+*
+WNI_CFG_HT_CAP_INFO I 4 10
+V RW NP RESTART
+LIM
+0 0xffff 0x016c
+V RW NP RESTART
+LIM
+0 0xffff 0x106e
+
+#ENUM ADVANCE_CODING 0
+#ENUM SUPPORTED_CHAN_WIDTH_SET 1
+#ENUM SM_POWER_SAVE 2
+#ENUM GREEN_FIELD 4
+#ENUM SHORT_GI_20MHZ 5
+#ENUM SHORT_GI_40MHZ 6
+#ENUM TX_STBC 7
+#ENUM RX_STBC 8
+#ENUM DELAYED_BA 10
+#ENUM MAX_AMSDU_SIZE 11
+#ENUM DSSS_CCK_MODE_40MHZ 12
+#ENUM PSMP 13
+#ENUM STBC_CONTROL_FRAME 14
+#ENUM LSIG_TXOP_PROTECTION 15
+
+*
+* 2. HT Parameters Info: 1 byte size
+*
+* Max AMPDU Rx Factor is defined using bit #0 and #1
+* MPDU Density is defined using bit #2 thru #4.
+* The default values are,
+* 7654 3210
+* 0000 0010 --> 2 for RX AMPDU Factor, 0 for MPDU density
+*
+WNI_CFG_HT_AMPDU_PARAMS I 4 7
+V RW NP RESTART
+LIM
+0 0xff 0x00
+V RW NP RESTART
+LIM
+0 0xff 0x02
+
+#ENUM MAX_RX_AMPDU_FACTOR 0
+#ENUM MPDU_DENSITY 2
+#ENUM RESERVED 5
+
+*
+* 3. Supported MCS Set: 16 bytes size
+*
+* MCS #0-15 and #32 is supported.
+*
+WNI_CFG_SUPPORTED_MCS_SET S 16 7
+V RW P RESTART
+LIM
+16 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+V RW P RESTART
+LIM
+16 255 255 0 0 1 0 0 0 0 0 0 0 0 0 0 0
+
+*
+* 4. Extended HT Capabilities Info: 2 bytes size
+*
+* Only HTC Support is enabled, rest all features are not
+* supported at this moment.
+*
+* fedc ba98 7654 3210
+* 0000 0100 0000 0000
+*
+WNI_CFG_EXT_HT_CAP_INFO I 4 10
+V RW P RESTART
+LIM
+0 0xffff 0x0400
+V RW P RESTART
+LIM
+0 0xffff 0x0400
+
+#ENUM PCO 0
+#ENUM TRANSITION_TIME 1
+#ENUM RESERVED1 3
+#ENUM MCS_FEEDBACK 8
+#ENUM HTC_SUPPORT 10
+#ENUM RD_RESPONDER 11
+#ENUM RESERVED2 12
+
+
+*
+* 5. Transmit Beam Forming Capabiliries Info: 4 bytes size
+*
+WNI_CFG_TX_BF_CAP I 4 7
+V RO NP RESTART
+LIM
+0 0xffffffff 0x00000000
+V RO NP RESTART
+LIM
+0 0xffffffff 0x00000000
+
+*
+* 6. Antenna Selection Capabilities: 1 byte size
+*
+WNI_CFG_AS_CAP I 4 7
+V RW P RESTART
+LIM
+0 0xff 0x00
+V RW P RESTART
+LIM
+0 0xff 0x00
+
+#ENUM ANTENNA_SELECTION 0
+#ENUM EXPLICIT_CSI_FEEDBACK_TX 1
+#ENUM ANTENNA_INDICES_FEEDBACK_TX 2
+#ENUM EXPLICIT_CSI_FEEDBACK 3
+#ENUM ANTENNA_INDICES_FEEDBACK 4
+#ENUM RX_AS 5
+#ENUM TX_SOUNDING_PPDUS 6
+#ENUM RESERVED 7
+
+**************************************************
+* Beacon HT (High Through) Info IE
+***************************************************
+*
+* 3. HT Info Field1: 1 byte size.
+*
+* Secondary Channel Offset is set to 3 (Down) by default and will
+* be updated dynamically by DFS algorithm.
+* Channel Width is set to 1 (40 Mhz)
+* RIFS Mode is enabled
+* Rest of the features are not supported at this moment.
+*
+* 7654 3210
+* 0000 1111
+*
+WNI_CFG_HT_INFO_FIELD1 I 4 10
+V RW NP RESTART
+LIM
+0 0xff 0x0f
+V RW NP RESTART
+LIM
+0 0xff 0x0f
+
+#ENUM SECONDARY_CHANNEL_OFFSET 0
+#ENUM RECOMMENDED_CHANNEL_WIDTH 2
+#ENUM RIFS_MODE 3
+#ENUM PSMP_ACCESS_ONLY 4
+#ENUM SERVICE_INTERVAL_GRANULARITY 5
+
+*
+* 4. HT Info Field2: 2 bytes
+*
+* Operation mode is set to 0(Pure, GF) to begin with and
+* will be updated dynamically.
+* 'NonGF Devices present is also set to zero and
+* will be updated dynamically.
+*
+* fedc ba98 7654 3210
+* 0000 0000 0000 0000
+*
+WNI_CFG_HT_INFO_FIELD2 I 4 10
+V RW P
+LIM
+0 0xffff 0x00
+V RW P
+LIM
+0 0xffff 0x00
+
+#ENUM OP_MODE 0
+#ENUM NON_GF_DEVICES_PRESENT 2
+#ENUM RESERVED 3
+
+*
+* 5. HT Info Field3: 2 bytes
+*
+* fedc ba98 7654 3210
+* 0000 0000 0000 0000
+*
+* LSIG TXOP Full Protection will be zero to begin with and
+* updated dynamically.
+* Everything else is not supported at this moment.
+*
+WNI_CFG_HT_INFO_FIELD3 I 4 10
+V RW P
+LIM
+0 0xffff 0x0000
+V RW P
+LIM
+0 0xffff 0x0000
+
+#ENUM BASIC_STBC_MCS 0
+#ENUM DUAL_STBC_PROTECTION 7
+#ENUM SECONDARY_BEACON 8
+#ENUM LSIG_TXOP_PROTECTION_FULL_SUPPORT 9
+#ENUM PCO_ACTIVE 10
+#ENUM PCO_PHASE 11
+#ENUM RESERVED 12
+
+*
+* 6. Basic MCS Set: 16 bytes size
+*
+* For now set this to zero and don't put any restrictions.
+*
+WNI_CFG_BASIC_MCS_SET S 16 7
+V RW P RESTART
+LIM
+16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+V RW P RESTART
+LIM
+16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+
+*
+* 7. Current supported MCS Set: 16 bytes size
+*
+* For now set this to zero and don't put any restrictions.
+*
+WNI_CFG_CURRENT_MCS_SET S 16 7
+V RW P RESTART
+LIM
+16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+V RW P RESTART
+LIM
+16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+
+
+
+*
+* Greenfield Capability
+* By default Greenfield is enabled
+*
+WNI_CFG_GREENFIELD_CAPABILITY I 4 7
+V RW NP RESTART
+LIM
+0 1 0
+V RW NP RESTART
+LIM
+0 1 0
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+*
+* Maximum AMPDU Length
+* By default set to zero for 3895 octets
+*
+WNI_CFG_VHT_MAX_MPDU_LENGTH I 4 19
+V RW NP
+LIM
+0 2 0
+V RW NP
+LIM
+0 2 0
+
+*
+* Supported Channel Width Set
+* By default set to zero for
+* STAs does not support either 160 or 80+80MHz
+*
+WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET I 4 19
+V RW NP
+LIM
+0 0 0
+V RW NP
+LIM
+0 0 0
+
+*
+* LDPC Coding Capability
+* Riva/Pronto supports, default set to 1
+*
+WNI_CFG_VHT_LDPC_CODING_CAP I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Short GI for 80MHz
+* Riva/Pronto supports, default set to 1
+*
+WNI_CFG_VHT_SHORT_GI_80MHZ I 4 19
+V RW NP
+LIM
+0 1 1
+V RW NP
+LIM
+0 1 1
+
+*
+* Short GI for 160MHz and 80+80MHz
+* Riva/Pronto does not supports, default set to 0
+*
+WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Support for Transmission of 2x1 STBC
+* Riva/Pronto does not supports, default set to 0
+*
+WNI_CFG_VHT_TXSTBC I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Support for Reception of PPDUs using STBC
+* Riva/Pronto supports, default set to 1
+*
+WNI_CFG_VHT_RXSTBC I 4 19
+V RW NP
+LIM
+0 1 1
+V RW NP
+LIM
+0 1 1
+
+*
+* Support for Operating as SU Beamformer
+* Riva/Pronto does not supports, default set to 0
+*
+WNI_CFG_VHT_SU_BEAMFORMER_CAP I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Support for Operating as SU Beamformee
+* Riva does not support, But Pronto supports, default set to 0
+*
+WNI_CFG_VHT_SU_BEAMFORMEE_CAP I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Compressed Steering Number of Beamformer Antennas Supported
+* Riva does not support,Pronto supports, default set to 0
+*
+WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED I 4 19
+V RW NP
+LIM
+0 4 0
+V RW NP
+LIM
+0 4 0
+
+*
+* Number of Sounding Dimensions indicates Number
+* of antennas used by the beamformer when sending beamformed transmissions
+* Riva/Pronto does not support beamformer, default set to 0
+*
+WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS I 4 19
+V RW NP
+LIM
+0 3 0
+V RW NP
+LIM
+0 3 0
+
+*
+* MU Beamformer Capable
+* Riva/Pronto does not support, default set to 0
+*
+WNI_CFG_VHT_MU_BEAMFORMER_CAP I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* MU Beamformee Capable
+* Riva does not support but pronto supports, default set to 0
+*
+WNI_CFG_VHT_MU_BEAMFORMEE_CAP I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* VHT TXOP PS
+* Riva does not support but pronto supports, default set to 0
+*
+WNI_CFG_VHT_TXOP_PS I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* +HTC-VHT Capable
+* Riva does not support but pronto supports, default set to 0
+*
+WNI_CFG_VHT_HTC_VHTC_CAP I 4 19
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Maximum AMPDU Length exponent range 0-7
+* 2^(13+Max AMPDU Length)-1, default set to 0
+*
+WNI_CFG_VHT_AMPDU_LEN_EXPONENT I 4 19
+V RW NP
+LIM
+0 7 3
+V RW NP
+LIM
+0 7 3
+
+*
+* VHT Link Adaptation Capable
+* Riva does not support but pronto supports, default set to 0
+*
+WNI_CFG_VHT_LINK_ADAPTATION_CAP I 4 19
+V RW NP
+LIM
+0 3 0
+V RW NP
+LIM
+0 3 0
+
+*
+* VHT Rx Antenna Pattern Consistency
+*
+WNI_CFG_VHT_RX_ANT_PATTERN I 4 19
+V RW NP
+LIM
+0 1 1
+V RW NP
+LIM
+0 1 1
+
+*
+* VHT Tx Antenna Pattern Consistency
+*
+WNI_CFG_VHT_TX_ANT_PATTERN I 4 19
+V RW NP
+LIM
+0 1 1
+V RW NP
+LIM
+0 1 1
+
+*
+* RxMCS Map is 16 bits, The 2bit Max MCS for n SS field.
+* Indicates the maximum MCS that can be received for each
+* number of spacial streams. Riva supports MCS 0-9
+*
+WNI_CFG_VHT_RX_MCS_MAP I 4 19
+V RW NP
+LIM
+0 0xFFFF 0xFFFE
+V RW NP
+LIM
+0 0xFFFF 0xFFFE
+
+* TxMCS Map is 16 bits, The 2bit Max MCS for n SS field.
+* Indicates the maximum MCS that can be transmitted for each
+* number of spacial streams.
+*
+WNI_CFG_VHT_TX_MCS_MAP I 4 19
+V RW NP
+LIM
+0 0xFFFF 0xFFFE
+V RW NP
+LIM
+0 0xFFFF 0xFFFE
+
+*
+* Rx Highest supported data rate.
+*
+WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE I 4 19
+V RW NP
+LIM
+0 780 780
+V RW NP
+LIM
+0 780 780
+
+*
+* Tx Highest supported data rate.
+*
+WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE I 4 19
+V RW NP
+LIM
+0 780 780
+V RW NP
+LIM
+0 780 780
+
+*
+* Channel center freq Seg1
+*
+WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1 I 4 19
+V RW NP
+LIM
+0 256 0
+V RW NP
+LIM
+0 256 0
+
+*
+* Channel center freq Seg2 for 80+80 Mhz
+*
+WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2 I 4 19
+V RW NP
+LIM
+0 0 0
+V RW NP
+LIM
+0 0 0
+
+*
+* Basic MCS Set
+*
+WNI_CFG_VHT_BASIC_MCS_SET I 4 19
+V RW NP
+LIM
+0 0xFFFF 0xFFFE
+V RW NP
+LIM
+0 0xFFFF 0xFFFE
+
+*
+* MU-MIMO Capable STA Count
+*
+WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT I 4 19
+V RW NP
+LIM
+0 4 0
+V RW NP
+LIM
+0 4 0
+
+*
+* Spatial Stream Under-Utilization
+*
+WNI_CFG_VHT_SS_UNDER_UTIL I 4 19
+V RW NP
+LIM
+0 0 0
+V RW NP
+LIM
+0 0 0
+
+*
+* Forty MHZ Utilization
+*
+WNI_CFG_VHT_40MHZ_UTILIZATION I 4 19
+V RW NP
+LIM
+0 0 0
+V RW NP
+LIM
+0 0 0
+
+*
+* Eighty MHz Utilization
+*
+WNI_CFG_VHT_80MHZ_UTILIZATION I 4 19
+V RW NP
+LIM
+0 0 0
+V RW NP
+LIM
+0 0 0
+
+*
+* Hundred Sixty MHz Utilization
+*
+WNI_CFG_VHT_160MHZ_UTILIZATION I 4 19
+V RW NP
+LIM
+0 0 0
+V RW NP
+LIM
+0 0 0
+
+*
+* Maximum AMSDU length
+* User can set it to either 3839 or 7935 bytes.
+*
+WNI_CFG_MAX_AMSDU_LENGTH I 4 7
+V RW NP RESTART
+LIM
+0 1 0
+V RW NP RESTART
+LIM
+0 1 0
+
+#ENUM SHORT_3839_BYTES 0
+#ENUM LONG_7935__BYTES 1
+
+
+*
+* Minimum MPDU Start Spacing
+* Determines the minimum time between the start of adjacent MPDUs within an AMPDU.
+* Set to 0 for no restriction
+* Set to 1 for 1/4 s
+* Set to 2 for 1/2 s
+* Set to 3 for 1 s
+* Set to 4 for 2 s
+* Set to 5 for 4 s
+* Set to 6 for 8 s
+* Set to 7 for 16 s
+* default is set to 0
+WNI_CFG_MPDU_DENSITY I 4 7
+V RW NP RESTART
+LIM
+0 7 0
+V RW NP RESTART
+LIM
+0 7 0
+
+*
+* NUM BUFFERS ADVERTISED
+* Defines number of buffers advertised in ADDBA
+*
+WNI_CFG_NUM_BUFF_ADVERT I 4 7
+V RW NP
+LIM
+0 128 64
+V RW NP
+LIM
+0 128 64
+
+*
+* Maximum Rx AMPDU Factor
+* Indicates the maximum length of A-MPDU
+* that the STA can receive.
+* The Maximum Rx A-MPDU defined by this field is equal to (2 ^ (13 + MAX RX AMPDU FActor))-1 octets.
+* Maximum Rx A-MPDU Factor is an integer in the range 0 to 3.
+* default is set to 2 for 32K max RX side.
+*
+WNI_CFG_MAX_RX_AMPDU_FACTOR I 4 7
+V RW NP RESTART
+LIM
+0 3 3
+V RW NP RESTART
+LIM
+0 3 3
+
+
+*
+* Short GI support for the reception of 20Mhz packets
+* By default it is enabled
+*
+WNI_CFG_SHORT_GI_20MHZ I 4 7
+V RW NP RESTART
+LIM
+0 1 1
+V RW NP RESTART
+LIM
+0 1 1
+
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+
+*
+* Short GI support for the reception of 40Mhz packets
+* By default it is enabled
+*
+WNI_CFG_SHORT_GI_40MHZ I 4 7
+V RW NP RESTART
+LIM
+0 1 0
+V RW NP RESTART
+LIM
+0 1 1
+
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+
+*
+* RIFS support on TX Side
+* on RX side it is always supported, it is mandatory
+*
+WNI_CFG_RIFS_ENABLED I 4 7
+V RW NP RESTART
+NONE
+0 1 1
+V RW NP RESTART
+NONE
+0 1 1
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+
+* *********************************************************
+*
+* Power Save Configuration
+*
+WNI_CFG_MAX_PS_POLL I 4 5
+V RW NP
+LIM
+0 255 0
+NV RW NP
+LIM
+0 255 0
+
+
+WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE I 4 5
+V RW NP
+LIM
+1 20 20
+NV RW NP
+LIM
+1 20 20
+
+
+*
+* Period for which Firmware will collect the
+* RSSI stats. Its in units of beacon interval.
+* Rssi Filter period should always be >=
+* the num_beacon_per_rssi_average.
+*
+WNI_CFG_RSSI_FILTER_PERIOD I 4 5
+V RW NP
+LIM
+0 255 5
+NV RW NP
+LIM
+0 255 5
+
+
+WNI_CFG_MIN_RSSI_THRESHOLD I 4 5
+V RW NP
+LIM
+0 10 10
+NV RW NP
+LIM
+0 10 10
+
+
+WNI_CFG_NTH_BEACON_FILTER I 4 5
+V RW NP
+LIM
+0 255 10
+NV RW NP
+LIM
+0 255 10
+
+
+WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE I 4 5
+V RW NP
+LIM
+0 1 0
+NV RW NP
+LIM
+0 1 0
+
+
+WNI_CFG_SCAN_IN_POWERSAVE I 4 5
+V RW NP
+LIM
+0 1 1
+V RW NP
+LIM
+0 1 1
+
+
+*
+* Ignore DTIM support - If disabled(value=0), HAL will
+* try to align the Listen Interval to the DTIM
+* period and the following rules will be applied:
+* 1) If LI=DTIM, then set LI=DTIM
+* 2) If LI<DTIM, then align LI to DTIM
+* 3) If LI>DTIM, then set LI=DTIM
+*
+WNI_CFG_IGNORE_DTIM I 4 5
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+* *********************************************************
+*
+* WoWLAN Configuration The following configurations
+* are valid only when magicPktEnable = 1.
+*
+WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE I 4 5
+V RW NP
+NONE
+0 1 1
+NV RW NP
+NONE
+0 1 0
+
+
+WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE I 4 5
+V RW NP
+NONE
+0 1 1
+NV RW NP
+NONE
+0 1 0
+
+
+WNI_CFG_WOWLAN_DEAUTH_ENABLE I 4 5
+V RW NP
+NONE
+0 1 1
+NV RW NP
+NONE
+0 1 0
+
+
+WNI_CFG_WOWLAN_DISASSOC_ENABLE I 4 5
+V RW NP
+NONE
+0 1 1
+NV RW NP
+NONE
+0 1 0
+
+
+WNI_CFG_WOWLAN_MAX_MISSED_BEACON I 4 5
+V RW NP
+NONE
+0 65535 40
+NV RW NP
+NONE
+0 65535 40
+
+*
+* Timeout value in units of us. It requests
+* hardware to unconditionally wake up after
+* it has stayed in WoWLAN mode for some time.
+*
+WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD I 4 5
+V RW NP
+NONE
+0 65535 65535
+NV RW NP
+NONE
+0 65535 65535
+
+
+*
+* BA timeout in TUs, set to 1 minute = approx 58593 TUs
+* 16 bit wide
+*
+WNI_CFG_BA_TIMEOUT I 4 7
+V RW NP RESTART
+HAL
+0 0xffff 0
+V RW NP
+HAL
+0 0xffff 0
+
+
+*
+* This threshold is registered with a traffic monitoring interface (probably HAL),
+* on a per-STA, per-TID basis. Once this threshold has been reached,
+* HAL will indicate to PE that the threshold has been reached for that TID.
+* PE is then free to negotiate a BA session for that peer
+* defaults to 128
+* 16 bit wide
+*
+WNI_CFG_BA_THRESHOLD_HIGH I 4 7
+V RW NP RESTART
+HAL
+0 0xffff 0x80
+V RW NP
+HAL
+0 0xffff 0x80
+
+
+*
+* MAX BA Buffers to be allocated.
+* This count is system wide.
+* 16 bit wide
+*
+WNI_CFG_MAX_BA_BUFFERS I 4 7
+V RW NP RESTART
+HAL
+0 2560 2560
+V RW NP
+HAL
+0 2560 2560
+
+
+*
+* MAX BA Sessions.
+* This count is system wide.
+* 16 bit wide
+*
+WNI_CFG_MAX_BA_SESSIONS I 4 7
+V RW NP RESTART
+HAL
+0 64 40
+V RW NP
+HAL
+0 64 40
+
+
+*
+* BA setup based on Traffic
+*
+WNI_CFG_BA_AUTO_SETUP I 4 7
+V RW NP RESTART
+HAL
+0 1 1
+V RW NP RESTART
+HAL
+0 1 1
+
+#ENUM ENABLE 1
+#ENUM DISABLE 0
+
+*
+* Decline an ADDBA Request
+*
+WNI_CFG_ADDBA_REQ_DECLINE I 4 7
+V RW NP RESTART
+LIM
+0 0xff 0
+V RW NP RESTART
+LIM
+0 0xff 0
+
+*
+* Valid Channel List
+*
+
+WNI_CFG_BG_SCAN_CHANNEL_LIST S 100 8
+V RW NP
+LIM
+55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252
+V RW NP
+LIM
+55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252
+
+
+*
+* AMPDU default TX medium Time (in us)
+*
+WNI_CFG_MAX_MEDIUM_TIME I 4 8
+V RW NP
+HAL
+0 65535 2048
+V RW NP
+HAL
+0 65535 2048
+
+
+*
+* Maximum number of MPDUs in single A-MPDU.
+*
+WNI_CFG_MAX_MPDUS_IN_AMPDU I 4 8
+V RW NP
+HAL
+0 65535 64
+V RW NP
+HAL
+0 65535 64
+
+
+*
+* Auto BSSID - When set, BSSID is generated automatically in IBSS, else BSSID in cfg will be used.
+*
+
+WNI_CFG_IBSS_AUTO_BSSID I 4 0
+V RW NP
+NONE
+0 1 1
+NV RW NP
+NONE
+0 1 1
+
+*
+* Include Additional IEs in probe request.
+*
+WNI_CFG_PROBE_REQ_ADDNIE_FLAG I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* Include Additional IE in probe request.
+*
+WNI_CFG_PROBE_REQ_ADDNIE_DATA S 255 0
+V RW NP
+NONE
+0 0
+V RW NP
+NONE
+0 0
+
+*
+* Include Additional IEs in probe response.
+*
+WNI_CFG_PROBE_RSP_ADDNIE_FLAG I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* Include Additional IE in probe response.
+*
+WNI_CFG_PROBE_RSP_ADDNIE_DATA1 S 255 0
+V RW NP
+NONE
+0 0
+V RW NP
+NONE
+0 0
+
+*
+* Include Additional IE in probe response.
+*
+WNI_CFG_PROBE_RSP_ADDNIE_DATA2 S 255 0
+V RW NP
+NONE
+0 0
+V RW NP
+NONE
+0 0
+
+*
+* Include Additional IE in probe response.
+*
+WNI_CFG_PROBE_RSP_ADDNIE_DATA3 S 255 0
+V RW NP
+NONE
+0 0
+V RW NP
+NONE
+0 0
+
+*
+* Include Additional IEs in assoc response.
+*
+WNI_CFG_ASSOC_RSP_ADDNIE_FLAG I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* Include Additional IE in assoc response.
+*
+WNI_CFG_ASSOC_RSP_ADDNIE_DATA S 255 0
+V RW NP
+NONE
+0 0
+V RW NP
+NONE
+0 0
+
+*
+* Include Additional P2P IEs in probe request.
+*
+WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* Include Additional P2P IE in probe request.
+*
+WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA S 255 0
+V RW NP
+NONE
+0 0
+V RW NP
+NONE
+0 0
+
+
+*
+* Include Additional IEs in probe response/beacon.
+*
+WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG I 4 0
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+
+*
+* Include Additional IEs in probe response/beacon.
+*
+WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA S 255 0
+V RW NP
+LIM
+0 0
+V RW NP
+LIM
+0 0
+
+
+*
+* wpsApEnable and wpsStaEnable is specified in here
+* wpsApEnable is bit #0 and wpsStaEnable is bit #1
+*
+WNI_CFG_WPS_ENABLE I 4 7
+V RW NP
+LIM
+0 0xff 0
+V RW NP
+LIM
+0 0xff 0
+
+#ENUM AP 1
+#ENUM STA 2
+
+WNI_CFG_WPS_STATE I 4 7
+V RW NP
+LIM
+0 0xff 1
+V RW NP
+LIM
+0 0xff 1
+
+*
+* TRUE => include this information in Probe Requests, FALSE => omit it
+*
+
+WNI_CFG_WPS_PROBE_REQ_FLAG I 4 7
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+*
+* Wi-Fi Protected Setup Version
+*
+* This one-byte field is broken into a four-bit major
+* part using the top MSBs and four-bit minor part
+* using the LSBs. As an example, version 3.2 would be 0x32.
+*
+
+WNI_CFG_WPS_VERSION I 4 7
+V RW NP
+LIM
+0 0xff 0x10
+V RW NP
+LIM
+0 0xff 0x10
+
+*
+* Wi-Fi Protected Setup Request type
+* 0x00: Enrollee, Info only
+* 0x01: Enrollee, open 802.1X
+* 0x02: Registrar
+* 0x03: WLAN Manager Registrar
+
+WNI_CFG_WPS_REQUEST_TYPE I 4 7
+V RW NP
+LIM
+0 0xff 0x00
+V RW NP
+LIM
+0 0xff 0x03
+
+* Configuration Method(s)
+*
+* The Config Methods Data component lists the configuration methods
+* the Enrollee or Registrar supports. The list is a bitwise OR of
+* values from the table below. In addition to Config Methods, APs and
+* STAs that support the UPnP Management Interface must support the
+* Permitted Config Methods attribute, which is used to control the
+* Config Methods that are enabled on that AP.
+*
+* Value Hardware Interface
+* 0x0001 USBA (Flash Drive)
+* 0x0002 Ethernet
+* 0x0004 Label
+* 0x0008 Display
+* 0x0010 External NFC Token
+* 0x0020 Integrated NFC Token
+* 0x0040 NFC Interface
+* 0x0080 PushButton
+* 0x0100 Keypad
+*
+* The bottom 16 bits contain the configuration method(s) when acting
+* as an Enrollee, and the top 16 when acting as a Registrar.
+*
+* QNE-TODO: Merge this with the inappropriately named
+* 'WNI_CFG_WSC_AP_CFG_METHOD'-- this one can serve both puposes.
+*
+
+WNI_CFG_WPS_CFG_METHOD I 4 7
+V RW NP
+LIM
+0 0xFFFFFFFF 0x00000008
+V RW NP
+LIM
+0 0xFFFFFFFF 0x018c018e
+
+* UUID
+* The universally unique identifier (UUID) element is a unique
+* GUID generated by the Enrollee or Registrar. It uniquely identifies
+* an operational device and should survive reboots and resets. The
+* UUID is provided in binary format. If the device also supports UPnP,
+* then the UUID corresponds to the UPnP UUID.
+*
+* QNE-TODO: Re-name their cfg from 'WNI_CFG_UUID'
+
+WNI_CFG_WPS_UUID S 16 8
+V RW NP
+LIM
+6 0xa 0xb 0xc 0xd 0xe 0xf
+V RW NP
+LIM
+6 0xa 0xb 0xc 0xd 0xe 0xf
+
+************************************************************************
+* The following cfgs contains the primary type of the device. Its format
+* follows:
+*
+* 0 1 2 3
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | Attribute ID | Length |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | Category ID | OUI (1-2) |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+* | OUI (3-4) | Sub Category ID |
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*
+* Vendor-specific sub-categories are designated by setting the OUI to the
+* value associated with that vendor. Note that a four-byte subdivided OUI
+* is used. For the predefined values, the Wi-Fi Alliance OUI of 00 50 F2 04
+* is used. The predefined values for Category ID and Sub Category ID are
+* provided in the next table. There is no way to indicate a vendor-specific
+* main device category. The OUI applies only to the interpretation of the
+* Sub Category. If a vendor does not use sub categories for their OUI, the
+* three-byte OUI occupies the first three bytes of the OUI field and the
+* fourth byte is set to zero.
+*
+* Category ID Value Sub Category ID Value
+* Computer 1 PC 1
+* Server 2
+* Media Center 3
+* Input Device 2
+* Printers, Scanners, Printer 1
+* Faxes and Copiers 3 Scanner 2
+* Camera 4 Digital Still Camera 1
+* Storage 5 NAS 1
+* Network AP 1
+* Infrastructure 6 Router 2
+* Switch 3
+* Displays 7 Television 1
+* Electronic Picture Frame 2
+* Projector 3
+* Multimedia Devices 8 DAR 1
+* PVR 2
+* MCX 3
+* Gaming Devices 9 Xbox 1
+* Xbox360 2
+* Playstation 3
+* Telephone 10 Windows Mobile 1
+*
+************************************************************************
+
+* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_CATEGORY'
+WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY I 4 7
+V RW NP
+LIM
+0 0xffff 1
+V RW NP
+LIM
+0 0xffff 6
+
+* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_OUI'
+WNI_CFG_WPS_PIMARY_DEVICE_OUI I 4 7
+V RW NP
+LIM
+0 0xffffffff 0x0050f204
+V RW NP
+LIM
+0 0xffffffff 0x0050f204
+
+* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_SUB_CATEGORY'
+WNI_CFG_WPS_DEVICE_SUB_CATEGORY I 4 7
+V RW NP
+LIM
+0 0xffff 1
+V RW NP
+LIM
+0 0xffff 1
+
+* Association State
+*
+
+* The Association State component shows the configuration and previous
+* association state of the wireless station when sending a Discovery
+* request.
+*
+* Association State Description
+* 0 Not Associated
+* 1 Connection Success
+* 2 Configuration Failure
+* 3 Association Failure
+* 4 IP Failure
+
+WNI_CFG_WPS_ASSOCIATION_STATE I 4 7
+V RW NP
+LIM
+0 0xffff 0
+V RW NP
+LIM
+0 0xffff 0
+
+* Configuration Error
+*
+* The Configuration Error component shows the result of the device
+* attempting to configure itself and to associate with the WLAN.
+*
+* Configuration Error Description
+* 0 No Error
+* 1 OOB Interface Read Error
+* 2 Decryption CRC Failure
+* 3 2.4 channel not supported
+* 4 5.0 channel not supported
+* 5 Signal too weak
+* 6 Network auth failure
+* 7 Network association failure
+* 8 No DHCP response
+* 9 Failed DHCP config
+* 10 IP address conflict
+* 11 Couldnt connect to Registrar
+* 12 Multiple PBC sessions detected
+* 13 Rogue activity suspected
+* 14 Device busy
+* 15 Setup locked
+* 16 Message Timeout
+* 17 Registration Session Timeout
+* 18 Device Password Auth Failure
+*
+* The Device busy error is returned if the sending device is unable to
+* respond to the request due to some internal conflict or resource
+* contention issue. For example, if a device is only capable of
+* performing a single instance of the Registration Protocol at a time,
+* it may return this error in response to attempts to start another
+* instance in the middle of an active session.
+
+WNI_CFG_WPS_CONFIGURATION_ERROR I 4 7
+V RW NP
+LIM
+0 0xffff 0
+V RW NP
+LIM
+0 0xffff 0
+
+* Device Password ID
+*
+
+* This attribute is used to identify a device password. There are six
+* predefined values and ten reserved values. If the Device Password ID is
+* Default, the Enrollee should use its PIN password (from the label or
+* display). This password may correspond to the label, display, or a
+* user-defined password that has been configured to replace the original
+* device password.
+*
+* User-specified indicates that the user has overridden the password with a
+* manually selected value. Machine-specified indicates that the original
+* PIN password has been overridden by a strong, machinegenerated device
+* password value. The Rekey value indicates that the device's 256-bit
+* rekeying password will be used. The PushButton value indicates that the
+* PIN is the all-zero value reserved for the PushButton Configuration
+* method.
+*
+* The Registrar-specified value indicates a PIN that has been obtained from
+* the Registrar (via a display or other out-of-band method). This value may
+* be further augmented with the optional 'Identity' attribute in M1. This
+* augmentation is useful when multiple predefined UserID/PIN pairs have been
+* established by a Registrar such as an authenticator used for Hotspot
+* access. If the Device Password ID in M1 is not one of the predefined or
+* reserved values, it corresponds to a password given to the Registrar as an
+* OOB Device Password.
+*
+* Value Description
+* 0x0000 Default (PIN)
+* 0x0001 User-specified
+* 0x0002 Machine-specified
+* 0x0003 Rekey
+* 0x0004 PushButton
+* 0x0005 Registrar-specified
+* 0x0006 - 0x000F Reserved'
+*
+
+WNI_CFG_WPS_DEVICE_PASSWORD_ID I 4 7
+V RW NP
+LIM
+0 0xffffffff 0
+V RW NP
+LIM
+0 0xffffffff 0
+
+*
+* WPS Association
+*
+* Wi-Fi Protected Setup requires a prospective enrollee to associate to
+* an AP in the network in which the STA would like to enroll. Once
+* associated, the enrollment takes place over an EAPOL conversation
+* (there's actually a new EAP method: EAP-WSC). The STA would
+* presumably send an EAPOL-Start over his new link, to which the AP
+* would respond with an EAP Identity Request. When the STA sends back
+* "WSC-Enrollee-1" as his EAP Identity, the AP knows that he's got a WPS
+* supplicant on his hands, and proceeds to talk EAP-WSC.
+*
+* Toward the end of the specification's development, a problem came up.
+* Microsoft's EAP supplicant on XP SP1 & SP2 will send an EAPOL-Start,
+* no matter what. Even if the AP is beaconing WPA-PSK, say, the MS
+* supplicant will send an EAPOL-Start. If it receives an EAP Identity
+* Request in return, it decides that the AP is really using 802.1x
+* authentication, and proceeds on that assumption.
+*
+* Now, imagine an AP that is configured for WPA-PSK, and is WPS-capable.
+* It receives an association request from some STA, and then sees an
+* EAPOL-Start from the newly joined STA. It naturally sends back an EAP
+* Identity Request to see if the new STA wants to talk EAP-WSC. On
+* Windows XP SP1 & SP2, the supplicant will take that to mean that this
+* AP is using 802.1x authentication, and will never let the user provide
+* the PSK. Consequently, WZC will never be able to associate with this
+* AP.
+*
+* Naturally, Microsoft's solution was to have the world change to
+* accommodate them. After a lot of back & forth, the WFA decided on the
+* following change to the WPS spec: when associating for purposes of WPS
+* enrollment, "A client that intends to use the EAP-WSC method with a
+* WSC enabled AP may include a WSC IE in its 802.11 (re)association
+* request. If a WSC IE is present in the (re)association request, the AP
+* shall engage in EAP-WSC with the station and must not attempt other
+* security handshake. If the client does not include a WSC IE in its
+* 802.11 (re)association request, it must send its 802.11 Authentication
+* frame with Authentication set to open and an 802.11 Association
+* Request frame without an RSN IE or SSN IE, regardless of the network
+* type that is hosted by the AP. On successful association, the client
+* will then send an EAPOL-Start to the AP and wait for
+* EAP-Request/Identity. When the client receives an EAP Request/
+* Identity, it will respond with EAP-Response/Identity and the
+* appropriate WSC string to indicate if it is an Enrollee or Registrar.
+* '
+*
+* This configuration variable contains a bitvector:
+*
+* 0x0001 Incldue the WPS Information Element in Assoc Request frames
+* 0x0002 Elide the the WPA and RSN Information Elements from the
+* Assoc Request frame
+*
+
+WNI_CFG_WPS_ASSOC_METHOD I 4 7
+V RW NP
+LIM
+0 0xffff 0
+V RW NP
+LIM
+0 0xffff 0
+
+*
+* Low gain override
+*
+
+WNI_CFG_LOW_GAIN_OVERRIDE I 4 9
+V RW NP
+HAL
+0 1 0
+V RW NP
+HAL
+0 1 0
+
+*
+* Listen Mode Enable/Disable
+*
+
+WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE I 4 7
+V RW NP
+HAL
+0 128 128
+V RW NP
+HAL
+0 128 128
+
+*
+* On chip reodering polling threshold
+*
+
+WNI_CFG_RPE_POLLING_THRESHOLD I 4 2
+V RW NP
+HAL
+0 65535 10
+V RW NP
+HAL
+0 65535 10
+
+*
+* On chip reodering aging threshold for AC0
+*
+
+WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG I 4 2
+V RW NP
+HAL
+0 65535 30
+V RW NP
+HAL
+0 65535 30
+
+*
+* On chip reodering aging threshold for AC1
+*
+
+WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG I 4 2
+V RW NP
+HAL
+0 65535 30
+V RW NP
+HAL
+0 65535 30
+
+*
+* On chip reodering aging threshold for AC2
+*
+
+WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG I 4 2
+V RW NP
+HAL
+0 65535 30
+V RW NP
+HAL
+0 65535 30
+
+*
+* On chip reodering aging threshold for AC3
+*
+
+WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG I 4 2
+V RW NP
+HAL
+0 65535 30
+V RW NP
+HAL
+0 65535 30
+
+*
+* Number of On-Chip reorder sessions
+*
+
+WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS I 4 2
+V RW NP
+HAL
+0 2 1
+V RW NP
+HAL
+0 2 1
+
+
+*
+* Single RC for all TID
+*
+
+WNI_CFG_SINGLE_TID_RC I 4 7
+V RW NP
+NONE
+0 1 1
+V RW NP
+NONE
+0 1 1
+
+*
+* RRM Enabled
+*
+
+WNI_CFG_RRM_ENABLED I 4 8
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* RRM measurement max duration. Section 11.10.3 802.11k-2008.
+* Max Duration represented as maxDuration inTUs = 2^(*WNI_CFG_RRM_IN_CHAN_MAX - 4) * bcnIntvl
+* Operating channel max measurement duration.
+*
+
+WNI_CFG_RRM_OPERATING_CHAN_MAX I 4 8
+V RW NP
+NONE
+0 8 0
+V RW NP
+NONE
+0 8 0
+
+*
+* Non-Operating channel max measurement duration.
+*
+
+WNI_CFG_RRM_NON_OPERATING_CHAN_MAX I 4 8
+V RW NP
+NONE
+0 8 0
+V RW NP
+NONE
+0 8 0
+
+*
+* TX power control feature
+*
+
+WNI_CFG_TX_PWR_CTRL_ENABLE I 4 8
+V RW NP
+NONE
+0 1 1
+V RW NP
+NONE
+0 1 1
+
+*
+* MCAST BCAST filter Setting
+* 0: No filter, 1: Block Mcast, 2: Block Bcast, 3: Block Mcast and Bcast
+*
+
+WNI_CFG_MCAST_BCAST_FILTER_SETTING I 4 7
+V RW NP
+HAL
+0 3 0
+V RW NP
+HAL
+0 3 0
+
+*
+* BTC DHCP No of Bt slots to block
+*
+WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK I 4 7
+V RW NP
+HAL
+0 0xFF 0
+V RW NP
+HAL
+0 0xFF 0
+
+*
+* Config parameter to Enable/Disable Dynamic PS-Poll mechanism
+* 0: Disable, x: FW will send x number of NULL frames before switching to PS-Poll mexhanism
+*
+WNI_CFG_DYNAMIC_PS_POLL_VALUE I 4 7
+V RW NP
+HAL
+0 0xFF 0
+V RW NP
+HAL
+0 0xFF 0
+
+*
+* PS Data InActivity Timeout (TU)
+*
+
+WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT I 4 7
+V RW NP
+HAL
+0 80 0
+NV RW NP
+NONE
+0 80 0
+
+*
+* Config parameter to Enable/Disable Telescopic Bcn Wakeups
+* 0: Disable, 1: Enable
+*
+
+WNI_CFG_TELE_BCN_WAKEUP_EN I 4 7
+V RW NP
+HAL
+0 1 0
+V RW NP
+HAL
+0 1 0
+
+
+*
+* Config parameter for Transient LI
+* 0: Disable, x: Transient LI
+*
+
+WNI_CFG_TELE_BCN_TRANS_LI I 4 7
+V RW NP
+HAL
+0 7 3
+V RW NP
+HAL
+0 7 3
+
+*
+* Config parameter for Idle bcns for Transient LI
+* x: Num Idle bcns before switch to trans LI
+*
+
+WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS I 4 7
+V RW NP
+HAL
+5 255 10
+V RW NP
+HAL
+5 255 10
+
+*
+* Config parameter for Max LI
+* 0: Disable, x: Max LI
+*
+
+WNI_CFG_TELE_BCN_MAX_LI I 4 7
+V RW NP
+HAL
+0 7 5
+V RW NP
+HAL
+0 7 5
+
+*
+* Config parameter for Idle bcns for max LI
+* x: Num Idle bcns before switch to max LI
+*
+
+WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS I 4 7
+V RW NP
+HAL
+5 255 15
+V RW NP
+HAL
+5 255 15
+
+*
+* BTC DHCP No of Bt sub interval during DHCP
+*
+WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS I 4 7
+V RW NP
+HAL
+0 0xFF 7
+V RW NP
+HAL
+0 0xFF 7
+
+*
+* Infra STA mode Keep alive period (in secs) for
+* sending keep alive (Qos)Null frames to the AP.
+* 0 = disabled. Recommended values is 30 secs
+*
+WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD I 4 7
+V RW NP
+HAL
+0 1000 0
+V RW NP
+HAL
+0 1000 0
+
+* Limit on number of associated stations
+* (applies to peer stations in IBSS, SoftAP, BT-AMP AP, & P2P-GO modes)
+*
+
+WNI_CFG_ASSOC_STA_LIMIT I 4 8
+V RW NP
+LIM
+1 32 10
+V RW NP
+LIM
+1 32 10
+
+*
+* SAP channel select start channel number
+*
+WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL I 4 7
+V RW NP
+NONE
+1 0xFC 1
+V RW NP
+NONE
+1 0xFC 1
+
+*
+* SAP channel select end channel number
+*
+WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL I 4 7
+V RW NP
+NONE
+1 0xFC 11
+V RW NP
+NONE
+1 0xFC 11
+
+*
+* SAP channel select operating band
+* 0- 2.4GHZ / 1- Low 5GHZ /2-MID /3-HIGH/4-Japan4.9GHZ
+*
+WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND I 4 7
+V RW NP
+NONE
+0 0x5 0
+V RW NP
+NONE
+0 0x5 0
+
+*
+* Softap data available poll period (in milliseconds) for
+* queueing (Qos)Null frames to the station if there
+* is no data available and PS-Poll/Trigger frame is pending.
+* 0 = disabled. Recommended values is 5ms
+*
+WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD I 4 8
+V RW NP
+NONE
+0 65535 5
+V RW NP
+NONE
+0 65535 5
+
+*
+* Close loop power control will be enabled if value is set to 1
+*
+*
+*
+WNI_CFG_ENABLE_CLOSE_LOOP I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* LTE Coexistence will be enabled if value is set to 1
+*
+*
+*
+WNI_CFG_ENABLE_LTE_COEX I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* AP Keep Alive Timeout (TU)
+*
+WNI_CFG_AP_KEEP_ALIVE_TIMEOUT I 4 7
+V RW NP
+HAL
+1 65535 20
+V RW NP
+HAL
+1 65535 20
+
+*
+* GO Keep Alive Timeout (TU)
+*
+WNI_CFG_GO_KEEP_ALIVE_TIMEOUT I 4 7
+V RW NP
+HAL
+1 65535 20
+V RW NP
+HAL
+1 65535 20
+
+*
+* MC Addr List power control will be enabled if value is set to 1
+*
+*
+*
+WNI_CFG_ENABLE_MC_ADDR_LIST I 4 0
+V RW NP
+HAL
+0 1 0
+V RW NP
+HAL
+0 1 0
+
+*
+* UC Filter will be enabled if value is set to 1
+*
+*
+*
+WNI_CFG_ENABLE_UC_FILTER I 4 0
+V RW NP
+HAL
+0 1 0
+V RW NP
+HAL
+0 1 0
+
+*
+* Low Power Image Transition will be enabled if value is set to 1
+*
+*
+*
+WNI_CFG_ENABLE_LPWR_IMG_TRANSITION I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* MCC Adaptive Scheduler will be enabled if value is set to 1
+*
+*
+*
+WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+*
+*Disable LDPC in STA mode when AP is TXBF capable
+*
+*
+*
+WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP I 4 0
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* AP Link Monitor Timeout (TU)
+*
+WNI_CFG_AP_LINK_MONITOR_TIMEOUT I 4 7
+V RW NP
+HAL
+1 255 3
+V RW NP
+HAL
+1 255 3
+
+*
+*TDLS Station's UAPSD MASK Configuration
+*
+*
+*
+WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK I 4 7
+V RW NP
+LIM
+0 15 0
+V RW NP
+LIM
+0 15 0
+*
+*TDLS Stations Buffer STA Capability
+*
+*
+*
+WNI_CFG_TDLS_BUF_STA_ENABLED I 4 7
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+*TDLS Stations PUAPSD Inactivity Timer
+*
+*
+*
+WNI_CFG_TDLS_PUAPSD_INACT_TIME I 4 7
+V RW NP
+LIM
+0 10 0
+V RW NP
+LIM
+0 10 0
+*TDLS Stations PUAPSD RX Frame Threshold
+*
+*
+*
+WNI_CFG_TDLS_RX_FRAME_THRESHOLD I 4 7
+V RW NP
+LIM
+10 20 10
+V RW NP
+LIM
+10 20 10
+
+*
+* PMF SA Query Maximum Retries
+*
+
+WNI_CFG_PMF_SA_QUERY_MAX_RETRIES I 4 1
+V RW NP RESTART
+NONE
+0 20 5
+V RW NP RESTART
+NONE
+0 20 5
+
+*
+* PMF SA Query Retry Interval (in TUs)
+*
+
+WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL I 4 1
+V RW NP RESTART
+NONE
+10 2000 200
+V RW NP RESTART
+NONE
+10 2000 200
+
+
+*
+*MCC ENABLE/DISABLE ADAPTIVE RX Drain feature
+*
+*
+*
+WNI_CFG_ENABLE_ADAPT_RX_DRAIN I 4 7
+V RW NP
+HAL
+0 1 1
+NV RW NP
+HAL
+0 1 1
+
+*
+* FlexConnect Power Factor
+* Default is set to 0 (disable)
+*
+*
+WNI_CFG_FLEX_CONNECT_POWER_FACTOR I 4 0
+V RW NP
+NONE
+0 9 0
+V RW NP
+NONE
+0 9 0
+
+*
+* Antenna Diversity
+*
+* 0 = disabled
+* 1 = Ant 1
+* 2 = Ant 2
+* 3 = Adaptive
+*
+WNI_CFG_ANTENNA_DIVESITY I 4 7
+V RW NP
+HAL
+0 3 0
+V RW NP
+HAL
+0 3 0
+
+* GO Link Monitor Timeout (TU)
+*
+WNI_CFG_GO_LINK_MONITOR_TIMEOUT I 4 7
+V RW NP
+HAL
+3 50 10
+V RW NP
+HAL
+3 50 10
+*
+*
+
+* RMC action period frequency (milli seconds)
+*
+WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY I 4 7
+V RW NP
+HAL
+100 1000 300
+V RW NP
+HAL
+100 1000 300
+*
+*
+
+* Current RSSI value (of connected AP)
+*
+WNI_CFG_CURRENT_RSSI I 4 7
+V RW NP
+NONE
+0 127 0
+V RW NP
+NONE
+0 127 0
+
+* RTT3 Bit Value
+*
+WNI_CFG_RTT3_ENABLE I 1 1
+V RW NP
+NONE
+0 1 1
+V RW NP
+NONE
+0 1 1
+
+* Debug p2p remain on channel
+*
+WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL I 4 7
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+*
+* TDLS Off Channel Implementation
+*
+WNI_CFG_TDLS_OFF_CHANNEL_ENABLED I 4 7
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
+
+WNI_CFG_IBSS_ATIM_WIN_SIZE I 4 7
+V RW NP
+NONE
+0 100 0
+V RW NP
+NONE
+0 100 0
+
+*
+* DFS Master capability (11h) enable/disable
+*
+
+WNI_CFG_DFS_MASTER_ENABLED I 4 7
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+
+WNI_CFG_VHT_ENABLE_TXBF_20MHZ I 4 7
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
+*
+*TDLS WMM Mode
+*
+*
+WNI_CFG_TDLS_WMM_MODE_ENABLED I 4 7
+V RW NP
+LIM
+0 1 0
+V RW NP
+LIM
+0 1 0
diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms
new file mode 100644
index 0000000..04165e7
--- /dev/null
+++ b/core/mac/src/cfg/cfgUtil/dot11f.frms
@@ -0,0 +1,3611 @@
+/*
+ * Copyright (c) 2006-2007, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ * \file dot11f.frms
+ *
+ * \brief Primary 'frames' file for the MAC parser
+ *
+ *
+ * This file defines several 802.11 frames (along with their associated
+ * constituents) in a little language called "frames". When run through the
+ * 'framesc' program, it will generate C code for working with these frames:
+ * C structs representing the 802.11 frame together with functions for
+ * packing & unpacking them.
+ *
+ * For more information on the "frames" language, run 'framesc --help'...
+ *
+ *
+ */
+
+
+// Tell framesc what types to use for...
+%8-bit-type uint8_t // 8,
+%16-bit-type uint16_t // 16,
+%32-bit-type uint32_t // & 32-bit unsigned integral types. These can also
+ // be specified on the command line.
+
+// Define some mnemonic constants; these are just for our use with the frames
+// files we're compiling. IOW, they won't result in any C code being
+// emitted.
+
+const EID_SSID = 0;
+const EID_SUPP_RATES = 1;
+const EID_FH_PARAM_SET = 2;
+const EID_DS_PARAM_SET = 3;
+const EID_CF_PARAM_SET = 4;
+const EID_TIM = 5;
+const EID_IBSS_PARAM_SET = 6;
+const EID_COUNTRY = 7;
+const EID_FH_PATTERN = 8;
+const EID_FH_PATT_TABLE = 9;
+const EID_REQUEST = 10;
+const EID_QBSS_LOAD = 11;
+const EID_EDCA_PARAM_SET = 12;
+const EID_TSPEC = 13;
+const EID_TCLAS = 14;
+const EID_SCHEDULE = 15;
+const EID_CHALLENGE_TEXT = 16;
+const EID_POWER_CONSTRAINTS = 32;
+const EID_POWER_CAPABILITY = 33;
+const EID_TPC_REQUEST = 34;
+const EID_TPC_REPORT = 35;
+const EID_SUPPORTED_CHANNELS = 36;
+const EID_CHANNEL_SWITCH_ANN = 37;
+const EID_MEAS_REQUEST = 38;
+const EID_MEAS_REPORT = 39;
+const EID_QUIET = 40;
+const EID_ERP_INFO = 42;
+const EID_TS_DELAY = 43;
+const EID_TCLASS_PROC = 44;
+const EID_HT_CAPABILITIES = 45;
+const EID_QOS_CAPABILITY = 46;
+const EID_RSN = 48;
+const EID_EXT_SUPP_RATES = 50;
+const EID_AP_CHAN_REPORT = 51;
+const EID_NEIGHBOR_REPORT = 52;
+const EID_RCPI = 53;
+const EID_FT_MOBILITY_DOMAIN = 54;
+const EID_FT_INFO = 55;
+const EID_TIMEOUT_INTERVAL = 56;
+const EID_FT_RIC_DATA = 57;
+const EID_SUPPORTED_OPER_CLASSES = 59;
+const EID_EXT_CHAN_SWITCH = 60;
+const EID_HT_INFO = 61;
+const EID_SEC_CHAN_OFFSET = 62;
+const EID_RSNI = 65;
+const EID_RRM_MEAS_PILOT_TX_INFO = 66;
+const EID_WAPI = 68;
+const EID_TIME_ADVERTISEMENT = 69;
+const EID_RRM_ENABLED_CAPS = 70;
+const EID_MULTIPLE_BSSID = 71;
+const EID_20_40_BSS_COEXISTENCE = 72;
+const EID_20_40_BSS_INTOLERANT_REPORT= 73;
+const EID_OBSS_SCAN_PARAMETERS = 74;
+const EID_FT_RIC_DESCRIPTOR = 75;
+const EID_LINK_IDENTIFIER = 101;
+const EID_PTI_CONTROL = 105;
+const EID_PU_BUFFER_STATUS = 106;
+const EID_QOS_MAP_SET = 110;
+const EID_ESE_SPECIFIC = 150;
+const EID_ESE_CCKM_SPECIFIC = 156;
+const EID_VHT_CAPABILITIES = 191;
+const EID_VHT_OPERATION_ELEMENT = 192;
+const EID_VHT_EXT_BSS_LOAD = 193;
+const EID_AID = 197;
+const EID_EXT_CAP = 127;
+const EID_OPERATING_MODE = 199;
+const EID_WIDER_BW_CHANNEL_SWITCH_ANN= 194;
+const EID_CHANNEL_SWITCH_WRAPPER = 196;
+const EID_VENDOR_SPECIFIC = 221;
+
+const SIR_MAC_PROP_EXT_RATES_TYPE = 0;
+const SIR_MAC_PROP_AP_NAME_TYPE = 1;
+const SIR_MAC_PROP_HCF_TYPE = 2;
+const SIR_MAC_PROP_WDS_TYPE = 3;
+const SIR_MAC_PROP_BP_IND_TYPE = 4;
+const SIR_MAC_PROP_NEIGHBOR_BSS_TYPE = 5;
+const SIR_MAC_PROP_LOAD_INFO_TYPE = 6;
+const SIR_MAC_PROP_ASSOC_TYPE = 7;
+const SIR_MAC_PROP_LOAD_BALANCE_TYPE = 8;
+const SIR_MAC_PROP_LL_ATTR_TYPE = 9;
+const SIR_MAC_PROP_CAPABILITY = 10;
+const SIR_MAC_PROP_VERSION = 11;
+const SIR_MAC_PROP_EDCAPARAMS = 12;
+const SIR_MAC_PROP_CHANNEL_SWITCH = 15;
+const SIR_MAC_PROP_QUIET_BSS = 16;
+const SIR_MAC_PROP_TRIG_STA_BK_SCAN = 17;
+
+const ANI_WDS_INFO_MAX_LENGTH = 64;
+const SIR_MAC_MAX_NUMBER_OF_RATES = 12;
+const HT_MAX_SUPPORTED_MCS_SET = 16;
+const MAX_SUPPORTED_NEIGHBOR_RPT = 15;
+
+/////////////////////////////////////////////////////////////////////////////
+// Wi-Fi Protected Setup TLV Identifiers //
+// WSC Version 2.0.0 Table 28 //
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Wi-Fi Simple Configuration TLV Identifiers //
+// WFA Vendor Extension Subelements //
+/////////////////////////////////////////////////////////////////////////////
+const TLV_VERSION2 = 0;
+const TLV_AUTHORIZED_MAC = 1;
+const TLV_NETWORK_KEY_SHAREABLE = 2;
+const TLV_REQUEST_TO_ENROLL = 3;
+const TLV_SETTINGS_DELAY_TIME = 4;
+
+const TLV_VERSION = 0x104A;
+const TLV_WI_FI_SIMPLE_CONFIG_STATE = 0x1044;
+const TLV_AP_SETUP_LOCKED = 0x1057;
+const TLV_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053;
+const TLV_DEVICE_PASSWORD_ID = 0x1012;
+const TLV_UUID_E = 0x1047;
+const TLV_UUID_R = 0x1048;
+const TLV_RF_BANDS = 0x103C;
+const TLV_REQUEST_TYPE = 0x103A;
+const TLV_RESPONSE_TYPE = 0x103B;
+const TLV_CONFIG_METHODS = 0x1008;
+const TLV_PRIMARY_DEVICE_TYPE = 0x1054;
+const TLV_ASSOCIATION_STATE = 0x1002;
+const TLV_CONFIGURATION_ERROR = 0x1009;
+const TLV_MANUFACTURER = 0x1021;
+const TLV_MODEL_NAME = 0x1023;
+const TLV_MODEL_NUMBER = 0x1024;
+const TLV_SERIAL_NUMBER = 0x1042;
+const TLV_DEVICE_NAME = 0x1011;
+const TLV_SELECTED_REGISTRAR = 0x1041;
+const TLV_VENDOR_EXTENSION = 0x1049;
+const TLV_REQUESTED_DEVICE_TYPE = 0x106A;
+
+/////////////////////////////////////////////////////////////////////////////
+// Wi-Fi Direct/P2P TLV Identifiers //
+/////////////////////////////////////////////////////////////////////////////
+const TLV_P2P_STATUS = 0;
+const TLV_MINOR_REASON_CODE = 1;
+const TLV_P2P_CAPABILITY = 2;
+const TLV_P2P_DEVICE_ID = 3;
+const TLV_P2P_GROUP_OWNER_INTENT = 4;
+const TLV_CONFIGURATION_TIMEOUT = 5;
+const TLV_LISTEN_CHANNEL = 6;
+const TLV_P2P_GROUP_BSSID = 7;
+const TLV_EXTENDED_LISTEN_TIMING = 8;
+const TLV_INTENDED_P2P_INTERFACE_ADDRESS = 9;
+const TLV_P2P_MANAGEABILITY = 10;
+const TLV_CHANNEL_LIST = 11;
+const TLV_NOTICE_OF_ABSENCE = 12;
+const TLV_P2P_DEVICE_INFO = 13;
+const TLV_P2P_GROUP_INFO = 14;
+const TLV_P2P_GROUP_ID = 15;
+const TLV_P2P_INTERFACE = 16;
+const TLV_OPERATING_CHANNEL = 17;
+const TLV_INVITATION_FLAGS = 18;
+const TLV_P2P_VENDOR_SPECIFIC = 221;
+
+/////////////////////////////////////////////////////////////////////////////
+// Fixed Fields
+
+FF AuthAlgo (2) // C.f. Sec. 7.3.1.1
+{
+ algo, 2;
+}
+
+FF AuthSeqNo (2) // 7.3.1.2
+{
+ no, 2;
+}
+
+FF BeaconInterval (2) // 7.3.1.3
+{
+ interval, 2;
+}
+
+FF Capabilities (2) // 7.3.1.4
+{
+ {
+ ess: 1;
+ ibss: 1;
+ cfPollable: 1;
+ cfPollReq: 1;
+ privacy: 1;
+ shortPreamble: 1;
+ pbcc: 1;
+ channelAgility: 1;
+ spectrumMgt: 1;
+ qos: 1;
+ shortSlotTime: 1;
+ apsd: 1;
+ rrm: 1;
+ dsssOfdm: 1;
+ delayedBA: 1;
+ immediateBA: 1;
+ }
+}
+
+FF CurrentAPAddress(6) // 7.3.1.5
+{
+ mac[6];
+}
+
+FF ListenInterval (2) // 7.3.1.6
+{
+ interval, 2;
+}
+
+FF Reason (2) // 7.3.1.7
+{
+ code, 2;
+}
+
+FF AID (2) // 7.3.1.8
+{
+ associd, 2;
+}
+
+FF Status (2) // 7.3.1.9
+{
+ status, 2;
+}
+
+FF TimeStamp (8) // 7.3.1.10
+{
+ timestamp, 8;
+}
+
+FF Category (1) // 7.3.1.11
+{
+ category, 1;
+}
+
+FF Action (1) // 7.3.1.11
+{
+ action, 1;
+}
+
+FF TransactionId (2) // 7.3.1.11
+{
+ transId[2];
+}
+
+FF DialogToken (1) // 7.3.1.12
+{
+ token, 1;
+}
+
+FF StatusCode (1) // WMM Spec 2.2.10
+{
+ statusCode, 1;
+}
+
+FF OperatingMode (1)
+{
+ {
+ //Operating Mode field
+ chanWidth: 2;
+ reserved: 2;
+ rxNSS: 3;
+ rxNSSType: 1;
+ }
+}
+
+FF SMPowerModeSet (1) //7.3.1.25
+{
+ {
+ PowerSave_En: 1;
+ Mode: 1;
+ reserved: 6;
+ }
+}
+
+FF TSInfo (3) // 7.3.2.30
+{
+ {
+ traffic_type: 1;
+ tsid: 4;
+ direction: 2;
+ access_policy: 2;
+ aggregation: 1;
+ psb: 1;
+ user_priority: 3;
+ tsinfo_ack_pol: 2;
+ schedule: 1;
+ unused: 15;
+ }
+}
+
+FF NumOfRepetitions (2)
+{
+ repetitions, 2;
+}
+
+FF TxPower (1)
+{
+ txPower, 1;
+}
+
+FF MaxTxPower (1)
+{
+ maxTxPower, 1;
+}
+FF TPCEleID (1)
+{
+ TPCId, 1;
+}
+FF TPCEleLen (1)
+{
+ TPCLen, 1;
+}
+FF LinkMargin (1)
+{
+ linkMargin, 1;
+}
+FF RxAntennaId (1)
+{
+ antennaId, 1;
+}
+FF TxAntennaId (1)
+{
+ antennaId, 1;
+}
+FF RCPI (1)
+{
+ rcpi, 1;
+}
+FF RSNI (1)
+{
+ rsni, 1;
+}
+
+FF VhtMembershipStatusArray(8) // 8.4.1.51
+{
+ membershipStatusArray[8];
+}
+
+FF VhtUserPositionArray(16) // 8.4.1.52
+{
+ userPositionArray[16];
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// TLVs //
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * \brief Version
+ *
+ * WPS 1.0h
+ * Version specifies the Easy Setup version. The one-byte field is broken
+ * into a four-bit major part using the top MSBs and four-bit minor part
+ * using the LSBs. As an example, version 3.2 would be 0x32.
+ *
+ * WSC 2.0.0
+ * Deprecated Version mechanism. This attribute is always set to value 0x10
+ * (version 1.0) for backwards compatibility. Version 1.0h of the specification
+ * did not fully describe the version negotiation mechanism and version 2.0
+ * introduced a new subelement (Version2) for indicating the version number
+ * to avoid potential interoperability issues with deployed 1.0h-based devices.
+ *
+ */
+
+TLV Version( TLV_VERSION ) ( 2 : 2 ) MSB
+{
+ {
+ minor: 4;
+ major: 4;
+ }
+}
+
+/// Wi-Fi Protected Setup State
+TLV WPSState( TLV_WI_FI_SIMPLE_CONFIG_STATE ) ( 2 : 2 ) MSB
+{
+ state, 1;
+}
+
+/**
+ * \brief AP Setup Locked
+ *
+ *
+ * This variable indicates that the AP has entered a state in which it will
+ * refuse to allow an external Registrar to attempt to run the Registration
+ * Protocol using the AP?s PIN (with the AP acting as Enrollee). The AP
+ * should enter this state if it believes a brute force attack is underway
+ * against the AP?s PIN.
+ *
+ * When the AP is in this state, it MUST continue to allow other Enrollees to
+ * connect and run the Registration Protocol with any external Registrars or
+ * the AP's built-in Registrar (if any). It is only the use of the AP' PIN
+ * for adding external Registrars that is disabled in this state.
+ *
+ * The AP Setup Locked state can be reset to FALSE through an authenticated
+ * call to SetAPSettings. APs may provide other implementation-specific
+ * methods of resetting the AP Setup Locked state as well.
+ *
+ *
+ */
+
+TLV APSetupLocked( TLV_AP_SETUP_LOCKED ) ( 2 : 2 ) MSB
+{
+ fLocked, 1;
+}
+
+/**
+ * \brief Selected Registrar Config Methods
+ *
+ *
+ * This attribute has the same values that Config Methods have. It is used in
+ * Probe Response messages to convey the Config Methods of the selected
+ * Registrar.
+ *
+ *
+ */
+
+TLV SelectedRegistrarConfigMethods ( TLV_SELECTED_REGISTRAR_CONFIG_METHODS ) ( 2 : 2 ) MSB
+{
+ methods, 2;
+}
+
+/**
+ * \brief UUID-E
+ *
+ *
+ * The universally unique identifier (UUID) element is a unique GUID
+ * generated by the Enrollee. It uniquely identifies an operational device
+ * and should survive reboots and resets. The UUID is provided in binary
+ * format. If the device also supports UPnP, then the UUID corresponds to the
+ * UPnP UUID.
+ *
+ *
+ */
+
+TLV UUID_E ( TLV_UUID_E ) ( 2 : 2 ) MSB
+{
+ uuid[ 16 ];
+}
+
+/**
+ * \brief UUID-R
+ *
+ *
+ * The universally unique identifier (UUID) element is a unique GUID
+ * generated by the Registrar. It uniquely identifies an operational device
+ * and should survive reboots and resets. The UUID is provided in binary
+ * format. If the device also supports UPnP, then the UUID corresponds to the
+ * UPnP UUID.
+ *
+ *
+ */
+
+TLV UUID_R ( TLV_UUID_R ) ( 2 : 2 ) MSB
+{
+ uuid[ 16 ];
+}
+
+/**
+ * \brief RF Bands
+ *
+ *
+ \code
+
+ 0x01 2.4GHz
+ 0x02 5.0GHz
+
+ \endcode
+ *
+ *
+ */
+
+TLV RFBands ( TLV_RF_BANDS ) ( 2 : 2 ) MSB
+{
+ bands, 1;
+}
+
+
+/**
+ * \brief Selected Registrar
+ *
+ *
+ * This field indicates that a Registrar has been selected by a user and that
+ * an Enrollee should proceed with setting up an 802.1X uncontrolled data
+ * port with the Registrar.
+ *
+ *
+ */
+
+TLV SelectedRegistrar ( TLV_SELECTED_REGISTRAR ) ( 2 : 2 ) MSB
+{
+ selected, 1;
+}
+
+/**
+ * \brief Config Methods
+ *
+ *
+ * The Config Methods Data component lists the configuration methods the
+ * Enrollee or Registrar supports. The list is a bitwise OR of values from
+ * the table below. In addition to Config Methods, APs and STAs that support
+ * the UPnP Management Interface must support the Permitted Config Methods
+ * attribute, which is used to control the Config Methods that are enabled on
+ * that AP.
+ *
+ \code
+
+ Value Hardware Interface
+ 0x0001 USBA (Flash Drive)
+ 0x0002 Ethernet
+ 0x0004 Label
+ 0x0008 Display
+ 0x0010 External NFC Token
+ 0x0020 Integrated NFC Token
+ 0x0040 NFC Interface
+ 0x0080 PushButton
+ 0x0100 Keypad
+
+ \endcode
+ *
+ *
+ */
+
+TLV ConfigMethods ( TLV_CONFIG_METHODS ) ( 2 : 2 ) MSB
+{
+ methods, 2;
+}
+
+/**
+ * \brief Association State
+ *
+ *
+ * The Association State component shows the configuration and previous
+ * association state of the wireless station when sending a Discovery
+ * request.
+ *
+ \code
+
+ Association State Description
+ 0 Not Associated
+ 1 Connection Success
+ 2 Configuration Failure
+ 3 Association Failure
+ 4 IP Failure
+
+ \endcode
+ *
+ *
+ */
+
+TLV AssociationState ( TLV_ASSOCIATION_STATE ) ( 2 : 2 ) MSB
+{
+ state, 2;
+}
+
+/**
+ * \brief Configuration Error
+ *
+ *
+ * The Configuration Error component shows the result of the device
+ * attempting to configure itself and to associate with the WLAN.
+ *
+ \code
+
+ Configuration Error Description
+ 0 No Error
+ 1 OOB Interface Read Error
+ 2 Decryption CRC Failure
+ 3 2.4 channel not supported
+ 4 5.0 channel not supported
+ 5 Signal too weak
+ 6 Network auth failure
+ 7 Network association failure
+ 8 No DHCP response
+ 9 Failed DHCP config
+ 10 IP address conflict
+ 11 Couldn't connect to Registrar
+ 12 Multiple PBC sessions detected
+ 13 Rogue activity suspected
+ 14 Device busy
+ 15 Setup locked
+ 16 Message Timeout
+ 17 Registration Session Timeout
+ 18 Device Password Auth Failure
+
+ \endcode
+ *
+ * The Device busy error is returned if the sending device is unable to
+ * respond to the request due to some internal conflict or resource
+ * contention issue. For example, if a device is only capable of performing a
+ * single instance of the Registration Protocol at a time, it may return this
+ * error in response to attempts to start another instance in the middle of
+ * an active session.
+ *
+ *
+ */
+
+TLV ConfigurationError ( TLV_CONFIGURATION_ERROR ) ( 2 : 2 ) MSB
+{
+ error, 2;
+}
+
+TLV Manufacturer ( TLV_MANUFACTURER ) ( 2 : 2 ) MSB
+{
+ name[ 0..64 ];
+}
+
+TLV ModelName ( TLV_MODEL_NAME ) ( 2 : 2 ) MSB
+{
+ text[ 0..32 ];
+}
+
+TLV ModelNumber ( TLV_MODEL_NUMBER ) ( 2 : 2 ) MSB
+{
+ text[ 0..32 ];
+}
+
+TLV SerialNumber ( TLV_SERIAL_NUMBER ) ( 2 : 2 ) MSB
+{
+ text[ 0..32 ];
+}
+
+TLV DeviceName ( TLV_DEVICE_NAME ) ( 2 : 2 ) MSB
+{
+ text[ 0..32 ];
+}
+
+/**
+ * \brief Device Password ID
+ *
+ *
+ * This attribute is used to identify a device password. There are six
+ * predefined values and ten reserved values. If the Device Password ID is
+ * Default, the Enrollee should use its PIN password (from the label or
+ * display). This password may correspond to the label, display, or a
+ * user-defined password that has been configured to replace the original
+ * device password.
+ *
+ * User-specified indicates that the user has overridden the password with a
+ * manually selected value. Machine-specified indicates that the original
+ * PIN password has been overridden by a strong, machinegenerated device
+ * password value. The Rekey value indicates that the device's 256-bit
+ * rekeying password will be used. The PushButton value indicates that the
+ * PIN is the all-zero value reserved for the PushButton Configuration
+ * method.
+ *
+ * The Registrar-specified value indicates a PIN that has been obtained from
+ * the Registrar (via a display or other out-of-band method). This value may
+ * be further augmented with the optional 'Identity' attribute in M1. This
+ * augmentation is useful when multiple predefined UserID/PIN pairs have been
+ * established by a Registrar such as an authenticator used for Hotspot
+ * access. If the Device Password ID in M1 is not one of the predefined or
+ * reserved values, it corresponds to a password given to the Registrar as an
+ * OOB Device Password.
+ *
+ \code
+
+ Value Description
+
+ 0x0000 Default (PIN)
+ 0x0001 User-specified
+ 0x0002 Machine-specified
+ 0x0003 Rekey
+ 0x0004 PushButton
+ 0x0005 Registrar-specified
+ 0x0006 - 0x000F Reserved
+
+ \endcode
+ *
+ *
+ */
+
+TLV DevicePasswordID ( TLV_DEVICE_PASSWORD_ID ) ( 2 : 2 ) MSB
+{
+ id, 2;
+}
+
+
+/**
+ * \brief Primary Device Type
+ *
+ *
+ * This attribute contains the primary type of the device. Its format
+ * follows:
+ *
+ \code
+
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Attribute ID | Length |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Category ID | OUI (1-2) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | OUI (3-4) | Sub Category ID |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ \endcode
+ *
+ * Vendor-specific sub-categories are designated by setting the OUI to the
+ * value associated with that vendor. Note that a four-byte subdivided OUI
+ * is used. For the predefined values, the Wi-Fi Alliance OUI of 00 50 F2 04
+ * is used. The predefined values for Category ID and Sub Category ID are
+ * provided in the next table. There is no way to indicate a vendor-specific
+ * main device category. The OUI applies only to the interpretation of the
+ * Sub Category. If a vendor does not use sub categories for their OUI, the
+ * three-byte OUI occupies the first three bytes of the OUI field and the
+ * fourth byte is set to zero.
+ *
+ *
+ \code
+
+ Category ID Value Sub Category ID Value
+ Computer 1 PC 1
+ Server 2
+ Media Center 3
+ Input Device 2
+ Printers, Scanners, Printer 1
+ Faxes and Copiers 3 Scanner 2
+ Camera 4 Digital Still Camera 1
+ Storage 5 NAS 1
+ Network AP 1
+ Infrastructure 6 Router 2
+ Switch 3
+ Displays 7 Television 1
+ Electronic Picture Frame 2
+ Projector 3
+ Multimedia Devices 8 DAR 1
+ PVR 2
+ MCX 3
+ Gaming Devices 9 Xbox 1
+ Xbox360 2
+ Playstation 3
+ Telephone 10 Windows Mobile 1
+
+ \endcode
+ *
+ *
+ */
+
+TLV PrimaryDeviceType ( TLV_PRIMARY_DEVICE_TYPE ) ( 2 : 2 ) MSB
+{
+ primary_category, 2;
+ oui[ 4 ];
+ sub_category, 2;
+}
+
+
+/**
+ * \brief Request Type
+ *
+ *
+ * The Request Type component specifies the mode in which the device will
+ * operate in for this setup exchange. If the device is an Enrollee, it may
+ * send only discovery messages or it may also request that the Registrar
+ * proceed with opening a data connection. This protocol allows Enrollees to
+ * more efficiently discover devices on the network.
+
+ * If the device indicates that it intends to engage setup either as a
+ * Registrar or an Enrollee, the Access Point continues to indicate that it
+ * will operate as an AP in the response. The Request Type attribute is
+ * carried throughout the 802.1X data channel setup process in the Wi-Fi
+ * Protected Setup IE. There are two sub-types of Registrars: WLAN Manager
+ * Registrar indicates that this Registrar intends to manage the AP or STA
+ * settings using UPnP. It will derive a UPnP AP or STA Management key. The
+ * ordinary Registrar type indicates that this Registrar does not intend to
+ * subsequently manage the Enrollee's settings. APs must not derive AP
+ * Management Keys for an ordinary Registrar. If a Registrar does not intend
+ * to be a WLAN Manager Registrar, it should set the Request Type to
+ * Registrar. Doing so avoids needlessly consuming resources on the AP.
+
+ \code
+
+ Request Type Value Description
+ 0x00 Enrollee, Info only
+ 0x01 Enrollee, open 802.1X
+ 0x02 Registrar
+ 0x03 WLAN Manager Registrar
+
+ \endcode
+ *
+ *
+ */
+
+TLV RequestType ( TLV_REQUEST_TYPE ) ( 2 : 2 ) MSB
+{
+ reqType, 1;
+}
+
+/**
+ * \brief Response Type
+ *
+ *
+ * The Response Type component specifies the operational mode of the
+ * device for this setup exchange. The Response Type IE is carried
+ * throughout the 802.1X data channel setup process.
+
+ \code
+
+ Response Type Value Description
+ 0x00 Enrollee, Info only
+ 0x01 Enrollee, open 802.1X
+ 0x02 Registrar
+ 0x03 AP
+
+\endcode
+ *
+ *
+ */
+
+TLV ResponseType ( TLV_RESPONSE_TYPE ) ( 2 : 2 ) MSB
+{
+ resType, 1;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// WiFi Direct/P2P TLVs //
+///////////////////////////////////////////////////////////////////////////
+
+/**
+ * \brief P2P Status Attribute
+ */
+
+TLV P2PStatus ( TLV_P2P_STATUS ) ( 1 : 2 ) LSB
+{
+ status, 1;
+}
+
+
+/**
+ * \brief Minor Reason Code Attribute
+ */
+
+TLV MinorReasonCode ( TLV_MINOR_REASON_CODE ) ( 1 : 2 ) LSB
+{
+ minorReasonCode, 1;
+}
+
+
+/**
+ * \brief P2P Capability Attribute
+ */
+
+TLV P2PCapability ( TLV_P2P_CAPABILITY ) ( 1 : 2 ) LSB
+{
+ deviceCapability, 1;
+ groupCapability, 1;
+}
+
+
+/**
+ * \brief P2P Device Id Attribute
+ */
+
+TLV P2PDeviceId ( TLV_P2P_DEVICE_ID ) ( 1 : 2 ) LSB
+{
+ P2PDeviceAddress[6];
+}
+
+/**
+ * \brief Listen Channel Attribute
+ */
+
+TLV ListenChannel ( TLV_LISTEN_CHANNEL ) ( 1 : 2 ) LSB
+{
+ countryString[3];
+ regulatoryClass, 1;
+ channel, 1;
+}
+
+/**
+ * \brief Extended Listen Attribute
+ */
+
+TLV ExtendedListenTiming ( TLV_EXTENDED_LISTEN_TIMING ) ( 1 : 2 ) LSB
+{
+ availibilityPeriod, 2;
+ availibilityInterval, 2;
+}
+
+
+/**
+ * \brief P2P Manageability Attribute
+ */
+
+TLV P2PManageability ( TLV_P2P_MANAGEABILITY ) ( 1 : 2 ) LSB
+{
+ manageability, 1;
+}
+
+
+/**
+ * \brief Notice of Absence
+ */
+
+TLV NoticeOfAbsence ( TLV_NOTICE_OF_ABSENCE ) ( 1 : 2 ) LSB
+{
+ index, 1;
+ CTSWindowOppPS, 1;
+ NoADesc[0..36];
+}
+
+/**
+ * \brief P2P Device Info Attribute
+ */
+
+TLV P2PDeviceInfo ( TLV_P2P_DEVICE_INFO ) ( 1 : 2 ) LSB
+{
+ P2PDeviceAddress[6];
+ configMethod, 2 , FLIPBYTEORDER;
+ primaryDeviceType[8];
+ MANDATORYTLV DeviceName;
+}
+
+
+/**
+ * \brief P2P Group Info Attribute
+ */
+
+TLV P2PGroupInfo ( TLV_P2P_GROUP_INFO ) ( 1 : 2 ) LSB
+{
+ P2PClientInfoDesc[0..1024];
+}
+
+
+/**
+ * \brief P2P Interface Attribute
+ */
+
+TLV P2PInterface ( TLV_P2P_INTERFACE ) ( 1 : 2 ) LSB
+{
+ P2PDeviceAddress[6];
+}
+
+
+/**
+ * \brief Operating Channel Attribute
+ */
+
+TLV OperatingChannel ( TLV_OPERATING_CHANNEL ) ( 1 : 2 ) LSB
+{
+ countryString[3];
+ regulatoryClass, 1;
+ channel, 1;
+}
+
+
+/**
+ * \brief Vendor Extension
+ *
+ * This variable permits vendor extensions in the Wi-Fi Simple
+ * Configuration TLV framework. The Vendor Extension figure
+ * illustrates the implementation of vendor extensions. Vendor
+ * ID is the SMI network management private enterprise code
+ *
+ * +-----------+----------------------+
+ * | Vendor ID | Vendor Data |
+ * +-----------+----------------------+
+ * |<--- 3 --->|<----- 1 - 1021 ----->|
+ *
+ */
+
+TLV VendorExtension ( TLV_VENDOR_EXTENSION ) ( 2 : 2 ) MSB
+{
+ /*
+ * vendorId is the SMI network management private enterprise code.
+ * WFA Vendor ID 0x00372A
+ *
+ */
+ vendorId[ 3 ];
+
+ /**
+ * \breif Version2
+ *
+ * The Version2 field specifies the version Wi-Fi Simple
+ * Configuration implemented by the device sending this attribute.
+ * The one-byte field is broken into a four-bit major part using
+ * the top MSBs and four-bit minor part using the LSBs. As an example,
+ * version 3.2 would be 0x32. This subelement was added in the
+ * specification version 2.0 and if the subelement is not included
+ * in a message, the transmitter of the message is assumed to
+ * use version 1.0.
+ *
+ */
+ OPTIONALTLV TLV Version2 ( TLV_VERSION2 ) ( 1 : 1 ) MSB
+ {
+ {
+ minor: 4;
+ major: 4;
+ }
+ }
+ /**
+ * \brief AuthorizedMACs
+ *
+ * This subelement contains a list of Enrollee MAC addresses (each
+ * being six bytes in length) that have been registered to start WSC.
+ * The AP includes this field in Beacon and Probe Response frames so
+ * Enrollees can tell if they have been registered to start WSC. There
+ * may be multiple Enrollees active on the network, but not all of them have
+ * been registered to start WSC. This element allows an Enrollee to detect
+ * if they should start WSC with the AP. The AuthorizedMACs field augments
+ * the use of the Selected Registrar.
+ *
+ */
+ OPTIONALTLV TLV AuthorizedMACs ( TLV_AUTHORIZED_MAC ) ( 1 : 1 ) MSB
+ {
+ mac[6];
+ }
+
+ /**
+ * \brief Request to Enroll
+ *
+ * This optional subelement in the WSC IE in Probe Request or M1 indicates
+ * the desire to enroll in the network by setting its value to TRUE. If the
+ * Registrar gets this subelement it can use this as a trigger that a device
+ * wants to enroll (maybe an indication can be shown to the user). The device
+ * must set it to FALSE after the registration protocol completion.
+ *
+ */
+ OPTIONALTLV TLV RequestToEnroll( TLV_REQUEST_TO_ENROLL ) ( 1 : 1 ) MSB
+ {
+ req, 1;
+ }
+}
+
+/**
+ * \brief Requested Device Type
+ *
+ * This attribute contains the requested device type of a Wi-Fi
+ * Direct device.
+ *
+ * This attribute allows a device to specify the Primary Device Type
+ * or the Secondary Device Type of other devices it is interested in.
+ * Only a device that receives a Probe Request containing a WSC IE with
+ * this attribute and with a Primary Device Type or Secondary Device Type
+ * that matches the Requested Device Type will respond with a Probe Response.
+ *
+ * Its format and contents is identical to the 'Primary Device Type'.
+ *
+ * Both the Category ID and Sub Category ID can be used as a filter. If only
+ * looking for devices with a certain Category ID, the OUI and Sub Category ID
+ * fields will have to be set to zero.
+ *
+ */
+TLV RequestDeviceType ( TLV_REQUESTED_DEVICE_TYPE ) ( 2 : 2 ) MSB
+{
+ primary_category, 2;
+ oui[ 4 ];
+ sub_category, 2;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Information Elements
+
+IE SSID (EID_SSID) // C.f. Sec. 7.3.2.1
+{
+ ssid[0..32];
+}
+
+IE SuppRates (EID_SUPP_RATES) // 7.3.2.2
+{
+ rates[0..SIR_MAC_MAX_NUMBER_OF_RATES];
+}
+
+IE FHParamSet (EID_FH_PARAM_SET) // 7.3.2.3
+{
+ dwell_time, 2;
+ hop_set, 1;
+ hop_pattern, 1;
+ hop_index, 1;
+}
+
+IE DSParams (EID_DS_PARAM_SET) // 7.3.2.4
+{
+ curr_channel, 1;
+}
+
+IE CFParams (EID_CF_PARAM_SET) // 7.3.2.5
+{
+ cfp_count, 1;
+ cfp_period, 1;
+ cfp_maxduration, 2;
+ cfp_durremaining, 2;
+}
+
+IE TIM (EID_TIM) // 7.3.2.6
+{
+ dtim_count, 1;
+ dtim_period, 1;
+ bmpctl, 1;
+ vbmp[1..251];
+}
+
+IE IBSSParams (EID_IBSS_PARAM_SET) // 7.3.2.7
+{
+ atim, 2;
+}
+
+IE ChallengeText (EID_CHALLENGE_TEXT) // 7.3.2.8
+{
+ text[1..253];
+}
+
+IE RequestedInfo (EID_REQUEST) // 7.3.2.12
+{
+ requested_eids[0..255];
+}
+
+IE Country (EID_COUNTRY) // 7.3.2.9
+{
+ country[3];
+ OPTIONAL triplets[3][0..84];
+}
+
+IE FHParams (EID_FH_PATTERN) // 7.3.2.10
+{
+ radix, 1;
+ nchannels, 1;
+}
+
+IE FHPattTable (EID_FH_PATT_TABLE) // 7.3.2.11
+{
+ flag, 1;
+ nsets, 1;
+ modulus, 1;
+ offset, 1;
+ randtable[0..251];
+}
+
+IE ERPInfo (EID_ERP_INFO) // 7.3.2.13
+{
+ {
+ non_erp_present : 1;
+ use_prot: 1;
+ barker_preamble: 1;
+ unused: 5;
+ }
+}
+
+IE ExtSuppRates (EID_EXT_SUPP_RATES) // 7.3.2.14
+{
+ rates[1..SIR_MAC_MAX_NUMBER_OF_RATES];
+}
+
+IE PowerConstraints (EID_POWER_CONSTRAINTS) // 7.3.2.15
+{
+ localPowerConstraints, 1;
+}
+
+IE PowerCaps (EID_POWER_CAPABILITY) // 7.3.2.16
+{
+ minTxPower, 1;
+ maxTxPower, 1;
+}
+
+IE TPCRequest (EID_TPC_REQUEST) // 7.3.2.17
+{ }
+
+IE TPCReport (EID_TPC_REPORT) // 7.3.2.18
+{
+ tx_power, 1;
+ link_margin, 1;
+}
+
+IE SuppChannels (EID_SUPPORTED_CHANNELS) // 7.2.3.19
+{
+ bands[2][1..48];
+}
+
+IE SuppOperatingClasses (EID_SUPPORTED_OPER_CLASSES)
+{
+ classes[1..32];
+}
+
+IE ChanSwitchAnn (EID_CHANNEL_SWITCH_ANN) // 7.3.2.20
+{
+ switchMode, 1;
+ newChannel, 1;
+ switchCount, 1;
+}
+
+IE ext_chan_switch_ann (EID_EXT_CHAN_SWITCH) // 8.4.2.55
+{
+ switch_mode, 1;
+ new_reg_class, 1;
+ new_channel, 1;
+ switch_count, 1;
+}
+
+IE sec_chan_offset_ele (EID_SEC_CHAN_OFFSET) // 7.3.2.20a
+{
+ secondaryChannelOffset, 1;
+}
+
+IE Quiet (EID_QUIET) // 7.3.2.23
+{
+ count, 1;
+ period, 1;
+ duration, 2;
+ offset, 2;
+}
+
+IE RSN (EID_RSN) // 7.3.2.25
+{
+ // The version is 2 octets, and we only support version 1.
+ version, 2 MUSTBE 1;
+ // The next four octets will be the Group Cipher Suite
+ gp_cipher_suite[4];
+ // The IE *may* stop here; if there's any more, we should see two more
+ // octets giving the number of Pairwise Cipher Suites
+ OPTIONAL pwise_cipher_suite_count, 2;
+ // I don't see anything in the Standard limiting the number of Pairwise
+ // Cypher Suites, other than the maximum length of an IE, which limits us
+ // to 61. However, that seems needlessly wasteful of space.
+ pwise_cipher_suites[4][0..4] COUNTIS pwise_cipher_suite_count;
+ // Optional count of AKM suite selectors
+ OPTIONAL akm_suite_count, 2;
+ // Again, I see nothing in the Standard explicitly limiting the number of
+ // AKM suite selectors other than the maximum size of an IE.
+ akm_suites[4][0..4] COUNTIS akm_suite_count;
+ OPTIONAL RSN_Cap[2];
+ // Finally, the IE may contain zero or more PMKIDs:
+ OPTIONAL pmkid_count, 2;
+ pmkid[16][0..4] COUNTIS pmkid_count;
+ OPTIONAL gp_mgmt_cipher_suite[4];
+}
+
+IE RSNOpaque (EID_RSN) // 7.3.2.25
+{
+ data[ 6..253 ];
+}
+
+IE WAPI (EID_WAPI) // 7.3.2.25
+{
+ // The version is 2 octets, and we only support version 1.
+ version, 2 MUSTBE 1;
+ // count of AKM suite selectors
+ akm_suite_count, 2;
+ // Again, I see nothing in the Standard explicitly limiting the number of
+ // AKM suite selectors other than the maximum size of an IE.
+ akm_suites[4][0..4] COUNTIS akm_suite_count;
+ // we should see two more
+ // octets giving the number of Unicast Cipher Suites
+ unicast_cipher_suite_count, 2;
+ // I don't see anything in the Standard limiting the number of Pairwise
+ // Cypher Suites, other than the maximum length of an IE, which limits us
+ // to 61. However, that seems needlessly wasteful of space.
+ unicast_cipher_suites[4][0..4] COUNTIS unicast_cipher_suite_count;
+ // The next four octets will be the Multicast Cipher Suite
+ multicast_cipher_suite[4];
+ // WAPI capabilities
+ {
+ preauth: 1;
+ reserved: 15;
+ }
+ // Finally, the IE may contain zero or more BKIDs:
+ OPTIONAL bkid_count, 2;
+ bkid[16][0..4] COUNTIS bkid_count;
+}
+
+IE WAPIOpaque (EID_WAPI) // 7.3.2.25
+{
+ data[ 6..253 ];
+}
+
+IE QBSSLoad (EID_QBSS_LOAD) // 7.3.2.28
+{
+ stacount, 2;
+ chautil, 1;
+ avail, 2;
+}
+
+IE EDCAParamSet (EID_EDCA_PARAM_SET) // 7.3.2.29
+{
+ qos, 1; // ToDo: This is a bitfield whose format
+ // depends on whether this is from an AP
+ // or a STA, information which I'm not
+ // sure we have at parse time...
+ reserved, 1;
+ {
+ acbe_aifsn: 4;
+ acbe_acm: 1;
+ acbe_aci: 2;
+ unused1: 1;
+ }
+ {
+ acbe_acwmin: 4;
+ acbe_acwmax: 4;
+ }
+ acbe_txoplimit, 2;
+ {
+ acbk_aifsn: 4;
+ acbk_acm: 1;
+ acbk_aci: 2;
+ unused2: 1;
+ }
+ {
+ acbk_acwmin: 4;
+ acbk_acwmax: 4;
+ }
+ acbk_txoplimit, 2;
+ {
+ acvi_aifsn: 4;
+ acvi_acm: 1;
+ acvi_aci: 2;
+ unused3: 1;
+ }
+ {
+ acvi_acwmin: 4;
+ acvi_acwmax: 4;
+ }
+ acvi_txoplimit, 2;
+ {
+ acvo_aifsn: 4;
+ acvo_acm: 1;
+ acvo_aci: 2;
+ unused4: 1;
+ }
+ {
+ acvo_acwmin: 4;
+ acvo_acwmax: 4;
+ }
+ acvo_txoplimit, 2;
+}
+
+IE TSPEC (EID_TSPEC) // 7.3.2.30
+{
+
+ // TS Info
+ {
+ traffic_type: 1;
+ tsid: 4;
+ direction: 2;
+ access_policy: 2;
+ aggregation: 1;
+ psb: 1;
+ user_priority: 3;
+ tsinfo_ack_pol: 2;
+ }
+ {
+ schedule: 1;
+ unused: 7;
+ }
+
+ // Nominal MSDU Size
+ {
+ size: 15;
+ fixed: 1;
+ }
+
+ max_msdu_size, 2;
+ min_service_int, 4;
+ max_service_int, 4;
+ inactivity_int, 4;
+ suspension_int, 4;
+ service_start_time, 4;
+ min_data_rate, 4;
+ mean_data_rate, 4;
+ peak_data_rate, 4;
+ burst_size, 4;
+ delay_bound, 4;
+ min_phy_rate, 4;
+ surplus_bw_allowance, 2;
+ medium_time, 2;
+
+} // End IE TSPEC.
+
+IE TCLAS (EID_TCLAS) // 7.3.2.31
+{
+ user_priority, 1;
+ classifier_type, 1;
+ classifier_mask, 1;
+ UNION info (DISCRIMINATOR classifier_type)
+ {
+ EthParams (classifier_type IS 0)
+ {
+ source[6];
+ dest[6];
+ type, 2;
+ }
+ IpParams (classifier_type IS 1)
+ {
+ version, 1;
+ UNION params (DISCRIMINATOR version)
+ {
+ IpV4Params (version IS 4)
+ {
+ source[4];
+ dest[4];
+ src_port, 2;
+ dest_port, 2;
+ DSCP, 1;
+ proto, 1;
+ reserved, 1;
+ }
+ IpV6Params (version IS 6)
+ {
+ source[16];
+ dest[16];
+ src_port, 2;
+ dest_port, 2;
+ flow_label[3];
+ }
+ };
+ }
+ Params8021dq (classifier_type IS 2)
+ {
+ tag_type, 2;
+ }
+ };
+} // End IE TCLASS
+
+const EID_RRM_BEACON_REPORTING = 1;
+const EID_RRM_BCN_REPORTING_DETAIL = 2;
+
+IE BeaconReporting (EID_RRM_BEACON_REPORTING)
+{
+ reportingCondition, 1;
+ threshold, 1;
+}
+
+IE BcnReportingDetail (EID_RRM_BCN_REPORTING_DETAIL)
+{
+ reportingDetail, 1;
+}
+
+IE APChannelReport (EID_AP_CHAN_REPORT)
+{
+ regulatoryClass, 1;
+ channelList[0..50];
+}
+
+IE MeasurementRequest (EID_MEAS_REQUEST) // 7.3.2.21
+{
+ measurement_token, 1;
+
+ // Measurement Request Mode
+ {
+ parallel: 1;
+ enable: 1;
+ request: 1;
+ report: 1;
+ durationMandatory: 1;
+ unused: 3;
+ }
+
+ measurement_type, 1;
+ UNION measurement_request (DISCRIMINATOR measurement_type)
+ {
+ Basic (measurement_type IS 0)
+ {
+ channel_no, 1;
+ meas_start_time[8];
+ meas_duration, 2;
+ }
+ CCA (measurement_type IS 1)
+ {
+ channel_no, 1;
+ meas_start_time[8];
+ meas_duration, 2;
+ }
+ RPIHistogram (measurement_type IS 2)
+ {
+ channel_no, 1;
+ meas_start_time[8];
+ meas_duration, 2;
+ }
+ Beacon (measurement_type IS 5)
+ {
+ regClass, 1;
+ channel, 1;
+ randomization, 2;
+ meas_duration, 2;
+ meas_mode, 1;
+ BSSID[6];
+ OPTIE SSID;
+ OPTIE BeaconReporting;
+ OPTIE BcnReportingDetail;
+ OPTIE RequestedInfo;
+ OPTIE APChannelReport[0..2];
+ //OPTIONAL vendor_specific[1..239];
+ }
+
+ };
+}
+
+const EID_BCN_REPORT_FRAME_BODY = 1;
+IE BeaconReportFrmBody (EID_BCN_REPORT_FRAME_BODY)
+{
+ reportedFields[0..224];
+}
+
+IE MeasurementReport (EID_MEAS_REPORT) // 7.3.2.22
+{
+ token, 1;
+ // Measurement Report Mode
+ {
+ late: 1;
+ incapable: 1;
+ refused: 1;
+ unused: 5;
+ }
+ type, 1;
+ OPTIONAL UNION report (DISCRIMINATOR type)
+ {
+ Basic (type IS 0) // 7.3.2.22.1
+ {
+ channel, 1;
+ meas_start_time, 8;
+ meas_duration, 2;
+ // Map
+ {
+ bss: 1;
+ ofdm_preamble: 1;
+ unid_signal: 1;
+ rader: 1;
+ unmeasured: 1;
+ unused: 3;
+ }
+ }
+ CCA (type IS 1)
+ {
+ channel, 1;
+ meas_start_time, 8;
+ meas_duration, 2;
+ cca_busy_fraction, 1;
+ }
+ RPIHistogram (type IS 2)
+ {
+ channel, 1;
+ meas_start_time, 8;
+ meas_duration, 2;
+ rpi0_density, 1;
+ rpi1_density, 1;
+ rpi2_density, 1;
+ rpi3_density, 1;
+ rpi4_density, 1;
+ rpi5_density, 1;
+ rpi6_density, 1;
+ rpi7_density, 1;
+ }
+ Beacon (type IS 5)
+ {
+ regClass, 1;
+ channel, 1;
+ meas_start_time, 8;
+ meas_duration, 2;
+ // reported_frame_info,
+ {
+ condensed_PHY: 7;
+ reported_frame_type: 1;
+ }
+ RCPI, 1;
+ RSNI, 1;
+ BSSID[6];
+ antenna_id, 1;
+ parent_TSF, 4;
+ OPTIE BeaconReportFrmBody;
+ //IE vendor_specific
+ }
+ };
+}
+
+IE TSDelay (EID_TS_DELAY) // 7.3.2.32
+{
+ delay, 4;
+}
+
+IE TCLASSPROC (EID_TCLASS_PROC) // 7.3.2.33
+{
+ processing, 1;
+}
+
+IE Schedule (EID_SCHEDULE) // 7.3.2.34
+{
+ {
+ aggregation: 1;
+ tsid: 4;
+ direction: 2;
+ reserved: 9;
+ }
+ service_start_time, 4;
+ service_interval, 4;
+ max_service_dur, 2;
+ spec_interval, 2;
+}
+
+IE QOSCapsAp (EID_QOS_CAPABILITY) // 7.3.2.35
+{
+ {
+ count: 4;
+ qack: 1;
+ qreq: 1;
+ txopreq: 1;
+ reserved: 1;
+ }
+}
+
+IE QOSCapsStation (EID_QOS_CAPABILITY) // 7.3.2.35
+{
+ {
+ acvo_uapsd: 1;
+ acvi_uapsd: 1;
+ acbk_uapsd: 1;
+ acbe_uapsd: 1;
+ qack: 1;
+ max_sp_length: 2;
+ more_data_ack: 1;
+ }
+}
+
+IE LinkIdentifier (EID_LINK_IDENTIFIER) // 7.3.2.62
+{
+ bssid[6];
+ InitStaAddr[6];
+ RespStaAddr[6];
+}
+
+IE WPA (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01)
+{
+ // This IE's first two octets should be interpreted as a version number;
+ // we only support version 1.
+ version, 2 MUSTBE 1;
+ // A four-octet Multicast Cipher may or may not appear next (hence the
+ // OPTIONAL keyword)
+ OPTIONAL multicast_cipher[4];
+ // Optional Unicast Cipher count
+ OPTIONAL unicast_cipher_count, 2;
+ // Next comes an array of four-octet Cipher Suite selectors; the COUNTIS
+ // clause indicates that the actual number of selectors seen is in the
+ // member 'unicast_cipher_count'.
+ unicast_ciphers[4][0..4] COUNTIS unicast_cipher_count;
+ // (Optional) Authentication suites:
+ OPTIONAL auth_suite_count, 2;
+ auth_suites[4][0..4] COUNTIS auth_suite_count;
+ // This field is declared optional as per bugs 15234, 14755, & 14991.
+ OPTIONAL caps, 2;
+}
+
+IE WPAOpaque (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01)
+{
+ data[ 2..249 ];
+}
+
+IE WMMInfoStation (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00)
+{
+ // This IE contains the QoS Info field when sent from WMM Station
+ version, 1;
+ {
+ acvo_uapsd: 1;
+ acvi_uapsd: 1;
+ acbk_uapsd: 1;
+ acbe_uapsd: 1;
+ reserved1: 1;
+ max_sp_length: 2;
+ reserved2: 1;
+ }
+}
+
+IE WMMInfoAp (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00)
+{
+ // This IE contains the QoS Info field when sent from WMM AP
+ version, 1;
+ {
+ param_set_count: 4;
+ reserved: 3;
+ uapsd: 1;
+ }
+}
+
+
+IE WMMParams (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x01)
+{
+ version, 1 MUSTBE 1;
+ qosInfo, 1; // ToDo: This is actually a
+ // bitfield, but it's format
+ // varies depending on whether
+ // the sender is a STA or AP...
+ reserved2, 1;
+ {
+ acbe_aifsn: 4;
+ acbe_acm: 1;
+ acbe_aci: 2;
+ unused1: 1;
+ }
+ {
+ acbe_acwmin: 4;
+ acbe_acwmax: 4;
+ }
+ acbe_txoplimit, 2;
+ {
+ acbk_aifsn: 4;
+ acbk_acm: 1;
+ acbk_aci: 2;
+ unused2: 1;
+ }
+ {
+ acbk_acwmin: 4;
+ acbk_acwmax: 4;
+ }
+ acbk_txoplimit, 2;
+ {
+ acvi_aifsn: 4;
+ acvi_acm: 1;
+ acvi_aci: 2;
+ unused3: 1;
+ }
+ {
+ acvi_acwmin: 4;
+ acvi_acwmax: 4;
+ }
+ acvi_txoplimit, 2;
+ {
+ acvo_aifsn: 4;
+ acvo_acm: 1;
+ acvo_aci: 2;
+ unused4: 1;
+ }
+ {
+ acvo_acwmin: 4;
+ acvo_acwmax: 4;
+ }
+ acvo_txoplimit, 2;
+}
+
+IE WMMTSPEC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xf2, 0x02, 0x02)
+{
+ version, 1 MUSTBE 1;
+
+ // TS Info
+ {
+ traffic_type: 1;
+ tsid: 4;
+ direction: 2;
+ access_policy: 2;
+ aggregation: 1;
+ psb: 1;
+ user_priority: 3;
+ tsinfo_ack_pol: 2;
+ }
+ {
+ tsinfo_rsvd: 7;
+ burst_size_defn: 1;
+ }
+
+ // Nominal MSDU Size
+ {
+ size: 15;
+ fixed: 1;
+ }
+
+ max_msdu_size, 2;
+ min_service_int, 4;
+ max_service_int, 4;
+ inactivity_int, 4;
+ suspension_int, 4;
+ service_start_time, 4;
+ min_data_rate, 4;
+ mean_data_rate, 4;
+ peak_data_rate, 4;
+ burst_size, 4;
+ delay_bound, 4;
+ min_phy_rate, 4;
+ surplus_bw_allowance, 2;
+ medium_time, 2;
+
+} // End IE WMMTSpec.
+
+IE WMMCaps (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x05)
+{
+ version, 1 MUSTBE 1;
+ {
+ reserved: 4;
+ qack: 1;
+ queue_request: 1;
+ txop_request: 1;
+ more_ack: 1;
+ }
+}
+
+IE WMMTCLAS (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x06)
+{
+ version, 1 MUSTBE 1;
+
+ user_priority, 1;
+ classifier_type, 1;
+ classifier_mask, 1;
+ UNION info (DISCRIMINATOR classifier_type)
+ {
+ EthParams (classifier_type IS 0)
+ {
+ source[6];
+ dest[6];
+ type, 2;
+ }
+ IpParams (classifier_type IS 1)
+ {
+ version, 1;
+ UNION params (DISCRIMINATOR version)
+ {
+ IpV4Params (version IS 4)
+ {
+ source[4];
+ dest[4];
+ src_port, 2;
+ dest_port, 2;
+ DSCP, 1;
+ proto, 1;
+ reserved, 1;
+ }
+ IpV6Params (version IS 6)
+ {
+ source[16];
+ dest[16];
+ src_port, 2;
+ dest_port, 2;
+ flow_label[3];
+ }
+ };
+ }
+ Params8021dq (classifier_type IS 2)
+ {
+ tag_type, 2;
+ }
+ };
+
+}
+
+IE WMMTCLASPROC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x07)
+{
+ version, 1 MUSTBE 1;
+ processing, 1;
+}
+
+IE WMMTSDelay (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x08)
+{
+ version, 1 MUSTBE 1;
+ delay, 4;
+}
+
+IE WMMSchedule (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x09)
+{
+ version, 1 MUSTBE 1;
+
+ {
+ aggregation: 1;
+ tsid: 4;
+ direction: 2;
+ reserved: 9;
+ }
+
+ service_start_time, 4;
+ service_interval, 4;
+ max_service_dur, 2;
+ spec_interval, 2;
+}
+
+IE ESERadMgmtCap (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x01)
+{
+
+ mgmt_state, 1;
+
+ {
+ mbssid_mask: 3;
+ reserved: 5;
+ }
+
+}
+
+IE Vendor1IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x10, 0x18)
+{
+}
+
+IE Vendor3IE (EID_VENDOR_SPECIFIC) OUI (0x00, 0x16, 0x32)
+{
+}
+
+IE QComVendorIE (EID_VENDOR_SPECIFIC) OUI (0x00, 0xA0, 0xC6)
+{
+ type, 1;
+ channel, 1;
+}
+
+IE ESETrafStrmMet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x07)
+{
+ tsid, 1;
+ state, 1;
+ msmt_interval, 2;
+}
+
+IE ESETrafStrmRateSet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x08)
+{
+ tsid, 1;
+ tsrates[0..8];
+}
+
+IE ESEVersion (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x03)
+{
+ version, 1;
+}
+
+IE ESETxmitPower (EID_ESE_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00)
+{
+ power_limit, 1;
+ reserved, 1;
+}
+
+IE ESECckmOpaque (EID_ESE_CCKM_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00)
+{
+ data[ 6..20 ];
+}
+
+IE RRMEnabledCap (EID_RRM_ENABLED_CAPS)
+{
+ //Capability bitmap
+ {
+ LinkMeasurement: 1;
+ NeighborRpt: 1;
+ parallel: 1;
+ repeated: 1;
+ BeaconPassive: 1;
+ BeaconActive: 1;
+ BeaconTable: 1;
+ BeaconRepCond: 1;
+ }
+ {
+ FrameMeasurement: 1;
+ ChannelLoad: 1;
+ NoiseHistogram: 1;
+ statistics: 1;
+ LCIMeasurement: 1;
+ LCIAzimuth: 1;
+ TCMCapability: 1;
+ triggeredTCM: 1;
+ }
+ {
+ APChanReport: 1;
+ RRMMIBEnabled: 1;
+ operatingChanMax: 3;
+ nonOperatinChanMax: 3;
+ }
+ {
+ MeasurementPilot: 3;
+ MeasurementPilotEnabled: 1;
+ NeighborTSFOffset: 1;
+ RCPIMeasurement: 1;
+ RSNIMeasurement: 1;
+ BssAvgAccessDelay: 1;
+ }
+ {
+ BSSAvailAdmission: 1;
+ AntennaInformation: 1;
+ fine_time_meas_rpt: 1;
+ lci_capability: 1;
+ reserved: 4;
+ }
+}
+
+IE MeasurementPilot (EID_RRM_MEAS_PILOT_TX_INFO)
+{
+ measurementPilot, 1;
+ vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now.
+}
+
+IE MultiBssid (EID_MULTIPLE_BSSID)
+{
+ maxBSSIDIndicator, 1;
+ vendorSpecific[0..255];
+}
+
+IE OBSSScanParameters (EID_OBSS_SCAN_PARAMETERS)
+{
+ obssScanPassiveDwell, 2;
+ obssScanActiveDwell, 2;
+ bssChannelWidthTriggerScanInterval, 2;
+ obssScanPassiveTotalPerChannel, 2;
+ obssScanActiveTotalPerChannel, 2;
+ bssWidthChannelTransitionDelayFactor, 2;
+ obssScanActivityThreshold, 2;
+}
+
+IE ht2040_bss_coexistence (EID_20_40_BSS_COEXISTENCE)
+{
+ // 20/40 BSS Coexistence Information
+ {
+ info_request: 1;
+ forty_mhz_intolerant: 1;
+ twenty_mhz_bsswidth_req: 1;
+ obss_scan_exemption_req: 1;
+ obss_scan_exemption_grant: 1;
+ unused: 3;
+ }
+}
+
+IE ht2040_bss_intolerant_report (EID_20_40_BSS_INTOLERANT_REPORT)
+{
+ operating_class, 1;
+ channel_list[0..50];
+}
+
+const EID_RRM_NBR_RPT_TSF = 1;
+const EID_RRM_NBR_CD_COUNTRY = 2;
+const EID_RRM_NBR_MSMT_PILOT_TX_INFO = 66;
+
+IE NeighborReport (EID_NEIGHBOR_REPORT)
+{
+ bssid[6];
+ //Bssid Info
+ {
+ APReachability: 2;
+ Security: 1;
+ KeyScope: 1;
+ //Capabilities
+ SpecMgmtCap: 1;
+ QosCap: 1;
+ apsd: 1;
+ rrm: 1;
+ }
+ //Capabilities contd.
+ {
+ DelayedBA: 1;
+ ImmBA: 1;
+ //Capabilities end.
+ MobilityDomain: 1;
+ reserved: 5;
+ }
+
+ reserved1, 2; //part of BSSID Info.
+
+ regulatoryClass, 1;
+ channel, 1;
+ PhyType, 1;
+ OPTIE IE TSFInfo (EID_RRM_NBR_RPT_TSF)
+ {
+ TsfOffset, 2;
+ BeaconIntvl, 2;
+ }
+ OPTIE IE CondensedCountryStr (EID_RRM_NBR_CD_COUNTRY)
+ {
+ countryStr[2];
+ }
+ OPTIE IE MeasurementPilot; // (EID_RRM_NBR_MSMT_PILOT_TX_INFO)
+// {
+// measurementPilot, 1;
+// vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now.
+// }
+ OPTIE IE RRMEnabledCap;
+ OPTIE IE MultiBssid;
+ //Ignoring vendor specific.
+}
+
+IE RCPIIE (EID_RCPI)
+{
+ rcpi, 1;
+}
+
+IE RSNIIE (EID_RSNI)
+{
+ rsni, 1;
+}
+
+IE WFATPC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x08, 0x00)
+{
+ txPower, 1;
+ linkMargin, 1;
+}
+
+IE MobilityDomain (EID_FT_MOBILITY_DOMAIN)
+{
+ MDID, 2;
+ //FT Capability and policy
+ {
+ overDSCap: 1;
+ resourceReqCap: 1;
+ reserved: 6;
+ }
+}
+const SUB_EID_FT_R1KH_ID = 1;
+const SUB_EID_FT_GTK = 2;
+const SUB_EID_FT_R0KH_ID = 3;
+const SUB_EID_FT_IGTK = 4;
+IE FTInfo (EID_FT_INFO)
+{
+ // MicControl, 2;
+ {
+ reserved: 8;
+ IECount: 8;
+ }
+ MIC[16];
+ Anonce[32];
+ Snonce[32];
+
+ OPTIE IE R1KH_ID (SUB_EID_FT_R1KH_ID)
+ {
+ PMK_R1_ID[6];
+ }
+
+ OPTIE IE GTK (SUB_EID_FT_GTK)
+ {
+ //Key Info
+ {
+ keyId: 2;
+ reserved: 14;
+ }
+ keyLength, 1;
+ RSC[8];
+ key[5..32];
+ }
+
+ OPTIE IE R0KH_ID (SUB_EID_FT_R0KH_ID)
+ {
+ PMK_R0_ID[1..48];
+ }
+
+ OPTIE IE IGTK (SUB_EID_FT_IGTK)
+ {
+ //Key Info
+ keyID[2];
+ IPN[6];
+ keyLength, 1;
+ key[24];
+ }
+}
+
+IE TimeoutInterval (EID_TIMEOUT_INTERVAL)
+{
+ timeoutType, 1;
+ timeoutValue, 4;
+}
+
+//TODO: need to define this properly.
+IE RICData (EID_FT_RIC_DATA)
+{
+ Identifier, 1;
+ resourceDescCount, 1;
+ statusCode, 2;
+}
+
+IE RICDescriptor (EID_FT_RIC_DESCRIPTOR)
+{
+ resourceType, 1;
+ variableData[0..255]; //Block ack param set...TODO:
+}
+
+IE WscIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x00, 0x50, 0xF2, 0x04 )
+{
+ data[ 2..249 ];
+}
+
+IE P2PIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ data[ 2..249 ];
+}
+
+IE WFDIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x0A )
+{
+ data[ 2..249 ];
+}
+
+IE PTIControl (EID_PTI_CONTROL) // 7.3.2.65
+{
+ tid, 1;
+ sequence_control, 2;
+}
+
+IE PUBufferStatus (EID_PU_BUFFER_STATUS) // 7.3.2.66
+{
+ {
+ ac_bk_traffic_aval: 1;
+ ac_be_traffic_aval: 1;
+ ac_vi_traffic_aval: 1;
+ ac_vo_traffic_aval: 1;
+ reserved: 4;
+ }
+}
+
+
+
+IE VHTCaps (EID_VHT_CAPABILITIES)
+{
+ //VHT Capability Info
+ {
+ maxMPDULen: 2;
+ supportedChannelWidthSet: 2;
+ ldpcCodingCap: 1;
+ shortGI80MHz: 1;
+ shortGI160and80plus80MHz: 1;
+ txSTBC: 1;
+ rxSTBC: 3;
+ suBeamFormerCap: 1;
+ suBeamformeeCap: 1;
+ csnofBeamformerAntSup: 3;
+ numSoundingDim: 3;
+ muBeamformerCap: 1;
+ muBeamformeeCap: 1;
+ vhtTXOPPS: 1;
+ htcVHTCap: 1;
+ maxAMPDULenExp: 3;
+ vhtLinkAdaptCap: 2;
+ rxAntPattern: 1;
+ txAntPattern: 1;
+ reserved1: 2;
+ }
+ rxMCSMap, 2;
+ {
+ rxHighSupDataRate: 13;
+ reserved2: 3;
+ }
+ txMCSMap, 2;
+ {
+ txSupDataRate: 13;
+ reserved3: 3;
+ }
+}
+
+IE VHTOperation (EID_VHT_OPERATION_ELEMENT)
+{
+ chanWidth, 1;
+ chanCenterFreqSeg1, 1;
+ chanCenterFreqSeg2, 1;
+ basicMCSSet, 2;
+}
+
+IE VHTExtBssLoad (EID_VHT_EXT_BSS_LOAD)
+{
+ muMIMOCapStaCount, 1;
+ ssUnderUtil, 1;
+ FortyMHzUtil, 1;
+ EightyMHzUtil, 1;
+ OneSixtyMHzUtil, 1;
+}
+
+IE AID (EID_AID)
+{
+ assocId, 2;
+}
+
+IE WiderBWChanSwitchAnn (EID_WIDER_BW_CHANNEL_SWITCH_ANN)
+{
+ newChanWidth, 1;
+ newCenterChanFreq0, 1;
+ newCenterChanFreq1, 1;
+}
+
+IE ChannelSwitchWrapper (EID_CHANNEL_SWITCH_WRAPPER)
+{
+ OPTIE IE WiderBWChanSwitchAnn;
+}
+IE ExtCap (EID_EXT_CAP)
+{
+ bytes[8..9];
+}
+
+IE HTCaps (EID_HT_CAPABILITIES)
+{
+ // HT Capability Info
+ {
+ advCodingCap: 1;
+ supportedChannelWidthSet: 1;
+ mimoPowerSave: 2;
+ greenField: 1;
+ shortGI20MHz: 1;
+ shortGI40MHz: 1;
+ txSTBC: 1;
+ rxSTBC: 2;
+ delayedBA: 1;
+ maximalAMSDUsize: 1;
+ dsssCckMode40MHz: 1;
+ psmp: 1;
+ stbcControlFrame: 1;
+ lsigTXOPProtection: 1;
+ }
+ // HT Parameters Info;
+ {
+ maxRxAMPDUFactor: 2;
+ mpduDensity: 3;
+ reserved1: 3;
+ }
+
+ supportedMCSSet[ HT_MAX_SUPPORTED_MCS_SET ];
+
+ // Extended HT Capability Info
+ {
+ pco: 1;
+ transitionTime: 2;
+ reserved2: 5;
+ mcsFeedback: 2;
+ reserved3: 6;
+ }
+ // TXBF Capability Info
+ {
+ txBF: 1;
+ rxStaggeredSounding: 1;
+ txStaggeredSounding: 1;
+ rxZLF: 1;
+ txZLF: 1;
+ implicitTxBF: 1;
+ calibration: 2;
+ explicitCSITxBF: 1;
+ explicitUncompressedSteeringMatrix: 1;
+ explicitBFCSIFeedback: 3;
+ explicitUncompressedSteeringMatrixFeedback: 3;
+ explicitCompressedSteeringMatrixFeedback: 3;
+ csiNumBFAntennae: 2;
+ uncompressedSteeringMatrixBFAntennae: 2;
+ compressedSteeringMatrixBFAntennae: 2;
+ reserved4: 7;
+ }
+ // AS Capability Info
+ {
+ antennaSelection: 1;
+ explicitCSIFeedbackTx: 1;
+ antennaIndicesFeedbackTx: 1;
+ explicitCSIFeedback: 1;
+ antennaIndicesFeedback: 1;
+ rxAS: 1;
+ txSoundingPPDUs: 1;
+ reserved5: 1;
+ }
+ //TODO: take it out when generic fix to remove extra bytes in IE is available.
+ //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE.
+ rsvd[0..32];
+
+} // End IE HTCaps.
+
+IE HTInfo (EID_HT_INFO)
+{
+ primaryChannel, 1;
+
+ // ahtInfoField1
+ {
+ secondaryChannelOffset: 2;
+ recommendedTxWidthSet: 1;
+ rifsMode: 1;
+ controlledAccessOnly: 1;
+ serviceIntervalGranularity: 3;
+ }
+
+ // ahtInfoField2
+
+
+ // ahtInfoField2
+ {
+ opMode: 2;
+ nonGFDevicesPresent: 1;
+ transmitBurstLimit: 1;
+ obssNonHTStaPresent:1;
+ reserved: 11;
+ }
+
+
+ // ahtInfoField3
+ {
+ basicSTBCMCS: 7;
+ dualCTSProtection: 1;
+ secondaryBeacon: 1;
+ lsigTXOPProtectionFullSupport: 1;
+ pcoActive: 1;
+ pcoPhase: 1;
+ reserved2: 4;
+ }
+
+ basicMCSSet[ HT_MAX_SUPPORTED_MCS_SET ];
+
+ //TODO: take it out when generic fix to remove extra bytes in IE is available.
+ //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE.
+ rsvd[0..32];
+
+} // End IE HTInfo.
+
+
+IE OperatingMode (EID_OPERATING_MODE)
+{
+ { //Operating Mode field
+ chanWidth: 2;
+ reserved: 2;
+ rxNSS: 3;
+ rxNSSType: 1;
+ }
+}
+
+IE QosMapSet (EID_QOS_MAP_SET)
+{
+ dscp_exceptions[0..60];
+}
+
+CONTAINERIE RICDataDesc
+{
+ MANDIE RICData;
+ OPTIE RICDescriptor;
+ OPTIE TSPEC;
+ OPTIE TCLAS[0..2];
+ OPTIE TCLASSPROC;
+ OPTIE TSDelay;
+ OPTIE Schedule;
+ OPTIE WMMTSPEC;
+ OPTIE WMMTCLAS[0..2];
+ OPTIE WMMTCLASPROC;
+ OPTIE WMMTSDelay;
+ OPTIE WMMSchedule;
+}
+
+IE TimeAdvertisement (EID_TIME_ADVERTISEMENT) // 8.4.2.63
+{
+ timing_capabilities, 1;
+ time_value[10];
+ time_error[5];
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// MULTIIEs //
+/////////////////////////////////////////////////////////////////////////////
+
+MULTIIE WSC ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // Must be 0x10
+ OPTIONALTLV WPSState;
+ OPTIONALTLV APSetupLocked;
+ OPTIONALTLV SelectedRegistrarConfigMethods;
+ OPTIONALTLV UUID_E;
+ OPTIONALTLV UUID_R;
+ OPTIONALTLV RFBands;
+ OPTIONALTLV SelectedRegistrar;
+ OPTIONALTLV ConfigMethods;
+ OPTIONALTLV AssociationState;
+ OPTIONALTLV ConfigurationError;
+ OPTIONALTLV Manufacturer;
+ OPTIONALTLV ModelName;
+ OPTIONALTLV ModelNumber;
+ OPTIONALTLV SerialNumber;
+ OPTIONALTLV DeviceName;
+ OPTIONALTLV DevicePasswordID;
+ OPTIONALTLV PrimaryDeviceType;
+ OPTIONALTLV RequestType;
+ OPTIONALTLV ResponseType;
+ OPTIONALTLV VendorExtension;
+ OPTIONALTLV RequestDeviceType;
+}
+
+MULTIIE WscBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ MANDATORYTLV WPSState; // 1 = unconfigured, 2 =
+ // configured
+ OPTIONALTLV APSetupLocked; // Must be included if value
+ // is TRUE
+ OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the
+ // user has recently
+ // activated a Registrar to
+ // add an Enrollee.
+ OPTIONALTLV DevicePasswordID; // Device Password ID
+ // indicates the method or
+ // identifies the specific
+ // password that the
+ // selected Registrar
+ // intends to use.
+ OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains
+ // the config methods active
+ // on the selected
+ // Registrar.
+ OPTIONALTLV UUID_E; // The AP's UUID is provided
+ // only when the AP is a
+ // dual-band AP in push
+ // button mode and
+ // indicating push button
+ // mode on both radios
+ OPTIONALTLV RFBands; // Indicates all RF bands
+ // available on the AP. A
+ // dual-band AP must provide
+ // this attribute.
+ // WSC 2.0
+ OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs
+
+} // End Multi-IE WscBeacon.
+
+MULTIIE WscAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ MANDATORYTLV RequestType; //
+ //
+ // WSC 2.0
+ OPTIONALTLV VendorExtension; // Version2
+
+} // End Multi-IE WscAssocReq.
+
+
+MULTIIE WscAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ MANDATORYTLV ResponseType; //
+ //
+ // WSC 2.0
+ OPTIONALTLV VendorExtension; // Version2
+
+} // End Multi-IE WscAssocRes.
+
+MULTIIE WscReassocRes ( 221 ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ MANDATORYTLV ResponseType; //
+ //
+ // WSC 2.0
+ OPTIONALTLV VendorExtension; // Version2
+
+} // End Multi-IE WscReassocRes
+
+MULTIIE WscProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ MANDATORYTLV RequestType; //
+ //
+ MANDATORYTLV ConfigMethods; // Configuration methods the
+ // Enrollee or Registrar
+ // supports
+ MANDATORYTLV UUID_E; // unique GUID generated by
+ // the Enrollee.
+ MANDATORYTLV PrimaryDeviceType;
+ MANDATORYTLV RFBands; // Specific RF bands used
+ // for this message
+ MANDATORYTLV AssociationState; // Configuration and previous
+ // association state
+ MANDATORYTLV ConfigurationError;
+ MANDATORYTLV DevicePasswordID;
+
+ // WSC 2.0
+ OPTIONALTLV Manufacturer; // Must be included in ver 2.0
+ // or higher.
+ OPTIONALTLV ModelName; // Must be included in ver 2.0
+ // or higher.
+ OPTIONALTLV ModelNumber; // Must be included in ver 2.0
+ // or higher.
+ OPTIONALTLV DeviceName; // Must be included in ver 2.0
+ // or higher.
+ OPTIONALTLV VendorExtension; // Version2 and RequestToEntroll
+
+ OPTIONALTLV RequestDeviceType; // When a device receives a Probe
+ // Request containing this type,
+ // It will only reponse if Primary
+ // or Secondary Device Type matches.
+
+} // End Multi-IE WscProbeReq.
+
+MULTIIE WscProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ MANDATORYTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ MANDATORYTLV WPSState; // 1 = unconfigured, 2 =
+ // configured
+ OPTIONALTLV APSetupLocked; // Must be included if value
+ // is TRUE
+ OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the
+ // user has recently
+ // activated a Registrar to
+ // add an Enrollee.
+ OPTIONALTLV DevicePasswordID; // Device Password ID
+ // indicates the method or
+ // identifies the specific
+ // password that the
+ // selected Registrar
+ // intends to use.
+ OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains
+ // the config methods active
+ // on the selected
+ // Registrar.
+ MANDATORYTLV ResponseType;
+ MANDATORYTLV UUID_E; // unique identifier of AP
+ MANDATORYTLV Manufacturer;
+ MANDATORYTLV ModelName;
+ MANDATORYTLV ModelNumber;
+ MANDATORYTLV SerialNumber;
+ MANDATORYTLV PrimaryDeviceType;
+ MANDATORYTLV DeviceName; // User-friendly description
+ // of device
+ MANDATORYTLV ConfigMethods; // Config Methods corresponds
+ // to the methods the AP
+ // supports as an Enrollee
+ // for adding external
+ // Registrars.
+ OPTIONALTLV RFBands; // Indicates all RF bands
+ // available on the AP. A
+ // dual-band AP must provide
+ // this attribute.
+ // WSC 2.0
+ OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs
+
+} // WscProbeRes.
+
+// This MULTIIE combines the fields from the WSC IEs as they appear in
+// Beacons *and* in Probe Responses, with the difference that they're all
+// optional. In our device drivers, we combine Probe Responses and Beacons
+// into one list, and parse their IEs later (c.f. frame BeaconIEs). Because
+// the WSC IE differs in those two frames, we'd often see warning messages
+// about either unexpected fields showing up (if we thought we were parsing a
+// Beacon, and we in fact had data from a Probe Response) or mandatory fields
+// missing (if we thought we were parsing a Probe Response, and in fact had
+// data from a Beacon).
+
+// I created this MULTIIE to stuff into the BeaconIEs frames to avoid this.
+// It's intended to be used on unpack only, and to do so in a very forgiving
+// way.
+
+MULTIIE WscBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 )
+{
+ OPTIONALTLV Version; // 0x10 = version 1.0, 0x11
+ // = version 1.1, etc.
+ OPTIONALTLV WPSState; // 1 = unconfigured, 2 =
+ // configured
+ OPTIONALTLV APSetupLocked; // Must be included if value
+ // is TRUE
+ OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the
+ // user has recently
+ // activated a Registrar to
+ // add an Enrollee.
+ OPTIONALTLV DevicePasswordID; // Device Password ID
+ // indicates the method or
+ // identifies the specific
+ // password that the
+ // selected Registrar
+ // intends to use.
+ OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains
+ // the config methods active
+ // on the selected
+ // Registrar.
+ OPTIONALTLV ResponseType;
+ OPTIONALTLV UUID_E; // unique identifier of AP
+ OPTIONALTLV Manufacturer;
+ OPTIONALTLV ModelName;
+ OPTIONALTLV ModelNumber;
+ OPTIONALTLV SerialNumber;
+ OPTIONALTLV PrimaryDeviceType;
+ OPTIONALTLV DeviceName; // User-friendly description
+ // of device
+ OPTIONALTLV ConfigMethods; // Config Methods corresponds
+ // to the methods the AP
+ // supports as an Enrollee
+ // for adding external
+ // Registrars.
+ OPTIONALTLV RFBands; // Indicates all RF bands
+ // available on the AP. A
+ // dual-band AP must provide
+ // this attribute.
+ // WSC 2.0
+ OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs
+
+} // WscProbeRes.
+/////////////////////////////////////////////////////////////////////////////
+// MULTIIEs //
+/////////////////////////////////////////////////////////////////////////////
+
+MULTIIE P2PBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV P2PCapability; // Contains P2P Device
+ // and P2P Group Capability
+ MANDATORYTLV P2PDeviceId; // Contains P2P Device
+ // Address
+ OPTIONALTLV NoticeOfAbsence; // Indicates Notice of
+ // Absence schedule and
+ // CT Window
+
+} // End P2PBeacon
+
+
+MULTIIE P2PAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV P2PCapability; // Contains P2P Device
+ // and P2P Group Capability
+ OPTIONALTLV ExtendedListenTiming;
+ MANDATORYTLV P2PDeviceInfo;
+
+} // End P2PAssocReq
+
+
+MULTIIE P2PAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV P2PStatus;
+ OPTIONALTLV ExtendedListenTiming;
+
+} // End P2PAssocRes
+
+
+MULTIIE P2PProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV P2PCapability;
+ OPTIONALTLV P2PDeviceId;
+ MANDATORYTLV ListenChannel;
+ OPTIONALTLV ExtendedListenTiming;
+ OPTIONALTLV OperatingChannel;
+} // End P2PProbeReq
+
+
+MULTIIE P2PProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV P2PCapability;
+ OPTIONALTLV ExtendedListenTiming;
+ OPTIONALTLV NoticeOfAbsence;
+ MANDATORYTLV P2PDeviceInfo;
+ OPTIONALTLV P2PGroupInfo;
+
+} // End P2PProbeRes
+
+
+MULTIIE P2PBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ OPTIONALTLV P2PCapability;
+ OPTIONALTLV P2PDeviceId;
+ OPTIONALTLV ExtendedListenTiming;
+ OPTIONALTLV NoticeOfAbsence;
+ OPTIONALTLV P2PDeviceInfo;
+ OPTIONALTLV P2PGroupInfo;
+
+} // End P2PBeaconProbeRes
+
+
+MULTIIE P2PDeAuth ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV MinorReasonCode;
+}
+
+
+MULTIIE P2PDisAssoc ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 )
+{
+ MANDATORYTLV MinorReasonCode;
+}
+
+IE vendor2_ie (EID_VENDOR_SPECIFIC) OUI (0x00, 0x90, 0x4c)
+{
+ type, 1;
+ sub_type, 1;
+ OPTIE IE VHTCaps;
+ OPTIE IE VHTOperation;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Frames
+
+FRAME Beacon // C.f. Sec. 7.2.3.1
+{
+ FF TimeStamp;
+ FF BeaconInterval;
+ FF Capabilities;
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE FHParamSet;
+ OPTIE DSParams;
+ OPTIE CFParams;
+ OPTIE IBSSParams;
+ OPTIE TIM;
+ OPTIE Country;
+ OPTIE FHParams;
+ OPTIE FHPattTable;
+ OPTIE PowerConstraints;
+ OPTIE ChanSwitchAnn;
+ OPTIE ext_chan_switch_ann;
+ OPTIE Quiet;
+ OPTIE TPCReport;
+ OPTIE ERPInfo;
+ OPTIE ExtSuppRates;
+ OPTIE RSN;
+ OPTIE QBSSLoad;
+ OPTIE EDCAParamSet;
+ OPTIE QOSCapsAp;
+ OPTIE APChannelReport;
+ OPTIE RRMEnabledCap;
+ OPTIE MobilityDomain;
+ OPTIE WPA;
+ OPTIE HTCaps;
+ OPTIE HTInfo;
+ OPTIE sec_chan_offset_ele;
+ OPTIE WMMInfoAp;
+ OPTIE WMMParams;
+ OPTIE WMMCaps;
+ OPTIE WAPI;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESETrafStrmMet;
+ OPTIE ESETxmitPower;
+
+ OPTIE WscBeacon;
+ OPTIE P2PBeacon;
+ OPTIE VHTCaps;
+ OPTIE VHTOperation;
+ OPTIE VHTExtBssLoad;
+ OPTIE ExtCap;
+ OPTIE OperatingMode;
+ OPTIE WiderBWChanSwitchAnn;
+ OPTIE OBSSScanParameters;
+ OPTIE Vendor1IE;
+ OPTIE vendor2_ie;
+ OPTIE Vendor3IE;
+ OPTIE ChannelSwitchWrapper;
+ OPTIE QComVendorIE;
+ OPTIE ESEVersion;
+} // End frame Beacon.
+
+// Ok, here's the story on Beacon1 & Beacon2. We presumably beacon a lot
+// more than we change configuration. So it makes sense to keep the beacon
+// we plan to send next in serialized format. We do this in struct schMisc.
+// Whenever our config changes in a way that would affect our beacons, we
+// just update our internal datastructures & re-generate the serialized
+// beacon.
+
+// The problem is that there are *some* fields that need to be updated at
+// send time, specifically the CF Param Set & the TIM. So, what we do is
+// this: whenever our config changes, call schSetFixedBeaconFields. There,
+// we serialize the following Beacon fields into gSchBeaconFrameBegin (after
+// the power template & MAC header): TimeStamp, BeaconInterval, Capabilities,
+// SSID, SuppRates, DSParams, & IBSSParams. It sets gSchBeaconOffsetBegin to
+// the length of this buffer (incl. power template & MAC header).
+
+// Next, it serializes the following fields into gSchBeaconFrameEnd: Country,
+// EDCAParamSet, PowerConstraints, TPCReport, ChannelSwitchAnn, Quiet,
+// ERPInfo, HTCaps, HTInfo, ExtSuppRates, WPA, RSN, WMMInfo,
+// WMMParams, WMMCaps.
+// The length of *this* buffer is kept in gSchBeaconOffsetEnd.
+
+// Then, in 'schBeaconInterruptHandler', we write CFParams & TIM at the end
+// of gSchBeaconFrameBegin, keeping track of the (new) size of this buffer in
+// the local 'beaconSize'.
+
+// After that, we call 'specialBeaconProcessing'. Note that this may
+// actually call schSetFixedBeaconFields repeatedly! The comments say they
+// try to avoid this, but...
+
+// Finally, we call writeBeaconToTFP, where the first thing we do is copy the
+// gSchBeaconFrameEnd buffer after the end of gSchBeaconFrameBegin.
+
+FRAME Beacon1
+{
+ FF TimeStamp;
+ FF BeaconInterval;
+ FF Capabilities;
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE DSParams;
+ OPTIE IBSSParams;
+}
+
+FRAME Beacon2
+{
+ OPTIE Country;
+ OPTIE PowerConstraints;
+ OPTIE ChanSwitchAnn;
+ OPTIE ext_chan_switch_ann;
+ OPTIE Quiet;
+ OPTIE TPCReport;
+ OPTIE ERPInfo;
+ OPTIE ExtSuppRates;
+ OPTIE RSNOpaque;
+ OPTIE EDCAParamSet;
+ OPTIE APChannelReport;
+ OPTIE RRMEnabledCap;
+ OPTIE MobilityDomain;
+ OPTIE WPA;
+ OPTIE HTCaps;
+ OPTIE HTInfo;
+ OPTIE sec_chan_offset_ele;
+ OPTIE WMMInfoAp;
+ OPTIE WMMParams;
+ OPTIE WMMCaps;
+ OPTIE WscBeacon;
+ OPTIE WAPI;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESETrafStrmMet;
+ OPTIE ESETxmitPower;
+ OPTIE P2PBeacon;
+ OPTIE VHTCaps;
+ OPTIE VHTOperation;
+ OPTIE VHTExtBssLoad;
+ OPTIE ExtCap;
+ OPTIE OperatingMode;
+ OPTIE WiderBWChanSwitchAnn;
+ OPTIE OBSSScanParameters;
+ OPTIE Vendor1IE;
+ OPTIE vendor2_ie;
+ OPTIE Vendor3IE;
+ OPTIE ChannelSwitchWrapper;
+ OPTIE QComVendorIE;
+ OPTIE ESEVersion;
+}
+
+// This frame is just Beacon with its Fixed Fields stripped out. It's handy
+// for use with struct 'tSirBssDescription', which has members corresponding
+// to some fixed fields, but keeps its IEs in un-parsed format.
+
+// Note that it also includes the IE 'WscBeaconProbeRes'.
+
+FRAME BeaconIEs
+{
+
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE FHParamSet;
+ OPTIE DSParams;
+ OPTIE CFParams;
+ OPTIE IBSSParams;
+ OPTIE TIM;
+ OPTIE Country;
+ OPTIE FHParams;
+ OPTIE FHPattTable;
+ OPTIE PowerConstraints;
+ OPTIE ChanSwitchAnn;
+ OPTIE ext_chan_switch_ann;
+ OPTIE Quiet;
+ OPTIE TPCReport;
+ OPTIE ERPInfo;
+ OPTIE ExtSuppRates;
+ OPTIE RSN;
+ OPTIE QBSSLoad;
+ OPTIE EDCAParamSet;
+ OPTIE QOSCapsAp;
+ OPTIE APChannelReport;
+ OPTIE RRMEnabledCap;
+ OPTIE MobilityDomain;
+ OPTIE WPA;
+ OPTIE HTCaps;
+ OPTIE HTInfo;
+ OPTIE sec_chan_offset_ele;
+ OPTIE WMMInfoAp;
+ OPTIE WMMParams;
+ OPTIE WMMCaps;
+ OPTIE WAPI;
+ OPTIE ESEVersion;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESETrafStrmMet;
+ OPTIE ESETxmitPower;
+
+ OPTIE WscBeaconProbeRes;
+ OPTIE P2PBeaconProbeRes;
+ OPTIE VHTCaps;
+ OPTIE VHTOperation;
+ OPTIE VHTExtBssLoad;
+ OPTIE ExtCap;
+ OPTIE OperatingMode;
+ OPTIE WiderBWChanSwitchAnn;
+ OPTIE OBSSScanParameters;
+ OPTIE Vendor1IE;
+ OPTIE vendor2_ie;
+ OPTIE Vendor3IE;
+ OPTIE ChannelSwitchWrapper;
+ OPTIE QComVendorIE;
+} // End frame BeaconIEs.
+
+FRAME Disassociation // 7.3.3.3
+{
+ FF Reason;
+ OPTIE P2PDisAssoc;
+}
+
+FRAME AssocRequest // 7.2.3.4
+{
+ FF Capabilities;
+ FF ListenInterval;
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE ExtSuppRates;
+ OPTIE PowerCaps;
+ OPTIE SuppChannels;
+ OPTIE RSNOpaque;
+ OPTIE QOSCapsStation;
+ OPTIE RRMEnabledCap;
+ OPTIE MobilityDomain;
+ OPTIE WPAOpaque;
+ OPTIE HTCaps;
+ OPTIE WMMCaps;
+ OPTIE WMMInfoStation;
+ OPTIE WscIEOpaque;
+ OPTIE WAPIOpaque;
+ OPTIE WAPI;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESEVersion;
+ OPTIE P2PIEOpaque;
+ OPTIE WFDIEOpaque;
+ OPTIE VHTCaps;
+ OPTIE ExtCap;
+ OPTIE OperatingMode;
+ OPTIE QosMapSet;
+ OPTIE vendor2_ie;
+} // End frame AssocRequest.
+
+FRAME AssocResponse // 7.2.3.5
+{
+ FF Capabilities;
+ FF Status;
+ FF AID;
+ MANDIE SuppRates;
+ OPTIE ExtSuppRates;
+ OPTIE EDCAParamSet;
+ OPTIE RCPIIE;
+ OPTIE RSNIIE;
+ OPTIE RRMEnabledCap;
+ OPTIE MobilityDomain;
+ OPTIE FTInfo;
+ OPTIE RICDataDesc[2];
+ OPTIE WPA;
+ OPTIE TimeoutInterval;
+ OPTIE HTCaps;
+ OPTIE HTInfo;
+ OPTIE WMMParams;
+ OPTIE WMMCaps;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESETrafStrmMet;
+ OPTIE ESETxmitPower;
+ OPTIE WMMTSPEC[0..4];
+ OPTIE WscAssocRes;
+ OPTIE P2PAssocRes;
+ OPTIE VHTCaps;
+ OPTIE VHTOperation;
+ OPTIE ExtCap;
+ OPTIE OBSSScanParameters;
+ OPTIE QosMapSet;
+ OPTIE vendor2_ie;
+} // End frame AssocResponse.
+
+FRAME ReAssocRequest // 7.2.3.6
+{
+ FF Capabilities;
+ FF ListenInterval;
+ FF CurrentAPAddress;
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE ExtSuppRates;
+ OPTIE PowerCaps;
+ OPTIE SuppChannels;
+ OPTIE RSNOpaque;
+ OPTIE QOSCapsStation;
+ OPTIE RRMEnabledCap;
+ OPTIE MobilityDomain;
+ OPTIE FTInfo;
+ OPTIE RICDataDesc[2];
+ OPTIE WPAOpaque;
+ OPTIE HTCaps;
+ OPTIE WMMCaps;
+ OPTIE WMMInfoStation;
+ OPTIE WscIEOpaque;
+ OPTIE WAPIOpaque;
+ OPTIE WAPI;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESEVersion;
+ OPTIE ESECckmOpaque;
+ OPTIE WMMTSPEC[0..4];
+ OPTIE ESETrafStrmRateSet;
+ OPTIE P2PIEOpaque;
+ OPTIE WFDIEOpaque;
+ OPTIE VHTCaps;
+ OPTIE ExtCap;
+ OPTIE OperatingMode;
+ OPTIE QosMapSet;
+ OPTIE vendor2_ie;
+} // End frame ReAssocRequest.
+
+FRAME ReAssocResponse // 7.2.3.7
+{
+ FF Capabilities;
+ FF Status;
+ FF AID;
+ MANDIE SuppRates;
+ OPTIE ExtSuppRates;
+ OPTIE EDCAParamSet;
+ OPTIE RCPIIE;
+ OPTIE RSNIIE;
+ OPTIE RRMEnabledCap;
+ OPTIE RSNOpaque;
+ OPTIE MobilityDomain;
+ OPTIE FTInfo;
+ OPTIE RICDataDesc[2];
+ OPTIE WPA;
+ OPTIE TimeoutInterval;
+ OPTIE HTCaps;
+ OPTIE HTInfo;
+ OPTIE WMMParams;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESETrafStrmMet;
+ OPTIE ESETxmitPower;
+ OPTIE WMMTSPEC[0..4];
+ OPTIE ESETrafStrmRateSet;
+ OPTIE WscReassocRes;
+ OPTIE P2PAssocRes;
+ OPTIE VHTCaps;
+ OPTIE VHTOperation;
+ OPTIE ExtCap;
+ OPTIE OBSSScanParameters;
+ OPTIE QosMapSet;
+ OPTIE vendor2_ie;
+} // End frame ReAssocResponse.
+
+FRAME ProbeRequest // 7.2.3.8
+{
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE RequestedInfo;
+ OPTIE ExtSuppRates;
+ OPTIE DSParams;
+ OPTIE HTCaps;
+ OPTIE WscProbeReq;
+ OPTIE WFATPC;
+ OPTIE P2PProbeReq;
+ OPTIE VHTCaps;
+ OPTIE ExtCap;
+} // End frame ProbeRequest.
+
+FRAME ProbeResponse // 7.2.3.9
+{
+ FF TimeStamp;
+ FF BeaconInterval;
+ FF Capabilities;
+ MANDIE SSID;
+ MANDIE SuppRates;
+ OPTIE FHParamSet;
+ OPTIE DSParams;
+ OPTIE CFParams;
+ OPTIE IBSSParams;
+ OPTIE Country;
+ OPTIE FHParams;
+ OPTIE FHPattTable;
+ OPTIE PowerConstraints;
+ OPTIE ChanSwitchAnn;
+ OPTIE ext_chan_switch_ann;
+ OPTIE Quiet;
+ OPTIE TPCReport;
+ OPTIE ERPInfo;
+ OPTIE ExtSuppRates;
+ OPTIE RSNOpaque;
+ OPTIE QBSSLoad;
+ OPTIE EDCAParamSet;
+ OPTIE RRMEnabledCap;
+ OPTIE APChannelReport;
+ OPTIE MobilityDomain;
+ OPTIE WPA;
+ OPTIE HTCaps;
+ OPTIE HTInfo;
+ OPTIE sec_chan_offset_ele;
+ OPTIE WMMInfoAp;
+ OPTIE WMMParams;
+ OPTIE WMMCaps;
+ OPTIE WAPI;
+ OPTIE ESERadMgmtCap;
+ OPTIE ESETrafStrmMet;
+ OPTIE ESETxmitPower;
+
+ OPTIE WscProbeRes;
+ OPTIE P2PProbeRes;
+
+ OPTIE VHTCaps;
+ OPTIE VHTOperation;
+ OPTIE VHTExtBssLoad;
+ OPTIE ExtCap;
+ OPTIE OBSSScanParameters;
+ OPTIE Vendor1IE;
+ OPTIE vendor2_ie;
+ OPTIE Vendor3IE;
+ OPTIE ChannelSwitchWrapper;
+ OPTIE QComVendorIE;
+ OPTIE ESEVersion;
+} // End frame ProbeResponse.
+
+FRAME Authentication // 7.2.3.10
+{
+ FF AuthAlgo;
+ FF AuthSeqNo;
+ FF Status;
+ OPTIE ChallengeText;
+ OPTIE RSNOpaque;
+ OPTIE MobilityDomain;
+ OPTIE FTInfo;
+ OPTIE TimeoutInterval;
+ OPTIE RICDataDesc[2];
+} // End frame Auth.
+
+FRAME DeAuth // 7.2.3.11
+{
+ FF Reason;
+ OPTIE P2PDeAuth;
+}
+
+FRAME AddTSRequest // 7.4.2.1
+{
+
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE TSPEC;
+ OPTIE TCLAS[0..2];
+ OPTIE TCLASSPROC;
+
+ // These IEs aren't in the spec, but our extant code *will* parse them if
+ // they're present. I included them to preserve that capability
+
+ OPTIE WMMTSPEC;
+ OPTIE WMMTCLAS[0..2];
+ OPTIE WMMTCLASPROC;
+ OPTIE ESETrafStrmRateSet;
+
+} // End frame AddTSRequest.
+
+FRAME WMMAddTSRequest
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF StatusCode;
+ MANDIE WMMTSPEC;
+ OPTIE ESETrafStrmRateSet;
+} // End Frame WMMAddTSRequest
+
+FRAME AddTSResponse // 7.4.2.2
+{
+
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF Status;
+ MANDIE TSDelay;
+ MANDIE TSPEC;
+ OPTIE TCLAS[0..2];
+ OPTIE TCLASSPROC;
+ OPTIE Schedule;
+
+ // These IEs aren't in the spec, but our extant code *will* parse them if
+ // they're present. I included them to preserve that capability
+ OPTIE WMMTSDelay;
+ OPTIE WMMSchedule;
+ OPTIE WMMTSPEC;
+ OPTIE WMMTCLAS[0..2];
+ OPTIE WMMTCLASPROC;
+ OPTIE ESETrafStrmMet;
+
+} // End frame AddTSResponse.
+
+FRAME WMMAddTSResponse
+{
+
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF StatusCode;
+ OPTIE WMMTSPEC;
+ OPTIE ESETrafStrmMet;
+
+} // End frame WMMAddTSResponse.
+
+FRAME DelTS // 7.4.2.3
+{
+ FF Category;
+ FF Action;
+ FF TSInfo;
+ FF Reason;
+}
+
+FRAME WMMDelTS
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF StatusCode;
+ MANDIE WMMTSPEC;
+}
+
+FRAME TPCRequest
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE TPCRequest;
+}
+
+FRAME TPCReport
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE TPCReport;
+}
+
+FRAME ChannelSwitch
+{
+ FF Category;
+ FF Action;
+ MANDIE ChanSwitchAnn;
+ OPTIE sec_chan_offset_ele;
+ OPTIE WiderBWChanSwitchAnn;
+}
+
+FRAME MeasurementRequest
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE MeasurementRequest[1..4];
+}
+
+FRAME MeasurementReport
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE MeasurementReport;
+}
+
+FRAME SMPowerSave
+{
+ FF Category;
+ FF Action;
+ FF SMPowerModeSet;
+}
+
+FRAME RadioMeasurementRequest
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF NumOfRepetitions;
+ //Measurement Request IE.
+ MANDIE MeasurementRequest[1..2];
+}
+
+FRAME RadioMeasurementReport
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ //Measurement Report elements.
+ MANDIE MeasurementReport[1..4];
+}
+
+FRAME LinkMeasurementRequest
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF TxPower;
+ FF MaxTxPower;
+ //Optional Sub Ies
+}
+
+FRAME LinkMeasurementReport
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF TPCEleID;
+ FF TPCEleLen;
+ FF TxPower;
+ FF LinkMargin;
+ FF RxAntennaId;
+ FF TxAntennaId;
+ FF RCPI;
+ FF RSNI;
+ //Optional Vendor specific IEs ... ignoring
+}
+
+FRAME NeighborReportRequest
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ OPTIE SSID;
+ //Optional vendor specific IE...ignoring.
+}
+
+FRAME NeighborReportResponse
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ OPTIE NeighborReport[1..MAX_SUPPORTED_NEIGHBOR_RPT];
+}
+
+FRAME OperatingMode
+{
+ FF Category;
+ FF Action;
+ //Operating Mode field
+ FF OperatingMode;
+}
+
+FRAME TDLSDisReq
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE LinkIdentifier;
+}
+
+FRAME TDLSDisRsp
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF Capabilities;
+ MANDIE SuppRates;
+ OPTIE ExtSuppRates;
+ OPTIE SuppChannels;
+ OPTIE SuppOperatingClasses;
+ OPTIE RSN;
+ OPTIE ExtCap;
+ OPTIE FTInfo;
+ OPTIE TimeoutInterval;
+ OPTIE RICData;
+ OPTIE HTCaps;
+ OPTIE ht2040_bss_coexistence;
+ MANDIE LinkIdentifier;
+ OPTIE VHTCaps;
+}
+
+FRAME TDLSSetupReq
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ FF Capabilities;
+ MANDIE SuppRates;
+ OPTIE Country;
+ OPTIE ExtSuppRates;
+ OPTIE SuppChannels;
+ OPTIE RSN;
+ OPTIE ExtCap;
+ OPTIE SuppOperatingClasses;
+ OPTIE QOSCapsStation;
+ OPTIE FTInfo;
+ OPTIE TimeoutInterval;
+ OPTIE RICData;
+ OPTIE HTCaps;
+ OPTIE ht2040_bss_coexistence;
+ MANDIE LinkIdentifier;
+ OPTIE WMMInfoStation;
+ OPTIE AID;
+ OPTIE VHTCaps;
+}
+
+FRAME TDLSSetupRsp
+{
+ FF Category;
+ FF Action;
+ FF Status;
+ FF DialogToken;
+ FF Capabilities ;
+ OPTIE SuppRates;
+ OPTIE Country;
+ OPTIE ExtSuppRates;
+ OPTIE SuppChannels;
+ OPTIE RSN;
+ OPTIE ExtCap;
+ OPTIE SuppOperatingClasses;
+ OPTIE QOSCapsStation;
+ OPTIE FTInfo;
+ OPTIE TimeoutInterval;
+ OPTIE RICData;
+ OPTIE HTCaps;
+ OPTIE ht2040_bss_coexistence;
+ OPTIE LinkIdentifier;
+ OPTIE WMMInfoStation;
+ OPTIE AID;
+ OPTIE VHTCaps;
+ OPTIE OperatingMode;
+}
+
+FRAME TDLSSetupCnf
+{
+ FF Category;
+ FF Action;
+ FF Status;
+ FF DialogToken;
+ OPTIE RSN;
+ OPTIE EDCAParamSet;
+ OPTIE FTInfo;
+ OPTIE TimeoutInterval;
+ OPTIE HTInfo;
+ OPTIE LinkIdentifier;
+ OPTIE WMMParams;
+ OPTIE VHTOperation;
+ OPTIE OperatingMode;
+}
+FRAME TDLSTeardown
+{
+ FF Category;
+ FF Action;
+ FF Reason;
+ OPTIE FTInfo;
+ MANDIE LinkIdentifier;
+}
+
+FRAME TDLSPeerTrafficInd
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE LinkIdentifier;
+ OPTIE PTIControl;
+ MANDIE PUBufferStatus;
+}
+
+FRAME TDLSPeerTrafficRsp
+{
+ FF Category;
+ FF Action;
+ FF DialogToken;
+ MANDIE LinkIdentifier;
+}
+
+FRAME SaQueryReq
+{
+ FF Category;
+ FF Action;
+ FF TransactionId;
+}
+
+FRAME SaQueryRsp
+{
+ FF Category;
+ FF Action;
+ FF TransactionId;
+}
+
+FRAME QosMapConfigure
+{
+ FF Category;
+ FF Action;
+ MANDIE QosMapSet;
+}
+
+FRAME VHTGidManagementActionFrame
+{
+ FF Category;
+ FF Action;
+ FF VhtMembershipStatusArray;
+ FF VhtUserPositionArray;
+}
+
+FRAME ht2040_bss_coexistence_mgmt_action_frame
+{
+ FF Category;
+ FF Action;
+ MANDIE ht2040_bss_coexistence;
+ MANDIE ht2040_bss_intolerant_report;
+}
+
+FRAME TimingAdvertisementFrame // 8.3.3.15
+{
+ FF TimeStamp;
+ FF Capabilities;
+ OPTIE Country;
+ OPTIE PowerConstraints;
+ OPTIE TimeAdvertisement;
+ OPTIE ExtCap;
+ OPTIE Vendor1IE;
+ OPTIE Vendor3IE;
+}
+
+// Local Variables:
+// mode: c++
+// fill-column: 77
+// comment-column: 42
+// indent-tabs-mode: nil
+// show-trailing-whitespace: t
+// End:
+
+// parser.frms ends here.
diff --git a/core/mac/src/cfg/cfg_api.c b/core/mac/src/cfg/cfg_api.c
new file mode 100644
index 0000000..3a0d689
--- /dev/null
+++ b/core/mac/src/cfg/cfg_api.c
@@ -0,0 +1,948 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file contains the source code for CFG API functions.
+ *
+ * Author: Kevin Nguyen
+ * Date: 04/09/02
+ * History:-
+ * 04/09/02 Created.
+ * --------------------------------------------------------------------
+ */
+
+#include "cds_api.h"
+#include "cfg_priv.h"
+#include "cfg_debug.h"
+#include "wma_types.h"
+#include "cfg_api.h"
+
+/* --------------------------------------------------------------------- */
+/* Static Variables */
+/* ---------------------------------------------------------------------- */
+static tCfgCtl __g_cfg_entry[CFG_PARAM_MAX_NUM];
+static uint32_t __g_cfg_i_buf_min[CFG_STA_IBUF_MAX_SIZE];
+static uint32_t __g_cfg_i_buf_max[CFG_STA_IBUF_MAX_SIZE];
+static uint32_t __g_cfg_i_buf[CFG_STA_IBUF_MAX_SIZE];
+static uint8_t __g_cfg_s_buf[CFG_STA_SBUF_MAX_SIZE];
+static uint8_t __g_s_buffer[CFG_MAX_STR_LEN];
+static uint32_t __g_param_list[WNI_CFG_MAX_PARAM_NUM +
+ WNI_CFG_GET_PER_STA_STAT_RSP_NUM];
+
+static void notify(tpAniSirGlobal, uint16_t, uint32_t);
+
+typedef enum {
+ eRF_BAND_UNKNOWN = 0,
+ eRF_BAND_2_4_GHZ = 1,
+ eRF_BAND_5_GHZ = 2
+} eRfBandMode;
+
+extern cfgstatic_string cfg_static_string[CFG_MAX_STATIC_STRING];
+extern cgstatic cfg_static[CFG_PARAM_MAX_NUM] ;
+
+/* --------------------------------------------------------------------- */
+uint32_t cfg_need_restart(tpAniSirGlobal pMac, uint16_t cfgId)
+{
+ if (!pMac->cfg.gCfgEntry) {
+ PELOGE(cfg_log(pMac, LOGE, FL("gCfgEntry is NULL"));)
+ return 0;
+ }
+ return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RESTART);
+}
+
+void cfg_get_strindex(tpAniSirGlobal pMac, uint16_t cfgId)
+{
+ uint16_t i = 0;
+
+ for (i = 0; i < CFG_MAX_STATIC_STRING; i++) {
+ if (cfgId == cfg_static_string[i].cfgId)
+ break;
+ }
+ if (i == CFG_MAX_STATIC_STRING) {
+ PELOGE(cfg_log(pMac, LOGE, FL("Entry not found for cfg id :%d"), cfgId);)
+ cfg_static[cfgId].pStrData = NULL;
+ return;
+ }
+ cfg_static[cfgId].pStrData = &cfg_static_string[i];
+}
+/* --------------------------------------------------------------------- */
+uint32_t cfg_need_reload(tpAniSirGlobal pMac, uint16_t cfgId)
+{
+ if (!pMac->cfg.gCfgEntry) {
+ PELOGE(cfg_log(pMac, LOGE, FL("gCfgEntry is NULL"));)
+ return 0;
+ }
+ return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RELOAD);
+}
+
+/* --------------------------------------------------------------------- */
+tSirRetStatus cfg_init(tpAniSirGlobal pMac)
+{
+ uint16_t i = 0;
+ pMac->cfg.gCfgIBufMin = __g_cfg_i_buf_min;
+ pMac->cfg.gCfgIBufMax = __g_cfg_i_buf_max;
+ pMac->cfg.gCfgIBuf = __g_cfg_i_buf;
+ pMac->cfg.gCfgSBuf = __g_cfg_s_buf;
+ pMac->cfg.gSBuffer = __g_s_buffer;
+ pMac->cfg.gCfgEntry = __g_cfg_entry;
+ pMac->cfg.gParamList = __g_param_list;
+
+ for (i = 0; i < CFG_PARAM_MAX_NUM; i++) {
+ if (!(cfg_static[i].control & CFG_CTL_INT)) {
+ cfg_get_strindex(pMac, i);
+ } else {
+ cfg_static[i].pStrData = NULL;
+ }
+ }
+ return (eSIR_SUCCESS);
+}
+
+/* ---------------------------------------------------------------------- */
+void cfg_de_init(tpAniSirGlobal pMac)
+{
+ pMac->cfg.gCfgIBufMin = NULL;
+ pMac->cfg.gCfgIBufMax = NULL;
+ pMac->cfg.gCfgIBuf = NULL;
+ pMac->cfg.gCfgSBuf = NULL;
+ pMac->cfg.gSBuffer = NULL;
+ pMac->cfg.gCfgEntry = NULL;
+ pMac->cfg.gParamList = NULL;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_check_valid()
+ *
+ * FUNCTION:
+ * This function is called to check if a parameter is valid
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ */
+tSirRetStatus cfg_check_valid(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint32_t *index)
+{
+ uint32_t control;
+
+ if (cfgId >= CFG_PARAM_MAX_NUM) {
+ PELOGE(cfg_log(pMac, LOG3, FL("Invalid cfg id %d"), cfgId);)
+ return eSIR_CFG_INVALID_ID;
+ }
+ if (!pMac->cfg.gCfgEntry) {
+ PELOGE(cfg_log(pMac, LOGE, FL("gCfgEntry is NULL"));)
+ return eSIR_CFG_INVALID_ID;
+ }
+
+ control = pMac->cfg.gCfgEntry[cfgId].control;
+
+ /* Check if parameter is valid */
+ if ((control & CFG_CTL_VALID) == 0) {
+ PELOGE(cfg_log(pMac, LOGE, FL("Not valid cfg id %d"), cfgId);)
+ return eSIR_CFG_INVALID_ID;
+ }
+
+ *index = control & CFG_BUF_INDX_MASK;
+
+ if (*index >= CFG_STA_SBUF_MAX_SIZE) {
+ PELOGE(cfg_log(pMac, LOGE, FL("cfg index out of bounds %d"),
+ *index);)
+ return eSIR_CFG_INVALID_ID;
+ }
+
+ return eSIR_SUCCESS;
+
+} /*** end cfg_check_valid() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_set_int()
+ *
+ * FUNCTION:
+ * This function is called to update an integer parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Range checking is performed by the calling function. In case this
+ * function call is being triggered by a request from host, then host
+ * is responsible for performing range checking before sending the
+ * request.
+ *
+ * - Host RW permission checking should already be done prior to calling
+ * this function by the message processing function.
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param value: 32-bit unsigned value
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ */
+
+tSirRetStatus cfg_set_int(tpAniSirGlobal pMac, uint16_t cfgId, uint32_t value)
+{
+ uint32_t index;
+ uint32_t control;
+ uint32_t mask;
+ tSirRetStatus status;
+
+ status = cfg_check_valid(pMac, cfgId, &index);
+
+ if (eSIR_SUCCESS != status)
+ return status;
+
+ if ((pMac->cfg.gCfgIBufMin[index] > value) ||
+ (pMac->cfg.gCfgIBufMax[index] < value)) {
+ PELOGE(cfg_log (pMac, LOGE, FL(
+ "Value %d out of range [%d,%d] cfg id %d"), value,
+ pMac->cfg.gCfgIBufMin[index],
+ pMac->cfg.gCfgIBufMax[index], cfgId);)
+ return eSIR_CFG_INVALID_ID;
+ } else {
+ /* Write integer value */
+ pMac->cfg.gCfgIBuf[index] = value;
+
+ control = pMac->cfg.gCfgEntry[cfgId].control;
+ /* Update hardware if necessary */
+ mask = control & CFG_CTL_NTF_MASK;
+ if ((mask & CFG_CTL_NTF_HW) != 0)
+ PELOGE(cfg_log(pMac, LOGE, FL(
+ "CFG notify HW not supported!!!"));)
+ /* notify other modules if necessary */
+ if ((mask & CFG_CTL_NTF_MASK) != 0)
+ notify(pMac, cfgId, mask);
+ }
+ return status;
+} /*** end cfg_set_int ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_int()
+ *
+ * FUNCTION:
+ * This function is called to read an integer parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param pVal: address where parameter value will be written
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ */
+
+tSirRetStatus wlan_cfg_get_int(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint32_t *pValue)
+{
+ uint32_t index;
+ tSirRetStatus status;
+
+ status = cfg_check_valid(pMac, cfgId, &index);
+
+ if (eSIR_SUCCESS != status)
+ return status;
+
+ /* Get integer value */
+ *pValue = pMac->cfg.gCfgIBuf[index];
+
+ return eSIR_SUCCESS;
+} /*** end wlan_cfg_get_int() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_set_str()
+ *
+ * FUNCTION:
+ * This function is called to set a string parameter.
+ *
+ * LOGIC:
+ * This function invokes the cfg_set_str_notify function passing the notify
+ * bool value set to true. This basically means that HAL needs to be
+ * notified. This is true in the case of non-integrated SOC's or Libra/Volans.
+ * In the case of Prima the cfg_set_str_notify is invoked with the bool value
+ * set to false.
+ *
+ * ASSUMPTIONS:
+ * - always notify has to be called
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param pStr: address of string data
+ * @param len: string length
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ * @return eSIR_CFG_INVALID_LEN: invalid CFG parameter length
+ *
+ */
+
+tSirRetStatus cfg_set_str(tpAniSirGlobal pMac, uint16_t cfgId, uint8_t *pStr,
+ uint32_t length)
+{
+ return cfg_set_str_notify(pMac, cfgId, pStr, length, true);
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_set_str_notify()
+ *
+ * FUNCTION:
+ * This function is called to set a string parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - No length checking will be performed. Should be done by calling
+ * module.
+ * - Host RW permission should be checked prior to calling this
+ * function.
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param pStr: address of string data
+ * @param len: string length
+ * @param notifyMod. notify respective Module
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ * @return eSIR_CFG_INVALID_LEN: invalid CFG parameter length
+ *
+ */
+
+tSirRetStatus cfg_set_str_notify(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint8_t *pStr, uint32_t length,
+ int notifyMod)
+{
+ uint8_t *pDst, *pDstEnd;
+ uint32_t index, paramLen, mask;
+ uint32_t control;
+ tSirRetStatus status;
+
+ status = cfg_check_valid(pMac, cfgId, &index);
+
+ if (eSIR_SUCCESS != status)
+ return status;
+
+ pDst = &pMac->cfg.gCfgSBuf[index];
+ paramLen = *pDst++;
+ control = pMac->cfg.gCfgEntry[cfgId].control;
+ if (length > paramLen) {
+ PELOGE(cfg_log(pMac, LOGE, FL(
+ "Invalid length %d (>%d) cfg id %d"),
+ length, paramLen, cfgId);)
+ return eSIR_CFG_INVALID_LEN;
+ } else {
+ *pDst++ = (uint8_t) length;
+ pDstEnd = pDst + length;
+ while (pDst < pDstEnd) {
+ *pDst++ = *pStr++;
+ }
+ if (notifyMod) {
+ /* Update hardware if necessary */
+ mask = control & CFG_CTL_NTF_MASK;
+ if ((mask & CFG_CTL_NTF_HW) != 0) {
+ PELOGE(cfg_log(pMac, LOGE, FL(
+ "CFG notify HW not supported!"));)
+ }
+ /* notify other modules if necessary */
+ if ((mask & CFG_CTL_NTF_MASK) != 0) {
+ notify(pMac, cfgId, mask);
+ }
+ }
+ }
+ return eSIR_SUCCESS;
+} /*** end cfg_set_str_notify() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_str()
+ *
+ * FUNCTION:
+ * This function is called to get a string parameter.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Host RW permission should be checked prior to calling this
+ * function.
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param pBuf: address of string buffer
+ * @param pLen: address of max buffer length
+ * actual length will be returned at this address
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ * @return eSIR_CFG_INVALID_LEN: invalid CFG parameter length
+ *
+ */
+
+tSirRetStatus wlan_cfg_get_str(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint8_t *pBuf, uint32_t *pLength)
+{
+ uint8_t *pSrc, *pSrcEnd;
+ uint32_t index;
+ tSirRetStatus status;
+
+ status = cfg_check_valid(pMac, cfgId, &index);
+
+ if (eSIR_SUCCESS != status)
+ return status;
+
+ /* Get string */
+ pSrc = &pMac->cfg.gCfgSBuf[index];
+ pSrc++; /* skip over max length */
+ if (*pLength < *pSrc) {
+ PELOGE(cfg_log(pMac, LOGE, FL(
+ "Invalid length %d (<%d) cfg id %d"),
+ *pLength, *pSrc, cfgId);)
+ return eSIR_CFG_INVALID_LEN;
+ } else {
+ *pLength = *pSrc++; /* save parameter length */
+ pSrcEnd = pSrc + *pLength;
+ while (pSrc < pSrcEnd)
+ *pBuf++ = *pSrc++;
+ }
+ return eSIR_SUCCESS;
+} /*** end wlan_cfg_get_str() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_str_max_len()
+ *
+ * FUNCTION:
+ * This function is called to get a string maximum length.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Host RW permission should be checked prior to calling this
+ * function.
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param pLen: maximum length will be returned at this address
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ *
+ */
+
+tSirRetStatus wlan_cfg_get_str_max_len(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint32_t *pLength)
+{
+ uint32_t index;
+ tSirRetStatus status;
+
+ status = cfg_check_valid(pMac, cfgId, &index);
+
+ if (eSIR_SUCCESS != status)
+ return status;
+
+ *pLength = pMac->cfg.gCfgSBuf[index];
+
+ return status;
+} /*** end wlan_cfg_get_str_max_len() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * wlan_cfg_get_str_len()
+ *
+ * FUNCTION:
+ * This function is called to get a string length.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - Host RW permission should be checked prior to calling this
+ * function.
+ *
+ * NOTE:
+ *
+ * @param cfgId: 16-bit CFG parameter ID
+ * @param pLen: current length will be returned at this address
+ *
+ * @return eSIR_SUCCESS: request completed successfully
+ * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID
+ *
+ */
+
+tSirRetStatus wlan_cfg_get_str_len(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint32_t *pLength)
+{
+ uint32_t index;
+ tSirRetStatus status;
+
+ status = cfg_check_valid(pMac, cfgId, &index);
+
+ if (eSIR_SUCCESS != status)
+ return status;
+
+ *pLength = pMac->cfg.gCfgSBuf[index + 1];
+
+ return status;
+
+} /*** end wlan_cfg_get_str_len() ***/
+
+/*-------------------------------------------------------------
+ \fn cfg_get_dot11d_transmit_power
+ \brief This function returns the regulatory max transmit power
+ \param pMac
+ \return tPowerdBm - Power
+ \-------------------------------------------------------------*/
+static tPowerdBm
+cfg_get_dot11d_transmit_power(tpAniSirGlobal pMac, uint16_t cfgId,
+ uint32_t cfgLength, uint8_t channel)
+{
+ uint8_t *pCountryInfo = NULL;
+ uint8_t count = 0;
+ tPowerdBm maxTxPwr = WMA_MAX_TXPOWER_INVALID;
+
+ /* At least one element is present */
+ if (cfgLength < sizeof(tSirMacChanInfo)) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Invalid CFGLENGTH %d while getting 11d txpower"),
+ cfgLength);
+ )
+ goto error;
+ }
+
+ pCountryInfo = cdf_mem_malloc(cfgLength);
+ if (NULL == pCountryInfo) {
+ cfg_log(pMac, LOGP, FL(" failed to allocate memory"));
+ goto error;
+ }
+ /* The CSR will always update this CFG. The contents will be from country IE if regulatory domain
+ * is enabled on AP else will contain EEPROM contents
+ */
+ if (wlan_cfg_get_str(pMac, cfgId, pCountryInfo, &cfgLength) !=
+ eSIR_SUCCESS) {
+ cdf_mem_free(pCountryInfo);
+ pCountryInfo = NULL;
+
+ cfg_log(pMac, LOGP,
+ FL
+ ("Failed to retrieve 11d configuration parameters while retrieving 11d tuples"));
+ goto error;
+ }
+ /* Identify the channel and maxtxpower */
+ while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) {
+ uint8_t firstChannel, maxChannels;
+
+ firstChannel = pCountryInfo[count++];
+ maxChannels = pCountryInfo[count++];
+ maxTxPwr = pCountryInfo[count++];
+
+ if ((channel >= firstChannel) &&
+ (channel < (firstChannel + maxChannels))) {
+ break;
+ }
+ }
+
+error:
+ if (NULL != pCountryInfo)
+ cdf_mem_free(pCountryInfo);
+
+ return maxTxPwr;
+}
+
+/**----------------------------------------------------------------------
+ \fn cfg_get_regulatory_max_transmit_power
+
+ \brief Gets regulatory tx power on the current channel.
+
+ \param pMac
+ \param channel
+ \param rfBand
+ -----------------------------------------------------------------------*/
+tPowerdBm cfg_get_regulatory_max_transmit_power(tpAniSirGlobal pMac, uint8_t channel)
+{
+ uint32_t cfgLength = 0;
+ uint16_t cfgId = 0;
+ tPowerdBm maxTxPwr;
+ eRfBandMode rfBand = eRF_BAND_UNKNOWN;
+
+ if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
+ (channel <= SIR_11A_CHANNEL_END))
+ rfBand = eRF_BAND_5_GHZ;
+ else
+ rfBand = eRF_BAND_2_4_GHZ;
+
+ /* Get the max transmit power for current channel for the current regulatory domain */
+ switch (rfBand) {
+ case eRF_BAND_2_4_GHZ:
+ cfgId = WNI_CFG_MAX_TX_POWER_2_4;
+ cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN;
+ PELOG2(cfg_log
+ (pMac, LOG2,
+ FL
+ ("HAL: Reading CFG for 2.4 GHz channels to get regulatory max tx power"));
+ )
+ break;
+
+ case eRF_BAND_5_GHZ:
+ cfgId = WNI_CFG_MAX_TX_POWER_5;
+ cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN;
+ PELOG2(cfg_log
+ (pMac, LOG2,
+ FL
+ ("HAL: Reading CFG for 5.0 GHz channels to get regulatory max tx power"));
+ )
+ break;
+
+ case eRF_BAND_UNKNOWN:
+ default:
+ PELOG2(cfg_log
+ (pMac, LOG2,
+ FL("HAL: Invalid current working band for the device"));
+ )
+ return WMA_MAX_TXPOWER_INVALID; /* Its return, not break. */
+ }
+
+ maxTxPwr = cfg_get_dot11d_transmit_power(pMac, cfgId, cfgLength, channel);
+
+ return (maxTxPwr);
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_get_capability_info
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+tSirRetStatus cfg_get_capability_info(tpAniSirGlobal pMac, uint16_t *pCap,
+ tpPESession sessionEntry)
+{
+ uint32_t val = 0;
+ tpSirMacCapabilityInfo pCapInfo;
+
+ *pCap = 0;
+ pCapInfo = (tpSirMacCapabilityInfo) pCap;
+
+ if (LIM_IS_IBSS_ROLE(sessionEntry))
+ pCapInfo->ibss = 1; /* IBSS bit */
+ else if (LIM_IS_AP_ROLE(sessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(sessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(sessionEntry) ||
+ LIM_IS_STA_ROLE(sessionEntry))
+ pCapInfo->ess = 1; /* ESS bit */
+ else if (LIM_IS_P2P_DEVICE_ROLE(sessionEntry)) {
+ pCapInfo->ess = 0;
+ pCapInfo->ibss = 0;
+ } else
+ cfg_log(pMac, LOGP,
+ FL("can't get capability, role is UNKNOWN!!"));
+
+ if (LIM_IS_AP_ROLE(sessionEntry)) {
+ val = sessionEntry->privacy;
+ } else {
+ /* PRIVACY bit */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED, &val) !=
+ eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP,
+ FL("cfg get WNI_CFG_PRIVACY_ENABLED failed"));
+ return eSIR_FAILURE;
+ }
+ }
+ if (val)
+ pCapInfo->privacy = 1;
+
+ /* Short preamble bit */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP, FL("cfg get WNI_CFG_SHORT_PREAMBLE failed"));
+ return eSIR_FAILURE;
+ }
+ if (val)
+ pCapInfo->shortPreamble = 1;
+
+ /* PBCC bit */
+ pCapInfo->pbcc = 0;
+
+ /* Channel agility bit */
+ pCapInfo->channelAgility = 0;
+ /* If STA/AP operating in 11B mode, don't set rest of the capability info bits. */
+ if (sessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B)
+ return eSIR_SUCCESS;
+
+ /* Short slot time bit */
+ if (LIM_IS_AP_ROLE(sessionEntry)) {
+ pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported;
+ } else {
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val)
+ != eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP,
+ FL
+ ("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed"));
+ return eSIR_FAILURE;
+ }
+ /* When in STA mode, we need to check if short slot is enabled as well as check if the current operating
+ * mode is short slot time and then decide whether to enable short slot or not. It is safe to check both
+ * cfg values to determine short slot value in this funcn since this funcn is always used after assoc when
+ * these cfg values are already set based on peer's capability. Even in case of IBSS, its value is set to
+ * correct value either in delBSS as part of deleting the previous IBSS or in start BSS as part of coalescing
+ */
+ if (val) {
+ pCapInfo->shortSlotTime =
+ sessionEntry->shortSlotTimeSupported;
+ }
+ }
+
+ /* Spectrum Management bit */
+ if (!LIM_IS_IBSS_ROLE(sessionEntry) && sessionEntry->lim11hEnable) {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &val) !=
+ eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP,
+ FL("cfg get WNI_CFG_11H_ENABLED failed"));
+ return eSIR_FAILURE;
+ }
+ if (val)
+ pCapInfo->spectrumMgt = 1;
+ }
+ /* QoS bit */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP, FL("cfg get WNI_CFG_QOS_ENABLED failed"));
+ return eSIR_FAILURE;
+ }
+ if (val)
+ pCapInfo->qos = 1;
+
+ /* APSD bit */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_APSD_ENABLED, &val) != eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP, FL("cfg get WNI_CFG_APSD_ENABLED failed"));
+ return eSIR_FAILURE;
+ }
+ if (val)
+ pCapInfo->apsd = 1;
+
+#if defined WLAN_FEATURE_VOWIFI
+ if (LIM_IS_STA_ROLE(sessionEntry)) {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_RRM_ENABLED, &val) !=
+ eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP,
+ FL("cfg get WNI_CFG_RRM_ENABLED failed"));
+ return eSIR_FAILURE;
+ }
+#if defined WLAN_VOWIFI_DEBUG
+ PELOGE(cfg_log(pMac, LOGE, "RRM = %d", val);)
+#endif
+ if (val)
+ pCapInfo->rrm = 1;
+ }
+#endif
+ /* DSSS-OFDM */
+ /* FIXME : no config defined yet. */
+
+ /* Block ack bit */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) !=
+ eSIR_SUCCESS) {
+ cfg_log(pMac, LOGP,
+ FL("cfg get WNI_CFG_BLOCK_ACK_ENABLED failed"));
+ return eSIR_FAILURE;
+ }
+ pCapInfo->delayedBA =
+ (uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
+ pCapInfo->immediateBA =
+ (uint16_t) ((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
+
+ return eSIR_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * cfg_set_capability_info
+ *
+ * FUNCTION:
+ * This function is called on BP based on the capabilities
+ * received in SME_JOIN/REASSOC_REQ message.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE: 1. ESS/IBSS capabilities are based on system role.
+ * 2. Since PBCC, Channel agility and Extended capabilities
+ * are not supported, they're not set at CFG
+ *
+ * @param pMac Pointer to global MAC structure
+ * @param caps 16-bit Capability Info field
+ * @return None
+ */
+
+void cfg_set_capability_info(tpAniSirGlobal pMac, uint16_t caps)
+{
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * cfg_cleanup()
+ *
+ * FUNCTION:
+ * CFG cleanup function.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ * This function must be called during system shutdown.
+ *
+ * @param None
+ *
+ * @return None.
+ *
+ */
+
+void cfg_cleanup(tpAniSirGlobal pMac)
+{
+ /* Set status to not-ready */
+ pMac->cfg.gCfgStatus = CFG_INCOMPLETE;
+
+} /*** end CfgCleanup() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * notify()
+ *
+ * FUNCTION:
+ * This function is called to notify other modules of parameter update.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param cfgId: configuration parameter ID
+ * @param mask: notification mask
+ *
+ * @return None.
+ *
+ */
+
+static void notify(tpAniSirGlobal pMac, uint16_t cfgId, uint32_t ntfMask)
+{
+
+ tSirMsgQ mmhMsg;
+
+ mmhMsg.type = SIR_CFG_PARAM_UPDATE_IND;
+ mmhMsg.bodyval = (uint32_t) cfgId;
+ mmhMsg.bodyptr = NULL;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+
+ if ((ntfMask & CFG_CTL_NTF_SCH) != 0)
+ sch_post_message(pMac, &mmhMsg);
+
+ if ((ntfMask & CFG_CTL_NTF_LIM) != 0)
+ lim_post_msg_api(pMac, &mmhMsg);
+
+ if ((ntfMask & CFG_CTL_NTF_HAL) != 0)
+ wma_post_ctrl_msg(pMac, &mmhMsg);
+
+ /* notify ARQ */
+
+} /*** end notify() ***/
+
+/**
+ * cfg_get_vendor_ie_ptr_from_oui() - returns IE pointer in IE buffer given its
+ * OUI and OUI size
+ * @mac_ctx: mac context.
+ * @oui: OUI string.
+ * @oui_size: length of OUI string
+ * One can provide multiple line descriptions
+ * for arguments.
+ * @ie: ie buffer
+ * @ie_len: length of ie buffer
+ *
+ * This function parses the IE buffer and finds the given OUI and returns its
+ * pointer
+ *
+ * Return: pointer of given OUI IE else NULL
+ */
+uint8_t *cfg_get_vendor_ie_ptr_from_oui(tpAniSirGlobal mac_ctx,
+ uint8_t *oui,
+ uint8_t oui_size,
+ uint8_t *ie,
+ uint16_t ie_len)
+{
+ int32_t left = ie_len;
+ uint8_t *ptr = ie;
+ uint8_t elem_id, elem_len;
+
+ while (left >= 2) {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if (elem_len > left) {
+ cfg_log(mac_ctx, LOGE,
+ FL("Invalid IEs eid = %d elem_len=%d left=%d"),
+ elem_id, elem_len, left);
+ return NULL;
+ }
+ if (SIR_MAC_EID_VENDOR == elem_id) {
+ if (memcmp(&ptr[2], oui, oui_size) == 0)
+ return ptr;
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ return NULL;
+}
+/* --------------------------------------------------------------------- */
diff --git a/core/mac/src/cfg/cfg_debug.c b/core/mac/src/cfg/cfg_debug.c
new file mode 100644
index 0000000..7d09c91
--- /dev/null
+++ b/core/mac/src/cfg/cfg_debug.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file cfg_debug.c
+
+ \brief implementation for log Debug related APIs
+
+ \author Sunit Bhatia
+
+ ========================================================================*/
+
+#include "cfg_debug.h"
+
+void cfg_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...)
+{
+#ifdef WLAN_DEBUG
+ /* Verify against current log level */
+ if (loglevel >
+ pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_CFG_MODULE_ID)])
+ return;
+ else {
+ va_list marker;
+
+ va_start(marker, pString); /* Initialize variable arguments. */
+
+ log_debug(pMac, SIR_CFG_MODULE_ID, loglevel, pString, marker);
+
+ va_end(marker); /* Reset variable arguments. */
+ }
+#endif
+}
diff --git a/core/mac/src/cfg/cfg_debug.h b/core/mac/src/cfg/cfg_debug.h
new file mode 100644
index 0000000..424152e
--- /dev/null
+++ b/core/mac/src/cfg/cfg_debug.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Author: Kevin Nguyen
+ * Date: 04/09/02
+ * History:-
+ * 04/09/02 Created.
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __CFG_DEBUG_H__
+#define __CFG_DEBUG_H__
+
+#include "sir_debug.h"
+#include "utils_api.h"
+#include "lim_trace.h"
+
+#if !defined(__printf)
+#define __printf(a, b)
+#endif
+
+void __printf(3, 4) cfg_log(tpAniSirGlobal pMac, uint32_t loglevel,
+ const char *pString, ...);
+
+#endif
diff --git a/core/mac/src/cfg/cfg_def.h b/core/mac/src/cfg/cfg_def.h
new file mode 100644
index 0000000..6239538
--- /dev/null
+++ b/core/mac/src/cfg/cfg_def.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This is the private header file for CFG module.
+ *
+ * Author: Kevin Nguyen
+ * Date: 03/20/02
+ * History:-
+ * 03/20/02 Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGDEF_H
+#define __CFGDEF_H
+
+/*
+ * CFG Control Flag definitions
+ */
+#define CFG_CTL_VALID 0x00010000
+#define CFG_CTL_RE 0x00020000
+#define CFG_CTL_WE 0x00040000
+#define CFG_CTL_INT 0x00080000
+#define CFG_CTL_SAVE 0x00100000
+#define CFG_CTL_RESTART 0x00200000
+#define CFG_CTL_RELOAD 0x00400000
+#define CFG_CTL_NTF_PHY 0x00800000
+#define CFG_CTL_NTF_MAC 0x01000000
+#define CFG_CTL_NTF_LOG 0x02000000
+#define CFG_CTL_NTF_HAL 0x04000000
+#define CFG_CTL_NTF_DPH 0x08000000
+#define CFG_CTL_NTF_ARQ 0x10000000
+#define CFG_CTL_NTF_SCH 0x20000000
+#define CFG_CTL_NTF_LIM 0x40000000
+#define CFG_CTL_NTF_HDD 0x80000000
+#define CFG_CTL_NTF_MASK 0xFFE00000
+
+#define CFG_CTL_NTF_TFP CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_RHP CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_RFP CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_SP CFG_CTL_NTF_MAC
+#define CFG_CTL_NTF_HW (CFG_CTL_NTF_MAC | CFG_CTL_NTF_PHY)
+
+#define CFG_BUF_INDX_MASK 0x00000fff
+
+#endif /* __CFGDEF_H */
diff --git a/core/mac/src/cfg/cfg_param_name.c b/core/mac/src/cfg/cfg_param_name.c
new file mode 100644
index 0000000..00be55d
--- /dev/null
+++ b/core/mac/src/cfg/cfg_param_name.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DO NOT EDIT - This file is generated automatically
+ */
+
+/*
+ * IMPORTANT: This file is for system that supports STA mode ONLY.
+ */
+#include "cfg_priv.h"
+
+unsigned char *g_cfg_param_name[] = {
+ (unsigned char *)"STA_ID",
+ (unsigned char *)"CF_POLLABLE",
+ (unsigned char *)"CFP_PERIOD",
+ (unsigned char *)"CFP_MAX_DURATION",
+ (unsigned char *)"SSID",
+ (unsigned char *)"BEACON_INTERVAL",
+ (unsigned char *)"DTIM_PERIOD",
+ (unsigned char *)"WEP_KEY_LENGTH",
+ (unsigned char *)"WEP_DEFAULT_KEY_1",
+ (unsigned char *)"WEP_DEFAULT_KEY_2",
+ (unsigned char *)"WEP_DEFAULT_KEY_3",
+ (unsigned char *)"WEP_DEFAULT_KEY_4",
+ (unsigned char *)"WEP_DEFAULT_KEYID",
+ (unsigned char *)"EXCLUDE_UNENCRYPTED",
+ (unsigned char *)"RTS_THRESHOLD",
+ (unsigned char *)"SHORT_RETRY_LIMIT",
+ (unsigned char *)"LONG_RETRY_LIMIT",
+ (unsigned char *)"FRAGMENTATION_THRESHOLD",
+ (unsigned char *)"ACTIVE_MINIMUM_CHANNEL_TIME",
+ (unsigned char *)"ACTIVE_MAXIMUM_CHANNEL_TIME",
+ (unsigned char *)"PASSIVE_MINIMUM_CHANNEL_TIME",
+ (unsigned char *)"PASSIVE_MAXIMUM_CHANNEL_TIME",
+ (unsigned char *)"JOIN_FAILURE_TIMEOUT",
+ (unsigned char *)"AUTHENTICATE_FAILURE_TIMEOUT",
+ (unsigned char *)"AUTHENTICATE_RSP_TIMEOUT",
+ (unsigned char *)"ASSOCIATION_FAILURE_TIMEOUT",
+ (unsigned char *)"REASSOCIATION_FAILURE_TIMEOUT",
+ (unsigned char *)"RA_PERIODICITY_TIMEOUT_IN_PS",
+ (unsigned char *)"PS_ENABLE_BCN_FILTER",
+ (unsigned char *)"PS_ENABLE_HEART_BEAT",
+ (unsigned char *)"PS_ENABLE_RSSI_MONITOR",
+ (unsigned char *)"PS_DATA_INACTIVITY_TIMEOUT",
+ (unsigned char *)"RF_SETTLING_TIME_CLK",
+ (unsigned char *)"SUPPORTED_RATES_11B",
+ (unsigned char *)"SUPPORTED_RATES_11A",
+ (unsigned char *)"PHY_MODE",
+ (unsigned char *)"DOT11_MODE",
+ (unsigned char *)"OPERATIONAL_RATE_SET",
+ (unsigned char *)"EXTENDED_OPERATIONAL_RATE_SET",
+ (unsigned char *)"PROPRIETARY_OPERATIONAL_RATE_SET",
+ (unsigned char *)"LISTEN_INTERVAL",
+ (unsigned char *)"VALID_CHANNEL_LIST",
+ (unsigned char *)"CURRENT_CHANNEL",
+ (unsigned char *)"DEFAULT_RATE_INDEX_5GHZ",
+ (unsigned char *)"DEFAULT_RATE_INDEX_24GHZ",
+ (unsigned char *)"RATE_ADAPTATION_TYPE",
+ (unsigned char *)"FIXED_RATE",
+ (unsigned char *)"FIXED_RATE_MULTICAST_24GHZ",
+ (unsigned char *)"FIXED_RATE_MULTICAST_5GHZ",
+ (unsigned char *)"RETRYRATE_POLICY",
+ (unsigned char *)"RETRYRATE_SECONDARY",
+ (unsigned char *)"RETRYRATE_TERTIARY",
+ (unsigned char *)"APSD_ENABLED",
+ (unsigned char *)"SHARED_KEY_AUTH_ENABLE",
+ (unsigned char *)"OPEN_SYSTEM_AUTH_ENABLE",
+ (unsigned char *)"AUTHENTICATION_TYPE",
+ (unsigned char *)"CF_POLL_REQUEST",
+ (unsigned char *)"PRIVACY_ENABLED",
+ (unsigned char *)"SHORT_PREAMBLE",
+ (unsigned char *)"SHORT_SLOT_TIME",
+ (unsigned char *)"ACCEPT_SHORT_SLOT_ASSOC_ONLY",
+ (unsigned char *)"QOS_ENABLED",
+ (unsigned char *)"HCF_ENABLED",
+ (unsigned char *)"RSN_ENABLED",
+ (unsigned char *)"BACKGROUND_SCAN_PERIOD",
+ (unsigned char *)"MAX_NUM_PRE_AUTH",
+ (unsigned char *)"PREAUTH_CLNUP_TIMEOUT",
+ (unsigned char *)"RELEASE_AID_TIMEOUT",
+ (unsigned char *)"HEART_BEAT_THRESHOLD",
+ (unsigned char *)"PROBE_AFTER_HB_FAIL_TIMEOUT",
+ (unsigned char *)"MANUFACTURER_OUI",
+ (unsigned char *)"MANUFACTURER_NAME",
+ (unsigned char *)"MODEL_NUMBER",
+ (unsigned char *)"MODEL_NAME",
+ (unsigned char *)"MANUFACTURER_PRODUCT_NAME",
+ (unsigned char *)"MANUFACTURER_PRODUCT_VERSION",
+ (unsigned char *)"11D_ENABLED",
+ (unsigned char *)"MAX_TX_POWER_2_4",
+ (unsigned char *)"MAX_TX_POWER_5",
+ (unsigned char *)"NETWORK_DENSITY",
+ (unsigned char *)"ADAPTIVE_THRESHOLD_ALGORITHM",
+ (unsigned char *)"CURRENT_TX_ANTENNA",
+ (unsigned char *)"CURRENT_RX_ANTENNA",
+ (unsigned char *)"CURRENT_TX_POWER_LEVEL",
+ (unsigned char *)"NEW_BSS_FOUND_IND",
+ (unsigned char *)"PROPRIETARY_RATES_ENABLED",
+ (unsigned char *)"AP_NODE_NAME",
+ (unsigned char *)"COUNTRY_CODE",
+ (unsigned char *)"11H_ENABLED",
+ (unsigned char *)"WT_CNF_TIMEOUT",
+ (unsigned char *)"KEEPALIVE_TIMEOUT",
+ (unsigned char *)"PROXIMITY",
+ (unsigned char *)"LOG_LEVEL",
+ (unsigned char *)"OLBC_DETECT_TIMEOUT",
+ (unsigned char *)"PROTECTION_ENABLED",
+ (unsigned char *)"11G_PROTECTION_ALWAYS",
+ (unsigned char *)"FORCE_POLICY_PROTECTION",
+ (unsigned char *)"11G_SHORT_PREAMBLE_ENABLED",
+ (unsigned char *)"11G_SHORT_SLOT_TIME_ENABLED",
+ (unsigned char *)"11G_ONLY_POLICY",
+ (unsigned char *)"PACKET_CLASSIFICATION",
+ (unsigned char *)"WME_ENABLED",
+ (unsigned char *)"ADDTS_RSP_TIMEOUT",
+ (unsigned char *)"MAX_SP_LENGTH",
+ (unsigned char *)"KEEP_ALIVE_STA_LIMIT_THRESHOLD",
+ (unsigned char *)"SEND_SINGLE_SSID_ALWAYS",
+ (unsigned char *)"WSM_ENABLED",
+ (unsigned char *)"EDCA_PROFILE",
+ (unsigned char *)"EDCA_ANI_ACBK_LOCAL",
+ (unsigned char *)"EDCA_ANI_ACBE_LOCAL",
+ (unsigned char *)"EDCA_ANI_ACVI_LOCAL",
+ (unsigned char *)"EDCA_ANI_ACVO_LOCAL",
+ (unsigned char *)"EDCA_ANI_ACBK",
+ (unsigned char *)"EDCA_ANI_ACBE",
+ (unsigned char *)"EDCA_ANI_ACVI",
+ (unsigned char *)"EDCA_ANI_ACVO",
+ (unsigned char *)"EDCA_WME_ACBK_LOCAL",
+ (unsigned char *)"EDCA_WME_ACBE_LOCAL",
+ (unsigned char *)"EDCA_WME_ACVI_LOCAL",
+ (unsigned char *)"EDCA_WME_ACVO_LOCAL",
+ (unsigned char *)"EDCA_WME_ACBK",
+ (unsigned char *)"EDCA_WME_ACBE",
+ (unsigned char *)"EDCA_WME_ACVI",
+ (unsigned char *)"EDCA_WME_ACVO",
+ (unsigned char *)"RDET_FLAG",
+ (unsigned char *)"RADAR_CHANNEL_LIST",
+ (unsigned char *)"LOCAL_POWER_CONSTRAINT",
+ (unsigned char *)"ADMIT_POLICY",
+ (unsigned char *)"ADMIT_BWFACTOR",
+ (unsigned char *)"MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE",
+ (unsigned char *)"CHANNEL_BONDING_MODE",
+ (unsigned char *)"CB_SECONDARY_CHANNEL_STATE",
+ (unsigned char *)"DYNAMIC_THRESHOLD_ZERO",
+ (unsigned char *)"DYNAMIC_THRESHOLD_ONE",
+ (unsigned char *)"DYNAMIC_THRESHOLD_TWO",
+ (unsigned char *)"TRIG_STA_BK_SCAN",
+ (unsigned char *)"DYNAMIC_PROFILE_SWITCHING",
+ (unsigned char *)"SCAN_CONTROL_LIST",
+ (unsigned char *)"MIMO_ENABLED",
+ (unsigned char *)"BLOCK_ACK_ENABLED",
+ (unsigned char *)"HT_RX_STBC",
+ (unsigned char *)"HT_CAP_INFO",
+ (unsigned char *)"HT_AMPDU_PARAMS",
+ (unsigned char *)"SUPPORTED_MCS_SET",
+ (unsigned char *)"EXT_HT_CAP_INFO",
+ (unsigned char *)"TX_BF_CAP",
+ (unsigned char *)"AS_CAP",
+ (unsigned char *)"HT_INFO_FIELD1",
+ (unsigned char *)"HT_INFO_FIELD2",
+ (unsigned char *)"HT_INFO_FIELD3",
+ (unsigned char *)"BASIC_MCS_SET",
+ (unsigned char *)"CURRENT_MCS_SET",
+ (unsigned char *)"GREENFIELD_CAPABILITY",
+ (unsigned char *)"VHT_MAX_MPDU_LENGTH",
+ (unsigned char *)"VHT_SUPPORTED_CHAN_WIDTH_SET",
+ (unsigned char *)"VHT_LDPC_CODING_CAP",
+ (unsigned char *)"VHT_SHORT_GI_80MHZ",
+ (unsigned char *)"VHT_SHORT_GI_160_AND_80_PLUS_80MHZ",
+ (unsigned char *)"VHT_TXSTBC",
+ (unsigned char *)"VHT_RXSTBC",
+ (unsigned char *)"VHT_SU_BEAMFORMER_CAP",
+ (unsigned char *)"VHT_SU_BEAMFORMEE_CAP",
+ (unsigned char *)"VHT_CSN_BEAMFORMEE_ANT_SUPPORTED",
+ (unsigned char *)"VHT_NUM_SOUNDING_DIMENSIONS",
+ (unsigned char *)"VHT_MU_BEAMFORMER_CAP",
+ (unsigned char *)"VHT_MU_BEAMFORMEE_CAP",
+ (unsigned char *)"VHT_TXOP_PS",
+ (unsigned char *)"VHT_HTC_VHTC_CAP",
+ (unsigned char *)"VHT_AMPDU_LEN_EXPONENT",
+ (unsigned char *)"VHT_LINK_ADAPTATION_CAP",
+ (unsigned char *)"VHT_RX_ANT_PATTERN",
+ (unsigned char *)"VHT_TX_ANT_PATTERN",
+ (unsigned char *)"VHT_RX_MCS_MAP",
+ (unsigned char *)"VHT_TX_MCS_MAP",
+ (unsigned char *)"VHT_RX_HIGHEST_SUPPORTED_DATA_RATE",
+ (unsigned char *)"VHT_TX_HIGHEST_SUPPORTED_DATA_RATE",
+ (unsigned char *)"VHT_CHANNEL_CENTER_FREQ_SEGMENT1",
+ (unsigned char *)"VHT_CHANNEL_CENTER_FREQ_SEGMENT2",
+ (unsigned char *)"VHT_BASIC_MCS_SET",
+ (unsigned char *)"VHT_MU_MIMO_CAP_STA_COUNT",
+ (unsigned char *)"VHT_SS_UNDER_UTIL",
+ (unsigned char *)"VHT_40MHZ_UTILIZATION",
+ (unsigned char *)"VHT_80MHZ_UTILIZATION",
+ (unsigned char *)"VHT_160MHZ_UTILIZATION",
+ (unsigned char *)"MAX_AMSDU_LENGTH",
+ (unsigned char *)"MPDU_DENSITY",
+ (unsigned char *)"NUM_BUFF_ADVERT",
+ (unsigned char *)"MAX_RX_AMPDU_FACTOR",
+ (unsigned char *)"SHORT_GI_20MHZ",
+ (unsigned char *)"SHORT_GI_40MHZ",
+ (unsigned char *)"RIFS_ENABLED",
+ (unsigned char *)"MAX_PS_POLL",
+ (unsigned char *)"NUM_BEACON_PER_RSSI_AVERAGE",
+ (unsigned char *)"RSSI_FILTER_PERIOD",
+ (unsigned char *)"MIN_RSSI_THRESHOLD",
+ (unsigned char *)"NTH_BEACON_FILTER",
+ (unsigned char *)"BROADCAST_FRAME_FILTER_ENABLE",
+ (unsigned char *)"SCAN_IN_POWERSAVE",
+ (unsigned char *)"IGNORE_DTIM",
+ (unsigned char *)"WOWLAN_UCAST_PATTERN_FILTER_ENABLE",
+ (unsigned char *)"WOWLAN_CHANNEL_SWITCH_ENABLE",
+ (unsigned char *)"WOWLAN_DEAUTH_ENABLE",
+ (unsigned char *)"WOWLAN_DISASSOC_ENABLE",
+ (unsigned char *)"WOWLAN_MAX_MISSED_BEACON",
+ (unsigned char *)"WOWLAN_MAX_SLEEP_PERIOD",
+ (unsigned char *)"BA_THRESHOLD_HIGH",
+ (unsigned char *)"BG_SCAN_CHANNEL_LIST",
+ (unsigned char *)"MAX_MEDIUM_TIME",
+ (unsigned char *)"MAX_MPDUS_IN_AMPDU",
+ (unsigned char *)"IBSS_AUTO_BSSID",
+ (unsigned char *)"PROBE_REQ_ADDNIE_FLAG",
+ (unsigned char *)"PROBE_REQ_ADDNIE_DATA",
+ (unsigned char *)"PROBE_RSP_ADDNIE_FLAG",
+ (unsigned char *)"PROBE_RSP_ADDNIE_DATA1",
+ (unsigned char *)"PROBE_RSP_ADDNIE_DATA2",
+ (unsigned char *)"PROBE_RSP_ADDNIE_DATA3",
+ (unsigned char *)"ASSOC_RSP_ADDNIE_FLAG",
+ (unsigned char *)"ASSOC_RSP_ADDNIE_DATA",
+ (unsigned char *)"PROBE_REQ_ADDNP2PIE_FLAG",
+ (unsigned char *)"PROBE_REQ_ADDNP2PIE_DATA",
+ (unsigned char *)"PROBE_RSP_BCN_ADDNIE_FLAG",
+ (unsigned char *)"PROBE_RSP_BCN_ADDNIE_DATA",
+ (unsigned char *)"WPS_ENABLE",
+ (unsigned char *)"WPS_STATE",
+ (unsigned char *)"WPS_PROBE_REQ_FLAG",
+ (unsigned char *)"WPS_VERSION",
+ (unsigned char *)"WPS_REQUEST_TYPE",
+ (unsigned char *)"WPS_CFG_METHOD",
+ (unsigned char *)"WPS_UUID",
+ (unsigned char *)"WPS_PRIMARY_DEVICE_CATEGORY",
+ (unsigned char *)"WPS_PIMARY_DEVICE_OUI",
+ (unsigned char *)"WPS_DEVICE_SUB_CATEGORY",
+ (unsigned char *)"WPS_ASSOCIATION_STATE",
+ (unsigned char *)"WPS_CONFIGURATION_ERROR",
+ (unsigned char *)"WPS_DEVICE_PASSWORD_ID",
+ (unsigned char *)"WPS_ASSOC_METHOD",
+ (unsigned char *)"LOW_GAIN_OVERRIDE",
+ (unsigned char *)"ENABLE_PHY_AGC_LISTEN_MODE",
+ (unsigned char *)"RPE_POLLING_THRESHOLD",
+ (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC0_REG",
+ (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC1_REG",
+ (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC2_REG",
+ (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC3_REG",
+ (unsigned char *)"NO_OF_ONCHIP_REORDER_SESSIONS",
+ (unsigned char *)"SINGLE_TID_RC",
+ (unsigned char *)"RRM_ENABLED",
+ (unsigned char *)"RRM_OPERATING_CHAN_MAX",
+ (unsigned char *)"RRM_NON_OPERATING_CHAN_MAX",
+ (unsigned char *)"TX_PWR_CTRL_ENABLE",
+ (unsigned char *)"MCAST_BCAST_FILTER_SETTING",
+ (unsigned char *)"BTC_DHCP_BT_SLOTS_TO_BLOCK",
+ (unsigned char *)"DYNAMIC_PS_POLL_VALUE",
+ (unsigned char *)"PS_NULLDATA_AP_RESP_TIMEOUT",
+ (unsigned char *)"TELE_BCN_WAKEUP_EN",
+ (unsigned char *)"TELE_BCN_TRANS_LI",
+ (unsigned char *)"TELE_BCN_TRANS_LI_IDLE_BCNS",
+ (unsigned char *)"TELE_BCN_MAX_LI",
+ (unsigned char *)"TELE_BCN_MAX_LI_IDLE_BCNS",
+ (unsigned char *)"BTC_A2DP_DHCP_BT_SUB_INTERVALS",
+ (unsigned char *)"INFRA_STA_KEEP_ALIVE_PERIOD",
+ (unsigned char *)"ASSOC_STA_LIMIT",
+ (unsigned char *)"SAP_CHANNEL_SELECT_START_CHANNEL",
+ (unsigned char *)"SAP_CHANNEL_SELECT_END_CHANNEL",
+ (unsigned char *)"SAP_CHANNEL_SELECT_OPERATING_BAND",
+ (unsigned char *)"AP_DATA_AVAIL_POLL_PERIOD",
+ (unsigned char *)"ENABLE_CLOSE_LOOP",
+ (unsigned char *)"ENABLE_LTE_COEX",
+ (unsigned char *)"AP_KEEP_ALIVE_TIMEOUT",
+ (unsigned char *)"GO_KEEP_ALIVE_TIMEOUT",
+ (unsigned char *)"ENABLE_MC_ADDR_LIST",
+ (unsigned char *)"ENABLE_UC_FILTER",
+ (unsigned char *)"ENABLE_LPWR_IMG_TRANSITION",
+ (unsigned char *)"ENABLE_MCC_ADAPTIVE_SCHED",
+ (unsigned char *)"DISABLE_LDPC_WITH_TXBF_AP",
+ (unsigned char *)"AP_LINK_MONITOR_TIMEOUT",
+ (unsigned char *)"TDLS_QOS_WMM_UAPSD_MASK",
+ (unsigned char *)"TDLS_BUF_STA_ENABLED",
+ (unsigned char *)"TDLS_PUAPSD_INACT_TIME",
+ (unsigned char *)"TDLS_RX_FRAME_THRESHOLD",
+ (unsigned char *)"PMF_SA_QUERY_MAX_RETRIES",
+ (unsigned char *)"PMF_SA_QUERY_RETRY_INTERVAL",
+ (unsigned char *)"ENABLE_ADAPT_RX_DRAIN",
+ (unsigned char *)"FLEX_CONNECT_POWER_FACTOR",
+ (unsigned char *)"ANTENNA_DIVESITY",
+ (unsigned char *)"GO_LINK_MONITOR_TIMEOUT",
+ (unsigned char *)"RMC_ACTION_PERIOD_FREQUENCY",
+ (unsigned char *)"CURRENT_RSSI",
+ (unsigned char *)"RTT3_ENABLE",
+ (unsigned char *)"DEBUG_P2P_REMAIN_ON_CHANNEL",
+ (unsigned char *)"TDLS_OFF_CHANNEL_ENABLED",
+ (unsigned char *)"IBSS_ATIM_WIN_SIZE",
+ (unsigned char *)"DFS_MASTER_ENABLED",
+ (unsigned char *)"VHT_ENABLE_TXBF_20MHZ",
+ (unsigned char *)"TDLS_WMM_MODE_ENABLED",
+};
diff --git a/core/mac/src/cfg/cfg_priv.h b/core/mac/src/cfg/cfg_priv.h
new file mode 100644
index 0000000..78769f5
--- /dev/null
+++ b/core/mac/src/cfg/cfg_priv.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This is the private header file for CFG module.
+ *
+ * Author: Kevin Nguyen
+ * Date: 03/20/02
+ * History:-
+ * 03/20/02 Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGPRIV_H
+#define __CFGPRIV_H
+
+#include <sir_common.h>
+#include <sir_types.h>
+#include <sir_debug.h>
+#include <utils_api.h>
+#include <lim_api.h>
+#include <sch_api.h>
+#include <cfg_api.h>
+#include "cfg_def.h"
+
+#include <wni_cfg.h>
+
+/*--------------------------------------------------------------------*/
+/* CFG miscellaneous definition */
+/*--------------------------------------------------------------------*/
+
+/* Function index bit mask */
+#define CFG_FUNC_INDX_MASK 0x7f
+#define CFG_GET_FUNC_INDX(val) (val & CFG_FUNC_INDX_MASK)
+
+/* Macro to convert return code to debug string index */
+#define CFG_GET_DBG_INDX(val) (val - eCFG_SUCCESS - 1)
+
+/*--------------------------------------------------------------------*/
+/* Binary header structure */
+/*--------------------------------------------------------------------*/
+typedef struct sCfgBinHdr {
+ uint32_t hdrInfo;
+ uint32_t controlSize;
+ uint32_t iBufSize;
+ uint32_t sBufSize;
+} tCfgBinHdr, *tpCfgBinHdr;
+
+/*--------------------------------------------------------------------*/
+/* Polaris HW counter access structure */
+/*--------------------------------------------------------------------*/
+
+#define CFG_STAT_CNT_LO_MASK 0x0000ffff
+#define CFG_STAT_CNT_HI_MASK 0xffff0000
+#define CFG_STAT_CNT_HI_INCR 0x00010000
+
+/*--------------------------------------------------------------------*/
+/* CFG function prototypes */
+/*--------------------------------------------------------------------*/
+
+extern void cfg_send_host_msg(tpAniSirGlobal, uint16_t, uint32_t, uint32_t,
+ uint32_t *, uint32_t, uint32_t *);
+
+#endif /* __CFGPRIV_H */
diff --git a/core/mac/src/cfg/cfg_proc_msg.c b/core/mac/src/cfg/cfg_proc_msg.c
new file mode 100644
index 0000000..0a477d0
--- /dev/null
+++ b/core/mac/src/cfg/cfg_proc_msg.c
@@ -0,0 +1,2607 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file contains CFG functions for processing host messages.
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+#include "cfg_priv.h"
+#include "cfg_debug.h"
+#include "wma_types.h"
+
+cgstatic cfg_static[CFG_PARAM_MAX_NUM] = {
+ {WNI_CFG_STA_ID,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RELOAD |
+ CFG_CTL_NTF_HAL,
+ 0, 255, 1},
+ {WNI_CFG_CF_POLLABLE,
+ CFG_CTL_RE | CFG_CTL_INT | CFG_CTL_RESTART,
+ 0, 255, 1},
+ {WNI_CFG_CFP_PERIOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT,
+ WNI_CFG_CFP_PERIOD_STAMIN,
+ WNI_CFG_CFP_PERIOD_STAMAX,
+ WNI_CFG_CFP_PERIOD_STADEF},
+ {WNI_CFG_CFP_MAX_DURATION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT,
+ WNI_CFG_CFP_MAX_DURATION_STAMIN,
+ WNI_CFG_CFP_MAX_DURATION_STAMAX,
+ WNI_CFG_CFP_MAX_DURATION_STADEF},
+ {WNI_CFG_SSID,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 255, 6},
+ {WNI_CFG_BEACON_INTERVAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_SCH,
+ WNI_CFG_BEACON_INTERVAL_STAMIN,
+ WNI_CFG_BEACON_INTERVAL_STAMAX,
+ WNI_CFG_BEACON_INTERVAL_STADEF},
+ {WNI_CFG_DTIM_PERIOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT,
+ WNI_CFG_DTIM_PERIOD_STAMIN,
+ WNI_CFG_DTIM_PERIOD_STAMAX,
+ WNI_CFG_DTIM_PERIOD_STADEF},
+ {WNI_CFG_WEP_KEY_LENGTH,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_WEP_KEY_LENGTH_STAMIN,
+ WNI_CFG_WEP_KEY_LENGTH_STAMAX,
+ WNI_CFG_WEP_KEY_LENGTH_STADEF},
+ {WNI_CFG_WEP_DEFAULT_KEY_1,
+ CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 65535, 0},
+ {WNI_CFG_WEP_DEFAULT_KEY_2,
+ CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART,
+ 1, 1, 1},
+ {WNI_CFG_WEP_DEFAULT_KEY_3,
+ CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 5, 5},
+ {WNI_CFG_WEP_DEFAULT_KEY_4,
+ CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 1, 0},
+ {WNI_CFG_WEP_DEFAULT_KEYID,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WEP_DEFAULT_KEYID_STAMIN,
+ WNI_CFG_WEP_DEFAULT_KEYID_STAMAX,
+ WNI_CFG_WEP_DEFAULT_KEYID_STADEF},
+ {WNI_CFG_EXCLUDE_UNENCRYPTED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_EXCLUDE_UNENCRYPTED_STAMIN,
+ WNI_CFG_EXCLUDE_UNENCRYPTED_STAMAX,
+ WNI_CFG_EXCLUDE_UNENCRYPTED_STADEF},
+ {WNI_CFG_RTS_THRESHOLD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RTS_THRESHOLD_STAMIN,
+ WNI_CFG_RTS_THRESHOLD_STAMAX,
+ WNI_CFG_RTS_THRESHOLD_STADEF},
+ {WNI_CFG_SHORT_RETRY_LIMIT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_SHORT_RETRY_LIMIT_STAMIN,
+ WNI_CFG_SHORT_RETRY_LIMIT_STAMAX,
+ WNI_CFG_SHORT_RETRY_LIMIT_STADEF},
+ {WNI_CFG_LONG_RETRY_LIMIT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_LONG_RETRY_LIMIT_STAMIN,
+ WNI_CFG_LONG_RETRY_LIMIT_STAMAX,
+ WNI_CFG_LONG_RETRY_LIMIT_STADEF},
+ {WNI_CFG_FRAGMENTATION_THRESHOLD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN,
+ WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX,
+ WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF},
+ {WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMIN,
+ WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMAX,
+ WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STADEF},
+ {WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN,
+ WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX,
+ WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF},
+ {WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMIN,
+ WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMAX,
+ WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STADEF},
+ {WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN,
+ WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX,
+ WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF},
+ {WNI_CFG_JOIN_FAILURE_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMIN,
+ WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMAX,
+ WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF},
+ {WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMIN,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMAX,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STADEF},
+ {WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMIN,
+ WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMAX,
+ WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STADEF},
+ {WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMIN,
+ WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMAX,
+ WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STADEF},
+ {WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN,
+ WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX,
+ WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF},
+ {WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMIN,
+ WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMAX,
+ WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STADEF},
+ {WNI_CFG_PS_ENABLE_BCN_FILTER,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PS_ENABLE_BCN_FILTER_STAMIN,
+ WNI_CFG_PS_ENABLE_BCN_FILTER_STAMAX,
+ WNI_CFG_PS_ENABLE_BCN_FILTER_STADEF},
+ {WNI_CFG_PS_ENABLE_HEART_BEAT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PS_ENABLE_HEART_BEAT_STAMIN,
+ WNI_CFG_PS_ENABLE_HEART_BEAT_STAMAX,
+ WNI_CFG_PS_ENABLE_HEART_BEAT_STADEF},
+ {WNI_CFG_PS_ENABLE_RSSI_MONITOR,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN,
+ WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX,
+ WNI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF},
+ {WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN,
+ WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX,
+ WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF},
+ {WNI_CFG_RF_SETTLING_TIME_CLK,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RF_SETTLING_TIME_CLK_STAMIN,
+ WNI_CFG_RF_SETTLING_TIME_CLK_STAMAX,
+ WNI_CFG_RF_SETTLING_TIME_CLK_STADEF},
+ {WNI_CFG_SUPPORTED_RATES_11B,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 3, 1},
+ {WNI_CFG_SUPPORTED_RATES_11A, CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 255, 15},
+ {WNI_CFG_PHY_MODE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_PHY_MODE_STAMIN,
+ WNI_CFG_PHY_MODE_STAMAX,
+ WNI_CFG_PHY_MODE_STADEF},
+ {WNI_CFG_DOT11_MODE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_DOT11_MODE_STAMIN,
+ WNI_CFG_DOT11_MODE_STAMAX,
+ WNI_CFG_DOT11_MODE_STADEF},
+ {WNI_CFG_OPERATIONAL_RATE_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 1, 1},
+ {WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 65535, 65534},
+ {WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_LISTEN_INTERVAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_LISTEN_INTERVAL_STAMIN,
+ WNI_CFG_LISTEN_INTERVAL_STAMAX,
+ WNI_CFG_LISTEN_INTERVAL_STADEF},
+ {WNI_CFG_VALID_CHANNEL_LIST,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART |
+ CFG_CTL_NTF_LIM,
+ 0, 1, 1},
+ {WNI_CFG_CURRENT_CHANNEL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT,
+ WNI_CFG_CURRENT_CHANNEL_STAMIN,
+ WNI_CFG_CURRENT_CHANNEL_STAMAX,
+ WNI_CFG_CURRENT_CHANNEL_STADEF},
+ {WNI_CFG_DEFAULT_RATE_INDEX_5GHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN,
+ WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX,
+ WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF},
+ {WNI_CFG_DEFAULT_RATE_INDEX_24GHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN,
+ WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX,
+ WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF},
+ {WNI_CFG_RATE_ADAPTATION_TYPE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_SCH,
+ WNI_CFG_RATE_ADAPTATION_TYPE_STAMIN,
+ WNI_CFG_RATE_ADAPTATION_TYPE_STAMAX,
+ WNI_CFG_RATE_ADAPTATION_TYPE_STADEF},
+ {WNI_CFG_FIXED_RATE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_FIXED_RATE_STAMIN,
+ WNI_CFG_FIXED_RATE_STAMAX,
+ WNI_CFG_FIXED_RATE_STADEF},
+ {WNI_CFG_FIXED_RATE_MULTICAST_24GHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN,
+ WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX,
+ WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF},
+ {WNI_CFG_FIXED_RATE_MULTICAST_5GHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN,
+ WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX,
+ WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF},
+ {WNI_CFG_RETRYRATE_POLICY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RETRYRATE_POLICY_STAMIN,
+ WNI_CFG_RETRYRATE_POLICY_STAMAX,
+ WNI_CFG_RETRYRATE_POLICY_STADEF},
+ {WNI_CFG_RETRYRATE_SECONDARY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RETRYRATE_SECONDARY_STAMIN,
+ WNI_CFG_RETRYRATE_SECONDARY_STAMAX,
+ WNI_CFG_RETRYRATE_SECONDARY_STADEF},
+ {WNI_CFG_RETRYRATE_TERTIARY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RETRYRATE_TERTIARY_STAMIN,
+ WNI_CFG_RETRYRATE_TERTIARY_STAMAX,
+ WNI_CFG_RETRYRATE_TERTIARY_STADEF},
+ {WNI_CFG_APSD_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_APSD_ENABLED_STAMIN,
+ WNI_CFG_APSD_ENABLED_STAMAX,
+ WNI_CFG_APSD_ENABLED_STADEF},
+ {WNI_CFG_SHARED_KEY_AUTH_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMIN,
+ WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMAX,
+ WNI_CFG_SHARED_KEY_AUTH_ENABLE_STADEF},
+ {WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMIN,
+ WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMAX,
+ WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STADEF},
+ {WNI_CFG_AUTHENTICATION_TYPE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_AUTHENTICATION_TYPE_STAMIN,
+ WNI_CFG_AUTHENTICATION_TYPE_STAMAX,
+ WNI_CFG_AUTHENTICATION_TYPE_STADEF},
+ {WNI_CFG_CF_POLL_REQUEST,
+ CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART,
+ 0, 255, 1},
+ {WNI_CFG_PRIVACY_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_PRIVACY_ENABLED_STAMIN,
+ WNI_CFG_PRIVACY_ENABLED_STAMAX,
+ WNI_CFG_PRIVACY_ENABLED_STADEF},
+ {WNI_CFG_SHORT_PREAMBLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_SHORT_PREAMBLE_STAMIN,
+ WNI_CFG_SHORT_PREAMBLE_STAMAX,
+ WNI_CFG_SHORT_PREAMBLE_STADEF},
+ {WNI_CFG_SHORT_SLOT_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SHORT_SLOT_TIME_STAMIN,
+ WNI_CFG_SHORT_SLOT_TIME_STAMAX,
+ WNI_CFG_SHORT_SLOT_TIME_STADEF},
+ {WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMIN,
+ WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMAX,
+ WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STADEF},
+ {WNI_CFG_QOS_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_QOS_ENABLED_STAMIN,
+ WNI_CFG_QOS_ENABLED_STAMAX,
+ WNI_CFG_QOS_ENABLED_STADEF},
+ {WNI_CFG_HCF_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_HCF_ENABLED_STAMIN,
+ WNI_CFG_HCF_ENABLED_STAMAX,
+ WNI_CFG_HCF_ENABLED_STADEF},
+ {WNI_CFG_RSN_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_RSN_ENABLED_STAMIN,
+ WNI_CFG_RSN_ENABLED_STAMAX,
+ WNI_CFG_RSN_ENABLED_STADEF},
+ {WNI_CFG_MAX_NUM_PRE_AUTH,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_MAX_NUM_PRE_AUTH_STAMIN,
+ WNI_CFG_MAX_NUM_PRE_AUTH_STAMAX,
+ WNI_CFG_MAX_NUM_PRE_AUTH_STADEF},
+ {WNI_CFG_PREAUTH_CLNUP_TIMEOUT,
+ CFG_CTL_INT,
+ 0, 255, 1},
+ {WNI_CFG_RELEASE_AID_TIMEOUT,
+ CFG_CTL_INT,
+ 0, 255, 1},
+ {WNI_CFG_HEART_BEAT_THRESHOLD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN,
+ WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX,
+ WNI_CFG_HEART_BEAT_THRESHOLD_STADEF},
+ {WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE |
+ CFG_CTL_INT,
+ WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMIN,
+ WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMAX,
+ WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STADEF},
+ {WNI_CFG_MANUFACTURER_OUI,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 0, 0},
+ {WNI_CFG_MANUFACTURER_NAME,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 0, 0},
+ {WNI_CFG_MODEL_NUMBER,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 0, 0},
+ {WNI_CFG_MODEL_NAME,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 0, 0},
+ {WNI_CFG_MANUFACTURER_PRODUCT_NAME,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 0, 0},
+ {WNI_CFG_MANUFACTURER_PRODUCT_VERSION,
+ CFG_CTL_VALID | CFG_CTL_RE,
+ 0, 0, 0},
+ {WNI_CFG_11D_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_11D_ENABLED_STAMIN,
+ WNI_CFG_11D_ENABLED_STAMAX,
+ WNI_CFG_11D_ENABLED_STADEF},
+ {WNI_CFG_MAX_TX_POWER_2_4,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_MAX_TX_POWER_5,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_NETWORK_DENSITY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_NETWORK_DENSITY_STAMIN,
+ WNI_CFG_NETWORK_DENSITY_STAMAX,
+ WNI_CFG_NETWORK_DENSITY_STADEF},
+ {WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMIN,
+ WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMAX,
+ WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STADEF},
+ {WNI_CFG_CURRENT_TX_ANTENNA,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_CURRENT_TX_ANTENNA_STAMIN,
+ WNI_CFG_CURRENT_TX_ANTENNA_STAMAX,
+ WNI_CFG_CURRENT_TX_ANTENNA_STADEF},
+ {WNI_CFG_CURRENT_RX_ANTENNA,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_CURRENT_RX_ANTENNA_STAMIN,
+ WNI_CFG_CURRENT_RX_ANTENNA_STAMAX,
+ WNI_CFG_CURRENT_RX_ANTENNA_STADEF},
+ {WNI_CFG_CURRENT_TX_POWER_LEVEL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN,
+ WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX,
+ WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF},
+ {WNI_CFG_NEW_BSS_FOUND_IND,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_NEW_BSS_FOUND_IND_STAMIN,
+ WNI_CFG_NEW_BSS_FOUND_IND_STAMAX,
+ WNI_CFG_NEW_BSS_FOUND_IND_STADEF},
+ {WNI_CFG_PROPRIETARY_RATES_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMIN,
+ WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMAX,
+ WNI_CFG_PROPRIETARY_RATES_ENABLED_STADEF},
+ {WNI_CFG_AP_NODE_NAME,
+ CFG_CTL_RE,
+ 0, 255, 1},
+ {WNI_CFG_COUNTRY_CODE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_11H_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_11H_ENABLED_STAMIN,
+ WNI_CFG_11H_ENABLED_STAMAX,
+ WNI_CFG_11H_ENABLED_STADEF},
+ {WNI_CFG_WT_CNF_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WT_CNF_TIMEOUT_STAMIN,
+ WNI_CFG_WT_CNF_TIMEOUT_STAMAX,
+ WNI_CFG_WT_CNF_TIMEOUT_STADEF},
+ {WNI_CFG_PROXIMITY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PROXIMITY_STAMIN,
+ WNI_CFG_PROXIMITY_STAMAX,
+ WNI_CFG_PROXIMITY_STADEF},
+ {WNI_CFG_LOG_LEVEL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_LOG_LEVEL_STAMIN,
+ WNI_CFG_LOG_LEVEL_STAMAX,
+ WNI_CFG_LOG_LEVEL_STADEF},
+ {WNI_CFG_OLBC_DETECT_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_OLBC_DETECT_TIMEOUT_STAMIN,
+ WNI_CFG_OLBC_DETECT_TIMEOUT_STAMAX,
+ WNI_CFG_OLBC_DETECT_TIMEOUT_STADEF},
+ {WNI_CFG_PROTECTION_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_PROTECTION_ENABLED_STAMIN,
+ WNI_CFG_PROTECTION_ENABLED_STAMAX,
+ WNI_CFG_PROTECTION_ENABLED_STADEF},
+ {WNI_CFG_11G_PROTECTION_ALWAYS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_11G_PROTECTION_ALWAYS_STAMIN,
+ WNI_CFG_11G_PROTECTION_ALWAYS_STAMAX,
+ WNI_CFG_11G_PROTECTION_ALWAYS_STADEF},
+ {WNI_CFG_FORCE_POLICY_PROTECTION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_HAL,
+ WNI_CFG_FORCE_POLICY_PROTECTION_STAMIN,
+ WNI_CFG_FORCE_POLICY_PROTECTION_STAMAX,
+ WNI_CFG_FORCE_POLICY_PROTECTION_STADEF},
+ {WNI_CFG_11G_SHORT_PREAMBLE_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMIN,
+ WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMAX,
+ WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STADEF},
+ {WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMIN,
+ WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMAX,
+ WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STADEF},
+ {WNI_CFG_11G_ONLY_POLICY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_11G_ONLY_POLICY_STAMIN,
+ WNI_CFG_11G_ONLY_POLICY_STAMAX,
+ WNI_CFG_11G_ONLY_POLICY_STADEF},
+ {WNI_CFG_PACKET_CLASSIFICATION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PACKET_CLASSIFICATION_STAMIN,
+ WNI_CFG_PACKET_CLASSIFICATION_STAMAX,
+ WNI_CFG_PACKET_CLASSIFICATION_STADEF},
+ {WNI_CFG_WME_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_WME_ENABLED_STAMIN,
+ WNI_CFG_WME_ENABLED_STAMAX,
+ WNI_CFG_WME_ENABLED_STADEF},
+ {WNI_CFG_ADDTS_RSP_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ADDTS_RSP_TIMEOUT_STAMIN,
+ WNI_CFG_ADDTS_RSP_TIMEOUT_STAMAX,
+ WNI_CFG_ADDTS_RSP_TIMEOUT_STADEF},
+ {WNI_CFG_MAX_SP_LENGTH,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_MAX_SP_LENGTH_STAMIN,
+ WNI_CFG_MAX_SP_LENGTH_STAMAX,
+ WNI_CFG_MAX_SP_LENGTH_STADEF},
+ {WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD,
+ CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ 0, 255, 1},
+ {WNI_CFG_SEND_SINGLE_SSID_ALWAYS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMIN,
+ WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMAX,
+ WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STADEF},
+ {WNI_CFG_WSM_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WSM_ENABLED_STAMIN,
+ WNI_CFG_WSM_ENABLED_STAMAX,
+ WNI_CFG_WSM_ENABLED_STADEF},
+ {WNI_CFG_EDCA_PROFILE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_SCH,
+ WNI_CFG_EDCA_PROFILE_STAMIN,
+ WNI_CFG_EDCA_PROFILE_STAMAX,
+ WNI_CFG_EDCA_PROFILE_STADEF},
+ {WNI_CFG_EDCA_ANI_ACBK_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACBE_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACVI_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACVO_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACBK,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACBE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACVI,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_ANI_ACVO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACBK_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACBE_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACVI_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACVO_LOCAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACBK,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACBE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACVI,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_EDCA_WME_ACVO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_RDET_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_RDET_FLAG_STAMIN,
+ WNI_CFG_RDET_FLAG_STAMAX,
+ WNI_CFG_RDET_FLAG_STADEF},
+ {WNI_CFG_RADAR_CHANNEL_LIST,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART,
+ 0, 0, 0},
+ {WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN,
+ WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX,
+ WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF},
+ {WNI_CFG_ADMIT_POLICY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_ADMIT_POLICY_STAMIN,
+ WNI_CFG_ADMIT_POLICY_STAMAX,
+ WNI_CFG_ADMIT_POLICY_STADEF},
+ {WNI_CFG_ADMIT_BWFACTOR,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_ADMIT_BWFACTOR_STAMIN,
+ WNI_CFG_ADMIT_BWFACTOR_STAMAX,
+ WNI_CFG_ADMIT_BWFACTOR_STADEF},
+ {WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMIN,
+ WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMAX,
+ WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STADEF},
+ {WNI_CFG_CHANNEL_BONDING_MODE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_CHANNEL_BONDING_MODE_STAMIN,
+ WNI_CFG_CHANNEL_BONDING_MODE_STAMAX,
+ WNI_CFG_CHANNEL_BONDING_MODE_STADEF},
+ {WNI_CFG_CB_SECONDARY_CHANNEL_STATE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMIN,
+ WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMAX,
+ WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STADEF},
+ {WNI_CFG_DYNAMIC_THRESHOLD_ZERO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN,
+ WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX,
+ WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF},
+ {WNI_CFG_DYNAMIC_THRESHOLD_ONE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN,
+ WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX,
+ WNI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF},
+ {WNI_CFG_DYNAMIC_THRESHOLD_TWO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN,
+ WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX,
+ WNI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF},
+ {WNI_CFG_TRIG_STA_BK_SCAN,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TRIG_STA_BK_SCAN_STAMIN,
+ WNI_CFG_TRIG_STA_BK_SCAN_STAMAX,
+ WNI_CFG_TRIG_STA_BK_SCAN_STADEF},
+ {WNI_CFG_DYNAMIC_PROFILE_SWITCHING,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMIN,
+ WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMAX,
+ WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STADEF},
+ {WNI_CFG_SCAN_CONTROL_LIST,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART |
+ CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_MIMO_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RELOAD,
+ WNI_CFG_MIMO_ENABLED_STAMIN,
+ WNI_CFG_MIMO_ENABLED_STAMAX,
+ WNI_CFG_MIMO_ENABLED_STADEF},
+ {WNI_CFG_BLOCK_ACK_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_BLOCK_ACK_ENABLED_STAMIN,
+ WNI_CFG_BLOCK_ACK_ENABLED_STAMAX,
+ WNI_CFG_BLOCK_ACK_ENABLED_STADEF},
+ {WNI_CFG_HT_RX_STBC,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_HT_RX_STBC_STAMIN,
+ WNI_CFG_HT_RX_STBC_STAMAX,
+ WNI_CFG_HT_RX_STBC_STADEF},
+ {WNI_CFG_HT_CAP_INFO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_HT_CAP_INFO_STAMIN,
+ WNI_CFG_HT_CAP_INFO_STAMAX,
+ WNI_CFG_HT_CAP_INFO_STADEF},
+ {WNI_CFG_HT_AMPDU_PARAMS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_HT_AMPDU_PARAMS_STAMIN,
+ WNI_CFG_HT_AMPDU_PARAMS_STAMAX,
+ WNI_CFG_HT_AMPDU_PARAMS_STADEF},
+ {WNI_CFG_SUPPORTED_MCS_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_SAVE |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_EXT_HT_CAP_INFO,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_EXT_HT_CAP_INFO_STAMIN,
+ WNI_CFG_EXT_HT_CAP_INFO_STAMAX,
+ WNI_CFG_EXT_HT_CAP_INFO_STADEF},
+ {WNI_CFG_TX_BF_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT | CFG_CTL_RESTART |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TX_BF_CAP_STAMIN,
+ 4294967295u,
+ WNI_CFG_TX_BF_CAP_STADEF},
+ {WNI_CFG_AS_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_AS_CAP_STAMIN,
+ WNI_CFG_AS_CAP_STAMAX,
+ WNI_CFG_AS_CAP_STADEF},
+ {WNI_CFG_HT_INFO_FIELD1,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_HT_INFO_FIELD1_STAMIN,
+ WNI_CFG_HT_INFO_FIELD1_STAMAX,
+ WNI_CFG_HT_INFO_FIELD1_STADEF},
+ {WNI_CFG_HT_INFO_FIELD2,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_HT_INFO_FIELD2_STAMIN,
+ WNI_CFG_HT_INFO_FIELD2_STAMAX,
+ WNI_CFG_HT_INFO_FIELD2_STADEF},
+ {WNI_CFG_HT_INFO_FIELD3,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_HT_INFO_FIELD3_STAMIN,
+ WNI_CFG_HT_INFO_FIELD3_STAMAX,
+ WNI_CFG_HT_INFO_FIELD3_STADEF},
+ {WNI_CFG_BASIC_MCS_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_SAVE |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_CURRENT_MCS_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_SAVE |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_GREENFIELD_CAPABILITY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_GREENFIELD_CAPABILITY_STAMIN,
+ WNI_CFG_GREENFIELD_CAPABILITY_STAMAX,
+ WNI_CFG_GREENFIELD_CAPABILITY_STADEF},
+ {WNI_CFG_VHT_MAX_MPDU_LENGTH,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMIN,
+ WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMAX,
+ WNI_CFG_VHT_MAX_MPDU_LENGTH_STADEF},
+ {WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMIN,
+ WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMAX,
+ WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STADEF},
+ {WNI_CFG_VHT_LDPC_CODING_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_LDPC_CODING_CAP_STAMIN,
+ WNI_CFG_VHT_LDPC_CODING_CAP_STAMAX,
+ WNI_CFG_VHT_LDPC_CODING_CAP_STADEF},
+ {WNI_CFG_VHT_SHORT_GI_80MHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_SHORT_GI_80MHZ_STAMIN,
+ WNI_CFG_VHT_SHORT_GI_80MHZ_STAMAX,
+ WNI_CFG_VHT_SHORT_GI_80MHZ_STADEF},
+ {WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMIN,
+ WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMAX,
+ WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STADEF},
+ {WNI_CFG_VHT_TXSTBC,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_TXSTBC_STAMIN,
+ WNI_CFG_VHT_TXSTBC_STAMAX,
+ WNI_CFG_VHT_TXSTBC_STADEF},
+ {WNI_CFG_VHT_RXSTBC,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_RXSTBC_STAMIN,
+ WNI_CFG_VHT_RXSTBC_STAMAX,
+ WNI_CFG_VHT_RXSTBC_STADEF},
+ {WNI_CFG_VHT_SU_BEAMFORMER_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMIN,
+ WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMAX,
+ WNI_CFG_VHT_SU_BEAMFORMER_CAP_STADEF},
+ {WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN,
+ WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX,
+ WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF},
+ {WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN,
+ WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX,
+ WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STADEF},
+ {WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMIN,
+ WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMAX,
+ WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STADEF},
+ {WNI_CFG_VHT_MU_BEAMFORMER_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMIN,
+ WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMAX,
+ WNI_CFG_VHT_MU_BEAMFORMER_CAP_STADEF},
+ {WNI_CFG_VHT_MU_BEAMFORMEE_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMIN,
+ WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMAX,
+ WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STADEF},
+ {WNI_CFG_VHT_TXOP_PS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_TXOP_PS_STAMIN,
+ WNI_CFG_VHT_TXOP_PS_STAMAX,
+ WNI_CFG_VHT_TXOP_PS_STADEF},
+ {WNI_CFG_VHT_HTC_VHTC_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_HTC_VHTC_CAP_STAMIN,
+ WNI_CFG_VHT_HTC_VHTC_CAP_STAMAX,
+ WNI_CFG_VHT_HTC_VHTC_CAP_STADEF},
+ {WNI_CFG_VHT_AMPDU_LEN_EXPONENT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMIN,
+ WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMAX,
+ WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STADEF},
+ {WNI_CFG_VHT_LINK_ADAPTATION_CAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMIN,
+ WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMAX,
+ WNI_CFG_VHT_LINK_ADAPTATION_CAP_STADEF},
+ {WNI_CFG_VHT_RX_ANT_PATTERN,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_RX_ANT_PATTERN_STAMIN,
+ WNI_CFG_VHT_RX_ANT_PATTERN_STAMAX,
+ WNI_CFG_VHT_RX_ANT_PATTERN_STADEF},
+ {WNI_CFG_VHT_TX_ANT_PATTERN,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_TX_ANT_PATTERN_STAMIN,
+ WNI_CFG_VHT_TX_ANT_PATTERN_STAMAX,
+ WNI_CFG_VHT_TX_ANT_PATTERN_STADEF},
+ {WNI_CFG_VHT_RX_MCS_MAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_RX_MCS_MAP_STAMIN,
+ WNI_CFG_VHT_RX_MCS_MAP_STAMAX,
+ WNI_CFG_VHT_RX_MCS_MAP_STADEF},
+ {WNI_CFG_VHT_TX_MCS_MAP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_TX_MCS_MAP_STAMIN,
+ WNI_CFG_VHT_TX_MCS_MAP_STAMAX,
+ WNI_CFG_VHT_TX_MCS_MAP_STADEF},
+ {WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN,
+ WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX,
+ WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STADEF},
+ {WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN,
+ WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX,
+ WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STADEF},
+ {WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMIN,
+ WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMAX,
+ WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STADEF},
+ {WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMIN,
+ WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMAX,
+ WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STADEF},
+ {WNI_CFG_VHT_BASIC_MCS_SET,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_BASIC_MCS_SET_STAMIN,
+ WNI_CFG_VHT_BASIC_MCS_SET_STAMAX,
+ WNI_CFG_VHT_BASIC_MCS_SET_STADEF},
+ {WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMIN,
+ WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMAX,
+ WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STADEF},
+ {WNI_CFG_VHT_SS_UNDER_UTIL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_SS_UNDER_UTIL_STAMIN,
+ WNI_CFG_VHT_SS_UNDER_UTIL_STAMAX,
+ WNI_CFG_VHT_SS_UNDER_UTIL_STADEF},
+ {WNI_CFG_VHT_40MHZ_UTILIZATION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_40MHZ_UTILIZATION_STAMIN,
+ WNI_CFG_VHT_40MHZ_UTILIZATION_STAMAX,
+ WNI_CFG_VHT_40MHZ_UTILIZATION_STADEF},
+ {WNI_CFG_VHT_80MHZ_UTILIZATION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_80MHZ_UTILIZATION_STAMIN,
+ WNI_CFG_VHT_80MHZ_UTILIZATION_STAMAX,
+ WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF},
+ {WNI_CFG_VHT_160MHZ_UTILIZATION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF,
+ WNI_CFG_VHT_160MHZ_UTILIZATION_STAMAX,
+ WNI_CFG_VHT_160MHZ_UTILIZATION_STADEF},
+ {WNI_CFG_MAX_AMSDU_LENGTH,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_MAX_AMSDU_LENGTH_STAMIN,
+ WNI_CFG_MAX_AMSDU_LENGTH_STAMAX,
+ WNI_CFG_MAX_AMSDU_LENGTH_STADEF},
+ {WNI_CFG_MPDU_DENSITY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_MPDU_DENSITY_STAMIN,
+ WNI_CFG_MPDU_DENSITY_STAMAX,
+ WNI_CFG_MPDU_DENSITY_STADEF},
+ {WNI_CFG_MAX_RX_AMPDU_FACTOR,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN,
+ WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX,
+ WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX},
+ {WNI_CFG_SHORT_GI_20MHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_SHORT_GI_20MHZ_STAMIN,
+ WNI_CFG_SHORT_GI_20MHZ_STAMAX,
+ WNI_CFG_SHORT_GI_20MHZ_STADEF},
+ {WNI_CFG_SHORT_GI_40MHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART | CFG_CTL_NTF_LIM,
+ WNI_CFG_SHORT_GI_40MHZ_STAMIN,
+ WNI_CFG_SHORT_GI_40MHZ_STAMAX,
+ WNI_CFG_SHORT_GI_40MHZ_STADEF},
+ {WNI_CFG_RIFS_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_RIFS_ENABLED_STAMIN,
+ WNI_CFG_RIFS_ENABLED_STAMAX,
+ WNI_CFG_RIFS_ENABLED_STADEF},
+ {WNI_CFG_MAX_PS_POLL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_MAX_PS_POLL_STAMIN,
+ WNI_CFG_MAX_PS_POLL_STAMAX,
+ WNI_CFG_MAX_PS_POLL_STADEF},
+ {WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN,
+ WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX,
+ WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF},
+ {WNI_CFG_RSSI_FILTER_PERIOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_RSSI_FILTER_PERIOD_STAMIN,
+ WNI_CFG_RSSI_FILTER_PERIOD_STAMAX,
+ WNI_CFG_RSSI_FILTER_PERIOD_STADEF},
+ {WNI_CFG_MIN_RSSI_THRESHOLD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_MIN_RSSI_THRESHOLD_STAMIN,
+ WNI_CFG_MIN_RSSI_THRESHOLD_STAMAX,
+ WNI_CFG_MIN_RSSI_THRESHOLD_STADEF},
+ {WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMIN,
+ WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMAX,
+ WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STADEF},
+ {WNI_CFG_SCAN_IN_POWERSAVE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_SCAN_IN_POWERSAVE_STAMIN,
+ WNI_CFG_SCAN_IN_POWERSAVE_STAMAX,
+ WNI_CFG_SCAN_IN_POWERSAVE_STADEF},
+ {WNI_CFG_IGNORE_DTIM,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_IGNORE_DTIM_STAMIN,
+ WNI_CFG_IGNORE_DTIM_STAMAX,
+ WNI_CFG_IGNORE_DTIM_STADEF},
+ {WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMIN,
+ WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMAX,
+ WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STADEF},
+ {WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMIN,
+ WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMAX,
+ WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STADEF},
+ {WNI_CFG_WOWLAN_DEAUTH_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMIN,
+ WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMAX,
+ WNI_CFG_WOWLAN_DEAUTH_ENABLE_STADEF},
+ {WNI_CFG_WOWLAN_DISASSOC_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMIN,
+ WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMAX,
+ WNI_CFG_WOWLAN_DISASSOC_ENABLE_STADEF},
+ {WNI_CFG_WOWLAN_MAX_MISSED_BEACON,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMIN,
+ WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMAX,
+ WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STADEF},
+ {WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMIN,
+ WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMAX,
+ WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STADEF},
+ {WNI_CFG_BG_SCAN_CHANNEL_LIST,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_MAX_MEDIUM_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_MAX_MEDIUM_TIME_STAMIN,
+ WNI_CFG_MAX_MEDIUM_TIME_STAMAX,
+ WNI_CFG_MAX_MEDIUM_TIME_STADEF},
+ {WNI_CFG_MAX_MPDUS_IN_AMPDU,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN,
+ WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX,
+ WNI_CFG_MAX_MPDUS_IN_AMPDU_STADEF},
+ {WNI_CFG_IBSS_AUTO_BSSID,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_IBSS_AUTO_BSSID_STAMIN,
+ WNI_CFG_IBSS_AUTO_BSSID_STAMAX,
+ WNI_CFG_IBSS_AUTO_BSSID_STADEF},
+ {WNI_CFG_PROBE_REQ_ADDNIE_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMIN,
+ WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMAX,
+ WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STADEF},
+ {WNI_CFG_PROBE_REQ_ADDNIE_DATA,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMIN,
+ WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMAX,
+ WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STADEF},
+ {WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_ASSOC_RSP_ADDNIE_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMIN,
+ WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMAX,
+ WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STADEF},
+ {WNI_CFG_ASSOC_RSP_ADDNIE_DATA,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMIN,
+ WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMAX,
+ WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STADEF},
+ {WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE,
+ 0, 0, 0},
+ {WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMIN,
+ WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMAX,
+ WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STADEF},
+ {WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_WPS_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_ENABLE_STAMIN,
+ WNI_CFG_WPS_ENABLE_STAMAX,
+ WNI_CFG_WPS_ENABLE_STADEF},
+ {WNI_CFG_WPS_STATE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_STATE_STAMIN,
+ WNI_CFG_WPS_STATE_STAMAX,
+ WNI_CFG_WPS_STATE_STADEF},
+ {WNI_CFG_WPS_PROBE_REQ_FLAG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_PROBE_REQ_FLAG_STAMIN,
+ WNI_CFG_WPS_PROBE_REQ_FLAG_STAMAX,
+ WNI_CFG_WPS_PROBE_REQ_FLAG_STADEF},
+ {WNI_CFG_WPS_VERSION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_VERSION_STAMIN,
+ WNI_CFG_WPS_VERSION_STAMAX,
+ WNI_CFG_WPS_VERSION_STADEF},
+ {WNI_CFG_WPS_REQUEST_TYPE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_REQUEST_TYPE_STAMIN,
+ WNI_CFG_WPS_REQUEST_TYPE_STAMAX,
+ WNI_CFG_WPS_REQUEST_TYPE_STADEF},
+ {WNI_CFG_WPS_CFG_METHOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_CFG_METHOD_STAMIN,
+ 4294967295u,
+ WNI_CFG_WPS_CFG_METHOD_STADEF},
+ {WNI_CFG_WPS_UUID,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM,
+ 0, 0, 0},
+ {WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMIN,
+ WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMAX,
+ WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STADEF},
+ {WNI_CFG_WPS_PIMARY_DEVICE_OUI,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMIN,
+ 4294967295u,
+ WNI_CFG_WPS_PIMARY_DEVICE_OUI_STADEF},
+ {WNI_CFG_WPS_DEVICE_SUB_CATEGORY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMIN,
+ WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMAX,
+ WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STADEF},
+ {WNI_CFG_WPS_ASSOCIATION_STATE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_ASSOCIATION_STATE_STAMIN,
+ WNI_CFG_WPS_ASSOCIATION_STATE_STAMAX,
+ WNI_CFG_WPS_ASSOCIATION_STATE_STADEF},
+ {WNI_CFG_WPS_CONFIGURATION_ERROR,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_CONFIGURATION_ERROR_STAMIN,
+ WNI_CFG_WPS_CONFIGURATION_ERROR_STAMAX,
+ WNI_CFG_WPS_CONFIGURATION_ERROR_STADEF},
+ {WNI_CFG_WPS_DEVICE_PASSWORD_ID,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMIN,
+ 4294967295u,
+ WNI_CFG_WPS_DEVICE_PASSWORD_ID_STADEF},
+ {WNI_CFG_WPS_ASSOC_METHOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_WPS_ASSOC_METHOD_STAMIN,
+ WNI_CFG_WPS_ASSOC_METHOD_STAMAX,
+ WNI_CFG_WPS_ASSOC_METHOD_STADEF},
+ {WNI_CFG_LOW_GAIN_OVERRIDE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN,
+ WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX,
+ WNI_CFG_LOW_GAIN_OVERRIDE_STADEF},
+ {WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMIN,
+ WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMAX,
+ WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STADEF},
+ {WNI_CFG_RPE_POLLING_THRESHOLD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RPE_POLLING_THRESHOLD_STAMIN,
+ WNI_CFG_RPE_POLLING_THRESHOLD_STAMAX,
+ WNI_CFG_RPE_POLLING_THRESHOLD_STADEF},
+ {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF},
+ {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF},
+ {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF},
+ {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX,
+ WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF},
+ {WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN,
+ WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX,
+ WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF},
+ {WNI_CFG_SINGLE_TID_RC,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SINGLE_TID_RC_STAMIN,
+ WNI_CFG_SINGLE_TID_RC_STAMAX,
+ WNI_CFG_SINGLE_TID_RC_STADEF},
+ {WNI_CFG_RRM_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_RRM_ENABLED_STAMIN,
+ WNI_CFG_RRM_ENABLED_STAMAX,
+ WNI_CFG_RRM_ENABLED_STADEF},
+ {WNI_CFG_RRM_OPERATING_CHAN_MAX,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMIN,
+ WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMAX,
+ WNI_CFG_RRM_OPERATING_CHAN_MAX_STADEF},
+ {WNI_CFG_RRM_NON_OPERATING_CHAN_MAX,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMIN,
+ WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMAX,
+ WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STADEF},
+ {WNI_CFG_TX_PWR_CTRL_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_TX_PWR_CTRL_ENABLE_STAMIN,
+ WNI_CFG_TX_PWR_CTRL_ENABLE_STAMAX,
+ WNI_CFG_TX_PWR_CTRL_ENABLE_STADEF},
+ {WNI_CFG_MCAST_BCAST_FILTER_SETTING,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN,
+ WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX,
+ WNI_CFG_MCAST_BCAST_FILTER_SETTING_STADEF},
+ {WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMIN,
+ WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMAX,
+ WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STADEF},
+ {WNI_CFG_DYNAMIC_PS_POLL_VALUE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN,
+ WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX,
+ WNI_CFG_DYNAMIC_PS_POLL_VALUE_STADEF},
+ {WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN,
+ WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX,
+ WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF},
+ {WNI_CFG_TELE_BCN_WAKEUP_EN,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN,
+ WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX,
+ WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF},
+ {WNI_CFG_TELE_BCN_TRANS_LI,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_TELE_BCN_TRANS_LI_STAMIN,
+ WNI_CFG_TELE_BCN_TRANS_LI_STAMAX,
+ WNI_CFG_TELE_BCN_TRANS_LI_STADEF},
+ {WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN,
+ WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX,
+ WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF},
+ {WNI_CFG_TELE_BCN_MAX_LI,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_TELE_BCN_MAX_LI_STAMIN,
+ WNI_CFG_TELE_BCN_MAX_LI_STAMAX,
+ WNI_CFG_TELE_BCN_MAX_LI_STADEF},
+ {WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN,
+ WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX,
+ WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF},
+ {WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMIN,
+ WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMAX,
+ WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STADEF},
+ {WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN,
+ WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX,
+ WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF},
+ {WNI_CFG_ASSOC_STA_LIMIT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_ASSOC_STA_LIMIT_STAMIN,
+ WNI_CFG_ASSOC_STA_LIMIT_STAMAX,
+ WNI_CFG_ASSOC_STA_LIMIT_STADEF},
+ {WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN,
+ WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX,
+ WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STADEF},
+ {WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN,
+ WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX,
+ WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STADEF},
+ {WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN,
+ WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX,
+ WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STADEF},
+ {WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN,
+ WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX,
+ WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF},
+ {WNI_CFG_ENABLE_CLOSE_LOOP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ENABLE_CLOSE_LOOP_STAMIN,
+ WNI_CFG_ENABLE_CLOSE_LOOP_STAMAX,
+ WNI_CFG_ENABLE_CLOSE_LOOP_STADEF},
+ {WNI_CFG_ENABLE_LTE_COEX,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ENABLE_LTE_COEX_STAMIN,
+ WNI_CFG_ENABLE_LTE_COEX_STAMAX,
+ WNI_CFG_ENABLE_LTE_COEX_STADEF},
+ {WNI_CFG_AP_KEEP_ALIVE_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMIN,
+ WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMAX,
+ WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STADEF},
+ {WNI_CFG_GO_KEEP_ALIVE_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMIN,
+ WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMAX,
+ WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STADEF},
+ {WNI_CFG_ENABLE_MC_ADDR_LIST,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_ENABLE_MC_ADDR_LIST_STAMIN,
+ WNI_CFG_ENABLE_MC_ADDR_LIST_STAMAX,
+ WNI_CFG_ENABLE_MC_ADDR_LIST_STADEF},
+ {WNI_CFG_ENABLE_UC_FILTER,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_ENABLE_UC_FILTER_STAMIN,
+ WNI_CFG_ENABLE_UC_FILTER_STAMAX,
+ WNI_CFG_ENABLE_UC_FILTER_STADEF},
+ {WNI_CFG_ENABLE_LPWR_IMG_TRANSITION,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMIN,
+ WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMAX,
+ WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STADEF},
+ {WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN,
+ WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX,
+ WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF},
+ {WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN,
+ WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX,
+ WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF},
+ {WNI_CFG_AP_LINK_MONITOR_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMIN,
+ WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMAX,
+ WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STADEF},
+ {WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMIN,
+ WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMAX,
+ WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STADEF},
+ {WNI_CFG_TDLS_BUF_STA_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TDLS_BUF_STA_ENABLED_STAMIN,
+ WNI_CFG_TDLS_BUF_STA_ENABLED_STAMAX,
+ WNI_CFG_TDLS_BUF_STA_ENABLED_STADEF},
+ {WNI_CFG_TDLS_PUAPSD_INACT_TIME,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMIN,
+ WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMAX,
+ WNI_CFG_TDLS_PUAPSD_INACT_TIME_STADEF},
+ {WNI_CFG_TDLS_RX_FRAME_THRESHOLD,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMIN,
+ WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMAX,
+ WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STADEF},
+ {WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMIN,
+ WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMAX,
+ WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STADEF},
+ {WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_RESTART,
+ WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN,
+ WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMAX,
+ WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF},
+ {WNI_CFG_ENABLE_ADAPT_RX_DRAIN,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN,
+ WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX,
+ WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF},
+ {WNI_CFG_FLEX_CONNECT_POWER_FACTOR,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMIN,
+ WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMAX,
+ WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STADEF},
+ {WNI_CFG_ANTENNA_DIVESITY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_ANTENNA_DIVESITY_STAMIN,
+ WNI_CFG_ANTENNA_DIVESITY_STAMAX,
+ WNI_CFG_ANTENNA_DIVESITY_STADEF},
+ {WNI_CFG_GO_LINK_MONITOR_TIMEOUT,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMIN,
+ WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX,
+ WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF},
+ {WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_HAL,
+ WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN,
+ WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX,
+ WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF},
+ {WNI_CFG_CURRENT_RSSI,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_CURRENT_RSSI_STAMIN,
+ WNI_CFG_CURRENT_RSSI_STAMAX,
+ WNI_CFG_CURRENT_RSSI_STADEF},
+ {WNI_CFG_RTT3_ENABLE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_RTT3_ENABLE_STAMIN,
+ WNI_CFG_RTT3_ENABLE_STAMAX,
+ WNI_CFG_RTT3_ENABLE_STADEF},
+ {WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMIN,
+ WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMAX,
+ WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STADEF},
+ {WNI_CFG_TDLS_OFF_CHANNEL_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMIN,
+ WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMAX,
+ WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STADEF},
+ {WNI_CFG_IBSS_ATIM_WIN_SIZE,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMIN,
+ WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMAX,
+ WNI_CFG_IBSS_ATIM_WIN_SIZE_STADEF},
+ {WNI_CFG_DFS_MASTER_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_DFS_MASTER_ENABLED_STAMIN,
+ WNI_CFG_DFS_MASTER_ENABLED_STAMAX,
+ WNI_CFG_DFS_MASTER_ENABLED_STADEF},
+ {WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT,
+ WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMIN,
+ WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STAMAX,
+ WNI_CFG_VHT_ENABLE_TXBF_20MHZ_STADEF},
+ {WNI_CFG_TDLS_WMM_MODE_ENABLED,
+ CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT |
+ CFG_CTL_NTF_LIM,
+ WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMIN,
+ WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX,
+ WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF}
+};
+
+
+cfgstatic_string cfg_static_string[CFG_MAX_STATIC_STRING] = {
+
+ {WNI_CFG_STA_ID,
+ WNI_CFG_STA_ID_LEN,
+ 6,
+ {0x22, 0x22, 0x44, 0x44, 0x33, 0x33} },
+ {WNI_CFG_SSID,
+ WNI_CFG_SSID_LEN,
+ 10,
+ {1, 2, 3, 4, 5, 6, 7, 8, 9, 0} },
+ {WNI_CFG_WEP_DEFAULT_KEY_1,
+ WNI_CFG_WEP_DEFAULT_KEY_1_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_WEP_DEFAULT_KEY_2,
+ WNI_CFG_WEP_DEFAULT_KEY_2_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_WEP_DEFAULT_KEY_3,
+ WNI_CFG_WEP_DEFAULT_KEY_3_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_WEP_DEFAULT_KEY_4,
+ WNI_CFG_WEP_DEFAULT_KEY_4_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_SUPPORTED_RATES_11B,
+ WNI_CFG_SUPPORTED_RATES_11B_LEN,
+ 4,
+ {2, 4, 11, 22} },
+ {WNI_CFG_SUPPORTED_RATES_11A,
+ WNI_CFG_SUPPORTED_RATES_11A_LEN,
+ 8,
+ {12, 18, 24, 36, 48, 72, 96, 108} },
+ {WNI_CFG_OPERATIONAL_RATE_SET,
+ WNI_CFG_OPERATIONAL_RATE_SET_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET,
+ WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN,
+ 4,
+ {1, 3, 5, 7} },
+ {WNI_CFG_VALID_CHANNEL_LIST,
+ WNI_CFG_VALID_CHANNEL_LIST_LEN,
+ 55,
+ {36, 40, 44, 48, 52, 56, 60, 64, 1, 6, 11, 34, 38, 42, 46, 2, 3, 4,
+ 5, 7, 8, 9, 10, 12, 13, 14, 100, 104, 108, 112, 116, 120, 124, 128,
+ 132, 136, 140, 149, 151, 153, 155, 157, 159, 161, 50, 54, 58, 62, 240,
+ 242, 244, 246, 248, 250, 252} },
+
+ {WNI_CFG_MANUFACTURER_OUI,
+ WNI_CFG_MANUFACTURER_OUI_LEN,
+ 3,
+ {0x0, 0xa, 0xf5} },
+ {WNI_CFG_MANUFACTURER_NAME,
+ WNI_CFG_MANUFACTURER_NAME_LEN,
+ 8,
+ {0x51, 0x75, 0x61, 0x6c, 0x63, 0x6f, 0x6d, 0x6d} },
+ {WNI_CFG_MODEL_NUMBER,
+ WNI_CFG_MODEL_NUMBER_LEN,
+ 6,
+ {0x4d, 0x4e, 0x31, 0x32, 0x33, 0x34} },
+ {WNI_CFG_MODEL_NAME,
+ WNI_CFG_MODEL_NAME_LEN,
+ 7,
+ {0x57, 0x46, 0x52, 0x34, 0x30, 0x33, 0x31} },
+ {WNI_CFG_MANUFACTURER_PRODUCT_NAME,
+ WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN,
+ 6,
+ {0x31, 0x31, 0x6e, 0x2d, 0x41, 0x50} },
+ {WNI_CFG_MANUFACTURER_PRODUCT_VERSION,
+ WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN,
+ 6,
+ {0x53, 0x4e, 0x31, 0x32, 0x33, 0x34} },
+ {WNI_CFG_MAX_TX_POWER_2_4,
+ WNI_CFG_MAX_TX_POWER_2_4_LEN,
+ 3,
+ {0x1, 0xe, 0x14} },
+ {WNI_CFG_MAX_TX_POWER_5,
+ WNI_CFG_MAX_TX_POWER_5_LEN,
+ 3,
+ {0x24, 0x7e, 0x14} },
+ {WNI_CFG_AP_NODE_NAME,
+ WNI_CFG_AP_NODE_NAME_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_COUNTRY_CODE,
+ WNI_CFG_COUNTRY_CODE_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_EDCA_ANI_ACBK_LOCAL,
+ WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN,
+ 17,
+ {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0,
+ 0xf, 0x3, 0xff, 0x0} },
+ {WNI_CFG_EDCA_ANI_ACBE_LOCAL,
+ WNI_CFG_EDCA_ANI_ACBE_LOCAL_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0xf, 0x3, 0xff, 0x64, 0x0, 0x1f, 0x3, 0xff, 0x64, 0x0,
+ 0xf, 0x3, 0xff, 0x64} },
+ {WNI_CFG_EDCA_ANI_ACVI_LOCAL,
+ WNI_CFG_EDCA_ANI_ACVI_LOCAL_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0xc8, 0x0, 0xf, 0x0, 0x1f, 0xbc, 0x0,
+ 0x7, 0x0, 0xf, 0xc8} },
+ {WNI_CFG_EDCA_ANI_ACVO_LOCAL,
+ WNI_CFG_EDCA_ANI_ACVO_LOCAL_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x64, 0x0, 0x7, 0x0, 0xf, 0x66, 0x0,
+ 0x3, 0x0, 0x7, 0x64} },
+ {WNI_CFG_EDCA_ANI_ACBK,
+ WNI_CFG_EDCA_ANI_ACBK_LEN,
+ 17,
+ {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0,
+ 0xf, 0x3, 0xff, 0x0} },
+ {WNI_CFG_EDCA_ANI_ACBE,
+ WNI_CFG_EDCA_ANI_ACBE_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0xf, 0x3, 0xff, 0x64, 0x0, 0x1f, 0x3, 0xff, 0x64, 0x0,
+ 0xf, 0x3, 0xff, 0x64} },
+ {WNI_CFG_EDCA_ANI_ACVI,
+ WNI_CFG_EDCA_ANI_ACVI_LEN,
+ 17, {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0xc8, 0x0, 0xf, 0x0, 0x1f,
+ 0xbc, 0x0, 0x7, 0x0, 0xf, 0xc8} },
+ {WNI_CFG_EDCA_ANI_ACVO,
+ WNI_CFG_EDCA_ANI_ACVO_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x64, 0x0, 0x7, 0x0, 0xf, 0x66, 0x0, 0x3,
+ 0x0, 0x7, 0x64} },
+ {WNI_CFG_EDCA_WME_ACBK_LOCAL,
+ WNI_CFG_EDCA_WME_ACBK_LOCAL_LEN,
+ 17, {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff,
+ 0x0, 0x0, 0xf, 0x3, 0xff, 0x0} },
+ {WNI_CFG_EDCA_WME_ACBE_LOCAL,
+ WNI_CFG_EDCA_WME_ACBE_LOCAL_LEN,
+ 17, {0x0, 0x3, 0x0, 0xf, 0x0, 0x3f, 0x0, 0x0, 0x1f, 0x3, 0xff,
+ 0x0, 0x0, 0xf, 0x0, 0x3f, 0x0} },
+ {WNI_CFG_EDCA_WME_ACVI_LOCAL,
+ WNI_CFG_EDCA_WME_ACVI_LOCAL_LEN,
+ 17,
+ {0x0, 0x1, 0x0, 0x7, 0x0, 0xf, 0x5e, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7,
+ 0x0, 0xf, 0x5e} },
+ {WNI_CFG_EDCA_WME_ACVO_LOCAL,
+ WNI_CFG_EDCA_WME_ACVO_LOCAL_LEN,
+ 17,
+ {0x0, 0x1, 0x0, 0x3, 0x0, 0x7, 0x2f, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3,
+ 0x0, 0x7, 0x2f} },
+ {WNI_CFG_EDCA_WME_ACBK,
+ WNI_CFG_EDCA_WME_ACBK_LEN,
+ 17,
+ {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf,
+ 0x3, 0xff, 0x0} },
+ {WNI_CFG_EDCA_WME_ACBE,
+ WNI_CFG_EDCA_WME_ACBE_LEN,
+ 17,
+ {0x0, 0x3, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf,
+ 0x3, 0xff, 0x0} },
+ {WNI_CFG_EDCA_WME_ACVI,
+ WNI_CFG_EDCA_WME_ACVI_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0x5e, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7,
+ 0x0, 0xf, 0x5e} },
+ {WNI_CFG_EDCA_WME_ACVO,
+ WNI_CFG_EDCA_WME_ACVO_LEN,
+ 17,
+ {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x2f, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3,
+ 0x0, 0x7, 0x2f} },
+ {WNI_CFG_RADAR_CHANNEL_LIST,
+ WNI_CFG_RADAR_CHANNEL_LIST_LEN,
+ 15,
+ {0x34, 0x38, 0x3c, 0x40, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80,
+ 0x84, 0x88, 0x8c} },
+ {WNI_CFG_SCAN_CONTROL_LIST,
+ WNI_CFG_SCAN_CONTROL_LIST_LEN,
+ 114,
+ {0x1, 0x1, 0x2, 0x1, 0x3, 0x1, 0x4, 0x1, 0x5, 0x1, 0x6, 0x1, 0x7, 0x1,
+ 0x8, 0x1, 0x9, 0x1, 0xa, 0x1, 0xb, 0x1, 0xc, 0x1, 0xd, 0x1, 0xe, 0x1,
+ 0x22, 0x1, 0x24, 0x1, 0x26, 0x1, 0x28, 0x1, 0x2a, 0x1, 0x2c, 0x1, 0x2e,
+ 0x1, 0x30, 0x1, 0x32, 0x1, 0x34, 0x0, 0x36, 0x0, 0x38, 0x0, 0x3a, 0x0,
+ 0x3c, 0x0, 0x3e, 0x0, 0x40, 0x0, 0x64, 0x0, 0x68, 0x0, 0x6c, 0x0, 0x70,
+ 0x0, 0x74, 0x0, 0x78, 0x0, 0x7c, 0x0, 0x80, 0x0, 0x84, 0x0, 0x88, 0x0,
+ 0x8c, 0x0, 0x90, 0x0, 0x95, 0x1, 0x97, 0x1, 0x99, 0x1, 0x9b, 0x1, 0x9d,
+ 0x1, 0x9f, 0x1, 0xa1, 0x1, 0xa5, 0x1, 0xf0, 0x1, 0xf2, 0x1, 0xf4, 0x1,
+ 0xf6, 0x1, 0xf8, 0x1, 0xfa, 0x1, 0xfc, 0x1} },
+ {WNI_CFG_SUPPORTED_MCS_SET,
+ WNI_CFG_SUPPORTED_MCS_SET_LEN,
+ 16,
+ {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0} },
+ {WNI_CFG_BASIC_MCS_SET,
+ WNI_CFG_BASIC_MCS_SET_LEN,
+ 16,
+ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0} },
+ {WNI_CFG_CURRENT_MCS_SET,
+ WNI_CFG_CURRENT_MCS_SET_LEN,
+ 16,
+ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0} },
+ {WNI_CFG_BG_SCAN_CHANNEL_LIST,
+ WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN,
+ 55,
+ {0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c, 0x40, 0x1, 0x6, 0xb, 0x22,
+ 0x26, 0x2a, 0x2e, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8, 0x9, 0xa, 0xc, 0xd,
+ 0xe, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x84, 0x88, 0x8c,
+ 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9f, 0xa1, 0x32, 0x36, 0x3a, 0x3e, 0xf0,
+ 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc} },
+ {WNI_CFG_PROBE_REQ_ADDNIE_DATA,
+ WNI_CFG_PROBE_REQ_ADDNIE_DATA_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
+ WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_ASSOC_RSP_ADDNIE_DATA,
+ WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA,
+ WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA,
+ WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
+ 0,
+ {0} },
+ {WNI_CFG_WPS_UUID,
+ WNI_CFG_WPS_UUID_LEN,
+ 6,
+ {0xa, 0xb, 0xc, 0xd, 0xe, 0xf} }
+};
+
+/*--------------------------------------------------------------------*/
+/* Static function prototypes */
+/*--------------------------------------------------------------------*/
+static void proc_dnld_rsp(tpAniSirGlobal, uint16_t, uint32_t *);
+static void proc_get_req(tpAniSirGlobal, uint16_t, uint32_t *);
+static void proc_set_req(tpAniSirGlobal, uint16_t, uint32_t *);
+static void proc_set_req_no_rsp(tpAniSirGlobal, uint16_t, uint32_t *);
+
+static uint8_t check_param(tpAniSirGlobal, uint16_t, uint32_t, uint32_t,
+ uint32_t *);
+static void get_str_value(uint8_t *, uint8_t *, uint32_t);
+
+/*--------------------------------------------------------------------*/
+/* Module global variables */
+/*--------------------------------------------------------------------*/
+
+/* CFG function table */
+void (*g_cfg_func[])(tpAniSirGlobal, uint16_t, uint32_t *) = {
+ proc_dnld_rsp, proc_get_req, proc_set_req, proc_set_req_no_rsp
+};
+
+/**---------------------------------------------------------------------
+ * cfg_process_mb_msg()
+ *
+ ***FUNCTION:
+ * CFG mailbox message processing function.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * None.
+ *
+ ***NOTE:
+ *
+ * @param pMsg Message pointer
+ *
+ * @return None.
+ *
+ */
+void cfg_process_mb_msg(tpAniSirGlobal pMac, tSirMbMsg *pMsg)
+{
+ uint16_t index;
+ uint16_t len;
+ uint32_t *pParam;
+
+ /* Use type[7:0] as index to function table */
+ index = CFG_GET_FUNC_INDX(pMsg->type);
+
+ if (index >= CDF_ARRAY_SIZE(g_cfg_func)) {
+ cdf_mem_free(pMsg);
+ return;
+ }
+ len = pMsg->msgLen - WNI_CFG_MB_HDR_LEN;
+ pParam = ((uint32_t *) pMsg) + 1;
+
+ /* Call processing function */
+ g_cfg_func[index] (pMac, len, pParam);
+
+ /* Free up buffer */
+ cdf_mem_free(pMsg);
+
+} /*** end cfg_process_mb_msg() ***/
+
+/**---------------------------------------------------------------------
+ * proc_dnld_rsp()
+ *
+ * FUNCTION:
+ * This function processes CFG_DNLD_RSP message from host.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param length: message length
+ * @param pParam: parameter list pointer
+ *
+ * @return None
+ *
+ */
+static void proc_dnld_rsp(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam)
+{
+ int32_t i;
+
+ uint32_t expLen, retVal, bufStart, bufEnd;
+ uint32_t *pSrc, *pDst, *pDstEnd;
+ uint32_t strSize, j;
+ uint8_t pStr[CFG_MAX_STR_LEN];
+ tpCfgBinHdr pHdr;
+ uint32_t logLevel;
+ tSirMsgQ mmhMsg;
+
+ /* First Dword must contain the AP or STA magic dword */
+ PELOGW(cfg_log(pMac, LOGW, FL("CFG size %d bytes MAGIC dword is 0x%x"),
+ length, sir_read_u32_n((uint8_t *) pParam));
+ )
+ /* if the string is not correct, return failure */
+ if (*pParam == CFG_STA_MAGIC_DWORD) {
+ }
+
+ else {
+ PELOGE(cfg_log
+ (pMac, LOGE, FL("Invalid magic dword 0x%x"),
+ sir_read_u32_n((uint8_t *) pParam));
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+
+ pParam++;
+ length -= 4;
+
+ /* Verify message length */
+ {
+ pMac->cfg.gCfgMaxIBufSize = CFG_STA_IBUF_MAX_SIZE;
+ pMac->cfg.gCfgMaxSBufSize = CFG_STA_SBUF_MAX_SIZE;
+ }
+
+ /* Parse the Cfg header */
+ pHdr = (tpCfgBinHdr) pParam;
+ pParam += (sizeof(tCfgBinHdr) >> 2);
+ PELOGW(cfg_log
+ (pMac, LOGW,
+ FL("CFG hdr totParams %d intParams %d strBufSize %d/%d"),
+ pHdr->controlSize, pHdr->iBufSize, pHdr->sBufSize,
+ pMac->cfg.gCfgMaxSBufSize);
+ )
+
+ expLen =
+ ((CFG_PARAM_MAX_NUM + 3 * pMac->cfg.gCfgMaxIBufSize) << 2) +
+ pHdr->sBufSize + sizeof(tCfgBinHdr);
+
+ if (length != expLen) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("<CFG> DNLD_RSP invalid length %d (exp %d)"), length,
+ expLen);
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+
+ if (pHdr->controlSize != CFG_PARAM_MAX_NUM) {
+ PELOGE(cfg_log
+ (pMac, LOGE, FL("<CFG> Total parameter count mismatch"));
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+
+ if (pHdr->iBufSize != pMac->cfg.gCfgMaxIBufSize) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("<CFG> Integer parameter count mismatch"));
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+ /* Copy control array */
+ pDst = (uint32_t *) pMac->cfg.gCfgEntry;
+ pDstEnd = pDst + CFG_PARAM_MAX_NUM;
+ pSrc = pParam;
+ while (pDst < pDstEnd) {
+ *pDst++ = *pSrc++;
+ }
+ /* Copy default values */
+ pDst = pMac->cfg.gCfgIBuf;
+ pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize;
+ while (pDst < pDstEnd) {
+ *pDst++ = *pSrc++;
+ }
+
+ /* Copy min values */
+ pDst = pMac->cfg.gCfgIBufMin;
+ pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize;
+ while (pDst < pDstEnd) {
+ *pDst++ = *pSrc++;
+ }
+
+ /* Copy max values */
+ pDst = pMac->cfg.gCfgIBufMax;
+ pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize;
+ while (pDst < pDstEnd) {
+ *pDst++ = *pSrc++;
+ }
+
+ for (i = 0; i < pMac->cfg.gCfgMaxIBufSize; i++)
+ if (pMac->cfg.gCfgIBuf[i] < pMac->cfg.gCfgIBufMin[i] ||
+ pMac->cfg.gCfgIBuf[i] > pMac->cfg.gCfgIBufMax[i]) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("cfg id %d Invalid def value %d "
+ "min %d max %d"), i, pMac->cfg.gCfgIBuf[i],
+ pMac->cfg.gCfgIBufMin[i],
+ pMac->cfg.gCfgIBufMax[i]);
+ )
+ }
+ /* Calculate max string buffer lengths for all string parameters */
+ bufEnd = pMac->cfg.gCfgMaxSBufSize;
+ for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) {
+ if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0)
+ continue;
+
+ if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0)
+ continue;
+
+ bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK;
+ pMac->cfg.gCfgSBuf[bufStart] =
+ (uint8_t) (bufEnd - bufStart - 2);
+
+ PELOG1(cfg_log
+ (pMac, LOG1, FL("id %d max %d bufStart %d bufEnd %d"), i,
+ pMac->cfg.gCfgSBuf[bufStart], bufStart, bufEnd);
+ )
+
+ bufEnd = bufStart;
+ }
+
+ /* Initialize string defaults */
+ strSize = pHdr->sBufSize;
+ while (strSize) {
+ uint32_t paramId, paramLen, paramLenCeil4;
+
+ if (strSize < 4) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Error parsing str defaults, rem %d bytes"),
+ strSize);
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+ paramId = *pSrc >> 16;
+ paramLen = *pSrc & 0xff;
+ pSrc++;
+ strSize -= 4;
+
+ paramLenCeil4 = ((paramLen + 3) >> 2);
+ if (strSize < paramLenCeil4 << 2) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Error parsing str defaults, rem %d bytes"),
+ strSize);
+ )
+ PELOGE(cfg_log
+ (pMac, LOGE, FL("param id %d len %d bytes"),
+ paramId, paramLen);
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+ for (j = 0; j < paramLenCeil4; j++) {
+ pStr[4 * j] = (uint8_t) (*pSrc >> 24) & 0xff;
+ pStr[4 * j + 1] = (uint8_t) (*pSrc >> 16) & 0xff;
+ pStr[4 * j + 2] = (uint8_t) (*pSrc >> 8) & 0xff;
+ pStr[4 * j + 3] = (uint8_t) (*pSrc) & 0xff;
+
+ pSrc++;
+ strSize -= 4;
+ }
+
+ PELOG1(cfg_log
+ (pMac, LOG1, FL("set str id %d len %d"), paramId,
+ paramLen);
+ )
+
+ if (cfg_set_str(pMac, (uint16_t) paramId, pStr, paramLen) !=
+ eSIR_SUCCESS) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Error setting str default param %d len %d"),
+ paramId, paramLen);
+ )
+ retVal = WNI_CFG_INVALID_LEN;
+ goto end;
+ }
+ }
+
+ /* Set the default log level based on config */
+ wlan_cfg_get_int(pMac, WNI_CFG_LOG_LEVEL, &logLevel);
+ for (i = 0; i < LOG_ENTRY_NUM; i++)
+ pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] =
+ logLevel;
+
+ /* Set status to READY */
+ pMac->cfg.gCfgStatus = CFG_SUCCESS;
+ retVal = WNI_CFG_SUCCESS;
+ PELOG1(cfg_log(pMac, LOG1, "<CFG> Completed successfully");)
+
+end :
+
+ if (retVal != WNI_CFG_SUCCESS)
+ pMac->cfg.gCfgStatus = CFG_FAILURE;
+
+ /* Send response message to host */
+ pMac->cfg.gParamList[WNI_CFG_DNLD_CNF_RES] = retVal;
+ cfg_send_host_msg(pMac, WNI_CFG_DNLD_CNF, WNI_CFG_DNLD_CNF_LEN,
+ WNI_CFG_DNLD_CNF_NUM, pMac->cfg.gParamList, 0, 0);
+
+ /* notify WMA that the config has downloaded */
+ mmhMsg.type = SIR_CFG_DOWNLOAD_COMPLETE_IND;
+ mmhMsg.bodyptr = NULL;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ if (wma_post_ctrl_msg(pMac, &mmhMsg) != eSIR_SUCCESS) {
+ PELOGE(cfg_log(pMac, LOGE, FL("WMAPostMsgApi failed!"));)
+ }
+
+} /*** end procDnldRsp() ***/
+
+/**---------------------------------------------------------------------
+ * proc_get_req()
+ *
+ * FUNCTION:
+ * This function processes CFG_GET_REQ message from host.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ * For every parameter ID specified on the list, CFG will send a separate
+ * CFG_GET_RSP back to host.
+ *
+ * @param length: message length
+ * @param pParam: parameter list pointer
+ *
+ * @return None
+ *
+ */
+static void proc_get_req(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam)
+{
+ uint16_t cfgId, i;
+ uint32_t value, valueLen, result;
+ uint32_t *pValue;
+
+ PELOG1(cfg_log(pMac, LOG1, FL("Rcvd cfg get request %d bytes"), length);)
+ for (i = 0; i < length / 4; i++)
+ PELOG2(cfg_log(pMac, LOG2, FL("[%2d] 0x%08x"), i, pParam[i]);)
+
+ if (!pMac->cfg.gCfgStatus) {
+ cfgId = (uint16_t) sir_read_u32_n((uint8_t *) pParam);
+ PELOGE(cfg_log(pMac, LOGE, FL("CFG not ready, param %d"), cfgId);)
+ pMac->cfg.gParamList[WNI_CFG_GET_RSP_RES] =
+ WNI_CFG_NOT_READY;
+ pMac->cfg.gParamList[WNI_CFG_GET_RSP_PID] = cfgId;
+ pMac->cfg.gParamList[WNI_CFG_GET_RSP_PLEN] = 0;
+ cfg_send_host_msg(pMac, WNI_CFG_GET_RSP,
+ WNI_CFG_GET_RSP_PARTIAL_LEN, WNI_CFG_GET_RSP_NUM,
+ pMac->cfg.gParamList, 0, 0);
+ } else {
+ /* Process all parameter ID's on the list */
+ while (length >= sizeof(uint32_t)) {
+ cfgId = (uint16_t) *pParam++;
+ pValue = 0;
+ valueLen = 0;
+
+ PELOG1(cfg_log
+ (pMac, LOG1, FL("Cfg get param %d"), cfgId);
+ )
+ /* Check for valid parameter ID, etc... */
+ if (check_param
+ (pMac, cfgId, CFG_CTL_RE, WNI_CFG_WO_PARAM,
+ &result)) {
+ if ((pMac->cfg.gCfgEntry[cfgId].
+ control & CFG_CTL_INT) != 0) {
+ /* Get integer parameter */
+ result =
+ (wlan_cfg_get_int(pMac, cfgId, &value)
+ ==
+ eSIR_SUCCESS ? WNI_CFG_SUCCESS :
+ WNI_CFG_OTHER_ERROR);
+ pValue = &value;
+ valueLen = sizeof(uint32_t);
+ } else {
+ /* Get string parameter */
+ valueLen = sizeof(pMac->cfg.gSBuffer);
+ result =
+ (wlan_cfg_get_str
+ (pMac, cfgId, pMac->cfg.gSBuffer,
+ &valueLen)
+ == eSIR_SUCCESS ? WNI_CFG_SUCCESS :
+ WNI_CFG_OTHER_ERROR);
+ pValue =
+ (uint32_t *) pMac->cfg.gSBuffer;
+ }
+ } else {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Check param failed, param %d"),
+ cfgId);
+ )
+ result = WNI_CFG_INVALID_LEN;
+ }
+
+ /* Send response message to host */
+ pMac->cfg.gParamList[WNI_CFG_GET_RSP_RES] = result;
+ pMac->cfg.gParamList[WNI_CFG_GET_RSP_PID] = cfgId;
+ pMac->cfg.gParamList[WNI_CFG_GET_RSP_PLEN] = valueLen;
+
+ /* We need to round up buffer length to word-increment */
+ valueLen = (((valueLen + 3) >> 2) << 2);
+ cfg_send_host_msg(pMac, WNI_CFG_GET_RSP,
+ WNI_CFG_GET_RSP_PARTIAL_LEN + valueLen,
+ WNI_CFG_GET_RSP_NUM,
+ pMac->cfg.gParamList, valueLen, pValue);
+
+ /* Decrement length */
+ length -= sizeof(uint32_t);
+ }
+ }
+
+} /*** end procGetReq() ***/
+
+/**---------------------------------------------------------------------
+ * proc_set_req_internal()
+ *
+ * FUNCTION:
+ * This function processes CFG_SET_REQ message from host.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * - The message content is coded in TLV format.
+ * - For string parameter, the length field is byte accurate. However,
+ * the next TLV set will begin on the next word boundary.
+ *
+ * NOTE:
+ * - For every parameter ID specified on the list, CFG will send a separate
+ * CFG_SET_RSP back to host.
+ *
+ * @param length: message length
+ * @param pParam: parameter list pointer
+ * @param fRsp: whether to send response to host. true means sending.
+ * @return None
+ *
+ */
+static void
+proc_set_req_internal(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam,
+ bool fRsp)
+{
+ uint16_t cfgId, valueLen, valueLenRoundedUp4;
+ uint32_t value, result;
+
+ PELOG1(cfg_log(pMac, LOGl, FL("Rcvd cfg set request %d bytes"), length);)
+
+ if (!pMac->cfg.gCfgStatus) {
+ cfgId = (uint16_t) sir_read_u32_n((uint8_t *) pParam);
+ PELOG1(cfg_log(pMac, LOGW, FL("CFG not ready, param %d"), cfgId);)
+ pMac->cfg.gParamList[WNI_CFG_SET_CNF_RES] =
+ WNI_CFG_NOT_READY;
+ pMac->cfg.gParamList[WNI_CFG_SET_CNF_PID] = cfgId;
+ if (fRsp) {
+ cfg_send_host_msg(pMac, WNI_CFG_SET_CNF,
+ WNI_CFG_SET_CNF_LEN, WNI_CFG_SET_CNF_NUM,
+ pMac->cfg.gParamList, 0, 0);
+ }
+ } else {
+ /* Process all TLVs in buffer */
+ while (length >= (sizeof(uint32_t) * 2)) {
+ cfgId = (uint16_t) *pParam++;
+ valueLen = (uint16_t) *pParam++;
+ length -= (sizeof(uint32_t) * 2);
+ /* value length rounded up to a 4 byte multiple */
+ valueLenRoundedUp4 = (((valueLen + 3) >> 2) << 2);
+
+ /* Check for valid request before proceeding */
+ if (check_param
+ (pMac, cfgId, CFG_CTL_WE, WNI_CFG_RO_PARAM,
+ &result)) {
+ PELOG1(cfg_log
+ (pMac, LOGW,
+ (char *)g_cfg_param_name[cfgId]);
+ )
+ /* Process integer parameter */
+ if ((pMac->cfg.gCfgEntry[cfgId].
+ control & CFG_CTL_INT) != 0) {
+ /* Set VALUE */
+ if (valueLen != sizeof(uint32_t)) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL
+ ("Invalid value length %d in set param %d (tot %d)"),
+ valueLen, cfgId,
+ length);
+ )
+ result =
+ WNI_CFG_INVALID_LEN;
+ } else {
+ value = *pParam;
+ PELOG1(cfg_log
+ (pMac, LOGW,
+ FL
+ ("Cfg set int %d len %d(%d) val %d"),
+ cfgId, valueLen,
+ valueLenRoundedUp4,
+ value);
+ )
+ result =
+ (cfg_set_int
+ (pMac, cfgId,
+ value) ==
+ eSIR_SUCCESS ?
+ WNI_CFG_SUCCESS :
+ WNI_CFG_OTHER_ERROR);
+ if (result == WNI_CFG_SUCCESS) {
+ if (cfg_need_restart
+ (pMac, cfgId)) {
+ result =
+ WNI_CFG_NEED_RESTART;
+ } else
+ if (cfg_need_reload
+ (pMac, cfgId)) {
+ result =
+ WNI_CFG_NEED_RELOAD;
+ }
+ }
+ }
+ }
+ /* Process string parameter */
+ else {
+ if (valueLenRoundedUp4 > length) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL
+ ("Invalid string length %d"
+ "in set param %d (tot %d)"),
+ valueLen, cfgId,
+ length);
+ )
+ result =
+ WNI_CFG_INVALID_LEN;
+ } else {
+ get_str_value((uint8_t *) pParam,
+ pMac->cfg.gSBuffer,
+ valueLen);
+ PELOG1(cfg_log
+ (pMac, LOGW,
+ FL
+ ("Cfg set str %d len %d(%d) bytes"),
+ cfgId, valueLen,
+ valueLenRoundedUp4);
+ )
+ result =
+ (cfg_set_str
+ (pMac, cfgId,
+ pMac->cfg.gSBuffer,
+ valueLen) ==
+ eSIR_SUCCESS ?
+ WNI_CFG_SUCCESS :
+ WNI_CFG_OTHER_ERROR);
+ if (result == WNI_CFG_SUCCESS) {
+ if (cfg_need_restart
+ (pMac, cfgId)) {
+ result =
+ WNI_CFG_NEED_RESTART;
+ } else
+ if (cfg_need_reload
+ (pMac, cfgId)) {
+ result =
+ WNI_CFG_NEED_RELOAD;
+ }
+ }
+ }
+ }
+ } else {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Check param failed, param %d"),
+ cfgId);
+ )
+ result = WNI_CFG_INVALID_LEN;
+ }
+
+ /* Send confirm message to host */
+ pMac->cfg.gParamList[WNI_CFG_SET_CNF_RES] = result;
+ pMac->cfg.gParamList[WNI_CFG_SET_CNF_PID] = cfgId;
+ if (fRsp) {
+ cfg_send_host_msg(pMac, WNI_CFG_SET_CNF,
+ WNI_CFG_SET_CNF_LEN,
+ WNI_CFG_SET_CNF_NUM,
+ pMac->cfg.gParamList, 0, 0);
+ } else {
+ PELOGW(cfg_log
+ (pMac, LOG2, " CFGID %d no rsp", cfgId);
+ )
+ }
+
+ if (valueLenRoundedUp4 > length)
+ length = 0;
+ else {
+ length -= valueLenRoundedUp4;
+ pParam += (valueLenRoundedUp4 >> 2);
+ }
+ }
+ }
+}
+
+static void proc_set_req(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam)
+{
+ proc_set_req_internal(pMac, length, pParam, true);
+}
+
+static void
+proc_set_req_no_rsp(tpAniSirGlobal pMac, uint16_t length, uint32_t *pParam)
+{
+ proc_set_req_internal(pMac, length, pParam, false);
+}
+
+/**---------------------------------------------------------------------
+ * check_param()
+ *
+ * FUNCTION:
+ * This function is called to perform various check on a parameter.
+ *
+ * LOGIC:
+ * - If cfgId is out of bound or parameter is not valid, result
+ * WNI_CFG_INVALID_PID is returned at address specified in pResult.
+ *
+ * - If specified 'flag' is not set in the parameter control entry,
+ * 'failedResult' is returned at address specified in pResult.
+ *
+ * ASSUMPTIONS:
+ * Since this function is used internally, 'pResult' is always valid.
+ *
+ * NOTE:
+ *
+ * @param None
+ *
+ * @return true: Parameter is valid and matches checked condition \n
+ * @return false: Parameter either is not valid or does not match
+ * checked condition.
+ *
+ */
+static uint8_t
+check_param(tpAniSirGlobal pMac, uint16_t cfgId, uint32_t flag,
+ uint32_t failedResult, uint32_t *pResult)
+{
+ /* Check if parameter ID is out of bound */
+ if (cfgId >= CFG_PARAM_MAX_NUM) {
+ PELOGE(cfg_log(pMac, LOGE, FL("Invalid param id %d"), cfgId);)
+ * pResult = WNI_CFG_INVALID_PID;
+ } else {
+ /* Check if parameter is valid */
+ if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_VALID) == 0) {
+ PELOGE(cfg_log
+ (pMac, LOGE, FL("Param id %d not valid"), cfgId);
+ )
+ * pResult = WNI_CFG_INVALID_PID;
+ } else {
+ /* Check control field against flag */
+ if ((pMac->cfg.gCfgEntry[cfgId].control & flag) == 0) {
+ PELOGE(cfg_log
+ (pMac, LOGE,
+ FL("Param id %d wrong permissions %x"),
+ cfgId,
+ pMac->cfg.gCfgEntry[cfgId].control);
+ )
+ * pResult = failedResult;
+ } else
+ return true;
+ }
+ }
+ return false;
+
+} /*** cfgParamCheck() ***/
+
+/**---------------------------------------------------------------------
+ * get_str_value()
+ *
+ * FUNCTION:
+ * This function copies a string value from the specified buffer.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pBuf: input data buffer
+ * @param pValue: address where data is returned
+ * @param length: number of bytes to copy
+ *
+ * @return None
+ *
+ */
+static void get_str_value(uint8_t *pBuf, uint8_t *pValue, uint32_t length)
+{
+ uint8_t *pEnd;
+
+ pEnd = pValue + length;
+ while (pValue < pEnd)
+ *pValue++ = *pBuf++;
+} /*** end get_str_value() ***/
+
+/**---------------------------------------------------------------------
+ * process_cfg_download_req()
+ *
+ * FUNCTION: This function does the Cfg Download and is invoked
+ * only in the case of Prima or the Integrated SOC
+ * solutions. Not applicable to Volans or Libra
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac: Pointer to Mac Structure
+ *
+ * @return None
+ *
+ */
+
+void
+process_cfg_download_req(tpAniSirGlobal pMac)
+{
+ int32_t i;
+ uint32_t index;
+ uint8_t *pDstTest, *pSrcTest;
+ uint8_t len;
+ cfgstatic_string *pStrCfg;
+ uint32_t bufStart, bufEnd;
+ uint32_t logLevel, retVal;
+ uint32_t iCount = 0;
+ uint32_t sCount = 0;
+
+ for (i = 0; i < CFG_PARAM_MAX_NUM ; i++) {
+ if ((cfg_static[i].control & CFG_CTL_VALID) != 0) {
+ if (!(cfg_static[i].control & CFG_CTL_INT)) {
+ pStrCfg = (cfgstatic_string *)cfg_static[i].
+ pStrData;
+ if (pStrCfg == NULL) {
+ PELOGE(cfg_log(pMac, LOGE,
+ FL("pStrCfg is NULL for CfigID : %d"),
+ i);)
+ continue;
+ }
+ index = sCount & CFG_BUF_INDX_MASK;
+ sCount += pStrCfg->maxLen + 1 + 1;
+ } else {
+ index = iCount & CFG_BUF_INDX_MASK;
+ iCount++;
+ }
+ } else {
+ index = 0;
+ }
+ pMac->cfg.gCfgEntry[i].control = cfg_static[i].control | index;
+ }
+
+ /*Fill the SBUF wih maxLength*/
+ bufEnd = pMac->cfg.gCfgMaxSBufSize;
+ for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) {
+ if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0)
+ continue;
+
+ if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0)
+ continue;
+
+ bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK;
+ pMac->cfg.gCfgSBuf[bufStart] = (uint8_t)(bufEnd - bufStart - 2);
+
+ PELOG1(cfgLog(pMac, LOG1, FL("id %d max %d bufStart %d bufEnd %d"),
+ i, pMac->cfg.gCfgSBuf[bufStart],
+ bufStart, bufEnd);)
+ bufEnd = bufStart;
+ }
+
+ for (i = 0; i < CFG_PARAM_MAX_NUM ; i++) {
+ index = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK;
+
+ if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) {
+ pMac->cfg.gCfgIBufMin[index] = cfg_static[i].cfgIMin;
+ pMac->cfg.gCfgIBufMax[index] = cfg_static[i].cfgIMax;
+ pMac->cfg.gCfgIBuf[index] = cfg_static[i].cfgIVal;
+ } else {
+ uint8_t maxSavedLen;
+ if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0)
+ continue;
+ if (index >= CFG_STA_SBUF_MAX_SIZE)
+ continue;
+
+ pDstTest = &pMac->cfg.gCfgSBuf[index];
+ pStrCfg = (cfgstatic_string *)cfg_static[i].pStrData;
+ pSrcTest = pStrCfg->data;
+ if ((pDstTest == NULL) || (pStrCfg == NULL) ||
+ (pSrcTest == NULL))
+ continue;
+ maxSavedLen = *pDstTest;
+ len = pStrCfg->length;
+ if (len > maxSavedLen)
+ continue;
+ *pDstTest++ = pStrCfg->maxLen;
+ *pDstTest++ = len;
+ while (len) {
+ *pDstTest++ = *pSrcTest++;
+ len--;
+ }
+ }
+ }
+
+ /* Set the default log level based on config */
+ wlan_cfg_get_int(pMac, WNI_CFG_LOG_LEVEL, &logLevel);
+ for (i = 0; i < LOG_ENTRY_NUM; i++)
+ pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] =
+ logLevel;
+
+ /* Set status to READY */
+ pMac->cfg.gCfgStatus = CFG_SUCCESS;
+ retVal = WNI_CFG_SUCCESS;
+ PELOG1(cfg_log(pMac, LOG1, "<CFG> Completed successfully");)
+
+ pMac->cfg.gParamList[WNI_CFG_DNLD_CNF_RES] = retVal;
+
+} /*** end ProcessDownloadReq() ***/
diff --git a/core/mac/src/cfg/cfg_send_msg.c b/core/mac/src/cfg/cfg_send_msg.c
new file mode 100644
index 0000000..ebad7c7
--- /dev/null
+++ b/core/mac/src/cfg/cfg_send_msg.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file contains the source code for composing and sending messages
+ * to host.
+ *
+ * Author: Kevin Nguyen
+ * Date: 04/09/02
+ * History:-
+ * 04/09/02 Created.
+ * --------------------------------------------------------------------
+ */
+#include "cds_api.h"
+#include "cfg_priv.h"
+#include "lim_trace.h"
+#include "cfg_debug.h"
+
+/*--------------------------------------------------------------------*/
+/* ATTENTION: The functions contained in this module are to be used */
+/* by CFG module ONLY. */
+/*--------------------------------------------------------------------*/
+
+/**---------------------------------------------------------------------
+ * cfg_send_host_msg()
+ *
+ * FUNCTION:
+ * Send CNF/RSP to host.
+ *
+ * LOGIC:
+ * Please see Configuration & Statistic Collection Micro-Architecture
+ * specification for details.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param msgType: message type
+ * @param msgLen: message length
+ * @param paramNum: number of parameters
+ * @param pParamList: pointer to parameter list
+ * @param dataLen: data length
+ * @param pData: pointer to additional data
+ *
+ * @return None.
+ *
+ */
+void
+cfg_send_host_msg(tpAniSirGlobal pMac, uint16_t msgType, uint32_t msgLen,
+ uint32_t paramNum, uint32_t *pParamList, uint32_t dataLen,
+ uint32_t *pData)
+{
+ uint32_t *pMsg, *pEnd;
+ tSirMsgQ mmhMsg;
+
+ /* sanity */
+ if ((paramNum > 0) && (NULL == pParamList)) {
+ PELOGE(cfg_log(pMac, LOGE,
+ FL
+ ("pParamList NULL when paramNum greater than 0!"));
+ )
+ return;
+ }
+ if ((dataLen > 0) && (NULL == pData)) {
+ PELOGE(cfg_log(pMac, LOGE,
+ FL("pData NULL when dataLen greater than 0!"));
+ )
+ return;
+ }
+ /* Allocate message buffer */
+ pMsg = cdf_mem_malloc(msgLen);
+ if (NULL == pMsg) {
+ PELOGE(cfg_log(pMac, LOGE, FL("Memory allocation failure!"));)
+ return;
+ }
+ /* Fill in message details */
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pMsg;
+ mmhMsg.bodyval = 0;
+ ((tSirMbMsg *) pMsg)->type = msgType;
+ ((tSirMbMsg *) pMsg)->msgLen = (uint16_t) msgLen;
+
+ switch (msgType) {
+ case WNI_CFG_GET_RSP:
+ case WNI_CFG_PARAM_UPDATE_IND:
+ case WNI_CFG_DNLD_REQ:
+ case WNI_CFG_DNLD_CNF:
+ case WNI_CFG_SET_CNF:
+ /* Fill in parameters */
+ pMsg++;
+ if (NULL != pParamList) {
+ pEnd = pMsg + paramNum;
+ while (pMsg < pEnd) {
+ *pMsg++ = *pParamList++;
+ }
+ }
+ /* Copy data if there is any */
+ if (NULL != pData) {
+ pEnd = pMsg + (dataLen >> 2);
+ while (pMsg < pEnd) {
+ *pMsg++ = *pData++;
+ }
+ }
+ break;
+
+ default:
+ PELOGE(cfg_log(pMac, LOGE, FL("Unknown msg %d!"), (int)msgType);)
+ cdf_mem_free(pMsg);
+ return;
+ }
+
+ /* Ship it */
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ sys_process_mmh_msg(pMac, &mmhMsg);
+
+} /*** end cfg_send_host_msg() ***/
diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c
new file mode 100644
index 0000000..e1bbe39
--- /dev/null
+++ b/core/mac/src/dph/dph_hash_table.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file dph_hash_table.cc implements the member functions of
+ * DPH hash table class.
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+#include "dph_global.h"
+#include "lim_debug.h"
+
+#include "wma_if.h"
+
+/* --------------------------------------------------------------------- */
+/**
+ * dphHashTableClass()
+ *
+ * FUNCTION:
+ * Constructor function
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void dph_hash_table_class_init(tpAniSirGlobal pMac,
+ dphHashTableClass *pDphHashTable)
+{
+ uint16_t i;
+
+ for (i = 0; i < pDphHashTable->size; i++) {
+ pDphHashTable->pHashTable[i] = 0;
+ }
+
+ for (i = 0; i < pDphHashTable->size; i++) {
+ pDphHashTable->pDphNodeArray[i].valid = 0;
+ pDphHashTable->pDphNodeArray[i].added = 0;
+ pDphHashTable->pDphNodeArray[i].assocId = i;
+ }
+
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * hash_function
+ *
+ * FUNCTION:
+ * Hashing function
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @return None
+ */
+
+uint16_t hash_function(tpAniSirGlobal pMac, uint8_t staAddr[], uint16_t numSta)
+{
+ int i;
+ uint16_t sum = 0;
+
+ for (i = 0; i < 6; i++)
+ sum += staAddr[i];
+
+ return (sum % numSta);
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_lookup_hash_entry
+ *
+ * FUNCTION:
+ * Look up an entry in hash table
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @param pStaId pointer to the Station ID assigned to the station
+ * @return pointer to STA hash entry if lookup was a success \n
+ * NULL if lookup was a failure
+ */
+
+tpDphHashNode dph_lookup_hash_entry(tpAniSirGlobal pMac, uint8_t staAddr[],
+ uint16_t *pAssocId,
+ dphHashTableClass *pDphHashTable)
+{
+ tpDphHashNode ptr = NULL;
+ uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);
+
+ for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) {
+ if (dph_compare_mac_addr(staAddr, ptr->staAddr)) {
+ *pAssocId = ptr->assocId;
+ break;
+ }
+ }
+ return ptr;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_get_hash_entry
+ *
+ * FUNCTION:
+ * Get a pointer to the hash node
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staId Station ID
+ * @return pointer to STA hash entry if lookup was a success \n
+ * NULL if lookup was a failure
+ */
+
+tpDphHashNode dph_get_hash_entry(tpAniSirGlobal pMac, uint16_t peerIdx,
+ dphHashTableClass *pDphHashTable)
+{
+ if (peerIdx < pDphHashTable->size) {
+ if (pDphHashTable->pDphNodeArray[peerIdx].added)
+ return &pDphHashTable->pDphNodeArray[peerIdx];
+ else
+ return NULL;
+ } else
+ return NULL;
+
+}
+
+static inline tpDphHashNode get_node(tpAniSirGlobal pMac, uint8_t assocId,
+ dphHashTableClass *pDphHashTable)
+{
+ return &pDphHashTable->pDphNodeArray[assocId];
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_lookup_assoc_id
+ *
+ * FUNCTION:
+ * This function looks up assocID given the station Id. It traverses the complete table to do this.
+ * Need to find an efficient way to do this.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac pointer to global Mac structure.
+ * @param staIdx station ID
+ * @param *assocId pointer to associd to be returned by this function.
+ * @return pointer to the dph node.
+ */
+tpDphHashNode dph_lookup_assoc_id(tpAniSirGlobal pMac, uint16_t staIdx,
+ uint16_t *assocId,
+ dphHashTableClass *pDphHashTable)
+{
+ uint8_t i;
+
+ for (i = 0; i < pDphHashTable->size; i++) {
+ if ((pDphHashTable->pDphNodeArray[i].added) &&
+ (pDphHashTable->pDphNodeArray[i].staIndex == staIdx)) {
+ *assocId = i;
+ break;
+ }
+
+ }
+ if (i == pDphHashTable->size)
+ return NULL;
+ return &pDphHashTable->pDphNodeArray[i];
+
+}
+
+/** -------------------------------------------------------------
+ \fn dph_init_sta_state
+ \brief Initialize STA state. this function saves the staId from the current entry in the DPH table with given assocId
+ \ if validStaIdx flag is set. Otherwise it sets the staId to invalid.
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr staAddr
+ \param uint16_t assocId
+ \param uint8_t validStaIdx - true ==> the staId in the DPH entry with given assocId is valid and restore it back.
+ \ false ==> set the staId to invalid.
+ \return tpDphHashNode - DPH hash node if found.
+ -------------------------------------------------------------*/
+
+tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac, tSirMacAddr staAddr,
+ uint16_t assocId, uint8_t validStaIdx,
+ dphHashTableClass *pDphHashTable)
+{
+ uint32_t val;
+
+ tpDphHashNode pStaDs;
+ uint16_t staIdx = STA_INVALID_IDX;
+
+ if (assocId >= pDphHashTable->size) {
+ PELOGE(lim_log(pMac, LOGE, FL("Invalid Assoc Id %d"), assocId);)
+ return NULL;
+ }
+
+ pStaDs = get_node(pMac, (uint8_t) assocId, pDphHashTable);
+ staIdx = pStaDs->staIndex;
+
+ PELOG1(lim_log
+ (pMac, LOG1, FL("Assoc Id %d, Addr %08X"), assocId, pStaDs);
+ )
+ /* Clear the STA node except for the next pointer (last 4 bytes) */
+ cdf_mem_set((uint8_t *) pStaDs,
+ sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0);
+
+ /* Initialize the assocId */
+ pStaDs->assocId = assocId;
+ if (true == validStaIdx)
+ pStaDs->staIndex = staIdx;
+ else
+ pStaDs->staIndex = STA_INVALID_IDX;
+
+ /* Initialize STA mac address */
+ cdf_mem_copy(pStaDs->staAddr, staAddr, sizeof(tSirMacAddr));
+
+ /* Initialize fragmentation threshold */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, &val) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve fragmentation threshold"));
+ else
+ pStaDs->fragSize = (uint16_t) val;
+
+ pStaDs->added = 1;
+ pStaDs->encPolicy = ENC_POLICY_NULL;
+ pStaDs->is_disassoc_deauth_in_progress = 0;
+#ifdef WLAN_FEATURE_11W
+ pStaDs->last_assoc_received_time = 0;
+#endif
+ pStaDs->valid = 1;
+ return pStaDs;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_add_hash_entry
+ *
+ * FUNCTION:
+ * Add entry to hash table
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @param staId Station ID assigned to the station
+ * @return Pointer to STA hash entry
+ */
+
+tpDphHashNode dph_add_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
+ uint16_t assocId,
+ dphHashTableClass *pDphHashTable)
+{
+ tpDphHashNode ptr, node;
+ uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);
+
+ PELOG1(lim_log(pMac, LOG1, FL("assocId %d index %d STA addr"),
+ assocId, index); dph_print_mac_addr(pMac, staAddr, LOG1);
+ )
+
+ if (assocId >= pDphHashTable->size) {
+ PELOGE(lim_log(pMac, LOGE, FL("invalid STA id %d"), assocId);)
+ return NULL;
+ }
+
+ if (pDphHashTable->pDphNodeArray[assocId].added) {
+ PELOGE(lim_log(pMac, LOGE, FL("already added STA %d"), assocId);)
+ return NULL;
+ }
+
+ for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) {
+ if (ptr == ptr->next) {
+ PELOGE(lim_log(pMac, LOGE, FL("Infinite Loop"));)
+ return NULL;
+ }
+
+ if (dph_compare_mac_addr(staAddr, ptr->staAddr)
+ || ptr->assocId == assocId)
+ break;
+ }
+
+ if (ptr) {
+ /* Duplicate entry */
+ lim_log(pMac, LOGE, FL("assocId %d hashIndex %d entry exists"),
+ assocId, index);
+ return NULL;
+ } else {
+ if (dph_init_sta_state
+ (pMac, staAddr, assocId, false, pDphHashTable) == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not Init STAid=%d"),
+ assocId);
+ )
+ return NULL;
+ }
+ /* Add the node to the link list */
+ pDphHashTable->pDphNodeArray[assocId].next =
+ pDphHashTable->pHashTable[index];
+ pDphHashTable->pHashTable[index] =
+ &pDphHashTable->pDphNodeArray[assocId];
+
+ node = pDphHashTable->pHashTable[index];
+ return node;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_delete_hash_entry
+ *
+ * FUNCTION:
+ * Delete entry from hash table
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param staAddr MAC address of the station
+ * @param staId Station ID assigned to the station
+ * @return eSIR_SUCCESS if successful,\n
+ * eSIR_FAILURE otherwise
+ */
+
+tSirRetStatus dph_delete_hash_entry(tpAniSirGlobal pMac, tSirMacAddr staAddr,
+ uint16_t assocId,
+ dphHashTableClass *pDphHashTable)
+{
+ tpDphHashNode ptr, prev;
+ uint16_t index = hash_function(pMac, staAddr, pDphHashTable->size);
+
+ PELOG1(lim_log(pMac, LOG1, FL("assocId %d index %d STA addr"),
+ assocId, index); dph_print_mac_addr(pMac, staAddr, LOG1);
+ )
+
+ if (assocId >= pDphHashTable->size) {
+ PELOGE(lim_log(pMac, LOGE, FL("invalid STA id %d"), assocId);)
+ return eSIR_FAILURE;
+ }
+
+ if (pDphHashTable->pDphNodeArray[assocId].added == 0) {
+ PELOGE(lim_log(pMac, LOGE, FL("STA %d never added"), assocId);)
+ return eSIR_FAILURE;
+ }
+
+ for (prev = 0, ptr = pDphHashTable->pHashTable[index];
+ ptr; prev = ptr, ptr = ptr->next) {
+ if (dph_compare_mac_addr(staAddr, ptr->staAddr))
+ break;
+ if (prev == ptr) {
+ PELOGE(lim_log(pMac, LOGE, FL("Infinite Loop"));)
+ return eSIR_FAILURE;
+ }
+ }
+
+ if (ptr) {
+ /* / Delete the entry after invalidating it */
+ ptr->valid = 0;
+ memset(ptr->staAddr, 0, sizeof(ptr->staAddr));
+ if (prev == 0)
+ pDphHashTable->pHashTable[index] = ptr->next;
+ else
+ prev->next = ptr->next;
+ ptr->added = 0;
+ ptr->is_disassoc_deauth_in_progress = 0;
+#ifdef WLAN_FEATURE_11W
+ ptr->last_assoc_received_time = 0;
+#endif
+ ptr->next = 0;
+ } else {
+ /* / Entry not present */
+ PELOGE(lim_log(pMac, LOGE, FL("Entry not present STA addr"));
+ dph_print_mac_addr(pMac, staAddr, LOGE);
+ )
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * dph_print_mac_addr
+ *
+ * FUNCTION:
+ * Print a MAC address
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param addr MAC address
+ * @return None
+ */
+
+void dph_print_mac_addr(tpAniSirGlobal pMac, uint8_t addr[], uint32_t level)
+{
+ lim_log(pMac, (uint16_t) level, FL("MAC ADDR = %d:%d:%d:%d:%d:%d"),
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+}
+
+/* --------------------------------------------------------------------- */
+
+
diff --git a/core/mac/src/dph/dph_hash_table.h b/core/mac/src/dph/dph_hash_table.h
new file mode 100644
index 0000000..1a55f58
--- /dev/null
+++ b/core/mac/src/dph/dph_hash_table.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file dph_hash_table.h contains the definition of the scheduler class.
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __DPH_HASH_TABLE_H__
+#define __DPH_HASH_TABLE_H__
+
+#include "ani_global.h"
+/* Compare MAC addresses, return true if same */
+static inline uint8_t dph_compare_mac_addr(uint8_t addr1[], uint8_t addr2[])
+{
+ return (addr1[0] == addr2[0]) &&
+ (addr1[1] == addr2[1]) &&
+ (addr1[2] == addr2[2]) &&
+ (addr1[3] == addr2[3]) &&
+ (addr1[4] == addr2[4]) && (addr1[5] == addr2[5]);
+}
+
+/* Hash table class */
+typedef struct {
+
+ /* The hash table itself */
+ tpDphHashNode *pHashTable;
+
+ /* The state array */
+ tDphHashNode *pDphNodeArray;
+ uint16_t size;
+} dphHashTableClass;
+
+/* The hash table object */
+extern dphHashTableClass dphHashTable;
+
+/* Print MAC addresse */
+extern void dph_print_mac_addr(struct sAniSirGlobal *pMac, uint8_t addr[],
+ uint32_t);
+
+tpDphHashNode dph_lookup_hash_entry(tpAniSirGlobal pMac, uint8_t staAddr[],
+ uint16_t *pStaId,
+ dphHashTableClass *pDphHashTable);
+tpDphHashNode dph_lookup_assoc_id(tpAniSirGlobal pMac, uint16_t staIdx,
+ uint16_t *assocId,
+ dphHashTableClass *pDphHashTable);
+
+/* Get a pointer to the hash node */
+extern tpDphHashNode dph_get_hash_entry(tpAniSirGlobal pMac, uint16_t staId,
+ dphHashTableClass *pDphHashTable);
+
+/* Add an entry to the hash table */
+extern tpDphHashNode dph_add_hash_entry(tpAniSirGlobal pMac,
+ tSirMacAddr staAddr,
+ uint16_t staId,
+ dphHashTableClass *pDphHashTable);
+
+/* Delete an entry from the hash table */
+extern tSirRetStatus dph_delete_hash_entry(tpAniSirGlobal pMac,
+ tSirMacAddr staAddr, uint16_t staId,
+ dphHashTableClass *pDphHashTable);
+
+void dph_hash_table_class_init(tpAniSirGlobal pMac,
+ dphHashTableClass *pDphHashTable);
+/* Initialize STA state */
+extern tpDphHashNode dph_init_sta_state(tpAniSirGlobal pMac,
+ tSirMacAddr staAddr,
+ uint16_t staId, uint8_t validStaIdx,
+ dphHashTableClass *pDphHashTable);
+
+#endif
diff --git a/core/mac/src/include/cfg_api.h b/core/mac/src/include/cfg_api.h
new file mode 100644
index 0000000..e165d5a
--- /dev/null
+++ b/core/mac/src/include/cfg_api.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2011-2012,2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Author: Kevin Nguyen
+ * Date: 04/09/02
+ * History:-
+ * 04/09/02 Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGAPI_H
+#define __CFGAPI_H
+
+#include <sir_common.h>
+#include <sir_params.h>
+#include <sir_mac_prot_def.h>
+#include <wni_api.h>
+#include <ani_global.h>
+
+/*---------------------------------------------------------------------*/
+/* CFG definitions */
+/*---------------------------------------------------------------------*/
+
+/* CFG status */
+typedef enum eCfgStatusTypes {
+ CFG_INCOMPLETE,
+ CFG_SUCCESS,
+ CFG_FAILURE
+} tCfgStatusTypes;
+
+/* WEP key mapping table row structure */
+typedef struct {
+ uint8_t keyMappingAddr[CDF_MAC_ADDR_SIZE];
+ uint32_t wepOn;
+ uint8_t key[SIR_MAC_KEY_LENGTH];
+ uint32_t status;
+} tCfgWepKeyEntry;
+
+/*---------------------------------------------------------------------*/
+/* CFG function prototypes */
+/*---------------------------------------------------------------------*/
+
+uint32_t cfg_need_restart(tpAniSirGlobal pMac, uint16_t cfgId);
+uint32_t cfg_need_reload(tpAniSirGlobal pMac, uint16_t cfgId);
+
+/* / Process host message */
+void cfg_process_mb_msg(tpAniSirGlobal, tSirMbMsg *);
+
+/* / Set integer parameter value */
+tSirRetStatus cfg_set_int(tpAniSirGlobal, uint16_t, uint32_t);
+
+/* / Check if the parameter is valid */
+tSirRetStatus cfg_check_valid(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Get integer parameter value */
+tSirRetStatus wlan_cfg_get_int(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Set string parameter value */
+tSirRetStatus cfg_set_str(tpAniSirGlobal, uint16_t, uint8_t *, uint32_t);
+
+tSirRetStatus cfg_set_str_notify(tpAniSirGlobal, uint16_t, uint8_t *, uint32_t,
+ int);
+
+/* Cfg Download function for Prima or Integrated solutions. */
+void process_cfg_download_req(tpAniSirGlobal);
+
+/* / Get string parameter value */
+tSirRetStatus wlan_cfg_get_str(tpAniSirGlobal, uint16_t, uint8_t *, uint32_t *);
+
+/* / Get string parameter maximum length */
+tSirRetStatus wlan_cfg_get_str_max_len(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Get string parameter maximum length */
+tSirRetStatus wlan_cfg_get_str_len(tpAniSirGlobal, uint16_t, uint32_t *);
+
+/* / Get the regulatory tx power on given channel */
+tPowerdBm cfg_get_regulatory_max_transmit_power(tpAniSirGlobal pMac,
+ uint8_t channel);
+
+/* / Dump CFG data to memory */
+void cfgDump(uint32_t *);
+
+/* / Save parameters with P flag set */
+void cfgSave(void);
+
+/* / Get capability info */
+extern tSirRetStatus cfg_get_capability_info(tpAniSirGlobal pMac, uint16_t *pCap,
+ tpPESession psessionEntry);
+
+/* / Set capability info */
+extern void cfg_set_capability_info(tpAniSirGlobal, uint16_t);
+
+/* / Cleanup CFG module */
+void cfg_cleanup(tpAniSirGlobal pMac);
+
+extern uint8_t *g_cfg_param_name[];
+
+uint8_t *cfg_get_vendor_ie_ptr_from_oui(tpAniSirGlobal mac_ctx,
+ uint8_t *oui,
+ uint8_t oui_size,
+ uint8_t *ie,
+ uint16_t ie_len);
+
+#endif /* __CFGAPI_H */
diff --git a/core/mac/src/include/cfg_global.h b/core/mac/src/include/cfg_global.h
new file mode 100644
index 0000000..8678f27
--- /dev/null
+++ b/core/mac/src/include/cfg_global.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Author: Sandesh Goel
+ * Date: 02/09/03
+ * History:-
+ * 04/09/02 Created.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __CFGGLOBAL_H
+#define __CFGGLOBAL_H
+
+#include "sir_common.h"
+#include "sir_types.h"
+#include "wni_cfg.h"
+
+#define CFG_MAX_NUM_STA SIR_MAX_NUM_STA_IN_IBSS
+
+#define CFG_MAX_STATIC_STRING 70
+/* as the number of channels grows, 128 is not big enough */
+#define CFG_MAX_STR_LEN 256
+
+/*--------------------------------------------------------------------*/
+/* Configuration Control Structure */
+/*--------------------------------------------------------------------*/
+typedef struct {
+ uint32_t control;
+} tCfgCtl;
+
+
+typedef struct sAniSirCfgStaticString {
+ uint16_t cfgId;
+ uint8_t maxLen;
+ uint8_t length;
+ uint8_t data[255];
+} cfgstatic_string;
+
+typedef struct sAniSirCfgStatic {
+ uint16_t cfgId;
+ uint32_t control;
+ uint32_t cfgIMin;
+ uint32_t cfgIMax;
+ uint32_t cfgIVal;
+ void *pStrData;
+} cgstatic;
+
+typedef struct sAniSirCfg {
+ /* CFG module status */
+ uint8_t gCfgStatus;
+
+ tCfgCtl *gCfgEntry;
+ uint32_t *gCfgIBufMin;
+ uint32_t *gCfgIBufMax;
+ uint32_t *gCfgIBuf;
+ uint8_t *gCfgSBuf;
+
+ uint16_t gCfgMaxIBufSize;
+ uint16_t gCfgMaxSBufSize;
+
+ /* Static buffer for string parameter (must be word-aligned) */
+ uint8_t *gSBuffer;
+
+ /* Message param list buffer (enough for largest possible response) */
+ uint32_t *gParamList;
+} tAniSirCfg, *tpAniSirCfg;
+
+#endif
diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h
new file mode 100644
index 0000000..0258abd
--- /dev/null
+++ b/core/mac/src/include/dot11f.h
@@ -0,0 +1,8920 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef DOT11F_H
+#define DOT11F_H
+/*
+ * \file dot11f.h
+ *
+ * \brief Structures, function prototypes & definitions
+ * for working with 802.11 Frames
+ *
+ *
+ * This file was automatically generated by 'framesc'
+ * Wed Oct 14 10:14:42 2015 from the following file(s):
+ *
+ * dot11f.frms
+ *
+ * PLEASE DON'T EDIT THIS FILE BY HAND!
+ *
+ * Instead, please update the input files & re-run
+ * 'framesc' For more information on 'framesc' & the
+ * frames language, run 'framesc --help'.
+ *
+ */
+
+typedef uint32_t tDOT11F_U64[2];
+
+#if defined (_MSC_VER)
+#pragma warning (disable:4214) /* nonstandard extension used */
+#endif /* Microsoft C/C++ bit field types other than int */
+
+/*
+ * Frames Return Codes:
+ *
+ * Success is indicated by a return value of zero. Failure is indicated
+ * by the presence of the high bit. Warnings encountered in the course
+ * of a successful parse are indicated by various bits in the lower 31
+ * being turned on.
+ *
+ * For instance, a return value of 0x0000000a would indicate that the
+ * parse succeeded, but that a mandatory IE wasn't present, and some IE
+ * was found to be corrupt.
+ *
+ *
+ */
+
+#define DOT11F_PARSE_SUCCESS (0x00000000)
+#define DOT11F_UNKNOWN_IES (0x00000001)
+#define DOT11F_MANDATORY_IE_MISSING (0x00000002)
+#define DOT11F_INCOMPLETE_IE (0x00000004)
+#define DOT11F_SKIPPED_BAD_IE (0x00000008)
+#define DOT11F_LAST_IE_TOO_LONG (0x00000010)
+#define DOT11F_DUPLICATE_IE (0x00000020)
+#define DOT11F_BAD_FIXED_VALUE (0x00000040)
+#define DOT11F_INCOMPLETE_TLV (0x00000080)
+#define DOT11F_INVALID_TLV_LENGTH (0x00000100)
+#define DOT11F_SKIPPED_BAD_TLV (0x00000200)
+#define DOT11F_UNKNOWN_TLVS (0x00000400)
+#define DOT11F_LAST_TLV_TOO_LONG (0x00000800)
+#define DOT11F_INTERNAL_ERROR (0x10000001)
+#define DOT11F_MISSING_FIXED_FIELD (0x10000002)
+#define DOT11F_BAD_INPUT_BUFFER (0x10000003)
+#define DOT11F_BAD_OUTPUT_BUFFER (0x10000004)
+#define DOT11F_BUFFER_OVERFLOW (0x10000005)
+#define DOT11F_MANDATORY_TLV_MISSING (0x00001000)
+#define DOT11F_FAILED(code) ((code) & 0x10000000)
+#define DOT11F_WARNED(code) (((0 == (code)) & 0x10000000) && code)
+#define DOT11F_SUCCEEDED(code) ((code) == 0)
+
+/*********************************************************************
+ * Fixed Fields *
+ ********************************************************************/
+
+typedef struct sDot11fFfAID {
+ uint16_t associd;
+} tDot11fFfAID;
+
+#define DOT11F_FF_AID_LEN (2)
+
+void dot11f_unpack_ff_AID(tpAniSirGlobal, uint8_t *, tDot11fFfAID *);
+
+void dot11f_pack_ff_aid(tpAniSirGlobal, tDot11fFfAID *, uint8_t *);
+
+typedef struct sDot11fFfAction {
+ uint8_t action;
+} tDot11fFfAction;
+
+#define DOT11F_FF_ACTION_LEN (1)
+
+void dot11f_unpack_ff_action(tpAniSirGlobal, uint8_t *, tDot11fFfAction *);
+
+void dot11f_pack_ff_action(tpAniSirGlobal, tDot11fFfAction *, uint8_t *);
+
+typedef struct sDot11fFfAuthAlgo {
+ uint16_t algo;
+} tDot11fFfAuthAlgo;
+
+#define DOT11F_FF_AUTHALGO_LEN (2)
+
+void dot11f_unpack_ff_AuthAlgo(tpAniSirGlobal, uint8_t *,
+ tDot11fFfAuthAlgo *);
+
+void dot11f_pack_ff_auth_algo(tpAniSirGlobal, tDot11fFfAuthAlgo *, uint8_t *);
+
+typedef struct sDot11fFfAuthSeqNo {
+ uint16_t no;
+} tDot11fFfAuthSeqNo;
+
+#define DOT11F_FF_AUTHSEQNO_LEN (2)
+
+void dot11f_unpack_ff_AuthSeqNo(tpAniSirGlobal, uint8_t *,
+ tDot11fFfAuthSeqNo *);
+
+void dot11f_pack_ff_auth_seq_no(tpAniSirGlobal, tDot11fFfAuthSeqNo *,
+ uint8_t *);
+
+typedef struct sDot11fFfBeaconInterval {
+ uint16_t interval;
+} tDot11fFfBeaconInterval;
+
+#define DOT11F_FF_BEACONINTERVAL_LEN (2)
+
+void dot11f_unpack_ff_BeaconInterval(tpAniSirGlobal, uint8_t *,
+ tDot11fFfBeaconInterval *);
+
+void dot11f_pack_ff_beacon_interval(tpAniSirGlobal, tDot11fFfBeaconInterval *,
+ uint8_t *);
+
+typedef struct sDot11fFfCapabilities {
+ uint16_t ess:1;
+ uint16_t ibss:1;
+ uint16_t cfPollable:1;
+ uint16_t cfPollReq:1;
+ uint16_t privacy:1;
+ uint16_t shortPreamble:1;
+ uint16_t pbcc:1;
+ uint16_t channelAgility:1;
+ uint16_t spectrumMgt:1;
+ uint16_t qos:1;
+ uint16_t shortSlotTime:1;
+ uint16_t apsd:1;
+ uint16_t rrm:1;
+ uint16_t dsssOfdm:1;
+ uint16_t delayedBA:1;
+ uint16_t immediateBA:1;
+} tDot11fFfCapabilities;
+
+#define DOT11F_FF_CAPABILITIES_LEN (2)
+
+void dot11f_unpack_ff_capabilities(tpAniSirGlobal, uint8_t *,
+ tDot11fFfCapabilities *);
+
+void dot11f_pack_ff_capabilities(tpAniSirGlobal, tDot11fFfCapabilities *,
+ uint8_t *);
+
+#define CAPABILITIES_ESS_OFFSET 0
+#define CAPABILITIES_ESS_WIDTH 1
+#define CAPABILITIES_IBSS_OFFSET 1
+#define CAPABILITIES_IBSS_WIDTH 1
+#define CAPABILITIES_CFPOLLABLE_OFFSET 2
+#define CAPABILITIES_CFPOLLABLE_WIDTH 1
+#define CAPABILITIES_CFPOLLREQ_OFFSET 3
+#define CAPABILITIES_CFPOLLREQ_WIDTH 1
+#define CAPABILITIES_PRIVACY_OFFSET 4
+#define CAPABILITIES_PRIVACY_WIDTH 1
+#define CAPABILITIES_SHORTPREAMBLE_OFFSET 5
+#define CAPABILITIES_SHORTPREAMBLE_WIDTH 1
+#define CAPABILITIES_PBCC_OFFSET 6
+#define CAPABILITIES_PBCC_WIDTH 1
+#define CAPABILITIES_CHANNELAGILITY_OFFSET 7
+#define CAPABILITIES_CHANNELAGILITY_WIDTH 1
+#define CAPABILITIES_SPECTRUMMGT_OFFSET 8
+#define CAPABILITIES_SPECTRUMMGT_WIDTH 1
+#define CAPABILITIES_QOS_OFFSET 9
+#define CAPABILITIES_QOS_WIDTH 1
+#define CAPABILITIES_SHORTSLOTTIME_OFFSET 10
+#define CAPABILITIES_SHORTSLOTTIME_WIDTH 1
+#define CAPABILITIES_APSD_OFFSET 11
+#define CAPABILITIES_APSD_WIDTH 1
+#define CAPABILITIES_RRM_OFFSET 12
+#define CAPABILITIES_RRM_WIDTH 1
+#define CAPABILITIES_DSSSOFDM_OFFSET 13
+#define CAPABILITIES_DSSSOFDM_WIDTH 1
+#define CAPABILITIES_DELAYEDBA_OFFSET 14
+#define CAPABILITIES_DELAYEDBA_WIDTH 1
+#define CAPABILITIES_IMMEDIATEBA_OFFSET 15
+#define CAPABILITIES_IMMEDIATEBA_WIDTH 1
+
+typedef struct sDot11fFfCategory {
+ uint8_t category;
+} tDot11fFfCategory;
+
+#define DOT11F_FF_CATEGORY_LEN (1)
+
+void dot11f_unpack_ff_category(tpAniSirGlobal, uint8_t *,
+ tDot11fFfCategory *);
+
+void dot11f_pack_ff_category(tpAniSirGlobal, tDot11fFfCategory *, uint8_t *);
+
+typedef struct sDot11fFfCurrentAPAddress {
+ uint8_t mac[6];
+} tDot11fFfCurrentAPAddress;
+
+#define DOT11F_FF_CURRENTAPADDRESS_LEN (6)
+
+void dot11f_unpack_ff_current_ap_address(tpAniSirGlobal, uint8_t *,
+ tDot11fFfCurrentAPAddress *);
+
+void dot11f_pack_ff_current_ap_address(tpAniSirGlobal,
+ tDot11fFfCurrentAPAddress *,
+ uint8_t *);
+
+
+typedef struct sDot11fFfDialogToken {
+ uint8_t token;
+} tDot11fFfDialogToken;
+
+#define DOT11F_FF_DIALOGTOKEN_LEN (1)
+
+void dot11f_unpack_ff_dialog_token(tpAniSirGlobal, uint8_t *,
+ tDot11fFfDialogToken *);
+
+void dot11f_pack_ff_dialog_token(tpAniSirGlobal, tDot11fFfDialogToken *,
+ uint8_t *);
+
+typedef struct sDot11fFfLinkMargin {
+ uint8_t linkMargin;
+} tDot11fFfLinkMargin;
+
+#define DOT11F_FF_LINKMARGIN_LEN (1)
+
+void dot11f_unpack_ff_link_margin(tpAniSirGlobal, uint8_t *,
+ tDot11fFfLinkMargin *);
+
+void dot11f_pack_ff_link_margin(tpAniSirGlobal, tDot11fFfLinkMargin *,
+ uint8_t *);
+
+typedef struct sDot11fFfListenInterval {
+ uint16_t interval;
+} tDot11fFfListenInterval;
+
+#define DOT11F_FF_LISTENINTERVAL_LEN (2)
+
+void dot11f_unpack_ff_ListenInterval(tpAniSirGlobal, uint8_t *,
+ tDot11fFfListenInterval *);
+
+void dot11f_pack_ff_listen_interval(tpAniSirGlobal, tDot11fFfListenInterval *,
+ uint8_t *);
+
+typedef struct sDot11fFfMaxTxPower {
+ uint8_t maxTxPower;
+} tDot11fFfMaxTxPower;
+
+#define DOT11F_FF_MAXTXPOWER_LEN (1)
+
+void dot11f_unpack_ff_max_tx_power(tpAniSirGlobal, uint8_t *,
+ tDot11fFfMaxTxPower *);
+
+void dot11f_pack_ff_max_tx_power(tpAniSirGlobal, tDot11fFfMaxTxPower *,
+ uint8_t *);
+
+typedef struct sDot11fFfNumOfRepetitions {
+ uint16_t repetitions;
+} tDot11fFfNumOfRepetitions;
+
+#define DOT11F_FF_NUMOFREPETITIONS_LEN (2)
+
+void dot11f_unpack_ff_num_of_repetitions(tpAniSirGlobal, uint8_t *,
+ tDot11fFfNumOfRepetitions *);
+
+void dot11f_pack_ff_num_of_repetitions(tpAniSirGlobal,
+ tDot11fFfNumOfRepetitions *,
+ uint8_t *);
+
+
+typedef struct sDot11fFfOperatingMode {
+ uint8_t chanWidth:2;
+ uint8_t reserved:2;
+ uint8_t rxNSS:3;
+ uint8_t rxNSSType:1;
+} tDot11fFfOperatingMode;
+
+#define DOT11F_FF_OPERATINGMODE_LEN (1)
+
+void dot11f_unpack_ff_operating_mode(tpAniSirGlobal, uint8_t *,
+ tDot11fFfOperatingMode *);
+
+void dot11f_pack_ff_operating_mode(tpAniSirGlobal, tDot11fFfOperatingMode *,
+ uint8_t *);
+
+#define OPERATINGMODE_CHANWIDTH_OFFSET 0
+#define OPERATINGMODE_CHANWIDTH_WIDTH 2
+#define OPERATINGMODE_RESERVED_OFFSET 2
+#define OPERATINGMODE_RESERVED_WIDTH 2
+#define OPERATINGMODE_RXNSS_OFFSET 4
+#define OPERATINGMODE_RXNSS_WIDTH 3
+#define OPERATINGMODE_RXNSSTYPE_OFFSET 7
+#define OPERATINGMODE_RXNSSTYPE_WIDTH 1
+
+typedef struct sDot11fFfRCPI {
+ uint8_t rcpi;
+} tDot11fFfRCPI;
+
+#define DOT11F_FF_RCPI_LEN (1)
+
+void dot11f_unpack_ff_rcpi(tpAniSirGlobal, uint8_t *, tDot11fFfRCPI *);
+
+void dot11f_pack_ff_rcpi(tpAniSirGlobal, tDot11fFfRCPI *, uint8_t *);
+
+typedef struct sDot11fFfRSNI {
+ uint8_t rsni;
+} tDot11fFfRSNI;
+
+#define DOT11F_FF_RSNI_LEN (1)
+
+void dot11f_unpack_ff_rsni(tpAniSirGlobal, uint8_t *, tDot11fFfRSNI *);
+
+void dot11f_pack_ff_rsni(tpAniSirGlobal, tDot11fFfRSNI *, uint8_t *);
+
+typedef struct sDot11fFfReason {
+ uint16_t code;
+} tDot11fFfReason;
+
+#define DOT11F_FF_REASON_LEN (2)
+
+void dot11f_unpack_ff_Reason(tpAniSirGlobal, uint8_t *, tDot11fFfReason *);
+
+void dot11f_pack_ff_reason(tpAniSirGlobal, tDot11fFfReason *, uint8_t *);
+
+typedef struct sDot11fFfRxAntennaId {
+ uint8_t antennaId;
+} tDot11fFfRxAntennaId;
+
+#define DOT11F_FF_RXANTENNAID_LEN (1)
+
+void dot11f_unpack_ff_rx_antenna_id(tpAniSirGlobal, uint8_t *,
+ tDot11fFfRxAntennaId *);
+
+void dot11f_pack_ff_rx_antenna_id(tpAniSirGlobal, tDot11fFfRxAntennaId *,
+ uint8_t *);
+
+typedef struct sDot11fFfSMPowerModeSet {
+ uint8_t PowerSave_En:1;
+ uint8_t Mode:1;
+ uint8_t reserved:6;
+} tDot11fFfSMPowerModeSet;
+
+#define DOT11F_FF_SMPOWERMODESET_LEN (1)
+
+void dot11f_unpack_ff_sm_power_mode_set(tpAniSirGlobal, uint8_t *,
+ tDot11fFfSMPowerModeSet *);
+
+void dot11f_pack_ff_sm_power_mode_set(tpAniSirGlobal, tDot11fFfSMPowerModeSet *,
+ uint8_t *);
+
+#define SMPOWERMODESET_POWERSAVE_EN_OFFSET 0
+#define SMPOWERMODESET_POWERSAVE_EN_WIDTH 1
+#define SMPOWERMODESET_MODE_OFFSET 1
+#define SMPOWERMODESET_MODE_WIDTH 1
+#define SMPOWERMODESET_RESERVED_OFFSET 2
+#define SMPOWERMODESET_RESERVED_WIDTH 6
+
+typedef struct sDot11fFfStatus {
+ uint16_t status;
+} tDot11fFfStatus;
+
+#define DOT11F_FF_STATUS_LEN (2)
+
+void dot11f_unpack_ff_Status(tpAniSirGlobal, uint8_t *, tDot11fFfStatus *);
+
+void dot11f_pack_ff_status(tpAniSirGlobal, tDot11fFfStatus *, uint8_t *);
+
+typedef struct sDot11fFfStatusCode {
+ uint8_t statusCode;
+} tDot11fFfStatusCode;
+
+#define DOT11F_FF_STATUSCODE_LEN (1)
+
+void dot11f_unpack_ff_status_code(tpAniSirGlobal, uint8_t *,
+ tDot11fFfStatusCode *);
+
+void dot11f_pack_ff_status_code(tpAniSirGlobal, tDot11fFfStatusCode *,
+ uint8_t *);
+
+typedef struct sDot11fFfTPCEleID {
+ uint8_t TPCId;
+} tDot11fFfTPCEleID;
+
+#define DOT11F_FF_TPCELEID_LEN (1)
+
+void dot11f_unpack_ff_tpc_ele_id(tpAniSirGlobal, uint8_t *,
+ tDot11fFfTPCEleID *);
+
+void dot11f_pack_ff_tpc_ele_id(tpAniSirGlobal, tDot11fFfTPCEleID *, uint8_t *);
+
+typedef struct sDot11fFfTPCEleLen {
+ uint8_t TPCLen;
+} tDot11fFfTPCEleLen;
+
+#define DOT11F_FF_TPCELELEN_LEN (1)
+
+void dot11f_unpack_ff_tpc_ele_len(tpAniSirGlobal, uint8_t *,
+ tDot11fFfTPCEleLen *);
+
+void dot11f_pack_ff_tpc_ele_len(tpAniSirGlobal, tDot11fFfTPCEleLen *,
+ uint8_t *);
+
+typedef struct sDot11fFfTSInfo {
+ uint32_t traffic_type:1;
+ uint32_t tsid:4;
+ uint32_t direction:2;
+ uint32_t access_policy:2;
+ uint32_t aggregation:1;
+ uint32_t psb:1;
+ uint32_t user_priority:3;
+ uint32_t tsinfo_ack_pol:2;
+ uint32_t schedule:1;
+ uint32_t unused:15;
+} tDot11fFfTSInfo;
+
+#define DOT11F_FF_TSINFO_LEN (3)
+
+void dot11f_unpack_ff_ts_info(tpAniSirGlobal, uint8_t *, tDot11fFfTSInfo *);
+
+void dot11f_pack_ff_ts_info(tpAniSirGlobal, tDot11fFfTSInfo *, uint8_t *);
+
+#define TSINFO_TRAFFIC_TYPE_OFFSET 0
+#define TSINFO_TRAFFIC_TYPE_WIDTH 1
+#define TSINFO_TSID_OFFSET 1
+#define TSINFO_TSID_WIDTH 4
+#define TSINFO_DIRECTION_OFFSET 5
+#define TSINFO_DIRECTION_WIDTH 2
+#define TSINFO_ACCESS_POLICY_OFFSET 7
+#define TSINFO_ACCESS_POLICY_WIDTH 2
+#define TSINFO_AGGREGATION_OFFSET 9
+#define TSINFO_AGGREGATION_WIDTH 1
+#define TSINFO_PSB_OFFSET 10
+#define TSINFO_PSB_WIDTH 1
+#define TSINFO_USER_PRIORITY_OFFSET 11
+#define TSINFO_USER_PRIORITY_WIDTH 3
+#define TSINFO_TSINFO_ACK_POL_OFFSET 14
+#define TSINFO_TSINFO_ACK_POL_WIDTH 2
+#define TSINFO_SCHEDULE_OFFSET 16
+#define TSINFO_SCHEDULE_WIDTH 1
+#define TSINFO_UNUSED_OFFSET 17
+#define TSINFO_UNUSED_WIDTH 15
+
+typedef struct sDot11fFfTimeStamp {
+ tDOT11F_U64 timestamp;
+} tDot11fFfTimeStamp;
+
+#define DOT11F_FF_TIMESTAMP_LEN (8)
+
+void dot11f_unpack_ff_time_stamp(tpAniSirGlobal, uint8_t *,
+ tDot11fFfTimeStamp *);
+
+void dot11f_pack_ff_time_stamp(tpAniSirGlobal, tDot11fFfTimeStamp *,
+ uint8_t *);
+
+typedef struct sDot11fFfTransactionId {
+ uint8_t transId[2];
+} tDot11fFfTransactionId;
+
+#define DOT11F_FF_TRANSACTIONID_LEN (2)
+
+void dot11f_unpack_ff_transaction_id(tpAniSirGlobal, uint8_t *,
+ tDot11fFfTransactionId *);
+
+void dot11f_pack_ff_transaction_id(tpAniSirGlobal, tDot11fFfTransactionId *,
+ uint8_t *);
+
+typedef struct sDot11fFfTxAntennaId {
+ uint8_t antennaId;
+} tDot11fFfTxAntennaId;
+
+#define DOT11F_FF_TXANTENNAID_LEN (1)
+
+void dot11f_unpack_ff_tx_antenna_id(tpAniSirGlobal, uint8_t *,
+ tDot11fFfTxAntennaId *);
+
+void dot11f_pack_ff_tx_antenna_id(tpAniSirGlobal, tDot11fFfTxAntennaId *,
+ uint8_t *);
+
+typedef struct sDot11fFfTxPower {
+ uint8_t txPower;
+} tDot11fFfTxPower;
+
+#define DOT11F_FF_TXPOWER_LEN (1)
+
+void dot11f_unpack_ff_tx_power(tpAniSirGlobal, uint8_t *,
+ tDot11fFfTxPower *);
+
+void dot11f_pack_ff_tx_power(tpAniSirGlobal, tDot11fFfTxPower *, uint8_t *);
+
+typedef struct sDot11fFfVhtMembershipStatusArray {
+ uint8_t membershipStatusArray[8];
+} tDot11fFfVhtMembershipStatusArray;
+
+#define DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN (8)
+
+void dot11f_unpack_ff_vht_membership_status_array(tpAniSirGlobal, uint8_t *,
+ tDot11fFfVhtMembershipStatusArray *);
+
+void dot11f_pack_ff_vht_membership_status_array(tpAniSirGlobal,
+ tDot11fFfVhtMembershipStatusArray *,
+ uint8_t *);
+
+
+typedef struct sDot11fFfVhtUserPositionArray {
+ uint8_t userPositionArray[16];
+} tDot11fFfVhtUserPositionArray;
+
+#define DOT11F_FF_VHTUSERPOSITIONARRAY_LEN (16)
+
+void dot11f_unpack_ff_vht_user_position_array(tpAniSirGlobal, uint8_t *,
+ tDot11fFfVhtUserPositionArray *);
+
+void dot11f_pack_ff_vht_user_position_array(tpAniSirGlobal,
+ tDot11fFfVhtUserPositionArray *,
+ uint8_t *);
+
+
+/*********************************************************************
+ * TLVs *
+ ********************************************************************/
+
+
+/* ID 1 (0x0001) */
+typedef struct sDot11fTLVAuthorizedMACs {
+ uint8_t present;
+ uint8_t mac[6];
+} tDot11fTLVAuthorizedMACs;
+
+#define DOT11F_TLV_AUTHORIZEDMACS (1)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_AUTHORIZEDMACS_MIN_LEN (6)
+
+#define DOT11F_TLV_AUTHORIZEDMACS_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_authorized_ma_cs(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVAuthorizedMACs*);
+
+uint32_t dot11f_pack_tlv_authorized_ma_cs(
+ tpAniSirGlobal,
+ tDot11fTLVAuthorizedMACs *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_AuthorizedMACs(
+ tpAniSirGlobal,
+ tDot11fTLVAuthorizedMACs *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 3 (0x0003) */
+typedef struct sDot11fTLVRequestToEnroll {
+ uint8_t present;
+ uint8_t req;
+} tDot11fTLVRequestToEnroll;
+
+#define DOT11F_TLV_REQUESTTOENROLL (3)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REQUESTTOENROLL_MIN_LEN (1)
+
+#define DOT11F_TLV_REQUESTTOENROLL_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_RequestToEnroll(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVRequestToEnroll*);
+
+uint32_t dot11f_pack_tlv_request_to_enroll(
+ tpAniSirGlobal,
+ tDot11fTLVRequestToEnroll *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RequestToEnroll(
+ tpAniSirGlobal,
+ tDot11fTLVRequestToEnroll *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 0 (0x0000) */
+typedef struct sDot11fTLVVersion2 {
+ uint8_t present;
+ uint8_t minor:4;
+ uint8_t major:4;
+} tDot11fTLVVersion2;
+
+#define DOT11F_TLV_VERSION2 (0)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_VERSION2_MIN_LEN (1)
+
+#define DOT11F_TLV_VERSION2_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_version2(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVVersion2*);
+
+uint32_t dot11f_pack_tlv_version2(
+ tpAniSirGlobal,
+ tDot11fTLVVersion2 *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_Version2(
+ tpAniSirGlobal,
+ tDot11fTLVVersion2 *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4183 (0x1057) */
+typedef struct sDot11fTLVAPSetupLocked {
+ uint8_t present;
+ uint8_t fLocked;
+} tDot11fTLVAPSetupLocked;
+
+#define DOT11F_TLV_APSETUPLOCKED (4183)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_APSETUPLOCKED_MIN_LEN (3)
+
+#define DOT11F_TLV_APSETUPLOCKED_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_APSetupLocked(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVAPSetupLocked*);
+
+uint32_t dot11f_pack_tlv_ap_setup_locked(
+ tpAniSirGlobal,
+ tDot11fTLVAPSetupLocked *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_APSetupLocked(
+ tpAniSirGlobal,
+ tDot11fTLVAPSetupLocked *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4098 (0x1002) */
+typedef struct sDot11fTLVAssociationState {
+ uint8_t present;
+ uint16_t state;
+} tDot11fTLVAssociationState;
+
+#define DOT11F_TLV_ASSOCIATIONSTATE (4098)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_ASSOCIATIONSTATE_MIN_LEN (4)
+
+#define DOT11F_TLV_ASSOCIATIONSTATE_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_AssociationState(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVAssociationState*);
+
+uint32_t dot11f_pack_tlv_association_state(
+ tpAniSirGlobal,
+ tDot11fTLVAssociationState *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_AssociationState(
+ tpAniSirGlobal,
+ tDot11fTLVAssociationState *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4104 (0x1008) */
+typedef struct sDot11fTLVConfigMethods {
+ uint8_t present;
+ uint16_t methods;
+} tDot11fTLVConfigMethods;
+
+#define DOT11F_TLV_CONFIGMETHODS (4104)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_CONFIGMETHODS_MIN_LEN (4)
+
+#define DOT11F_TLV_CONFIGMETHODS_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_ConfigMethods(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVConfigMethods*);
+
+uint32_t dot11f_pack_tlv_config_methods(
+ tpAniSirGlobal,
+ tDot11fTLVConfigMethods *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ConfigMethods(
+ tpAniSirGlobal,
+ tDot11fTLVConfigMethods *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4105 (0x1009) */
+typedef struct sDot11fTLVConfigurationError {
+ uint8_t present;
+ uint16_t error;
+} tDot11fTLVConfigurationError;
+
+#define DOT11F_TLV_CONFIGURATIONERROR (4105)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_CONFIGURATIONERROR_MIN_LEN (4)
+
+#define DOT11F_TLV_CONFIGURATIONERROR_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_ConfigurationError(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVConfigurationError*);
+
+uint32_t dot11f_pack_tlv_configuration_error(
+ tpAniSirGlobal,
+ tDot11fTLVConfigurationError *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ConfigurationError(
+ tpAniSirGlobal,
+ tDot11fTLVConfigurationError *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4113 (0x1011) */
+typedef struct sDot11fTLVDeviceName {
+ uint8_t present;
+ uint8_t num_text;
+ uint8_t text[32];
+} tDot11fTLVDeviceName;
+
+#define DOT11F_TLV_DEVICENAME (4113)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_DEVICENAME_MIN_LEN (2)
+
+#define DOT11F_TLV_DEVICENAME_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_device_name(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVDeviceName*);
+
+uint32_t dot11f_pack_tlv_device_name(
+ tpAniSirGlobal,
+ tDot11fTLVDeviceName *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_DeviceName(
+ tpAniSirGlobal,
+ tDot11fTLVDeviceName *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4114 (0x1012) */
+typedef struct sDot11fTLVDevicePasswordID {
+ uint8_t present;
+ uint16_t id;
+} tDot11fTLVDevicePasswordID;
+
+#define DOT11F_TLV_DEVICEPASSWORDID (4114)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_DEVICEPASSWORDID_MIN_LEN (4)
+
+#define DOT11F_TLV_DEVICEPASSWORDID_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_DevicePasswordID(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVDevicePasswordID*);
+
+uint32_t dot11f_pack_tlv_device_password_id(
+ tpAniSirGlobal,
+ tDot11fTLVDevicePasswordID *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_DevicePasswordID(
+ tpAniSirGlobal,
+ tDot11fTLVDevicePasswordID *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 8 (0x0008) */
+typedef struct sDot11fTLVExtendedListenTiming {
+ uint8_t present;
+ uint16_t availibilityPeriod;
+ uint16_t availibilityInterval;
+} tDot11fTLVExtendedListenTiming;
+
+#define DOT11F_TLV_EXTENDEDLISTENTIMING (8)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_EXTENDEDLISTENTIMING_MIN_LEN (5)
+
+#define DOT11F_TLV_EXTENDEDLISTENTIMING_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_extended_listen_timing(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVExtendedListenTiming*);
+
+uint32_t dot11f_pack_tlv_extended_listen_timing(
+ tpAniSirGlobal,
+ tDot11fTLVExtendedListenTiming *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ExtendedListenTiming(
+ tpAniSirGlobal,
+ tDot11fTLVExtendedListenTiming *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 6 (0x0006) */
+typedef struct sDot11fTLVListenChannel {
+ uint8_t present;
+ uint8_t countryString[3];
+ uint8_t regulatoryClass;
+ uint8_t channel;
+} tDot11fTLVListenChannel;
+
+#define DOT11F_TLV_LISTENCHANNEL (6)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_LISTENCHANNEL_MIN_LEN (6)
+
+#define DOT11F_TLV_LISTENCHANNEL_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_listen_channel(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVListenChannel*);
+
+uint32_t dot11f_pack_tlv_listen_channel(
+ tpAniSirGlobal,
+ tDot11fTLVListenChannel *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ListenChannel(
+ tpAniSirGlobal,
+ tDot11fTLVListenChannel *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4129 (0x1021) */
+typedef struct sDot11fTLVManufacturer {
+ uint8_t present;
+ uint8_t num_name;
+ uint8_t name[64];
+} tDot11fTLVManufacturer;
+
+#define DOT11F_TLV_MANUFACTURER (4129)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MANUFACTURER_MIN_LEN (2)
+
+#define DOT11F_TLV_MANUFACTURER_MAX_LEN (66)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_manufacturer(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVManufacturer*);
+
+uint32_t dot11f_pack_tlv_manufacturer(
+ tpAniSirGlobal,
+ tDot11fTLVManufacturer *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_Manufacturer(
+ tpAniSirGlobal,
+ tDot11fTLVManufacturer *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 1 (0x0001) */
+typedef struct sDot11fTLVMinorReasonCode {
+ uint8_t present;
+ uint8_t minorReasonCode;
+} tDot11fTLVMinorReasonCode;
+
+#define DOT11F_TLV_MINORREASONCODE (1)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MINORREASONCODE_MIN_LEN (2)
+
+#define DOT11F_TLV_MINORREASONCODE_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_MinorReasonCode(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVMinorReasonCode*);
+
+uint32_t dot11f_pack_tlv_minor_reason_code(
+ tpAniSirGlobal,
+ tDot11fTLVMinorReasonCode *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_MinorReasonCode(
+ tpAniSirGlobal,
+ tDot11fTLVMinorReasonCode *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4131 (0x1023) */
+typedef struct sDot11fTLVModelName {
+ uint8_t present;
+ uint8_t num_text;
+ uint8_t text[32];
+} tDot11fTLVModelName;
+
+#define DOT11F_TLV_MODELNAME (4131)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MODELNAME_MIN_LEN (2)
+
+#define DOT11F_TLV_MODELNAME_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_model_name(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVModelName*);
+
+uint32_t dot11f_pack_tlv_model_name(
+ tpAniSirGlobal,
+ tDot11fTLVModelName *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ModelName(
+ tpAniSirGlobal,
+ tDot11fTLVModelName *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4132 (0x1024) */
+typedef struct sDot11fTLVModelNumber {
+ uint8_t present;
+ uint8_t num_text;
+ uint8_t text[32];
+} tDot11fTLVModelNumber;
+
+#define DOT11F_TLV_MODELNUMBER (4132)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_MODELNUMBER_MIN_LEN (2)
+
+#define DOT11F_TLV_MODELNUMBER_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_model_number(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVModelNumber*);
+
+uint32_t dot11f_pack_tlv_model_number(
+ tpAniSirGlobal,
+ tDot11fTLVModelNumber *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ModelNumber(
+ tpAniSirGlobal,
+ tDot11fTLVModelNumber *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 12 (0x000c) */
+typedef struct sDot11fTLVNoticeOfAbsence {
+ uint8_t present;
+ uint8_t index;
+ uint8_t CTSWindowOppPS;
+ uint8_t num_NoADesc;
+ uint8_t NoADesc[36];
+} tDot11fTLVNoticeOfAbsence;
+
+#define DOT11F_TLV_NOTICEOFABSENCE (12)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_NOTICEOFABSENCE_MIN_LEN (3)
+
+#define DOT11F_TLV_NOTICEOFABSENCE_MAX_LEN (39)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_notice_of_absence(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVNoticeOfAbsence*);
+
+uint32_t dot11f_pack_tlv_notice_of_absence(
+ tpAniSirGlobal,
+ tDot11fTLVNoticeOfAbsence *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_NoticeOfAbsence(
+ tpAniSirGlobal,
+ tDot11fTLVNoticeOfAbsence *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 17 (0x0011) */
+typedef struct sDot11fTLVOperatingChannel {
+ uint8_t present;
+ uint8_t countryString[3];
+ uint8_t regulatoryClass;
+ uint8_t channel;
+} tDot11fTLVOperatingChannel;
+
+#define DOT11F_TLV_OPERATINGCHANNEL (17)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_OPERATINGCHANNEL_MIN_LEN (6)
+
+#define DOT11F_TLV_OPERATINGCHANNEL_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_operating_channel(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVOperatingChannel*);
+
+uint32_t dot11f_pack_tlv_operating_channel(
+ tpAniSirGlobal,
+ tDot11fTLVOperatingChannel *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_OperatingChannel(
+ tpAniSirGlobal,
+ tDot11fTLVOperatingChannel *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 2 (0x0002) */
+typedef struct sDot11fTLVP2PCapability {
+ uint8_t present;
+ uint8_t deviceCapability;
+ uint8_t groupCapability;
+} tDot11fTLVP2PCapability;
+
+#define DOT11F_TLV_P2PCAPABILITY (2)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PCAPABILITY_MIN_LEN (3)
+
+#define DOT11F_TLV_P2PCAPABILITY_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_capability(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PCapability*);
+
+uint32_t dot11f_pack_tlv_p2_p_capability(
+ tpAniSirGlobal,
+ tDot11fTLVP2PCapability *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PCapability(
+ tpAniSirGlobal,
+ tDot11fTLVP2PCapability *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 3 (0x0003) */
+typedef struct sDot11fTLVP2PDeviceId {
+ uint8_t present;
+ uint8_t P2PDeviceAddress[6];
+} tDot11fTLVP2PDeviceId;
+
+#define DOT11F_TLV_P2PDEVICEID (3)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PDEVICEID_MIN_LEN (7)
+
+#define DOT11F_TLV_P2PDEVICEID_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_device_id(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PDeviceId*);
+
+uint32_t dot11f_pack_tlv_p2_p_device_id(
+ tpAniSirGlobal,
+ tDot11fTLVP2PDeviceId *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PDeviceId(
+ tpAniSirGlobal,
+ tDot11fTLVP2PDeviceId *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 13 (0x000d) */
+typedef struct sDot11fTLVP2PDeviceInfo {
+ uint8_t present;
+ uint8_t P2PDeviceAddress[6];
+ uint16_t configMethod;
+ uint8_t primaryDeviceType[8];
+ tDot11fTLVDeviceName DeviceName;
+} tDot11fTLVP2PDeviceInfo;
+
+#define DOT11F_TLV_P2PDEVICEINFO (13)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PDEVICEINFO_MIN_LEN (17)
+
+#define DOT11F_TLV_P2PDEVICEINFO_MAX_LEN (53)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_device_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PDeviceInfo*);
+
+uint32_t dot11f_pack_tlv_p2_p_device_info(
+ tpAniSirGlobal,
+ tDot11fTLVP2PDeviceInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PDeviceInfo(
+ tpAniSirGlobal,
+ tDot11fTLVP2PDeviceInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 14 (0x000e) */
+typedef struct sDot11fTLVP2PGroupInfo {
+ uint8_t present;
+ uint8_t num_P2PClientInfoDesc;
+ uint8_t P2PClientInfoDesc[1024];
+} tDot11fTLVP2PGroupInfo;
+
+#define DOT11F_TLV_P2PGROUPINFO (14)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PGROUPINFO_MIN_LEN (1)
+
+#define DOT11F_TLV_P2PGROUPINFO_MAX_LEN (1025)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_group_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PGroupInfo*);
+
+uint32_t dot11f_pack_tlv_p2_p_group_info(
+ tpAniSirGlobal,
+ tDot11fTLVP2PGroupInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PGroupInfo(
+ tpAniSirGlobal,
+ tDot11fTLVP2PGroupInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 0 (0x0000) */
+typedef struct sDot11fTLVP2PStatus {
+ uint8_t present;
+ uint8_t status;
+} tDot11fTLVP2PStatus;
+
+#define DOT11F_TLV_P2PSTATUS (0)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PSTATUS_MIN_LEN (2)
+
+#define DOT11F_TLV_P2PSTATUS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_P2PStatus(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PStatus*);
+
+uint32_t dot11f_pack_tlv_p2_p_status(
+ tpAniSirGlobal,
+ tDot11fTLVP2PStatus *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PStatus(
+ tpAniSirGlobal,
+ tDot11fTLVP2PStatus *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4180 (0x1054) */
+typedef struct sDot11fTLVPrimaryDeviceType {
+ uint8_t present;
+ uint16_t primary_category;
+ uint8_t oui[4];
+ uint16_t sub_category;
+} tDot11fTLVPrimaryDeviceType;
+
+#define DOT11F_TLV_PRIMARYDEVICETYPE (4180)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_PRIMARYDEVICETYPE_MIN_LEN (10)
+
+#define DOT11F_TLV_PRIMARYDEVICETYPE_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_primary_device_type(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVPrimaryDeviceType*);
+
+uint32_t dot11f_pack_tlv_primary_device_type(
+ tpAniSirGlobal,
+ tDot11fTLVPrimaryDeviceType *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_PrimaryDeviceType(
+ tpAniSirGlobal,
+ tDot11fTLVPrimaryDeviceType *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4156 (0x103c) */
+typedef struct sDot11fTLVRFBands {
+ uint8_t present;
+ uint8_t bands;
+} tDot11fTLVRFBands;
+
+#define DOT11F_TLV_RFBANDS (4156)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_RFBANDS_MIN_LEN (3)
+
+#define DOT11F_TLV_RFBANDS_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_RFBands(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVRFBands*);
+
+uint32_t dot11f_pack_tlv_rf_bands(
+ tpAniSirGlobal,
+ tDot11fTLVRFBands *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RFBands(
+ tpAniSirGlobal,
+ tDot11fTLVRFBands *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4202 (0x106a) */
+typedef struct sDot11fTLVRequestDeviceType {
+ uint8_t present;
+ uint16_t primary_category;
+ uint8_t oui[4];
+ uint16_t sub_category;
+} tDot11fTLVRequestDeviceType;
+
+#define DOT11F_TLV_REQUESTDEVICETYPE (4202)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REQUESTDEVICETYPE_MIN_LEN (10)
+
+#define DOT11F_TLV_REQUESTDEVICETYPE_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_request_device_type(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVRequestDeviceType*);
+
+uint32_t dot11f_pack_tlv_request_device_type(
+ tpAniSirGlobal,
+ tDot11fTLVRequestDeviceType *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RequestDeviceType(
+ tpAniSirGlobal,
+ tDot11fTLVRequestDeviceType *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4154 (0x103a) */
+typedef struct sDot11fTLVRequestType {
+ uint8_t present;
+ uint8_t reqType;
+} tDot11fTLVRequestType;
+
+#define DOT11F_TLV_REQUESTTYPE (4154)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_REQUESTTYPE_MIN_LEN (3)
+
+#define DOT11F_TLV_REQUESTTYPE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_RequestType(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVRequestType*);
+
+uint32_t dot11f_pack_tlv_request_type(
+ tpAniSirGlobal,
+ tDot11fTLVRequestType *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_RequestType(
+ tpAniSirGlobal,
+ tDot11fTLVRequestType *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4155 (0x103b) */
+typedef struct sDot11fTLVResponseType {
+ uint8_t present;
+ uint8_t resType;
+} tDot11fTLVResponseType;
+
+#define DOT11F_TLV_RESPONSETYPE (4155)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_RESPONSETYPE_MIN_LEN (3)
+
+#define DOT11F_TLV_RESPONSETYPE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_ResponseType(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVResponseType*);
+
+uint32_t dot11f_pack_tlv_response_type(
+ tpAniSirGlobal,
+ tDot11fTLVResponseType *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_ResponseType(
+ tpAniSirGlobal,
+ tDot11fTLVResponseType *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4161 (0x1041) */
+typedef struct sDot11fTLVSelectedRegistrar {
+ uint8_t present;
+ uint8_t selected;
+} tDot11fTLVSelectedRegistrar;
+
+#define DOT11F_TLV_SELECTEDREGISTRAR (4161)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_SELECTEDREGISTRAR_MIN_LEN (3)
+
+#define DOT11F_TLV_SELECTEDREGISTRAR_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_SelectedRegistrar(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVSelectedRegistrar*);
+
+uint32_t dot11f_pack_tlv_selected_registrar(
+ tpAniSirGlobal,
+ tDot11fTLVSelectedRegistrar *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_SelectedRegistrar(
+ tpAniSirGlobal,
+ tDot11fTLVSelectedRegistrar *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4179 (0x1053) */
+typedef struct sDot11fTLVSelectedRegistrarConfigMethods {
+ uint8_t present;
+ uint16_t methods;
+} tDot11fTLVSelectedRegistrarConfigMethods;
+
+#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS (4179)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MIN_LEN (4)
+
+#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_SelectedRegistrarConfigMethods(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVSelectedRegistrarConfigMethods*);
+
+uint32_t dot11f_pack_tlv_selected_registrar_config_methods(
+ tpAniSirGlobal,
+ tDot11fTLVSelectedRegistrarConfigMethods *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_SelectedRegistrarConfigMethods(
+ tpAniSirGlobal,
+ tDot11fTLVSelectedRegistrarConfigMethods *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4162 (0x1042) */
+typedef struct sDot11fTLVSerialNumber {
+ uint8_t present;
+ uint8_t num_text;
+ uint8_t text[32];
+} tDot11fTLVSerialNumber;
+
+#define DOT11F_TLV_SERIALNUMBER (4162)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_SERIALNUMBER_MIN_LEN (2)
+
+#define DOT11F_TLV_SERIALNUMBER_MAX_LEN (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_serial_number(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVSerialNumber*);
+
+uint32_t dot11f_pack_tlv_serial_number(
+ tpAniSirGlobal,
+ tDot11fTLVSerialNumber *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_SerialNumber(
+ tpAniSirGlobal,
+ tDot11fTLVSerialNumber *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4167 (0x1047) */
+typedef struct sDot11fTLVUUID_E {
+ uint8_t present;
+ uint8_t uuid[16];
+} tDot11fTLVUUID_E;
+
+#define DOT11F_TLV_UUID_E (4167)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_UUID_E_MIN_LEN (18)
+
+#define DOT11F_TLV_UUID_E_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_uuid_e(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVUUID_E*);
+
+uint32_t dot11f_pack_tlv_uuid_e(
+ tpAniSirGlobal,
+ tDot11fTLVUUID_E *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_UUID_E(
+ tpAniSirGlobal,
+ tDot11fTLVUUID_E *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4168 (0x1048) */
+typedef struct sDot11fTLVUUID_R {
+ uint8_t present;
+ uint8_t uuid[16];
+} tDot11fTLVUUID_R;
+
+#define DOT11F_TLV_UUID_R (4168)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_UUID_R_MIN_LEN (18)
+
+#define DOT11F_TLV_UUID_R_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_uuid_r(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVUUID_R*);
+
+uint32_t dot11f_pack_tlv_uuid_r(
+ tpAniSirGlobal,
+ tDot11fTLVUUID_R *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_UUID_R(
+ tpAniSirGlobal,
+ tDot11fTLVUUID_R *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4169 (0x1049) */
+typedef struct sDot11fTLVVendorExtension {
+ uint8_t present;
+ uint8_t vendorId[3];
+ tDot11fTLVVersion2 Version2;
+ tDot11fTLVAuthorizedMACs AuthorizedMACs;
+ tDot11fTLVRequestToEnroll RequestToEnroll;
+} tDot11fTLVVendorExtension;
+
+#define DOT11F_TLV_VENDOREXTENSION (4169)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_VENDOREXTENSION_MIN_LEN (5)
+
+#define DOT11F_TLV_VENDOREXTENSION_MAX_LEN (19)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_vendor_extension(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVVendorExtension*);
+
+uint32_t dot11f_pack_tlv_vendor_extension(
+ tpAniSirGlobal,
+ tDot11fTLVVendorExtension *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_VendorExtension(
+ tpAniSirGlobal,
+ tDot11fTLVVendorExtension *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4170 (0x104a) */
+typedef struct sDot11fTLVVersion {
+ uint8_t present;
+ uint8_t minor:4;
+ uint8_t major:4;
+} tDot11fTLVVersion;
+
+#define DOT11F_TLV_VERSION (4170)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_VERSION_MIN_LEN (3)
+
+#define DOT11F_TLV_VERSION_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_version(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVVersion*);
+
+uint32_t dot11f_pack_tlv_version(
+ tpAniSirGlobal,
+ tDot11fTLVVersion *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_Version(
+ tpAniSirGlobal,
+ tDot11fTLVVersion *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 4164 (0x1044) */
+typedef struct sDot11fTLVWPSState {
+ uint8_t present;
+ uint8_t state;
+} tDot11fTLVWPSState;
+
+#define DOT11F_TLV_WPSSTATE (4164)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_WPSSTATE_MIN_LEN (3)
+
+#define DOT11F_TLV_WPSSTATE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_WPSState(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVWPSState*);
+
+uint32_t dot11f_pack_tlv_wps_state(
+ tpAniSirGlobal,
+ tDot11fTLVWPSState *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_WPSState(
+ tpAniSirGlobal,
+ tDot11fTLVWPSState *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 16 (0x0010) */
+typedef struct sDot11fTLVP2PInterface {
+ uint8_t present;
+ uint8_t P2PDeviceAddress[6];
+} tDot11fTLVP2PInterface;
+
+#define DOT11F_TLV_P2PINTERFACE (16)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PINTERFACE_MIN_LEN (7)
+
+#define DOT11F_TLV_P2PINTERFACE_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_p2_p_interface(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PInterface*);
+
+uint32_t dot11f_pack_tlv_p2_p_interface(
+ tpAniSirGlobal,
+ tDot11fTLVP2PInterface *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PInterface(
+ tpAniSirGlobal,
+ tDot11fTLVP2PInterface *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* ID 10 (0x000a) */
+typedef struct sDot11fTLVP2PManageability {
+ uint8_t present;
+ uint8_t manageability;
+} tDot11fTLVP2PManageability;
+
+#define DOT11F_TLV_P2PMANAGEABILITY (10)
+
+/* N.B. These #defines do *not* include the ID & length */
+#define DOT11F_TLV_P2PMANAGEABILITY_MIN_LEN (2)
+
+#define DOT11F_TLV_P2PMANAGEABILITY_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_tlv_P2PManageability(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint16_t,
+ tDot11fTLVP2PManageability*);
+
+uint32_t dot11f_pack_tlv_p2_p_manageability(
+ tpAniSirGlobal,
+ tDot11fTLVP2PManageability *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_tlv_P2PManageability(
+ tpAniSirGlobal,
+ tDot11fTLVP2PManageability *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+/*********************************************************************
+ * Information Elements *
+ ********************************************************************/
+
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIECondensedCountryStr {
+ uint8_t present;
+ uint8_t countryStr[2];
+} tDot11fIECondensedCountryStr;
+
+#define DOT11F_EID_CONDENSEDCOUNTRYSTR (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MIN_LEN (2)
+
+#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_condensed_country_str(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIECondensedCountryStr*);
+
+uint32_t dot11f_pack_ie_condensed_country_str(
+ tpAniSirGlobal,
+ tDot11fIECondensedCountryStr *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_CondensedCountryStr(
+ tpAniSirGlobal,
+ tDot11fIECondensedCountryStr *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEGTK {
+ uint8_t present;
+ uint16_t keyId:2;
+ uint16_t reserved:14;
+ uint8_t keyLength;
+ uint8_t RSC[8];
+ uint8_t num_key;
+ uint8_t key[32];
+} tDot11fIEGTK;
+
+#define DOT11F_EID_GTK (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_GTK_MIN_LEN (16)
+
+#define DOT11F_IE_GTK_MAX_LEN (43)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_gtk(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEGTK*);
+
+uint32_t dot11f_pack_ie_gtk(
+ tpAniSirGlobal,
+ tDot11fIEGTK *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_GTK(
+ tpAniSirGlobal,
+ tDot11fIEGTK *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 4 (0x04) */
+typedef struct sDot11fIEIGTK {
+ uint8_t present;
+ uint8_t keyID[2];
+ uint8_t IPN[6];
+ uint8_t keyLength;
+ uint8_t key[24];
+} tDot11fIEIGTK;
+
+#define DOT11F_EID_IGTK (4)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_IGTK_MIN_LEN (33)
+
+#define DOT11F_IE_IGTK_MAX_LEN (33)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_igtk(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEIGTK*);
+
+uint32_t dot11f_pack_ie_igtk(
+ tpAniSirGlobal,
+ tDot11fIEIGTK *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_IGTK(
+ tpAniSirGlobal,
+ tDot11fIEIGTK *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 3 (0x03) */
+typedef struct sDot11fIER0KH_ID {
+ uint8_t present;
+ uint8_t num_PMK_R0_ID;
+ uint8_t PMK_R0_ID[48];
+} tDot11fIER0KH_ID;
+
+#define DOT11F_EID_R0KH_ID (3)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_R0KH_ID_MIN_LEN (1)
+
+#define DOT11F_IE_R0KH_ID_MAX_LEN (48)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_r0_kh_id(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIER0KH_ID*);
+
+uint32_t dot11f_pack_ie_r0_kh_id(
+ tpAniSirGlobal,
+ tDot11fIER0KH_ID *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_R0KH_ID(
+ tpAniSirGlobal,
+ tDot11fIER0KH_ID *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIER1KH_ID {
+ uint8_t present;
+ uint8_t PMK_R1_ID[6];
+} tDot11fIER1KH_ID;
+
+#define DOT11F_EID_R1KH_ID (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_R1KH_ID_MIN_LEN (6)
+
+#define DOT11F_IE_R1KH_ID_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_r1_kh_id(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIER1KH_ID*);
+
+uint32_t dot11f_pack_ie_r1_kh_id(
+ tpAniSirGlobal,
+ tDot11fIER1KH_ID *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_R1KH_ID(
+ tpAniSirGlobal,
+ tDot11fIER1KH_ID *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIETSFInfo {
+ uint8_t present;
+ uint16_t TsfOffset;
+ uint16_t BeaconIntvl;
+} tDot11fIETSFInfo;
+
+#define DOT11F_EID_TSFINFO (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TSFINFO_MIN_LEN (4)
+
+#define DOT11F_IE_TSFINFO_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tsf_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETSFInfo*);
+
+uint32_t dot11f_pack_ie_tsf_info(
+ tpAniSirGlobal,
+ tDot11fIETSFInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TSFInfo(
+ tpAniSirGlobal,
+ tDot11fIETSFInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 51 (0x33) */
+typedef struct sDot11fIEAPChannelReport {
+ uint8_t present;
+ uint8_t regulatoryClass;
+ uint8_t num_channelList;
+ uint8_t channelList[50];
+} tDot11fIEAPChannelReport;
+
+#define DOT11F_EID_APCHANNELREPORT (51)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_APCHANNELREPORT_MIN_LEN (1)
+
+#define DOT11F_IE_APCHANNELREPORT_MAX_LEN (51)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ap_channel_report(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEAPChannelReport*);
+
+uint32_t dot11f_pack_ie_ap_channel_report(
+ tpAniSirGlobal,
+ tDot11fIEAPChannelReport *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_APChannelReport(
+ tpAniSirGlobal,
+ tDot11fIEAPChannelReport *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEBcnReportingDetail {
+ uint8_t present;
+ uint8_t reportingDetail;
+} tDot11fIEBcnReportingDetail;
+
+#define DOT11F_EID_BCNREPORTINGDETAIL (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BCNREPORTINGDETAIL_MIN_LEN (1)
+
+#define DOT11F_IE_BCNREPORTINGDETAIL_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_bcn_reporting_detail(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEBcnReportingDetail*);
+
+uint32_t dot11f_pack_ie_bcn_reporting_detail(
+ tpAniSirGlobal,
+ tDot11fIEBcnReportingDetail *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_BcnReportingDetail(
+ tpAniSirGlobal,
+ tDot11fIEBcnReportingDetail *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIEBeaconReportFrmBody {
+ uint8_t present;
+ uint8_t num_reportedFields;
+ uint8_t reportedFields[224];
+} tDot11fIEBeaconReportFrmBody;
+
+#define DOT11F_EID_BEACONREPORTFRMBODY (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BEACONREPORTFRMBODY_MIN_LEN (0)
+
+#define DOT11F_IE_BEACONREPORTFRMBODY_MAX_LEN (224)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_beacon_report_frm_body(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEBeaconReportFrmBody*);
+
+uint32_t dot11f_pack_ie_beacon_report_frm_body(
+ tpAniSirGlobal,
+ tDot11fIEBeaconReportFrmBody *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_BeaconReportFrmBody(
+ tpAniSirGlobal,
+ tDot11fIEBeaconReportFrmBody *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIEBeaconReporting {
+ uint8_t present;
+ uint8_t reportingCondition;
+ uint8_t threshold;
+} tDot11fIEBeaconReporting;
+
+#define DOT11F_EID_BEACONREPORTING (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_BEACONREPORTING_MIN_LEN (2)
+
+#define DOT11F_IE_BEACONREPORTING_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_beacon_reporting(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEBeaconReporting*);
+
+uint32_t dot11f_pack_ie_beacon_reporting(
+ tpAniSirGlobal,
+ tDot11fIEBeaconReporting *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_BeaconReporting(
+ tpAniSirGlobal,
+ tDot11fIEBeaconReporting *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 66 (0x42) */
+typedef struct sDot11fIEMeasurementPilot {
+ uint8_t present;
+ uint8_t measurementPilot;
+ uint8_t num_vendorSpecific;
+ uint8_t vendorSpecific[255];
+} tDot11fIEMeasurementPilot;
+
+#define DOT11F_EID_MEASUREMENTPILOT (66)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MEASUREMENTPILOT_MIN_LEN (1)
+
+#define DOT11F_IE_MEASUREMENTPILOT_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_measurement_pilot(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEMeasurementPilot*);
+
+uint32_t dot11f_pack_ie_measurement_pilot(
+ tpAniSirGlobal,
+ tDot11fIEMeasurementPilot *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MeasurementPilot(
+ tpAniSirGlobal,
+ tDot11fIEMeasurementPilot *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 71 (0x47) */
+typedef struct sDot11fIEMultiBssid {
+ uint8_t present;
+ uint8_t maxBSSIDIndicator;
+ uint8_t num_vendorSpecific;
+ uint8_t vendorSpecific[255];
+} tDot11fIEMultiBssid;
+
+#define DOT11F_EID_MULTIBSSID (71)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MULTIBSSID_MIN_LEN (1)
+
+#define DOT11F_IE_MULTIBSSID_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_multi_bssid(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEMultiBssid*);
+
+uint32_t dot11f_pack_ie_multi_bssid(
+ tpAniSirGlobal,
+ tDot11fIEMultiBssid *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MultiBssid(
+ tpAniSirGlobal,
+ tDot11fIEMultiBssid *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 57 (0x39) */
+typedef struct sDot11fIERICData {
+ uint8_t present;
+ uint8_t Identifier;
+ uint8_t resourceDescCount;
+ uint16_t statusCode;
+} tDot11fIERICData;
+
+#define DOT11F_EID_RICDATA (57)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RICDATA_MIN_LEN (4)
+
+#define DOT11F_IE_RICDATA_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ric_data(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERICData*);
+
+uint32_t dot11f_pack_ie_ric_data(
+ tpAniSirGlobal,
+ tDot11fIERICData *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RICData(
+ tpAniSirGlobal,
+ tDot11fIERICData *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 75 (0x4b) */
+typedef struct sDot11fIERICDescriptor {
+ uint8_t present;
+ uint8_t resourceType;
+ uint8_t num_variableData;
+ uint8_t variableData[255];
+} tDot11fIERICDescriptor;
+
+#define DOT11F_EID_RICDESCRIPTOR (75)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RICDESCRIPTOR_MIN_LEN (1)
+
+#define DOT11F_IE_RICDESCRIPTOR_MAX_LEN (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ric_descriptor(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERICDescriptor*);
+
+uint32_t dot11f_pack_ie_ric_descriptor(
+ tpAniSirGlobal,
+ tDot11fIERICDescriptor *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RICDescriptor(
+ tpAniSirGlobal,
+ tDot11fIERICDescriptor *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 70 (0x46) */
+typedef struct sDot11fIERRMEnabledCap {
+ uint8_t present;
+ uint8_t LinkMeasurement:1;
+ uint8_t NeighborRpt:1;
+ uint8_t parallel:1;
+ uint8_t repeated:1;
+ uint8_t BeaconPassive:1;
+ uint8_t BeaconActive:1;
+ uint8_t BeaconTable:1;
+ uint8_t BeaconRepCond:1;
+ uint8_t FrameMeasurement:1;
+ uint8_t ChannelLoad:1;
+ uint8_t NoiseHistogram:1;
+ uint8_t statistics:1;
+ uint8_t LCIMeasurement:1;
+ uint8_t LCIAzimuth:1;
+ uint8_t TCMCapability:1;
+ uint8_t triggeredTCM:1;
+ uint8_t APChanReport:1;
+ uint8_t RRMMIBEnabled:1;
+ uint8_t operatingChanMax:3;
+ uint8_t nonOperatinChanMax:3;
+ uint8_t MeasurementPilot:3;
+ uint8_t MeasurementPilotEnabled:1;
+ uint8_t NeighborTSFOffset:1;
+ uint8_t RCPIMeasurement:1;
+ uint8_t RSNIMeasurement:1;
+ uint8_t BssAvgAccessDelay:1;
+ uint8_t BSSAvailAdmission:1;
+ uint8_t AntennaInformation:1;
+ uint8_t fine_time_meas_rpt:1;
+ uint8_t lci_capability:1;
+ uint8_t reserved:4;
+} tDot11fIERRMEnabledCap;
+
+#define DOT11F_EID_RRMENABLEDCAP (70)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RRMENABLEDCAP_MIN_LEN (5)
+
+#define DOT11F_IE_RRMENABLEDCAP_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_rrm_enabled_cap(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERRMEnabledCap*);
+
+uint32_t dot11f_pack_ie_rrm_enabled_cap(
+ tpAniSirGlobal,
+ tDot11fIERRMEnabledCap *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RRMEnabledCap(
+ tpAniSirGlobal,
+ tDot11fIERRMEnabledCap *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 10 (0x0a) */
+typedef struct sDot11fIERequestedInfo {
+ uint8_t present;
+ uint8_t num_requested_eids;
+ uint8_t requested_eids[255];
+} tDot11fIERequestedInfo;
+
+#define DOT11F_EID_REQUESTEDINFO (10)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_REQUESTEDINFO_MIN_LEN (0)
+
+#define DOT11F_IE_REQUESTEDINFO_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_requested_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERequestedInfo*);
+
+uint32_t dot11f_pack_ie_requested_info(
+ tpAniSirGlobal,
+ tDot11fIERequestedInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RequestedInfo(
+ tpAniSirGlobal,
+ tDot11fIERequestedInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 0 (0x00) */
+typedef struct sDot11fIESSID {
+ uint8_t present;
+ uint8_t num_ssid;
+ uint8_t ssid[32];
+} tDot11fIESSID;
+
+#define DOT11F_EID_SSID (0)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SSID_MIN_LEN (0)
+
+#define DOT11F_IE_SSID_MAX_LEN (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ssid(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIESSID*);
+
+uint32_t dot11f_pack_ie_ssid(
+ tpAniSirGlobal,
+ tDot11fIESSID *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SSID(
+ tpAniSirGlobal,
+ tDot11fIESSID *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 15 (0x0f) */
+typedef struct sDot11fIESchedule {
+ uint8_t present;
+ uint16_t aggregation:1;
+ uint16_t tsid:4;
+ uint16_t direction:2;
+ uint16_t reserved:9;
+ uint32_t service_start_time;
+ uint32_t service_interval;
+ uint16_t max_service_dur;
+ uint16_t spec_interval;
+} tDot11fIESchedule;
+
+#define DOT11F_EID_SCHEDULE (15)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SCHEDULE_MIN_LEN (14)
+
+#define DOT11F_IE_SCHEDULE_MAX_LEN (14)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_schedule(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIESchedule*);
+
+uint32_t dot11f_pack_ie_schedule(
+ tpAniSirGlobal,
+ tDot11fIESchedule *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Schedule(
+ tpAniSirGlobal,
+ tDot11fIESchedule *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 14 (0x0e) */
+typedef struct sDot11fIETCLAS {
+ uint8_t present;
+ uint8_t user_priority;
+ uint8_t classifier_type;
+ uint8_t classifier_mask;
+ union {
+ struct {
+ uint8_t source[6];
+ uint8_t dest[6];
+ uint16_t type;
+ } EthParams; /* classifier_type = 0 */
+ struct {
+ uint8_t version;
+ union {
+ struct {
+ uint8_t source[4];
+ uint8_t dest[4];
+ uint16_t src_port;
+ uint16_t dest_port;
+ uint8_t DSCP;
+ uint8_t proto;
+ uint8_t reserved;
+ } IpV4Params; /* version = 4 */
+ struct {
+ uint8_t source[16];
+ uint8_t dest[16];
+ uint16_t src_port;
+ uint16_t dest_port;
+ uint8_t flow_label[3];
+ } IpV6Params; /* version = 6 */
+ } params;
+ } IpParams; /* classifier_type = 1 */
+ struct {
+ uint16_t tag_type;
+ } Params8021dq; /* classifier_type = 2 */
+ } info;
+} tDot11fIETCLAS;
+
+#define DOT11F_EID_TCLAS (14)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TCLAS_MIN_LEN (5)
+
+#define DOT11F_IE_TCLAS_MAX_LEN (43)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tclas(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETCLAS*);
+
+uint32_t dot11f_pack_ie_tclas(
+ tpAniSirGlobal,
+ tDot11fIETCLAS *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ietclas(
+ tpAniSirGlobal,
+ tDot11fIETCLAS *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 44 (0x2c) */
+typedef struct sDot11fIETCLASSPROC {
+ uint8_t present;
+ uint8_t processing;
+} tDot11fIETCLASSPROC;
+
+#define DOT11F_EID_TCLASSPROC (44)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TCLASSPROC_MIN_LEN (1)
+
+#define DOT11F_IE_TCLASSPROC_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tclasSPROC(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETCLASSPROC*);
+
+uint32_t dot11f_pack_ie_tclassproc(
+ tpAniSirGlobal,
+ tDot11fIETCLASSPROC *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ietclasSPROC(
+ tpAniSirGlobal,
+ tDot11fIETCLASSPROC *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 43 (0x2b) */
+typedef struct sDot11fIETSDelay {
+ uint8_t present;
+ uint32_t delay;
+} tDot11fIETSDelay;
+
+#define DOT11F_EID_TSDELAY (43)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TSDELAY_MIN_LEN (4)
+
+#define DOT11F_IE_TSDELAY_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ts_delay(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETSDelay*);
+
+uint32_t dot11f_pack_ie_ts_delay(
+ tpAniSirGlobal,
+ tDot11fIETSDelay *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TSDelay(
+ tpAniSirGlobal,
+ tDot11fIETSDelay *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 13 (0x0d) */
+typedef struct sDot11fIETSPEC {
+ uint8_t present;
+ uint16_t traffic_type:1;
+ uint16_t tsid:4;
+ uint16_t direction:2;
+ uint16_t access_policy:2;
+ uint16_t aggregation:1;
+ uint16_t psb:1;
+ uint16_t user_priority:3;
+ uint16_t tsinfo_ack_pol:2;
+ uint8_t schedule:1;
+ uint8_t unused:7;
+ uint16_t size:15;
+ uint16_t fixed:1;
+ uint16_t max_msdu_size;
+ uint32_t min_service_int;
+ uint32_t max_service_int;
+ uint32_t inactivity_int;
+ uint32_t suspension_int;
+ uint32_t service_start_time;
+ uint32_t min_data_rate;
+ uint32_t mean_data_rate;
+ uint32_t peak_data_rate;
+ uint32_t burst_size;
+ uint32_t delay_bound;
+ uint32_t min_phy_rate;
+ uint16_t surplus_bw_allowance;
+ uint16_t medium_time;
+} tDot11fIETSPEC;
+
+#define DOT11F_EID_TSPEC (13)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TSPEC_MIN_LEN (55)
+
+#define DOT11F_IE_TSPEC_MAX_LEN (55)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tspec(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETSPEC*);
+
+uint32_t dot11f_pack_ie_tspec(
+ tpAniSirGlobal,
+ tDot11fIETSPEC *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TSPEC(
+ tpAniSirGlobal,
+ tDot11fIETSPEC *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 191 (0xbf) */
+typedef struct sDot11fIEVHTCaps {
+ uint8_t present;
+ uint32_t maxMPDULen:2;
+ uint32_t supportedChannelWidthSet:2;
+ uint32_t ldpcCodingCap:1;
+ uint32_t shortGI80MHz:1;
+ uint32_t shortGI160and80plus80MHz:1;
+ uint32_t txSTBC:1;
+ uint32_t rxSTBC:3;
+ uint32_t suBeamFormerCap:1;
+ uint32_t suBeamformeeCap:1;
+ uint32_t csnofBeamformerAntSup:3;
+ uint32_t numSoundingDim:3;
+ uint32_t muBeamformerCap:1;
+ uint32_t muBeamformeeCap:1;
+ uint32_t vhtTXOPPS:1;
+ uint32_t htcVHTCap:1;
+ uint32_t maxAMPDULenExp:3;
+ uint32_t vhtLinkAdaptCap:2;
+ uint32_t rxAntPattern:1;
+ uint32_t txAntPattern:1;
+ uint32_t reserved1:2;
+ uint16_t rxMCSMap;
+ uint16_t rxHighSupDataRate:13;
+ uint16_t reserved2:3;
+ uint16_t txMCSMap;
+ uint16_t txSupDataRate:13;
+ uint16_t reserved3:3;
+} tDot11fIEVHTCaps;
+
+#define DOT11F_EID_VHTCAPS (191)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHTCAPS_MIN_LEN (12)
+
+#define DOT11F_IE_VHTCAPS_MAX_LEN (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_vht_caps(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEVHTCaps*);
+
+uint32_t dot11f_pack_ie_vht_caps(
+ tpAniSirGlobal,
+ tDot11fIEVHTCaps *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_VHTCaps(
+ tpAniSirGlobal,
+ tDot11fIEVHTCaps *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 192 (0xc0) */
+typedef struct sDot11fIEVHTOperation {
+ uint8_t present;
+ uint8_t chanWidth;
+ uint8_t chanCenterFreqSeg1;
+ uint8_t chanCenterFreqSeg2;
+ uint16_t basicMCSSet;
+} tDot11fIEVHTOperation;
+
+#define DOT11F_EID_VHTOPERATION (192)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHTOPERATION_MIN_LEN (5)
+
+#define DOT11F_IE_VHTOPERATION_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_vht_operation(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEVHTOperation*);
+
+uint32_t dot11f_pack_ie_vht_operation(
+ tpAniSirGlobal,
+ tDot11fIEVHTOperation *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_VHTOperation(
+ tpAniSirGlobal,
+ tDot11fIEVHTOperation *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x09} */
+typedef struct sDot11fIEWMMSchedule {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint16_t aggregation:1;
+ uint16_t tsid:4;
+ uint16_t direction:2;
+ uint16_t reserved:9;
+ uint32_t service_start_time;
+ uint32_t service_interval;
+ uint16_t max_service_dur;
+ uint16_t spec_interval;
+} tDot11fIEWMMSchedule;
+
+#define DOT11F_EID_WMMSCHEDULE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMSCHEDULE_MIN_LEN (20)
+
+#define DOT11F_IE_WMMSCHEDULE_MAX_LEN (20)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmm_schedule(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMSchedule*);
+
+uint32_t dot11f_pack_ie_wmm_schedule(
+ tpAniSirGlobal,
+ tDot11fIEWMMSchedule *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMSchedule(
+ tpAniSirGlobal,
+ tDot11fIEWMMSchedule *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x06} */
+typedef struct sDot11fIEWMMTCLAS {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint8_t user_priority;
+ uint8_t classifier_type;
+ uint8_t classifier_mask;
+ union {
+ struct {
+ uint8_t source[6];
+ uint8_t dest[6];
+ uint16_t type;
+ } EthParams; /* classifier_type = 0 */
+ struct {
+ uint8_t version;
+ union {
+ struct {
+ uint8_t source[4];
+ uint8_t dest[4];
+ uint16_t src_port;
+ uint16_t dest_port;
+ uint8_t DSCP;
+ uint8_t proto;
+ uint8_t reserved;
+ } IpV4Params; /* version = 4 */
+ struct {
+ uint8_t source[16];
+ uint8_t dest[16];
+ uint16_t src_port;
+ uint16_t dest_port;
+ uint8_t flow_label[3];
+ } IpV6Params; /* version = 6 */
+ } params;
+ } IpParams; /* classifier_type = 1 */
+ struct {
+ uint16_t tag_type;
+ } Params8021dq; /* classifier_type = 2 */
+ } info;
+} tDot11fIEWMMTCLAS;
+
+#define DOT11F_EID_WMMTCLAS (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTCLAS_MIN_LEN (11)
+
+#define DOT11F_IE_WMMTCLAS_MAX_LEN (49)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmmtclas(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMTCLAS*);
+
+uint32_t dot11f_pack_ie_wmmtclas(
+ tpAniSirGlobal,
+ tDot11fIEWMMTCLAS *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewmmtclas(
+ tpAniSirGlobal,
+ tDot11fIEWMMTCLAS *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x07} */
+typedef struct sDot11fIEWMMTCLASPROC {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint8_t processing;
+} tDot11fIEWMMTCLASPROC;
+
+#define DOT11F_EID_WMMTCLASPROC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTCLASPROC_MIN_LEN (7)
+
+#define DOT11F_IE_WMMTCLASPROC_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmmtclasproc(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMTCLASPROC*);
+
+uint32_t dot11f_pack_ie_wmmtclasproc(
+ tpAniSirGlobal,
+ tDot11fIEWMMTCLASPROC *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewmmtclasPROC(
+ tpAniSirGlobal,
+ tDot11fIEWMMTCLASPROC *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x08} */
+typedef struct sDot11fIEWMMTSDelay {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint32_t delay;
+} tDot11fIEWMMTSDelay;
+
+#define DOT11F_EID_WMMTSDELAY (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTSDELAY_MIN_LEN (10)
+
+#define DOT11F_IE_WMMTSDELAY_MAX_LEN (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmmts_delay(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMTSDelay*);
+
+uint32_t dot11f_pack_ie_wmmts_delay(
+ tpAniSirGlobal,
+ tDot11fIEWMMTSDelay *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMTSDelay(
+ tpAniSirGlobal,
+ tDot11fIEWMMTSDelay *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x02} */
+typedef struct sDot11fIEWMMTSPEC {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint16_t traffic_type:1;
+ uint16_t tsid:4;
+ uint16_t direction:2;
+ uint16_t access_policy:2;
+ uint16_t aggregation:1;
+ uint16_t psb:1;
+ uint16_t user_priority:3;
+ uint16_t tsinfo_ack_pol:2;
+ uint8_t tsinfo_rsvd:7;
+ uint8_t burst_size_defn:1;
+ uint16_t size:15;
+ uint16_t fixed:1;
+ uint16_t max_msdu_size;
+ uint32_t min_service_int;
+ uint32_t max_service_int;
+ uint32_t inactivity_int;
+ uint32_t suspension_int;
+ uint32_t service_start_time;
+ uint32_t min_data_rate;
+ uint32_t mean_data_rate;
+ uint32_t peak_data_rate;
+ uint32_t burst_size;
+ uint32_t delay_bound;
+ uint32_t min_phy_rate;
+ uint16_t surplus_bw_allowance;
+ uint16_t medium_time;
+} tDot11fIEWMMTSPEC;
+
+#define DOT11F_EID_WMMTSPEC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMTSPEC_MIN_LEN (61)
+
+#define DOT11F_IE_WMMTSPEC_MAX_LEN (61)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmmtspec(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMTSPEC*);
+
+uint32_t dot11f_pack_ie_wmmtspec(
+ tpAniSirGlobal,
+ tDot11fIEWMMTSPEC *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMTSPEC(
+ tpAniSirGlobal,
+ tDot11fIEWMMTSPEC *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 194 (0xc2) */
+typedef struct sDot11fIEWiderBWChanSwitchAnn {
+ uint8_t present;
+ uint8_t newChanWidth;
+ uint8_t newCenterChanFreq0;
+ uint8_t newCenterChanFreq1;
+} tDot11fIEWiderBWChanSwitchAnn;
+
+#define DOT11F_EID_WIDERBWCHANSWITCHANN (194)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WIDERBWCHANSWITCHANN_MIN_LEN (3)
+
+#define DOT11F_IE_WIDERBWCHANSWITCHANN_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wider_bw_chan_switch_ann(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWiderBWChanSwitchAnn*);
+
+uint32_t dot11f_pack_ie_wider_bw_chan_switch_ann(
+ tpAniSirGlobal,
+ tDot11fIEWiderBWChanSwitchAnn *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WiderBWChanSwitchAnn(
+ tpAniSirGlobal,
+ tDot11fIEWiderBWChanSwitchAnn *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 197 (0xc5) */
+typedef struct sDot11fIEAID {
+ uint8_t present;
+ uint16_t assocId;
+} tDot11fIEAID;
+
+#define DOT11F_EID_AID (197)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_AID_MIN_LEN (2)
+
+#define DOT11F_IE_AID_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_aid(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEAID*);
+
+uint32_t dot11f_pack_ie_aid(
+ tpAniSirGlobal,
+ tDot11fIEAID *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_AID(
+ tpAniSirGlobal,
+ tDot11fIEAID *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 4 (0x04) */
+typedef struct sDot11fIECFParams {
+ uint8_t present;
+ uint8_t cfp_count;
+ uint8_t cfp_period;
+ uint16_t cfp_maxduration;
+ uint16_t cfp_durremaining;
+} tDot11fIECFParams;
+
+#define DOT11F_EID_CFPARAMS (4)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CFPARAMS_MIN_LEN (6)
+
+#define DOT11F_IE_CFPARAMS_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_cf_params(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIECFParams*);
+
+uint32_t dot11f_pack_ie_cf_params(
+ tpAniSirGlobal,
+ tDot11fIECFParams *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_CFParams(
+ tpAniSirGlobal,
+ tDot11fIECFParams *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 16 (0x10) */
+typedef struct sDot11fIEChallengeText {
+ uint8_t present;
+ uint8_t num_text;
+ uint8_t text[253];
+} tDot11fIEChallengeText;
+
+#define DOT11F_EID_CHALLENGETEXT (16)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CHALLENGETEXT_MIN_LEN (1)
+
+#define DOT11F_IE_CHALLENGETEXT_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_challenge_text(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEChallengeText*);
+
+uint32_t dot11f_pack_ie_challenge_text(
+ tpAniSirGlobal,
+ tDot11fIEChallengeText *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ChallengeText(
+ tpAniSirGlobal,
+ tDot11fIEChallengeText *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 37 (0x25) */
+typedef struct sDot11fIEChanSwitchAnn {
+ uint8_t present;
+ uint8_t switchMode;
+ uint8_t newChannel;
+ uint8_t switchCount;
+} tDot11fIEChanSwitchAnn;
+
+#define DOT11F_EID_CHANSWITCHANN (37)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CHANSWITCHANN_MIN_LEN (3)
+
+#define DOT11F_IE_CHANSWITCHANN_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_chan_switch_ann(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEChanSwitchAnn*);
+
+uint32_t dot11f_pack_ie_chan_switch_ann(
+ tpAniSirGlobal,
+ tDot11fIEChanSwitchAnn *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ChanSwitchAnn(
+ tpAniSirGlobal,
+ tDot11fIEChanSwitchAnn *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 196 (0xc4) */
+typedef struct sDot11fIEChannelSwitchWrapper {
+ uint8_t present;
+ tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+} tDot11fIEChannelSwitchWrapper;
+
+#define DOT11F_EID_CHANNELSWITCHWRAPPER (196)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_CHANNELSWITCHWRAPPER_MIN_LEN (0)
+
+#define DOT11F_IE_CHANNELSWITCHWRAPPER_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_channel_switch_wrapper(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEChannelSwitchWrapper*);
+
+uint32_t dot11f_pack_ie_channel_switch_wrapper(
+ tpAniSirGlobal,
+ tDot11fIEChannelSwitchWrapper *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_channel_switch_wrapper(
+ tpAniSirGlobal,
+ tDot11fIEChannelSwitchWrapper *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 7 (0x07) */
+typedef struct sDot11fIECountry {
+ uint8_t present;
+ uint8_t country[3];
+ uint8_t num_triplets;
+ uint8_t triplets[84][3];
+} tDot11fIECountry;
+
+#define DOT11F_EID_COUNTRY (7)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_COUNTRY_MIN_LEN (3)
+
+#define DOT11F_IE_COUNTRY_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_country(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIECountry*);
+
+uint32_t dot11f_pack_ie_country(
+ tpAniSirGlobal,
+ tDot11fIECountry *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_country(
+ tpAniSirGlobal,
+ tDot11fIECountry *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 3 (0x03) */
+typedef struct sDot11fIEDSParams {
+ uint8_t present;
+ uint8_t curr_channel;
+} tDot11fIEDSParams;
+
+#define DOT11F_EID_DSPARAMS (3)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_DSPARAMS_MIN_LEN (1)
+
+#define DOT11F_IE_DSPARAMS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_DSParams(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEDSParams*);
+
+uint32_t dot11f_pack_ie_ds_params(
+ tpAniSirGlobal,
+ tDot11fIEDSParams *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_DSParams(
+ tpAniSirGlobal,
+ tDot11fIEDSParams *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 12 (0x0c) */
+typedef struct sDot11fIEEDCAParamSet {
+ uint8_t present;
+ uint8_t qos;
+ uint8_t reserved;
+ uint8_t acbe_aifsn:4;
+ uint8_t acbe_acm:1;
+ uint8_t acbe_aci:2;
+ uint8_t unused1:1;
+ uint8_t acbe_acwmin:4;
+ uint8_t acbe_acwmax:4;
+ uint16_t acbe_txoplimit;
+ uint8_t acbk_aifsn:4;
+ uint8_t acbk_acm:1;
+ uint8_t acbk_aci:2;
+ uint8_t unused2:1;
+ uint8_t acbk_acwmin:4;
+ uint8_t acbk_acwmax:4;
+ uint16_t acbk_txoplimit;
+ uint8_t acvi_aifsn:4;
+ uint8_t acvi_acm:1;
+ uint8_t acvi_aci:2;
+ uint8_t unused3:1;
+ uint8_t acvi_acwmin:4;
+ uint8_t acvi_acwmax:4;
+ uint16_t acvi_txoplimit;
+ uint8_t acvo_aifsn:4;
+ uint8_t acvo_acm:1;
+ uint8_t acvo_aci:2;
+ uint8_t unused4:1;
+ uint8_t acvo_acwmin:4;
+ uint8_t acvo_acwmax:4;
+ uint16_t acvo_txoplimit;
+} tDot11fIEEDCAParamSet;
+
+#define DOT11F_EID_EDCAPARAMSET (12)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EDCAPARAMSET_MIN_LEN (18)
+
+#define DOT11F_IE_EDCAPARAMSET_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_edca_param_set(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEEDCAParamSet*);
+
+uint32_t dot11f_pack_ie_edca_param_set(
+ tpAniSirGlobal,
+ tDot11fIEEDCAParamSet *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_EDCAParamSet(
+ tpAniSirGlobal,
+ tDot11fIEEDCAParamSet *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 42 (0x2a) */
+typedef struct sDot11fIEERPInfo {
+ uint8_t present;
+ uint8_t non_erp_present:1;
+ uint8_t use_prot:1;
+ uint8_t barker_preamble:1;
+ uint8_t unused:5;
+} tDot11fIEERPInfo;
+
+#define DOT11F_EID_ERPINFO (42)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ERPINFO_MIN_LEN (1)
+
+#define DOT11F_IE_ERPINFO_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_erp_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEERPInfo*);
+
+uint32_t dot11f_pack_ie_erp_info(
+ tpAniSirGlobal,
+ tDot11fIEERPInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ERPInfo(
+ tpAniSirGlobal,
+ tDot11fIEERPInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 156 (0x9c) {OUI 0x00, 0x40, 0x96, 0x00} */
+typedef struct sDot11fIEESECckmOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[20];
+} tDot11fIEESECckmOpaque;
+
+#define DOT11F_EID_ESECCKMOPAQUE (156)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESECCKMOPAQUE_MIN_LEN (10)
+
+#define DOT11F_IE_ESECCKMOPAQUE_MAX_LEN (24)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ese_cckm_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEESECckmOpaque*);
+
+uint32_t dot11f_pack_ie_ese_cckm_opaque(
+ tpAniSirGlobal,
+ tDot11fIEESECckmOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESECckmOpaque(
+ tpAniSirGlobal,
+ tDot11fIEESECckmOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x01} */
+typedef struct sDot11fIEESERadMgmtCap {
+ uint8_t present;
+ uint8_t mgmt_state;
+ uint8_t mbssid_mask:3;
+ uint8_t reserved:5;
+} tDot11fIEESERadMgmtCap;
+
+#define DOT11F_EID_ESERADMGMTCAP (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESERADMGMTCAP_MIN_LEN (6)
+
+#define DOT11F_IE_ESERADMGMTCAP_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ese_rad_mgmt_cap(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEESERadMgmtCap*);
+
+uint32_t dot11f_pack_ie_ese_rad_mgmt_cap(
+ tpAniSirGlobal,
+ tDot11fIEESERadMgmtCap *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESERadMgmtCap(
+ tpAniSirGlobal,
+ tDot11fIEESERadMgmtCap *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x07} */
+typedef struct sDot11fIEESETrafStrmMet {
+ uint8_t present;
+ uint8_t tsid;
+ uint8_t state;
+ uint16_t msmt_interval;
+} tDot11fIEESETrafStrmMet;
+
+#define DOT11F_EID_ESETRAFSTRMMET (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESETRAFSTRMMET_MIN_LEN (8)
+
+#define DOT11F_IE_ESETRAFSTRMMET_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ese_traf_strm_met(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEESETrafStrmMet*);
+
+uint32_t dot11f_pack_ie_ese_traf_strm_met(
+ tpAniSirGlobal,
+ tDot11fIEESETrafStrmMet *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESETrafStrmMet(
+ tpAniSirGlobal,
+ tDot11fIEESETrafStrmMet *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x08} */
+typedef struct sDot11fIEESETrafStrmRateSet {
+ uint8_t present;
+ uint8_t tsid;
+ uint8_t num_tsrates;
+ uint8_t tsrates[8];
+} tDot11fIEESETrafStrmRateSet;
+
+#define DOT11F_EID_ESETRAFSTRMRATESET (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESETRAFSTRMRATESET_MIN_LEN (5)
+
+#define DOT11F_IE_ESETRAFSTRMRATESET_MAX_LEN (13)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ese_traf_strm_rate_set(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEESETrafStrmRateSet*);
+
+uint32_t dot11f_pack_ie_ese_traf_strm_rate_set(
+ tpAniSirGlobal,
+ tDot11fIEESETrafStrmRateSet *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESETrafStrmRateSet(
+ tpAniSirGlobal,
+ tDot11fIEESETrafStrmRateSet *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 150 (0x96) {OUI 0x00, 0x40, 0x96, 0x00} */
+typedef struct sDot11fIEESETxmitPower {
+ uint8_t present;
+ uint8_t power_limit;
+ uint8_t reserved;
+} tDot11fIEESETxmitPower;
+
+#define DOT11F_EID_ESETXMITPOWER (150)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESETXMITPOWER_MIN_LEN (6)
+
+#define DOT11F_IE_ESETXMITPOWER_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ese_txmit_power(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEESETxmitPower*);
+
+uint32_t dot11f_pack_ie_ese_txmit_power(
+ tpAniSirGlobal,
+ tDot11fIEESETxmitPower *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESETxmitPower(
+ tpAniSirGlobal,
+ tDot11fIEESETxmitPower *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x03} */
+typedef struct sDot11fIEESEVersion {
+ uint8_t present;
+ uint8_t version;
+} tDot11fIEESEVersion;
+
+#define DOT11F_EID_ESEVERSION (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_ESEVERSION_MIN_LEN (5)
+
+#define DOT11F_IE_ESEVERSION_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ese_version(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEESEVersion*);
+
+uint32_t dot11f_pack_ie_ese_version(
+ tpAniSirGlobal,
+ tDot11fIEESEVersion *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ESEVersion(
+ tpAniSirGlobal,
+ tDot11fIEESEVersion *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 127 (0x7f) */
+typedef struct sDot11fIEExtCap {
+ uint8_t present;
+ uint8_t num_bytes;
+ uint8_t bytes[9];
+} tDot11fIEExtCap;
+
+#define DOT11F_EID_EXTCAP (127)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EXTCAP_MIN_LEN (8)
+
+#define DOT11F_IE_EXTCAP_MAX_LEN (9)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ext_cap(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEExtCap*);
+
+uint32_t dot11f_pack_ie_ext_cap(
+ tpAniSirGlobal,
+ tDot11fIEExtCap *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ExtCap(
+ tpAniSirGlobal,
+ tDot11fIEExtCap *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 50 (0x32) */
+typedef struct sDot11fIEExtSuppRates {
+ uint8_t present;
+ uint8_t num_rates;
+ uint8_t rates[12];
+} tDot11fIEExtSuppRates;
+
+#define DOT11F_EID_EXTSUPPRATES (50)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EXTSUPPRATES_MIN_LEN (1)
+
+#define DOT11F_IE_EXTSUPPRATES_MAX_LEN (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ext_supp_rates(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEExtSuppRates*);
+
+uint32_t dot11f_pack_ie_ext_supp_rates(
+ tpAniSirGlobal,
+ tDot11fIEExtSuppRates *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ExtSuppRates(
+ tpAniSirGlobal,
+ tDot11fIEExtSuppRates *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 2 (0x02) */
+typedef struct sDot11fIEFHParamSet {
+ uint8_t present;
+ uint16_t dwell_time;
+ uint8_t hop_set;
+ uint8_t hop_pattern;
+ uint8_t hop_index;
+} tDot11fIEFHParamSet;
+
+#define DOT11F_EID_FHPARAMSET (2)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FHPARAMSET_MIN_LEN (5)
+
+#define DOT11F_IE_FHPARAMSET_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_fh_param_set(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEFHParamSet*);
+
+uint32_t dot11f_pack_ie_fh_param_set(
+ tpAniSirGlobal,
+ tDot11fIEFHParamSet *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_FHParamSet(
+ tpAniSirGlobal,
+ tDot11fIEFHParamSet *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 8 (0x08) */
+typedef struct sDot11fIEFHParams {
+ uint8_t present;
+ uint8_t radix;
+ uint8_t nchannels;
+} tDot11fIEFHParams;
+
+#define DOT11F_EID_FHPARAMS (8)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FHPARAMS_MIN_LEN (2)
+
+#define DOT11F_IE_FHPARAMS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_fh_params(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEFHParams*);
+
+uint32_t dot11f_pack_ie_fh_params(
+ tpAniSirGlobal,
+ tDot11fIEFHParams *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_FHParams(
+ tpAniSirGlobal,
+ tDot11fIEFHParams *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 9 (0x09) */
+typedef struct sDot11fIEFHPattTable {
+ uint8_t present;
+ uint8_t flag;
+ uint8_t nsets;
+ uint8_t modulus;
+ uint8_t offset;
+ uint8_t num_randtable;
+ uint8_t randtable[251];
+} tDot11fIEFHPattTable;
+
+#define DOT11F_EID_FHPATTTABLE (9)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FHPATTTABLE_MIN_LEN (4)
+
+#define DOT11F_IE_FHPATTTABLE_MAX_LEN (255)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_fh_patt_table(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEFHPattTable*);
+
+uint32_t dot11f_pack_ie_fh_patt_table(
+ tpAniSirGlobal,
+ tDot11fIEFHPattTable *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_FHPattTable(
+ tpAniSirGlobal,
+ tDot11fIEFHPattTable *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 55 (0x37) */
+typedef struct sDot11fIEFTInfo {
+ uint8_t present;
+ uint16_t reserved:8;
+ uint16_t IECount:8;
+ uint8_t MIC[16];
+ uint8_t Anonce[32];
+ uint8_t Snonce[32];
+ tDot11fIER1KH_ID R1KH_ID;
+ tDot11fIEGTK GTK;
+ tDot11fIER0KH_ID R0KH_ID;
+ tDot11fIEIGTK IGTK;
+} tDot11fIEFTInfo;
+
+#define DOT11F_EID_FTINFO (55)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_FTINFO_MIN_LEN (82)
+
+#define DOT11F_IE_FTINFO_MAX_LEN (220)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ft_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEFTInfo*);
+
+uint32_t dot11f_pack_ie_ft_info(
+ tpAniSirGlobal,
+ tDot11fIEFTInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ieft_info(
+ tpAniSirGlobal,
+ tDot11fIEFTInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 45 (0x2d) */
+typedef struct sDot11fIEHTCaps {
+ uint8_t present;
+ uint16_t advCodingCap:1;
+ uint16_t supportedChannelWidthSet:1;
+ uint16_t mimoPowerSave:2;
+ uint16_t greenField:1;
+ uint16_t shortGI20MHz:1;
+ uint16_t shortGI40MHz:1;
+ uint16_t txSTBC:1;
+ uint16_t rxSTBC:2;
+ uint16_t delayedBA:1;
+ uint16_t maximalAMSDUsize:1;
+ uint16_t dsssCckMode40MHz:1;
+ uint16_t psmp:1;
+ uint16_t stbcControlFrame:1;
+ uint16_t lsigTXOPProtection:1;
+ uint8_t maxRxAMPDUFactor:2;
+ uint8_t mpduDensity:3;
+ uint8_t reserved1:3;
+ uint8_t supportedMCSSet[16];
+ uint16_t pco:1;
+ uint16_t transitionTime:2;
+ uint16_t reserved2:5;
+ uint16_t mcsFeedback:2;
+ uint16_t reserved3:6;
+ uint32_t txBF:1;
+ uint32_t rxStaggeredSounding:1;
+ uint32_t txStaggeredSounding:1;
+ uint32_t rxZLF:1;
+ uint32_t txZLF:1;
+ uint32_t implicitTxBF:1;
+ uint32_t calibration:2;
+ uint32_t explicitCSITxBF:1;
+ uint32_t explicitUncompressedSteeringMatrix:1;
+ uint32_t explicitBFCSIFeedback:3;
+ uint32_t explicitUncompressedSteeringMatrixFeedback:3;
+ uint32_t explicitCompressedSteeringMatrixFeedback:3;
+ uint32_t csiNumBFAntennae:2;
+ uint32_t uncompressedSteeringMatrixBFAntennae:2;
+ uint32_t compressedSteeringMatrixBFAntennae:2;
+ uint32_t reserved4:7;
+ uint8_t antennaSelection:1;
+ uint8_t explicitCSIFeedbackTx:1;
+ uint8_t antennaIndicesFeedbackTx:1;
+ uint8_t explicitCSIFeedback:1;
+ uint8_t antennaIndicesFeedback:1;
+ uint8_t rxAS:1;
+ uint8_t txSoundingPPDUs:1;
+ uint8_t reserved5:1;
+ uint8_t num_rsvd;
+ uint8_t rsvd[32];
+} tDot11fIEHTCaps;
+
+#define DOT11F_EID_HTCAPS (45)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HTCAPS_MIN_LEN (26)
+
+#define DOT11F_IE_HTCAPS_MAX_LEN (58)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ht_caps(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEHTCaps*);
+
+uint32_t dot11f_pack_ie_ht_caps(
+ tpAniSirGlobal,
+ tDot11fIEHTCaps *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_HTCaps(
+ tpAniSirGlobal,
+ tDot11fIEHTCaps *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 61 (0x3d) */
+typedef struct sDot11fIEHTInfo {
+ uint8_t present;
+ uint8_t primaryChannel;
+ uint8_t secondaryChannelOffset:2;
+ uint8_t recommendedTxWidthSet:1;
+ uint8_t rifsMode:1;
+ uint8_t controlledAccessOnly:1;
+ uint8_t serviceIntervalGranularity:3;
+ uint16_t opMode:2;
+ uint16_t nonGFDevicesPresent:1;
+ uint16_t transmitBurstLimit:1;
+ uint16_t obssNonHTStaPresent:1;
+ uint16_t reserved:11;
+ uint16_t basicSTBCMCS:7;
+ uint16_t dualCTSProtection:1;
+ uint16_t secondaryBeacon:1;
+ uint16_t lsigTXOPProtectionFullSupport:1;
+ uint16_t pcoActive:1;
+ uint16_t pcoPhase:1;
+ uint16_t reserved2:4;
+ uint8_t basicMCSSet[16];
+ uint8_t num_rsvd;
+ uint8_t rsvd[32];
+} tDot11fIEHTInfo;
+
+#define DOT11F_EID_HTINFO (61)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HTINFO_MIN_LEN (22)
+
+#define DOT11F_IE_HTINFO_MAX_LEN (54)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ht_info(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEHTInfo*);
+
+uint32_t dot11f_pack_ie_ht_info(
+ tpAniSirGlobal,
+ tDot11fIEHTInfo *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_HTInfo(
+ tpAniSirGlobal,
+ tDot11fIEHTInfo *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 6 (0x06) */
+typedef struct sDot11fIEIBSSParams {
+ uint8_t present;
+ uint16_t atim;
+} tDot11fIEIBSSParams;
+
+#define DOT11F_EID_IBSSPARAMS (6)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_IBSSPARAMS_MIN_LEN (2)
+
+#define DOT11F_IE_IBSSPARAMS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ibss_params(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEIBSSParams*);
+
+uint32_t dot11f_pack_ie_ibss_params(
+ tpAniSirGlobal,
+ tDot11fIEIBSSParams *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_IBSSParams(
+ tpAniSirGlobal,
+ tDot11fIEIBSSParams *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 101 (0x65) */
+typedef struct sDot11fIELinkIdentifier {
+ uint8_t present;
+ uint8_t bssid[6];
+ uint8_t InitStaAddr[6];
+ uint8_t RespStaAddr[6];
+} tDot11fIELinkIdentifier;
+
+#define DOT11F_EID_LINKIDENTIFIER (101)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_LINKIDENTIFIER_MIN_LEN (18)
+
+#define DOT11F_IE_LINKIDENTIFIER_MAX_LEN (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_link_identifier(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIELinkIdentifier*);
+
+uint32_t dot11f_pack_ie_link_identifier(
+ tpAniSirGlobal,
+ tDot11fIELinkIdentifier *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_LinkIdentifier(
+ tpAniSirGlobal,
+ tDot11fIELinkIdentifier *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 39 (0x27) */
+typedef struct sDot11fIEMeasurementReport {
+ uint8_t present;
+ uint8_t token;
+ uint8_t late:1;
+ uint8_t incapable:1;
+ uint8_t refused:1;
+ uint8_t unused:5;
+ uint8_t type;
+ union {
+ struct {
+ uint8_t channel;
+ tDOT11F_U64 meas_start_time;
+ uint16_t meas_duration;
+ uint8_t bss:1;
+ uint8_t ofdm_preamble:1;
+ uint8_t unid_signal:1;
+ uint8_t rader:1;
+ uint8_t unmeasured:1;
+ uint8_t unused:3;
+ } Basic; /* type = 0 */
+ struct {
+ uint8_t channel;
+ tDOT11F_U64 meas_start_time;
+ uint16_t meas_duration;
+ uint8_t cca_busy_fraction;
+ } CCA; /* type = 1 */
+ struct {
+ uint8_t channel;
+ tDOT11F_U64 meas_start_time;
+ uint16_t meas_duration;
+ uint8_t rpi0_density;
+ uint8_t rpi1_density;
+ uint8_t rpi2_density;
+ uint8_t rpi3_density;
+ uint8_t rpi4_density;
+ uint8_t rpi5_density;
+ uint8_t rpi6_density;
+ uint8_t rpi7_density;
+ } RPIHistogram; /* type = 2 */
+ struct {
+ uint8_t regClass;
+ uint8_t channel;
+ tDOT11F_U64 meas_start_time;
+ uint16_t meas_duration;
+ uint8_t condensed_PHY:7;
+ uint8_t reported_frame_type:1;
+ uint8_t RCPI;
+ uint8_t RSNI;
+ uint8_t BSSID[6];
+ uint8_t antenna_id;
+ uint32_t parent_TSF;
+ tDot11fIEBeaconReportFrmBody BeaconReportFrmBody;
+ } Beacon; /* type = 5 */
+ } report;
+} tDot11fIEMeasurementReport;
+
+#define DOT11F_EID_MEASUREMENTREPORT (39)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MEASUREMENTREPORT_MIN_LEN (3)
+
+#define DOT11F_IE_MEASUREMENTREPORT_MAX_LEN (29)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_measurement_report(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEMeasurementReport*);
+
+uint32_t dot11f_pack_ie_measurement_report(
+ tpAniSirGlobal,
+ tDot11fIEMeasurementReport *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_measurement_report(
+ tpAniSirGlobal,
+ tDot11fIEMeasurementReport *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 38 (0x26) */
+typedef struct sDot11fIEMeasurementRequest {
+ uint8_t present;
+ uint8_t measurement_token;
+ uint8_t parallel:1;
+ uint8_t enable:1;
+ uint8_t request:1;
+ uint8_t report:1;
+ uint8_t durationMandatory:1;
+ uint8_t unused:3;
+ uint8_t measurement_type;
+ union {
+ struct {
+ uint8_t channel_no;
+ uint8_t meas_start_time[8];
+ uint16_t meas_duration;
+ } Basic; /* measurement_type = 0 */
+ struct {
+ uint8_t channel_no;
+ uint8_t meas_start_time[8];
+ uint16_t meas_duration;
+ } CCA; /* measurement_type = 1 */
+ struct {
+ uint8_t channel_no;
+ uint8_t meas_start_time[8];
+ uint16_t meas_duration;
+ } RPIHistogram; /* measurement_type = 2 */
+ struct {
+ uint8_t regClass;
+ uint8_t channel;
+ uint16_t randomization;
+ uint16_t meas_duration;
+ uint8_t meas_mode;
+ uint8_t BSSID[6];
+ tDot11fIESSID SSID;
+ tDot11fIEBeaconReporting BeaconReporting;
+ tDot11fIEBcnReportingDetail BcnReportingDetail;
+ tDot11fIERequestedInfo RequestedInfo;
+ uint16_t num_APChannelReport;
+ tDot11fIEAPChannelReport APChannelReport[2];
+ } Beacon; /* measurement_type = 5 */
+ } measurement_request;
+} tDot11fIEMeasurementRequest;
+
+#define DOT11F_EID_MEASUREMENTREQUEST (38)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN (14)
+
+#define DOT11F_IE_MEASUREMENTREQUEST_MAX_LEN (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_measurement_request(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEMeasurementRequest*);
+
+uint32_t dot11f_pack_ie_measurement_request(
+ tpAniSirGlobal,
+ tDot11fIEMeasurementRequest *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_measurement_request(
+ tpAniSirGlobal,
+ tDot11fIEMeasurementRequest *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 54 (0x36) */
+typedef struct sDot11fIEMobilityDomain {
+ uint8_t present;
+ uint16_t MDID;
+ uint8_t overDSCap:1;
+ uint8_t resourceReqCap:1;
+ uint8_t reserved:6;
+} tDot11fIEMobilityDomain;
+
+#define DOT11F_EID_MOBILITYDOMAIN (54)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_MOBILITYDOMAIN_MIN_LEN (3)
+
+#define DOT11F_IE_MOBILITYDOMAIN_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_mobility_domain(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEMobilityDomain*);
+
+uint32_t dot11f_pack_ie_mobility_domain(
+ tpAniSirGlobal,
+ tDot11fIEMobilityDomain *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_MobilityDomain(
+ tpAniSirGlobal,
+ tDot11fIEMobilityDomain *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 52 (0x34) */
+typedef struct sDot11fIENeighborReport {
+ uint8_t present;
+ uint8_t bssid[6];
+ uint8_t APReachability:2;
+ uint8_t Security:1;
+ uint8_t KeyScope:1;
+ uint8_t SpecMgmtCap:1;
+ uint8_t QosCap:1;
+ uint8_t apsd:1;
+ uint8_t rrm:1;
+ uint8_t DelayedBA:1;
+ uint8_t ImmBA:1;
+ uint8_t MobilityDomain:1;
+ uint8_t reserved:5;
+ uint16_t reserved1;
+ uint8_t regulatoryClass;
+ uint8_t channel;
+ uint8_t PhyType;
+ tDot11fIETSFInfo TSFInfo;
+ tDot11fIECondensedCountryStr CondensedCountryStr;
+ tDot11fIEMeasurementPilot MeasurementPilot;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMultiBssid MultiBssid;
+} tDot11fIENeighborReport;
+
+#define DOT11F_EID_NEIGHBORREPORT (52)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_NEIGHBORREPORT_MIN_LEN (13)
+
+#define DOT11F_IE_NEIGHBORREPORT_MAX_LEN (546)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_neighbor_report(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIENeighborReport*);
+
+uint32_t dot11f_pack_ie_neighbor_report(
+ tpAniSirGlobal,
+ tDot11fIENeighborReport *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_neighbor_report(
+ tpAniSirGlobal,
+ tDot11fIENeighborReport *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 74 (0x4a) */
+typedef struct sDot11fIEOBSSScanParameters {
+ uint8_t present;
+ uint16_t obssScanPassiveDwell;
+ uint16_t obssScanActiveDwell;
+ uint16_t bssChannelWidthTriggerScanInterval;
+ uint16_t obssScanPassiveTotalPerChannel;
+ uint16_t obssScanActiveTotalPerChannel;
+ uint16_t bssWidthChannelTransitionDelayFactor;
+ uint16_t obssScanActivityThreshold;
+} tDot11fIEOBSSScanParameters;
+
+#define DOT11F_EID_OBSSSCANPARAMETERS (74)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_OBSSSCANPARAMETERS_MIN_LEN (14)
+
+#define DOT11F_IE_OBSSSCANPARAMETERS_MAX_LEN (14)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_obss_scan_parameters(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEOBSSScanParameters*);
+
+uint32_t dot11f_pack_ie_obss_scan_parameters(
+ tpAniSirGlobal,
+ tDot11fIEOBSSScanParameters *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_OBSSScanParameters(
+ tpAniSirGlobal,
+ tDot11fIEOBSSScanParameters *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 199 (0xc7) */
+typedef struct sDot11fIEOperatingMode {
+ uint8_t present;
+ uint8_t chanWidth:2;
+ uint8_t reserved:2;
+ uint8_t rxNSS:3;
+ uint8_t rxNSSType:1;
+} tDot11fIEOperatingMode;
+
+#define DOT11F_EID_OPERATINGMODE (199)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_OPERATINGMODE_MIN_LEN (1)
+
+#define DOT11F_IE_OPERATINGMODE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_operating_mode(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEOperatingMode*);
+
+uint32_t dot11f_pack_ie_operating_mode(
+ tpAniSirGlobal,
+ tDot11fIEOperatingMode *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_OperatingMode(
+ tpAniSirGlobal,
+ tDot11fIEOperatingMode *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PAssocReq {
+ uint8_t present;
+ tDot11fTLVP2PCapability P2PCapability;
+ tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+ tDot11fTLVP2PDeviceInfo P2PDeviceInfo;
+} tDot11fIEP2PAssocReq;
+
+#define DOT11F_EID_P2PASSOCREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PASSOCREQ_MIN_LEN (4)
+
+#define DOT11F_IE_P2PASSOCREQ_MAX_LEN (71)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_assoc_req(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PAssocReq*);
+
+uint32_t dot11f_pack_ie_p2_p_assoc_req(
+ tpAniSirGlobal,
+ tDot11fIEP2PAssocReq *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_assoc_req(
+ tpAniSirGlobal,
+ tDot11fIEP2PAssocReq *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PAssocRes {
+ uint8_t present;
+ tDot11fTLVP2PStatus P2PStatus;
+ tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+} tDot11fIEP2PAssocRes;
+
+#define DOT11F_EID_P2PASSOCRES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PASSOCRES_MIN_LEN (4)
+
+#define DOT11F_IE_P2PASSOCRES_MAX_LEN (15)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_assoc_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PAssocRes*);
+
+uint32_t dot11f_pack_ie_p2_p_assoc_res(
+ tpAniSirGlobal,
+ tDot11fIEP2PAssocRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_assoc_res(
+ tpAniSirGlobal,
+ tDot11fIEP2PAssocRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PBeacon {
+ uint8_t present;
+ tDot11fTLVP2PCapability P2PCapability;
+ tDot11fTLVP2PDeviceId P2PDeviceId;
+ tDot11fTLVNoticeOfAbsence NoticeOfAbsence;
+} tDot11fIEP2PBeacon;
+
+#define DOT11F_EID_P2PBEACON (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PBEACON_MIN_LEN (4)
+
+#define DOT11F_IE_P2PBEACON_MAX_LEN (59)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_beacon(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PBeacon*);
+
+uint32_t dot11f_pack_ie_p2_p_beacon(
+ tpAniSirGlobal,
+ tDot11fIEP2PBeacon *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_beacon(
+ tpAniSirGlobal,
+ tDot11fIEP2PBeacon *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PBeaconProbeRes {
+ uint8_t present;
+ tDot11fTLVP2PCapability P2PCapability;
+ tDot11fTLVP2PDeviceId P2PDeviceId;
+ tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+ tDot11fTLVNoticeOfAbsence NoticeOfAbsence;
+ tDot11fTLVP2PDeviceInfo P2PDeviceInfo;
+ tDot11fTLVP2PGroupInfo P2PGroupInfo;
+} tDot11fIEP2PBeaconProbeRes;
+
+#define DOT11F_EID_P2PBEACONPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PBEACONPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_P2PBEACONPROBERES_MAX_LEN (1148)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_beacon_probe_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PBeaconProbeRes*);
+
+uint32_t dot11f_pack_ie_p2_p_beacon_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEP2PBeaconProbeRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_beacon_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEP2PBeaconProbeRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PDeAuth {
+ uint8_t present;
+ tDot11fTLVMinorReasonCode MinorReasonCode;
+} tDot11fIEP2PDeAuth;
+
+#define DOT11F_EID_P2PDEAUTH (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PDEAUTH_MIN_LEN (4)
+
+#define DOT11F_IE_P2PDEAUTH_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_de_auth(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PDeAuth*);
+
+uint32_t dot11f_pack_ie_p2_p_de_auth(
+ tpAniSirGlobal,
+ tDot11fIEP2PDeAuth *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_de_auth(
+ tpAniSirGlobal,
+ tDot11fIEP2PDeAuth *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PDisAssoc {
+ uint8_t present;
+ tDot11fTLVMinorReasonCode MinorReasonCode;
+} tDot11fIEP2PDisAssoc;
+
+#define DOT11F_EID_P2PDISASSOC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PDISASSOC_MIN_LEN (4)
+
+#define DOT11F_IE_P2PDISASSOC_MAX_LEN (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_dis_assoc(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PDisAssoc*);
+
+uint32_t dot11f_pack_ie_p2_p_dis_assoc(
+ tpAniSirGlobal,
+ tDot11fIEP2PDisAssoc *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_dis_assoc(
+ tpAniSirGlobal,
+ tDot11fIEP2PDisAssoc *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} */
+typedef struct sDot11fIEP2PIEOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[249];
+} tDot11fIEP2PIEOpaque;
+
+#define DOT11F_EID_P2PIEOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PIEOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_P2PIEOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_pie_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PIEOpaque*);
+
+uint32_t dot11f_pack_ie_p2_pie_opaque(
+ tpAniSirGlobal,
+ tDot11fIEP2PIEOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_P2PIEOpaque(
+ tpAniSirGlobal,
+ tDot11fIEP2PIEOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PProbeReq {
+ uint8_t present;
+ tDot11fTLVP2PCapability P2PCapability;
+ tDot11fTLVP2PDeviceId P2PDeviceId;
+ tDot11fTLVListenChannel ListenChannel;
+ tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+ tDot11fTLVOperatingChannel OperatingChannel;
+} tDot11fIEP2PProbeReq;
+
+#define DOT11F_EID_P2PPROBEREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PPROBEREQ_MIN_LEN (4)
+
+#define DOT11F_IE_P2PPROBEREQ_MAX_LEN (41)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_probe_req(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PProbeReq*);
+
+uint32_t dot11f_pack_ie_p2_p_probe_req(
+ tpAniSirGlobal,
+ tDot11fIEP2PProbeReq *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_probe_req(
+ tpAniSirGlobal,
+ tDot11fIEP2PProbeReq *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) */
+typedef struct sDot11fIEP2PProbeRes {
+ uint8_t present;
+ tDot11fTLVP2PCapability P2PCapability;
+ tDot11fTLVExtendedListenTiming ExtendedListenTiming;
+ tDot11fTLVNoticeOfAbsence NoticeOfAbsence;
+ tDot11fTLVP2PDeviceInfo P2PDeviceInfo;
+ tDot11fTLVP2PGroupInfo P2PGroupInfo;
+} tDot11fIEP2PProbeRes;
+
+#define DOT11F_EID_P2PPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_P2PPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_P2PPROBERES_MAX_LEN (1139)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_p2_p_probe_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEP2PProbeRes*);
+
+uint32_t dot11f_pack_ie_p2_p_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEP2PProbeRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iep2_p_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEP2PProbeRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 105 (0x69) */
+typedef struct sDot11fIEPTIControl {
+ uint8_t present;
+ uint8_t tid;
+ uint16_t sequence_control;
+} tDot11fIEPTIControl;
+
+#define DOT11F_EID_PTICONTROL (105)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_PTICONTROL_MIN_LEN (3)
+
+#define DOT11F_IE_PTICONTROL_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_pti_control(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEPTIControl*);
+
+uint32_t dot11f_pack_ie_pti_control(
+ tpAniSirGlobal,
+ tDot11fIEPTIControl *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PTIControl(
+ tpAniSirGlobal,
+ tDot11fIEPTIControl *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 106 (0x6a) */
+typedef struct sDot11fIEPUBufferStatus {
+ uint8_t present;
+ uint8_t ac_bk_traffic_aval:1;
+ uint8_t ac_be_traffic_aval:1;
+ uint8_t ac_vi_traffic_aval:1;
+ uint8_t ac_vo_traffic_aval:1;
+ uint8_t reserved:4;
+} tDot11fIEPUBufferStatus;
+
+#define DOT11F_EID_PUBUFFERSTATUS (106)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_PUBUFFERSTATUS_MIN_LEN (1)
+
+#define DOT11F_IE_PUBUFFERSTATUS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_pu_buffer_status(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEPUBufferStatus*);
+
+uint32_t dot11f_pack_ie_pu_buffer_status(
+ tpAniSirGlobal,
+ tDot11fIEPUBufferStatus *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PUBufferStatus(
+ tpAniSirGlobal,
+ tDot11fIEPUBufferStatus *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 33 (0x21) */
+typedef struct sDot11fIEPowerCaps {
+ uint8_t present;
+ uint8_t minTxPower;
+ uint8_t maxTxPower;
+} tDot11fIEPowerCaps;
+
+#define DOT11F_EID_POWERCAPS (33)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_POWERCAPS_MIN_LEN (2)
+
+#define DOT11F_IE_POWERCAPS_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_power_caps(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEPowerCaps*);
+
+uint32_t dot11f_pack_ie_power_caps(
+ tpAniSirGlobal,
+ tDot11fIEPowerCaps *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PowerCaps(
+ tpAniSirGlobal,
+ tDot11fIEPowerCaps *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 32 (0x20) */
+typedef struct sDot11fIEPowerConstraints {
+ uint8_t present;
+ uint8_t localPowerConstraints;
+} tDot11fIEPowerConstraints;
+
+#define DOT11F_EID_POWERCONSTRAINTS (32)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_POWERCONSTRAINTS_MIN_LEN (1)
+
+#define DOT11F_IE_POWERCONSTRAINTS_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_power_constraints(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEPowerConstraints*);
+
+uint32_t dot11f_pack_ie_power_constraints(
+ tpAniSirGlobal,
+ tDot11fIEPowerConstraints *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_PowerConstraints(
+ tpAniSirGlobal,
+ tDot11fIEPowerConstraints *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 11 (0x0b) */
+typedef struct sDot11fIEQBSSLoad {
+ uint8_t present;
+ uint16_t stacount;
+ uint8_t chautil;
+ uint16_t avail;
+} tDot11fIEQBSSLoad;
+
+#define DOT11F_EID_QBSSLOAD (11)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QBSSLOAD_MIN_LEN (5)
+
+#define DOT11F_IE_QBSSLOAD_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_qbss_load(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEQBSSLoad*);
+
+uint32_t dot11f_pack_ie_qbss_load(
+ tpAniSirGlobal,
+ tDot11fIEQBSSLoad *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QBSSLoad(
+ tpAniSirGlobal,
+ tDot11fIEQBSSLoad *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0xa0, 0xc6} */
+typedef struct sDot11fIEQComVendorIE {
+ uint8_t present;
+ uint8_t type;
+ uint8_t channel;
+} tDot11fIEQComVendorIE;
+
+#define DOT11F_EID_QCOMVENDORIE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QCOMVENDORIE_MIN_LEN (5)
+
+#define DOT11F_IE_QCOMVENDORIE_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_QComVendorIE(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEQComVendorIE*);
+
+uint32_t dot11f_pack_ie_QComVendorIE(
+ tpAniSirGlobal,
+ tDot11fIEQComVendorIE *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QComVendorIE(
+ tpAniSirGlobal,
+ tDot11fIEQComVendorIE *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 46 (0x2e) */
+typedef struct sDot11fIEQOSCapsAp {
+ uint8_t present;
+ uint8_t count:4;
+ uint8_t qack:1;
+ uint8_t qreq:1;
+ uint8_t txopreq:1;
+ uint8_t reserved:1;
+} tDot11fIEQOSCapsAp;
+
+#define DOT11F_EID_QOSCAPSAP (46)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QOSCAPSAP_MIN_LEN (1)
+
+#define DOT11F_IE_QOSCAPSAP_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_qos_caps_ap(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEQOSCapsAp*);
+
+uint32_t dot11f_pack_ie_qos_caps_ap(
+ tpAniSirGlobal,
+ tDot11fIEQOSCapsAp *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QOSCapsAp(
+ tpAniSirGlobal,
+ tDot11fIEQOSCapsAp *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 46 (0x2e) */
+typedef struct sDot11fIEQOSCapsStation {
+ uint8_t present;
+ uint8_t acvo_uapsd:1;
+ uint8_t acvi_uapsd:1;
+ uint8_t acbk_uapsd:1;
+ uint8_t acbe_uapsd:1;
+ uint8_t qack:1;
+ uint8_t max_sp_length:2;
+ uint8_t more_data_ack:1;
+} tDot11fIEQOSCapsStation;
+
+#define DOT11F_EID_QOSCAPSSTATION (46)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QOSCAPSSTATION_MIN_LEN (1)
+
+#define DOT11F_IE_QOSCAPSSTATION_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_qos_caps_station(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEQOSCapsStation*);
+
+uint32_t dot11f_pack_ie_qos_caps_station(
+ tpAniSirGlobal,
+ tDot11fIEQOSCapsStation *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QOSCapsStation(
+ tpAniSirGlobal,
+ tDot11fIEQOSCapsStation *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 110 (0x6e) */
+typedef struct sDot11fIEQosMapSet {
+ uint8_t present;
+ uint8_t num_dscp_exceptions;
+ uint8_t dscp_exceptions[60];
+} tDot11fIEQosMapSet;
+
+#define DOT11F_EID_QOSMAPSET (110)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QOSMAPSET_MIN_LEN (0)
+
+#define DOT11F_IE_QOSMAPSET_MAX_LEN (60)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_qos_map_set(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEQosMapSet*);
+
+uint32_t dot11f_pack_ie_qos_map_set(
+ tpAniSirGlobal,
+ tDot11fIEQosMapSet *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_QosMapSet(
+ tpAniSirGlobal,
+ tDot11fIEQosMapSet *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 40 (0x28) */
+typedef struct sDot11fIEQuiet {
+ uint8_t present;
+ uint8_t count;
+ uint8_t period;
+ uint16_t duration;
+ uint16_t offset;
+} tDot11fIEQuiet;
+
+#define DOT11F_EID_QUIET (40)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_QUIET_MIN_LEN (6)
+
+#define DOT11F_IE_QUIET_MAX_LEN (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_quiet(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEQuiet*);
+
+uint32_t dot11f_pack_ie_quiet(
+ tpAniSirGlobal,
+ tDot11fIEQuiet *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Quiet(
+ tpAniSirGlobal,
+ tDot11fIEQuiet *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 53 (0x35) */
+typedef struct sDot11fIERCPIIE {
+ uint8_t present;
+ uint8_t rcpi;
+} tDot11fIERCPIIE;
+
+#define DOT11F_EID_RCPIIE (53)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RCPIIE_MIN_LEN (1)
+
+#define DOT11F_IE_RCPIIE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_rcpiie(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERCPIIE*);
+
+uint32_t dot11f_pack_ie_rcpiie(
+ tpAniSirGlobal,
+ tDot11fIERCPIIE *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_RCPIIE(
+ tpAniSirGlobal,
+ tDot11fIERCPIIE *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 57 (0x39) */
+typedef struct sDot11fIERICDataDesc {
+ uint8_t present;
+ tDot11fIERICData RICData;
+ tDot11fIERICDescriptor RICDescriptor;
+ tDot11fIETSPEC TSPEC;
+ uint16_t num_TCLAS;
+ tDot11fIETCLAS TCLAS[2];
+ tDot11fIETCLASSPROC TCLASSPROC;
+ tDot11fIETSDelay TSDelay;
+ tDot11fIESchedule Schedule;
+ tDot11fIEWMMTSPEC WMMTSPEC;
+ uint16_t num_WMMTCLAS;
+ tDot11fIEWMMTCLAS WMMTCLAS[2];
+ tDot11fIEWMMTCLASPROC WMMTCLASPROC;
+ tDot11fIEWMMTSDelay WMMTSDelay;
+ tDot11fIEWMMSchedule WMMSchedule;
+} tDot11fIERICDataDesc;
+
+#define DOT11F_EID_RICDATADESC (57)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RICDATADESC_MIN_LEN (0)
+
+#define DOT11F_IE_RICDATADESC_MAX_LEN (548)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ric_data_desc(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERICDataDesc*);
+
+uint32_t dot11f_pack_ie_ric_data_desc(
+ tpAniSirGlobal,
+ tDot11fIERICDataDesc *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ieric_data_desc(
+ tpAniSirGlobal,
+ tDot11fIERICDataDesc *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 48 (0x30) */
+typedef struct sDot11fIERSN {
+ uint8_t present;
+ uint16_t version /* Must be 1! */;
+ uint8_t gp_cipher_suite[4];
+ uint16_t pwise_cipher_suite_count;
+ uint8_t pwise_cipher_suites[4][4];
+ uint16_t akm_suite_count;
+ uint8_t akm_suites[4][4];
+ uint8_t RSN_Cap[2];
+ uint16_t pmkid_count;
+ uint8_t pmkid[4][16];
+ uint8_t gp_mgmt_cipher_suite[4];
+} tDot11fIERSN;
+
+#define DOT11F_EID_RSN (48)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RSN_MIN_LEN (6)
+
+#define DOT11F_IE_RSN_MAX_LEN (114)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_rsn(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERSN*);
+
+uint32_t dot11f_pack_ie_rsn(
+ tpAniSirGlobal,
+ tDot11fIERSN *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iersn(
+ tpAniSirGlobal,
+ tDot11fIERSN *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 65 (0x41) */
+typedef struct sDot11fIERSNIIE {
+ uint8_t present;
+ uint8_t rsni;
+} tDot11fIERSNIIE;
+
+#define DOT11F_EID_RSNIIE (65)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RSNIIE_MIN_LEN (1)
+
+#define DOT11F_IE_RSNIIE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_rsniie(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERSNIIE*);
+
+uint32_t dot11f_pack_ie_rsniie(
+ tpAniSirGlobal,
+ tDot11fIERSNIIE *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iersnIIE(
+ tpAniSirGlobal,
+ tDot11fIERSNIIE *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 48 (0x30) */
+typedef struct sDot11fIERSNOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[253];
+} tDot11fIERSNOpaque;
+
+#define DOT11F_EID_RSNOPAQUE (48)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_RSNOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_RSNOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_rsn_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIERSNOpaque*);
+
+uint32_t dot11f_pack_ie_rsn_opaque(
+ tpAniSirGlobal,
+ tDot11fIERSNOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iersnOpaque(
+ tpAniSirGlobal,
+ tDot11fIERSNOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 36 (0x24) */
+typedef struct sDot11fIESuppChannels {
+ uint8_t present;
+ uint8_t num_bands;
+ uint8_t bands[48][2];
+} tDot11fIESuppChannels;
+
+#define DOT11F_EID_SUPPCHANNELS (36)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SUPPCHANNELS_MIN_LEN (2)
+
+#define DOT11F_IE_SUPPCHANNELS_MAX_LEN (96)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_supp_channels(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIESuppChannels*);
+
+uint32_t dot11f_pack_ie_supp_channels(
+ tpAniSirGlobal,
+ tDot11fIESuppChannels *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SuppChannels(
+ tpAniSirGlobal,
+ tDot11fIESuppChannels *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 59 (0x3b) */
+typedef struct sDot11fIESuppOperatingClasses {
+ uint8_t present;
+ uint8_t num_classes;
+ uint8_t classes[32];
+} tDot11fIESuppOperatingClasses;
+
+#define DOT11F_EID_SUPPOPERATINGCLASSES (59)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SUPPOPERATINGCLASSES_MIN_LEN (1)
+
+#define DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_supp_operating_classes(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIESuppOperatingClasses*);
+
+uint32_t dot11f_pack_ie_supp_operating_classes(
+ tpAniSirGlobal,
+ tDot11fIESuppOperatingClasses *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SuppOperatingClasses(
+ tpAniSirGlobal,
+ tDot11fIESuppOperatingClasses *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 1 (0x01) */
+typedef struct sDot11fIESuppRates {
+ uint8_t present;
+ uint8_t num_rates;
+ uint8_t rates[12];
+} tDot11fIESuppRates;
+
+#define DOT11F_EID_SUPPRATES (1)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SUPPRATES_MIN_LEN (0)
+
+#define DOT11F_IE_SUPPRATES_MAX_LEN (12)
+
+#define DOT11F_IS_BG_RATE(_x) (((_x) == 02) || \
+ ((_x) == 04) || \
+ ((_x) == 11) || \
+ ((_x) == 22) || \
+ ((_x) == 12) || \
+ ((_x) == 18) || \
+ ((_x) == 24) || \
+ ((_x) == 36) || \
+ ((_x) == 48) || \
+ ((_x) == 72) || \
+ ((_x) == 96) || \
+ ((_x) == 108))
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_supp_rates(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIESuppRates*);
+
+uint32_t dot11f_pack_ie_supp_rates(
+ tpAniSirGlobal,
+ tDot11fIESuppRates *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_SuppRates(
+ tpAniSirGlobal,
+ tDot11fIESuppRates *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 5 (0x05) */
+typedef struct sDot11fIETIM {
+ uint8_t present;
+ uint8_t dtim_count;
+ uint8_t dtim_period;
+ uint8_t bmpctl;
+ uint8_t num_vbmp;
+ uint8_t vbmp[251];
+} tDot11fIETIM;
+
+#define DOT11F_EID_TIM (5)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TIM_MIN_LEN (4)
+
+#define DOT11F_IE_TIM_MAX_LEN (254)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tim(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETIM*);
+
+uint32_t dot11f_pack_ie_tim(
+ tpAniSirGlobal,
+ tDot11fIETIM *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TIM(
+ tpAniSirGlobal,
+ tDot11fIETIM *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 35 (0x23) */
+typedef struct sDot11fIETPCReport {
+ uint8_t present;
+ uint8_t tx_power;
+ uint8_t link_margin;
+} tDot11fIETPCReport;
+
+#define DOT11F_EID_TPCREPORT (35)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TPCREPORT_MIN_LEN (2)
+
+#define DOT11F_IE_TPCREPORT_MAX_LEN (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tpc_report(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETPCReport*);
+
+uint32_t dot11f_pack_ie_tpc_report(
+ tpAniSirGlobal,
+ tDot11fIETPCReport *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TPCReport(
+ tpAniSirGlobal,
+ tDot11fIETPCReport *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 34 (0x22) */
+typedef struct sDot11fIETPCRequest {
+ uint8_t present;
+} tDot11fIETPCRequest;
+
+#define DOT11F_EID_TPCREQUEST (34)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TPCREQUEST_MIN_LEN (0)
+
+#define DOT11F_IE_TPCREQUEST_MAX_LEN (0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_tpc_request(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETPCRequest*);
+
+uint32_t dot11f_pack_ie_tpc_request(
+ tpAniSirGlobal,
+ tDot11fIETPCRequest *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TPCRequest(
+ tpAniSirGlobal,
+ tDot11fIETPCRequest *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 69 (0x45) */
+typedef struct sDot11fIETimeAdvertisement {
+ uint8_t present;
+ uint8_t timing_capabilities;
+ uint8_t time_value[10];
+ uint8_t time_error[5];
+} tDot11fIETimeAdvertisement;
+
+#define DOT11F_EID_TIMEADVERTISEMENT (69)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TIMEADVERTISEMENT_MIN_LEN (16)
+
+#define DOT11F_IE_TIMEADVERTISEMENT_MAX_LEN (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_time_advertisement(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETimeAdvertisement*);
+
+uint32_t dot11f_pack_ie_time_advertisement(
+ tpAniSirGlobal,
+ tDot11fIETimeAdvertisement *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_time_advertisement(
+ tpAniSirGlobal,
+ tDot11fIETimeAdvertisement *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 56 (0x38) */
+typedef struct sDot11fIETimeoutInterval {
+ uint8_t present;
+ uint8_t timeoutType;
+ uint32_t timeoutValue;
+} tDot11fIETimeoutInterval;
+
+#define DOT11F_EID_TIMEOUTINTERVAL (56)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_TIMEOUTINTERVAL_MIN_LEN (5)
+
+#define DOT11F_IE_TIMEOUTINTERVAL_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_timeout_interval(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIETimeoutInterval*);
+
+uint32_t dot11f_pack_ie_timeout_interval(
+ tpAniSirGlobal,
+ tDot11fIETimeoutInterval *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_TimeoutInterval(
+ tpAniSirGlobal,
+ tDot11fIETimeoutInterval *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 193 (0xc1) */
+typedef struct sDot11fIEVHTExtBssLoad {
+ uint8_t present;
+ uint8_t muMIMOCapStaCount;
+ uint8_t ssUnderUtil;
+ uint8_t FortyMHzUtil;
+ uint8_t EightyMHzUtil;
+ uint8_t OneSixtyMHzUtil;
+} tDot11fIEVHTExtBssLoad;
+
+#define DOT11F_EID_VHTEXTBSSLOAD (193)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VHTEXTBSSLOAD_MIN_LEN (5)
+
+#define DOT11F_IE_VHTEXTBSSLOAD_MAX_LEN (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_vht_ext_bss_load(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEVHTExtBssLoad*);
+
+uint32_t dot11f_pack_ie_vht_ext_bss_load(
+ tpAniSirGlobal,
+ tDot11fIEVHTExtBssLoad *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_VHTExtBssLoad(
+ tpAniSirGlobal,
+ tDot11fIEVHTExtBssLoad *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x10, 0x18} */
+typedef struct sDot11fIEVendor1IE {
+ uint8_t present;
+} tDot11fIEVendor1IE;
+
+#define DOT11F_EID_VENDOR1IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VENDOR1IE_MIN_LEN (3)
+
+#define DOT11F_IE_VENDOR1IE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_vendor1_ie(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEVendor1IE*);
+
+uint32_t dot11f_pack_ie_vendor1_ie(
+ tpAniSirGlobal,
+ tDot11fIEVendor1IE *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Vendor1IE(
+ tpAniSirGlobal,
+ tDot11fIEVendor1IE *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x16, 0x32} */
+typedef struct sDot11fIEVendor3IE {
+ uint8_t present;
+} tDot11fIEVendor3IE;
+
+#define DOT11F_EID_VENDOR3IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VENDOR3IE_MIN_LEN (3)
+
+#define DOT11F_IE_VENDOR3IE_MAX_LEN (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_vendor3_ie(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEVendor3IE*);
+
+uint32_t dot11f_pack_ie_vendor3_ie(
+ tpAniSirGlobal,
+ tDot11fIEVendor3IE *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_Vendor3IE(
+ tpAniSirGlobal,
+ tDot11fIEVendor3IE *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 68 (0x44) */
+typedef struct sDot11fIEWAPI {
+ uint8_t present;
+ uint16_t version /* Must be 1! */;
+ uint16_t akm_suite_count;
+ uint8_t akm_suites[4][4];
+ uint16_t unicast_cipher_suite_count;
+ uint8_t unicast_cipher_suites[4][4];
+ uint8_t multicast_cipher_suite[4];
+ uint16_t preauth:1;
+ uint16_t reserved:15;
+ uint16_t bkid_count;
+ uint8_t bkid[4][16];
+} tDot11fIEWAPI;
+
+#define DOT11F_EID_WAPI (68)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WAPI_MIN_LEN (12)
+
+#define DOT11F_IE_WAPI_MAX_LEN (110)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wapi(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWAPI*);
+
+uint32_t dot11f_pack_ie_wapi(
+ tpAniSirGlobal,
+ tDot11fIEWAPI *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewapi(
+ tpAniSirGlobal,
+ tDot11fIEWAPI *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 68 (0x44) */
+typedef struct sDot11fIEWAPIOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[253];
+} tDot11fIEWAPIOpaque;
+
+#define DOT11F_EID_WAPIOPAQUE (68)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WAPIOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WAPIOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wapi_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWAPIOpaque*);
+
+uint32_t dot11f_pack_ie_wapi_opaque(
+ tpAniSirGlobal,
+ tDot11fIEWAPIOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewapiOpaque(
+ tpAniSirGlobal,
+ tDot11fIEWAPIOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x08, 0x00} */
+typedef struct sDot11fIEWFATPC {
+ uint8_t present;
+ uint8_t txPower;
+ uint8_t linkMargin;
+} tDot11fIEWFATPC;
+
+#define DOT11F_EID_WFATPC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WFATPC_MIN_LEN (7)
+
+#define DOT11F_IE_WFATPC_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wfatpc(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWFATPC*);
+
+uint32_t dot11f_pack_ie_wfatpc(
+ tpAniSirGlobal,
+ tDot11fIEWFATPC *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WFATPC(
+ tpAniSirGlobal,
+ tDot11fIEWFATPC *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x0a} */
+typedef struct sDot11fIEWFDIEOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[249];
+} tDot11fIEWFDIEOpaque;
+
+#define DOT11F_EID_WFDIEOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WFDIEOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WFDIEOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wfdie_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWFDIEOpaque*);
+
+uint32_t dot11f_pack_ie_wfdie_opaque(
+ tpAniSirGlobal,
+ tDot11fIEWFDIEOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WFDIEOpaque(
+ tpAniSirGlobal,
+ tDot11fIEWFDIEOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x05} */
+typedef struct sDot11fIEWMMCaps {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint8_t reserved:4;
+ uint8_t qack:1;
+ uint8_t queue_request:1;
+ uint8_t txop_request:1;
+ uint8_t more_ack:1;
+} tDot11fIEWMMCaps;
+
+#define DOT11F_EID_WMMCAPS (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMCAPS_MIN_LEN (7)
+
+#define DOT11F_IE_WMMCAPS_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmm_caps(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMCaps*);
+
+uint32_t dot11f_pack_ie_wmm_caps(
+ tpAniSirGlobal,
+ tDot11fIEWMMCaps *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMCaps(
+ tpAniSirGlobal,
+ tDot11fIEWMMCaps *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} */
+typedef struct sDot11fIEWMMInfoAp {
+ uint8_t present;
+ uint8_t version;
+ uint8_t param_set_count:4;
+ uint8_t reserved:3;
+ uint8_t uapsd:1;
+} tDot11fIEWMMInfoAp;
+
+#define DOT11F_EID_WMMINFOAP (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMINFOAP_MIN_LEN (7)
+
+#define DOT11F_IE_WMMINFOAP_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmm_info_ap(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMInfoAp*);
+
+uint32_t dot11f_pack_ie_wmm_info_ap(
+ tpAniSirGlobal,
+ tDot11fIEWMMInfoAp *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMInfoAp(
+ tpAniSirGlobal,
+ tDot11fIEWMMInfoAp *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} */
+typedef struct sDot11fIEWMMInfoStation {
+ uint8_t present;
+ uint8_t version;
+ uint8_t acvo_uapsd:1;
+ uint8_t acvi_uapsd:1;
+ uint8_t acbk_uapsd:1;
+ uint8_t acbe_uapsd:1;
+ uint8_t reserved1:1;
+ uint8_t max_sp_length:2;
+ uint8_t reserved2:1;
+} tDot11fIEWMMInfoStation;
+
+#define DOT11F_EID_WMMINFOSTATION (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMINFOSTATION_MIN_LEN (7)
+
+#define DOT11F_IE_WMMINFOSTATION_MAX_LEN (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmm_info_station(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMInfoStation*);
+
+uint32_t dot11f_pack_ie_wmm_info_station(
+ tpAniSirGlobal,
+ tDot11fIEWMMInfoStation *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMInfoStation(
+ tpAniSirGlobal,
+ tDot11fIEWMMInfoStation *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x01} */
+typedef struct sDot11fIEWMMParams {
+ uint8_t present;
+ uint8_t version /* Must be 1! */;
+ uint8_t qosInfo;
+ uint8_t reserved2;
+ uint8_t acbe_aifsn:4;
+ uint8_t acbe_acm:1;
+ uint8_t acbe_aci:2;
+ uint8_t unused1:1;
+ uint8_t acbe_acwmin:4;
+ uint8_t acbe_acwmax:4;
+ uint16_t acbe_txoplimit;
+ uint8_t acbk_aifsn:4;
+ uint8_t acbk_acm:1;
+ uint8_t acbk_aci:2;
+ uint8_t unused2:1;
+ uint8_t acbk_acwmin:4;
+ uint8_t acbk_acwmax:4;
+ uint16_t acbk_txoplimit;
+ uint8_t acvi_aifsn:4;
+ uint8_t acvi_acm:1;
+ uint8_t acvi_aci:2;
+ uint8_t unused3:1;
+ uint8_t acvi_acwmin:4;
+ uint8_t acvi_acwmax:4;
+ uint16_t acvi_txoplimit;
+ uint8_t acvo_aifsn:4;
+ uint8_t acvo_acm:1;
+ uint8_t acvo_aci:2;
+ uint8_t unused4:1;
+ uint8_t acvo_acwmin:4;
+ uint8_t acvo_acwmax:4;
+ uint16_t acvo_txoplimit;
+} tDot11fIEWMMParams;
+
+#define DOT11F_EID_WMMPARAMS (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WMMPARAMS_MIN_LEN (24)
+
+#define DOT11F_IE_WMMPARAMS_MAX_LEN (24)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wmm_params(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWMMParams*);
+
+uint32_t dot11f_pack_ie_wmm_params(
+ tpAniSirGlobal,
+ tDot11fIEWMMParams *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WMMParams(
+ tpAniSirGlobal,
+ tDot11fIEWMMParams *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} */
+typedef struct sDot11fIEWPA {
+ uint8_t present;
+ uint16_t version /* Must be 1! */;
+ /* field added to fix the bug in dot11fPackIEWPA */
+ uint8_t multicast_cipher_present;
+ uint8_t multicast_cipher[4];
+ uint16_t unicast_cipher_count;
+ uint8_t unicast_ciphers[4][4];
+ uint16_t auth_suite_count;
+ uint8_t auth_suites[4][4];
+ uint16_t caps;
+} tDot11fIEWPA;
+
+#define DOT11F_EID_WPA (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WPA_MIN_LEN (6)
+
+#define DOT11F_IE_WPA_MAX_LEN (48)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wpa(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWPA*);
+
+uint32_t dot11f_pack_ie_wpa(
+ tpAniSirGlobal,
+ tDot11fIEWPA *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewpa(
+ tpAniSirGlobal,
+ tDot11fIEWPA *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} */
+typedef struct sDot11fIEWPAOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[249];
+} tDot11fIEWPAOpaque;
+
+#define DOT11F_EID_WPAOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WPAOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WPAOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wpa_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWPAOpaque*);
+
+uint32_t dot11f_pack_ie_wpa_opaque(
+ tpAniSirGlobal,
+ tDot11fIEWPAOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewpaOpaque(
+ tpAniSirGlobal,
+ tDot11fIEWPAOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWSC {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVWPSState WPSState;
+ tDot11fTLVAPSetupLocked APSetupLocked;
+ tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+ tDot11fTLVUUID_E UUID_E;
+ tDot11fTLVUUID_R UUID_R;
+ tDot11fTLVRFBands RFBands;
+ tDot11fTLVSelectedRegistrar SelectedRegistrar;
+ tDot11fTLVConfigMethods ConfigMethods;
+ tDot11fTLVAssociationState AssociationState;
+ tDot11fTLVConfigurationError ConfigurationError;
+ tDot11fTLVManufacturer Manufacturer;
+ tDot11fTLVModelName ModelName;
+ tDot11fTLVModelNumber ModelNumber;
+ tDot11fTLVSerialNumber SerialNumber;
+ tDot11fTLVDeviceName DeviceName;
+ tDot11fTLVDevicePasswordID DevicePasswordID;
+ tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+ tDot11fTLVRequestType RequestType;
+ tDot11fTLVResponseType ResponseType;
+ tDot11fTLVVendorExtension VendorExtension;
+ tDot11fTLVRequestDeviceType RequestDeviceType;
+} tDot11fIEWSC;
+
+#define DOT11F_EID_WSC (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSC_MIN_LEN (4)
+
+#define DOT11F_IE_WSC_MAX_LEN (366)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWSC*);
+
+uint32_t dot11f_pack_ie_wsc(
+ tpAniSirGlobal,
+ tDot11fIEWSC *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_iewsc(
+ tpAniSirGlobal,
+ tDot11fIEWSC *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscAssocReq {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVRequestType RequestType;
+ tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscAssocReq;
+
+#define DOT11F_EID_WSCASSOCREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCASSOCREQ_MIN_LEN (4)
+
+#define DOT11F_IE_WSCASSOCREQ_MAX_LEN (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_assoc_req(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscAssocReq*);
+
+uint32_t dot11f_pack_ie_wsc_assoc_req(
+ tpAniSirGlobal,
+ tDot11fIEWscAssocReq *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_req(
+ tpAniSirGlobal,
+ tDot11fIEWscAssocReq *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscAssocRes {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVResponseType ResponseType;
+ tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscAssocRes;
+
+#define DOT11F_EID_WSCASSOCRES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCASSOCRES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCASSOCRES_MAX_LEN (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_assoc_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscAssocRes*);
+
+uint32_t dot11f_pack_ie_wsc_assoc_res(
+ tpAniSirGlobal,
+ tDot11fIEWscAssocRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_res(
+ tpAniSirGlobal,
+ tDot11fIEWscAssocRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscBeacon {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVWPSState WPSState;
+ tDot11fTLVAPSetupLocked APSetupLocked;
+ tDot11fTLVSelectedRegistrar SelectedRegistrar;
+ tDot11fTLVDevicePasswordID DevicePasswordID;
+ tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+ tDot11fTLVUUID_E UUID_E;
+ tDot11fTLVRFBands RFBands;
+ tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscBeacon;
+
+#define DOT11F_EID_WSCBEACON (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCBEACON_MIN_LEN (4)
+
+#define DOT11F_IE_WSCBEACON_MAX_LEN (82)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_beacon(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscBeacon*);
+
+uint32_t dot11f_pack_ie_wsc_beacon(
+ tpAniSirGlobal,
+ tDot11fIEWscBeacon *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_beacon(
+ tpAniSirGlobal,
+ tDot11fIEWscBeacon *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscBeaconProbeRes {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVWPSState WPSState;
+ tDot11fTLVAPSetupLocked APSetupLocked;
+ tDot11fTLVSelectedRegistrar SelectedRegistrar;
+ tDot11fTLVDevicePasswordID DevicePasswordID;
+ tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+ tDot11fTLVResponseType ResponseType;
+ tDot11fTLVUUID_E UUID_E;
+ tDot11fTLVManufacturer Manufacturer;
+ tDot11fTLVModelName ModelName;
+ tDot11fTLVModelNumber ModelNumber;
+ tDot11fTLVSerialNumber SerialNumber;
+ tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+ tDot11fTLVDeviceName DeviceName;
+ tDot11fTLVConfigMethods ConfigMethods;
+ tDot11fTLVRFBands RFBands;
+ tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscBeaconProbeRes;
+
+#define DOT11F_EID_WSCBEACONPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCBEACONPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCBEACONPROBERES_MAX_LEN (317)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_beacon_probe_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscBeaconProbeRes*);
+
+uint32_t dot11f_pack_ie_wsc_beacon_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEWscBeaconProbeRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_beacon_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEWscBeaconProbeRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} */
+typedef struct sDot11fIEWscIEOpaque {
+ uint8_t present;
+ uint8_t num_data;
+ uint8_t data[249];
+} tDot11fIEWscIEOpaque;
+
+#define DOT11F_EID_WSCIEOPAQUE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCIEOPAQUE_MIN_LEN (6)
+
+#define DOT11F_IE_WSCIEOPAQUE_MAX_LEN (253)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_ie_opaque(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscIEOpaque*);
+
+uint32_t dot11f_pack_ie_wsc_ie_opaque(
+ tpAniSirGlobal,
+ tDot11fIEWscIEOpaque *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_WscIEOpaque(
+ tpAniSirGlobal,
+ tDot11fIEWscIEOpaque *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscProbeReq {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVRequestType RequestType;
+ tDot11fTLVConfigMethods ConfigMethods;
+ tDot11fTLVUUID_E UUID_E;
+ tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+ tDot11fTLVRFBands RFBands;
+ tDot11fTLVAssociationState AssociationState;
+ tDot11fTLVConfigurationError ConfigurationError;
+ tDot11fTLVDevicePasswordID DevicePasswordID;
+ tDot11fTLVManufacturer Manufacturer;
+ tDot11fTLVModelName ModelName;
+ tDot11fTLVModelNumber ModelNumber;
+ tDot11fTLVDeviceName DeviceName;
+ tDot11fTLVVendorExtension VendorExtension;
+ tDot11fTLVRequestDeviceType RequestDeviceType;
+} tDot11fIEWscProbeReq;
+
+#define DOT11F_EID_WSCPROBEREQ (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCPROBEREQ_MIN_LEN (4)
+
+#define DOT11F_IE_WSCPROBEREQ_MAX_LEN (284)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_probe_req(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscProbeReq*);
+
+uint32_t dot11f_pack_ie_wsc_probe_req(
+ tpAniSirGlobal,
+ tDot11fIEWscProbeReq *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_probe_req(
+ tpAniSirGlobal,
+ tDot11fIEWscProbeReq *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscProbeRes {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVWPSState WPSState;
+ tDot11fTLVAPSetupLocked APSetupLocked;
+ tDot11fTLVSelectedRegistrar SelectedRegistrar;
+ tDot11fTLVDevicePasswordID DevicePasswordID;
+ tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods;
+ tDot11fTLVResponseType ResponseType;
+ tDot11fTLVUUID_E UUID_E;
+ tDot11fTLVManufacturer Manufacturer;
+ tDot11fTLVModelName ModelName;
+ tDot11fTLVModelNumber ModelNumber;
+ tDot11fTLVSerialNumber SerialNumber;
+ tDot11fTLVPrimaryDeviceType PrimaryDeviceType;
+ tDot11fTLVDeviceName DeviceName;
+ tDot11fTLVConfigMethods ConfigMethods;
+ tDot11fTLVRFBands RFBands;
+ tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscProbeRes;
+
+#define DOT11F_EID_WSCPROBERES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCPROBERES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCPROBERES_MAX_LEN (317)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_probe_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscProbeRes*);
+
+uint32_t dot11f_pack_ie_wsc_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEWscProbeRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_probe_res(
+ tpAniSirGlobal,
+ tDot11fIEWscProbeRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) */
+typedef struct sDot11fIEWscReassocRes {
+ uint8_t present;
+ tDot11fTLVVersion Version;
+ tDot11fTLVResponseType ResponseType;
+ tDot11fTLVVendorExtension VendorExtension;
+} tDot11fIEWscReassocRes;
+
+#define DOT11F_EID_WSCREASSOCRES (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_WSCREASSOCRES_MIN_LEN (4)
+
+#define DOT11F_IE_WSCREASSOCRES_MAX_LEN (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_wsc_reassoc_res(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEWscReassocRes*);
+
+uint32_t dot11f_pack_ie_wsc_reassoc_res(
+ tpAniSirGlobal,
+ tDot11fIEWscReassocRes *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_wsc_reassoc_res(
+ tpAniSirGlobal,
+ tDot11fIEWscReassocRes *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 60 (0x3c) */
+typedef struct sDot11fIEext_chan_switch_ann {
+ uint8_t present;
+ uint8_t switch_mode;
+ uint8_t new_reg_class;
+ uint8_t new_channel;
+ uint8_t switch_count;
+} tDot11fIEext_chan_switch_ann;
+
+#define DOT11F_EID_EXT_CHAN_SWITCH_ANN (60)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_EXT_CHAN_SWITCH_ANN_MIN_LEN (4)
+
+#define DOT11F_IE_EXT_CHAN_SWITCH_ANN_MAX_LEN (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ext_chan_switch_ann(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEext_chan_switch_ann*);
+
+uint32_t dot11f_pack_ie_ext_chan_switch_ann(
+ tpAniSirGlobal,
+ tDot11fIEext_chan_switch_ann *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ext_chan_switch_ann(
+ tpAniSirGlobal,
+ tDot11fIEext_chan_switch_ann *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 72 (0x48) */
+typedef struct sDot11fIEht2040_bss_coexistence {
+ uint8_t present;
+ uint8_t info_request:1;
+ uint8_t forty_mhz_intolerant:1;
+ uint8_t twenty_mhz_bsswidth_req:1;
+ uint8_t obss_scan_exemption_req:1;
+ uint8_t obss_scan_exemption_grant:1;
+ uint8_t unused:3;
+} tDot11fIEht2040_bss_coexistence;
+
+#define DOT11F_EID_HT2040_BSS_COEXISTENCE (72)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HT2040_BSS_COEXISTENCE_MIN_LEN (1)
+
+#define DOT11F_IE_HT2040_BSS_COEXISTENCE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEht2040_bss_coexistence*);
+
+uint32_t dot11f_pack_ie_ht2040_bss_coexistence(
+ tpAniSirGlobal,
+ tDot11fIEht2040_bss_coexistence *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ht2040_bss_coexistence(
+ tpAniSirGlobal,
+ tDot11fIEht2040_bss_coexistence *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 73 (0x49) */
+typedef struct sDot11fIEht2040_bss_intolerant_report {
+ uint8_t present;
+ uint8_t operating_class;
+ uint8_t num_channel_list;
+ uint8_t channel_list[50];
+} tDot11fIEht2040_bss_intolerant_report;
+
+#define DOT11F_EID_HT2040_BSS_INTOLERANT_REPORT (73)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_HT2040_BSS_INTOLERANT_REPORT_MIN_LEN (1)
+
+#define DOT11F_IE_HT2040_BSS_INTOLERANT_REPORT_MAX_LEN (51)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEht2040_bss_intolerant_report*);
+
+uint32_t dot11f_pack_ie_ht2040_bss_intolerant_report(
+ tpAniSirGlobal,
+ tDot11fIEht2040_bss_intolerant_report *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_ht2040_bss_intolerant_report(
+ tpAniSirGlobal,
+ tDot11fIEht2040_bss_intolerant_report *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 62 (0x3e) */
+typedef struct sDot11fIEsec_chan_offset_ele {
+ uint8_t present;
+ uint8_t secondaryChannelOffset;
+} tDot11fIEsec_chan_offset_ele;
+
+#define DOT11F_EID_SEC_CHAN_OFFSET_ELE (62)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_SEC_CHAN_OFFSET_ELE_MIN_LEN (1)
+
+#define DOT11F_IE_SEC_CHAN_OFFSET_ELE_MAX_LEN (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_sec_chan_offset_ele(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEsec_chan_offset_ele*);
+
+uint32_t dot11f_pack_ie_sec_chan_offset_ele(
+ tpAniSirGlobal,
+ tDot11fIEsec_chan_offset_ele *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_sec_chan_offset_ele(
+ tpAniSirGlobal,
+ tDot11fIEsec_chan_offset_ele *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+
+/* EID 221 (0xdd) {OUI 0x00, 0x90, 0x4c} */
+typedef struct sDot11fIEvendor2_ie {
+ uint8_t present;
+ uint8_t type;
+ uint8_t sub_type;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+} tDot11fIEvendor2_ie;
+
+#define DOT11F_EID_VENDOR2_IE (221)
+
+/* N.B. These #defines do *not* include the EID & length */
+#define DOT11F_IE_VENDOR2_IE_MIN_LEN (5)
+
+#define DOT11F_IE_VENDOR2_IE_MAX_LEN (26)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+uint32_t dot11f_unpack_ie_vendor2_ie(
+ tpAniSirGlobal,
+ uint8_t *,
+ uint8_t,
+ tDot11fIEvendor2_ie*);
+
+uint32_t dot11f_pack_ie_vendor2_ie(
+ tpAniSirGlobal,
+ tDot11fIEvendor2_ie *,
+ uint8_t *,
+ uint32_t,
+ uint32_t*);
+
+uint32_t dot11f_get_packed_ie_vendor2_ie(
+ tpAniSirGlobal,
+ tDot11fIEvendor2_ie *,
+ uint32_t*);
+
+#ifdef __cplusplus
+}; /* End extern "C". */
+#endif /* C++ */
+/************************************************************************
+ * Frames
+ **********************************************************************/
+
+typedef struct sDot11fAddTSRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIETSPEC TSPEC;
+ uint16_t num_TCLAS;
+ tDot11fIETCLAS TCLAS[2];
+ tDot11fIETCLASSPROC TCLASSPROC;
+ tDot11fIEWMMTSPEC WMMTSPEC;
+ uint16_t num_WMMTCLAS;
+ tDot11fIEWMMTCLAS WMMTCLAS[2];
+ tDot11fIEWMMTCLASPROC WMMTCLASPROC;
+ tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet;
+} tDot11fAddTSRequest;
+
+#define DOT11F_ADDTSREQUEST (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_add_ts_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAddTSRequest * pFrm);
+uint32_t dot11f_pack_add_ts_request(tpAniSirGlobal pCtx,
+ tDot11fAddTSRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_add_ts_request_size(tpAniSirGlobal pCtx,
+ tDot11fAddTSRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAddTSResponse{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfStatus Status;
+ tDot11fIETSDelay TSDelay;
+ tDot11fIETSPEC TSPEC;
+ uint16_t num_TCLAS;
+ tDot11fIETCLAS TCLAS[2];
+ tDot11fIETCLASSPROC TCLASSPROC;
+ tDot11fIESchedule Schedule;
+ tDot11fIEWMMTSDelay WMMTSDelay;
+ tDot11fIEWMMSchedule WMMSchedule;
+ tDot11fIEWMMTSPEC WMMTSPEC;
+ uint16_t num_WMMTCLAS;
+ tDot11fIEWMMTCLAS WMMTCLAS[2];
+ tDot11fIEWMMTCLASPROC WMMTCLASPROC;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+} tDot11fAddTSResponse;
+
+#define DOT11F_ADDTSRESPONSE (2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_add_ts_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAddTSResponse * pFrm);
+uint32_t dot11f_pack_add_ts_response(tpAniSirGlobal pCtx,
+ tDot11fAddTSResponse *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_add_ts_response_size(tpAniSirGlobal pCtx,
+ tDot11fAddTSResponse *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAssocRequest{
+ tDot11fFfCapabilities Capabilities;
+ tDot11fFfListenInterval ListenInterval;
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIEPowerCaps PowerCaps;
+ tDot11fIESuppChannels SuppChannels;
+ tDot11fIERSNOpaque RSNOpaque;
+ tDot11fIEQOSCapsStation QOSCapsStation;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEWPAOpaque WPAOpaque;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEWMMInfoStation WMMInfoStation;
+ tDot11fIEWscIEOpaque WscIEOpaque;
+ tDot11fIEWAPIOpaque WAPIOpaque;
+ tDot11fIEWAPI WAPI;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESEVersion ESEVersion;
+ tDot11fIEP2PIEOpaque P2PIEOpaque;
+ tDot11fIEWFDIEOpaque WFDIEOpaque;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOperatingMode OperatingMode;
+ tDot11fIEQosMapSet QosMapSet;
+ tDot11fIEvendor2_ie vendor2_ie;
+} tDot11fAssocRequest;
+
+#define DOT11F_ASSOCREQUEST (3)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_assoc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAssocRequest * pFrm);
+uint32_t dot11f_pack_assoc_request(tpAniSirGlobal pCtx,
+ tDot11fAssocRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_assoc_request_size(tpAniSirGlobal pCtx,
+ tDot11fAssocRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAssocResponse{
+ tDot11fFfCapabilities Capabilities;
+ tDot11fFfStatus Status;
+ tDot11fFfAID AID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIERCPIIE RCPIIE;
+ tDot11fIERSNIIE RSNIIE;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEFTInfo FTInfo;
+ uint16_t num_RICDataDesc;
+ tDot11fIERICDataDesc RICDataDesc[2];
+ tDot11fIEWPA WPA;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+ tDot11fIEESETxmitPower ESETxmitPower;
+ uint16_t num_WMMTSPEC;
+ tDot11fIEWMMTSPEC WMMTSPEC[4];
+ tDot11fIEWscAssocRes WscAssocRes;
+ tDot11fIEP2PAssocRes P2PAssocRes;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEQosMapSet QosMapSet;
+ tDot11fIEvendor2_ie vendor2_ie;
+} tDot11fAssocResponse;
+
+#define DOT11F_ASSOCRESPONSE (4)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_assoc_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAssocResponse * pFrm);
+uint32_t dot11f_pack_assoc_response(tpAniSirGlobal pCtx,
+ tDot11fAssocResponse *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_assoc_response_size(tpAniSirGlobal pCtx,
+ tDot11fAssocResponse *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fAuthentication{
+ tDot11fFfAuthAlgo AuthAlgo;
+ tDot11fFfAuthSeqNo AuthSeqNo;
+ tDot11fFfStatus Status;
+ tDot11fIEChallengeText ChallengeText;
+ tDot11fIERSNOpaque RSNOpaque;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEFTInfo FTInfo;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ uint16_t num_RICDataDesc;
+ tDot11fIERICDataDesc RICDataDesc[2];
+} tDot11fAuthentication;
+
+#define DOT11F_AUTHENTICATION (5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_authentication(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAuthentication * pFrm);
+uint32_t dot11f_pack_authentication(tpAniSirGlobal pCtx,
+ tDot11fAuthentication *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_authentication_size(tpAniSirGlobal pCtx,
+ tDot11fAuthentication *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeacon{
+ tDot11fFfTimeStamp TimeStamp;
+ tDot11fFfBeaconInterval BeaconInterval;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEFHParamSet FHParamSet;
+ tDot11fIEDSParams DSParams;
+ tDot11fIECFParams CFParams;
+ tDot11fIEIBSSParams IBSSParams;
+ tDot11fIETIM TIM;
+ tDot11fIECountry Country;
+ tDot11fIEFHParams FHParams;
+ tDot11fIEFHPattTable FHPattTable;
+ tDot11fIEPowerConstraints PowerConstraints;
+ tDot11fIEChanSwitchAnn ChanSwitchAnn;
+ tDot11fIEext_chan_switch_ann ext_chan_switch_ann;
+ tDot11fIEQuiet Quiet;
+ tDot11fIETPCReport TPCReport;
+ tDot11fIEERPInfo ERPInfo;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIERSN RSN;
+ tDot11fIEQBSSLoad QBSSLoad;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIEQOSCapsAp QOSCapsAp;
+ tDot11fIEAPChannelReport APChannelReport;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEWPA WPA;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEsec_chan_offset_ele sec_chan_offset_ele;
+ tDot11fIEWMMInfoAp WMMInfoAp;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEWAPI WAPI;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+ tDot11fIEESETxmitPower ESETxmitPower;
+ tDot11fIEWscBeacon WscBeacon;
+ tDot11fIEP2PBeacon P2PBeacon;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOperatingMode OperatingMode;
+ tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+ tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEVendor1IE Vendor1IE;
+ tDot11fIEvendor2_ie vendor2_ie;
+ tDot11fIEVendor3IE Vendor3IE;
+ tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper;
+ tDot11fIEQComVendorIE QComVendorIE;
+ tDot11fIEESEVersion ESEVersion;
+} tDot11fBeacon;
+
+#define DOT11F_BEACON (6)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeacon * pFrm);
+uint32_t dot11f_pack_beacon(tpAniSirGlobal pCtx,
+ tDot11fBeacon *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon_size(tpAniSirGlobal pCtx,
+ tDot11fBeacon *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeacon1{
+ tDot11fFfTimeStamp TimeStamp;
+ tDot11fFfBeaconInterval BeaconInterval;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEDSParams DSParams;
+ tDot11fIEIBSSParams IBSSParams;
+} tDot11fBeacon1;
+
+#define DOT11F_BEACON1 (7)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon1(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeacon1 * pFrm);
+uint32_t dot11f_pack_beacon1(tpAniSirGlobal pCtx,
+ tDot11fBeacon1 *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon1_size(tpAniSirGlobal pCtx,
+ tDot11fBeacon1 *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeacon2{
+ tDot11fIECountry Country;
+ tDot11fIEPowerConstraints PowerConstraints;
+ tDot11fIEChanSwitchAnn ChanSwitchAnn;
+ tDot11fIEext_chan_switch_ann ext_chan_switch_ann;
+ tDot11fIEQuiet Quiet;
+ tDot11fIETPCReport TPCReport;
+ tDot11fIEERPInfo ERPInfo;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIERSNOpaque RSNOpaque;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIEAPChannelReport APChannelReport;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEWPA WPA;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEsec_chan_offset_ele sec_chan_offset_ele;
+ tDot11fIEWMMInfoAp WMMInfoAp;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEWscBeacon WscBeacon;
+ tDot11fIEWAPI WAPI;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+ tDot11fIEESETxmitPower ESETxmitPower;
+ tDot11fIEP2PBeacon P2PBeacon;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOperatingMode OperatingMode;
+ tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+ tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEVendor1IE Vendor1IE;
+ tDot11fIEvendor2_ie vendor2_ie;
+ tDot11fIEVendor3IE Vendor3IE;
+ tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper;
+ tDot11fIEQComVendorIE QComVendorIE;
+ tDot11fIEESEVersion ESEVersion;
+} tDot11fBeacon2;
+
+#define DOT11F_BEACON2 (8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon2(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeacon2 * pFrm);
+uint32_t dot11f_pack_beacon2(tpAniSirGlobal pCtx,
+ tDot11fBeacon2 *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon2_size(tpAniSirGlobal pCtx,
+ tDot11fBeacon2 *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fBeaconIEs{
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEFHParamSet FHParamSet;
+ tDot11fIEDSParams DSParams;
+ tDot11fIECFParams CFParams;
+ tDot11fIEIBSSParams IBSSParams;
+ tDot11fIETIM TIM;
+ tDot11fIECountry Country;
+ tDot11fIEFHParams FHParams;
+ tDot11fIEFHPattTable FHPattTable;
+ tDot11fIEPowerConstraints PowerConstraints;
+ tDot11fIEChanSwitchAnn ChanSwitchAnn;
+ tDot11fIEext_chan_switch_ann ext_chan_switch_ann;
+ tDot11fIEQuiet Quiet;
+ tDot11fIETPCReport TPCReport;
+ tDot11fIEERPInfo ERPInfo;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIERSN RSN;
+ tDot11fIEQBSSLoad QBSSLoad;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIEQOSCapsAp QOSCapsAp;
+ tDot11fIEAPChannelReport APChannelReport;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEWPA WPA;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEsec_chan_offset_ele sec_chan_offset_ele;
+ tDot11fIEWMMInfoAp WMMInfoAp;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEWAPI WAPI;
+ tDot11fIEESEVersion ESEVersion;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+ tDot11fIEESETxmitPower ESETxmitPower;
+ tDot11fIEWscBeaconProbeRes WscBeaconProbeRes;
+ tDot11fIEP2PBeaconProbeRes P2PBeaconProbeRes;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOperatingMode OperatingMode;
+ tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+ tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEVendor1IE Vendor1IE;
+ tDot11fIEvendor2_ie vendor2_ie;
+ tDot11fIEVendor3IE Vendor3IE;
+ tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper;
+ tDot11fIEQComVendorIE QComVendorIE;
+} tDot11fBeaconIEs;
+
+#define DOT11F_BEACONIES (9)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_beacon_i_es(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeaconIEs * pFrm);
+uint32_t dot11f_pack_beacon_i_es(tpAniSirGlobal pCtx,
+ tDot11fBeaconIEs *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_beacon_i_es_size(tpAniSirGlobal pCtx,
+ tDot11fBeaconIEs *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fChannelSwitch{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fIEChanSwitchAnn ChanSwitchAnn;
+ tDot11fIEsec_chan_offset_ele sec_chan_offset_ele;
+ tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+} tDot11fChannelSwitch;
+
+#define DOT11F_CHANNELSWITCH (10)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_channel_switch(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fChannelSwitch * pFrm);
+uint32_t dot11f_pack_channel_switch(tpAniSirGlobal pCtx,
+ tDot11fChannelSwitch *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_channel_switch_size(tpAniSirGlobal pCtx,
+ tDot11fChannelSwitch *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fDeAuth{
+ tDot11fFfReason Reason;
+ tDot11fIEP2PDeAuth P2PDeAuth;
+} tDot11fDeAuth;
+
+#define DOT11F_DEAUTH (11)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_de_auth(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fDeAuth * pFrm);
+uint32_t dot11f_pack_de_auth(tpAniSirGlobal pCtx,
+ tDot11fDeAuth *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_de_auth_size(tpAniSirGlobal pCtx,
+ tDot11fDeAuth *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fDelTS{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfTSInfo TSInfo;
+ tDot11fFfReason Reason;
+} tDot11fDelTS;
+
+#define DOT11F_DELTS (12)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_del_ts(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fDelTS * pFrm);
+uint32_t dot11f_pack_del_ts(tpAniSirGlobal pCtx,
+ tDot11fDelTS *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_del_ts_size(tpAniSirGlobal pCtx,
+ tDot11fDelTS *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fDisassociation{
+ tDot11fFfReason Reason;
+ tDot11fIEP2PDisAssoc P2PDisAssoc;
+} tDot11fDisassociation;
+
+#define DOT11F_DISASSOCIATION (13)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_disassociation(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fDisassociation * pFrm);
+uint32_t dot11f_pack_disassociation(tpAniSirGlobal pCtx,
+ tDot11fDisassociation *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_disassociation_size(tpAniSirGlobal pCtx,
+ tDot11fDisassociation *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fLinkMeasurementReport{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfTPCEleID TPCEleID;
+ tDot11fFfTPCEleLen TPCEleLen;
+ tDot11fFfTxPower TxPower;
+ tDot11fFfLinkMargin LinkMargin;
+ tDot11fFfRxAntennaId RxAntennaId;
+ tDot11fFfTxAntennaId TxAntennaId;
+ tDot11fFfRCPI RCPI;
+ tDot11fFfRSNI RSNI;
+} tDot11fLinkMeasurementReport;
+
+#define DOT11F_LINKMEASUREMENTREPORT (14)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_link_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fLinkMeasurementReport * pFrm);
+uint32_t dot11f_pack_link_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementReport *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_link_measurement_report_size(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementReport *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fLinkMeasurementRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfTxPower TxPower;
+ tDot11fFfMaxTxPower MaxTxPower;
+} tDot11fLinkMeasurementRequest;
+
+#define DOT11F_LINKMEASUREMENTREQUEST (15)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_link_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fLinkMeasurementRequest * pFrm);
+uint32_t dot11f_pack_link_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_link_measurement_request_size(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fMeasurementReport{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIEMeasurementReport MeasurementReport;
+} tDot11fMeasurementReport;
+
+#define DOT11F_MEASUREMENTREPORT (16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fMeasurementReport * pFrm);
+uint32_t dot11f_pack_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fMeasurementReport *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_measurement_report_size(tpAniSirGlobal pCtx,
+ tDot11fMeasurementReport *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fMeasurementRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ uint16_t num_MeasurementRequest;
+ tDot11fIEMeasurementRequest MeasurementRequest[4];
+} tDot11fMeasurementRequest;
+
+#define DOT11F_MEASUREMENTREQUEST (17)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fMeasurementRequest * pFrm);
+uint32_t dot11f_pack_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fMeasurementRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_measurement_request_size(tpAniSirGlobal pCtx,
+ tDot11fMeasurementRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fNeighborReportRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIESSID SSID;
+} tDot11fNeighborReportRequest;
+
+#define DOT11F_NEIGHBORREPORTREQUEST (18)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_neighbor_report_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fNeighborReportRequest * pFrm);
+uint32_t dot11f_pack_neighbor_report_request(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_neighbor_report_request_size(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fNeighborReportResponse{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ uint16_t num_NeighborReport;
+ tDot11fIENeighborReport NeighborReport[15];
+} tDot11fNeighborReportResponse;
+
+#define DOT11F_NEIGHBORREPORTRESPONSE (19)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_neighbor_report_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fNeighborReportResponse * pFrm);
+uint32_t dot11f_pack_neighbor_report_response(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportResponse *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_neighbor_report_response_size(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportResponse *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fOperatingMode{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfOperatingMode OperatingMode;
+} tDot11fOperatingMode;
+
+#define DOT11F_OPERATINGMODE (20)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_operating_mode(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fOperatingMode * pFrm);
+uint32_t dot11f_pack_operating_mode(tpAniSirGlobal pCtx,
+ tDot11fOperatingMode *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_operating_mode_size(tpAniSirGlobal pCtx,
+ tDot11fOperatingMode *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fProbeRequest{
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIERequestedInfo RequestedInfo;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIEDSParams DSParams;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEWscProbeReq WscProbeReq;
+ tDot11fIEWFATPC WFATPC;
+ tDot11fIEP2PProbeReq P2PProbeReq;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEExtCap ExtCap;
+} tDot11fProbeRequest;
+
+#define DOT11F_PROBEREQUEST (21)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_probe_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fProbeRequest * pFrm);
+uint32_t dot11f_pack_probe_request(tpAniSirGlobal pCtx,
+ tDot11fProbeRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_probe_request_size(tpAniSirGlobal pCtx,
+ tDot11fProbeRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fProbeResponse{
+ tDot11fFfTimeStamp TimeStamp;
+ tDot11fFfBeaconInterval BeaconInterval;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEFHParamSet FHParamSet;
+ tDot11fIEDSParams DSParams;
+ tDot11fIECFParams CFParams;
+ tDot11fIEIBSSParams IBSSParams;
+ tDot11fIECountry Country;
+ tDot11fIEFHParams FHParams;
+ tDot11fIEFHPattTable FHPattTable;
+ tDot11fIEPowerConstraints PowerConstraints;
+ tDot11fIEChanSwitchAnn ChanSwitchAnn;
+ tDot11fIEext_chan_switch_ann ext_chan_switch_ann;
+ tDot11fIEQuiet Quiet;
+ tDot11fIETPCReport TPCReport;
+ tDot11fIEERPInfo ERPInfo;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIERSNOpaque RSNOpaque;
+ tDot11fIEQBSSLoad QBSSLoad;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEAPChannelReport APChannelReport;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEWPA WPA;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEsec_chan_offset_ele sec_chan_offset_ele;
+ tDot11fIEWMMInfoAp WMMInfoAp;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEWAPI WAPI;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+ tDot11fIEESETxmitPower ESETxmitPower;
+ tDot11fIEWscProbeRes WscProbeRes;
+ tDot11fIEP2PProbeRes P2PProbeRes;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEVendor1IE Vendor1IE;
+ tDot11fIEvendor2_ie vendor2_ie;
+ tDot11fIEVendor3IE Vendor3IE;
+ tDot11fIEChannelSwitchWrapper ChannelSwitchWrapper;
+ tDot11fIEQComVendorIE QComVendorIE;
+ tDot11fIEESEVersion ESEVersion;
+} tDot11fProbeResponse;
+
+#define DOT11F_PROBERESPONSE (22)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_probe_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fProbeResponse * pFrm);
+uint32_t dot11f_pack_probe_response(tpAniSirGlobal pCtx,
+ tDot11fProbeResponse *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_probe_response_size(tpAniSirGlobal pCtx,
+ tDot11fProbeResponse *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fQosMapConfigure{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fIEQosMapSet QosMapSet;
+} tDot11fQosMapConfigure;
+
+#define DOT11F_QOSMAPCONFIGURE (23)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_qos_map_configure(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fQosMapConfigure * pFrm);
+uint32_t dot11f_pack_qos_map_configure(tpAniSirGlobal pCtx,
+ tDot11fQosMapConfigure *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_qos_map_configure_size(tpAniSirGlobal pCtx,
+ tDot11fQosMapConfigure *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fRadioMeasurementReport{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ uint16_t num_MeasurementReport;
+ tDot11fIEMeasurementReport MeasurementReport[4];
+} tDot11fRadioMeasurementReport;
+
+#define DOT11F_RADIOMEASUREMENTREPORT (24)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_radio_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fRadioMeasurementReport * pFrm);
+uint32_t dot11f_pack_radio_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementReport *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_radio_measurement_report_size(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementReport *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fRadioMeasurementRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfNumOfRepetitions NumOfRepetitions;
+ uint16_t num_MeasurementRequest;
+ tDot11fIEMeasurementRequest MeasurementRequest[2];
+} tDot11fRadioMeasurementRequest;
+
+#define DOT11F_RADIOMEASUREMENTREQUEST (25)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_radio_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fRadioMeasurementRequest * pFrm);
+uint32_t dot11f_pack_radio_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_radio_measurement_request_size(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fReAssocRequest{
+ tDot11fFfCapabilities Capabilities;
+ tDot11fFfListenInterval ListenInterval;
+ tDot11fFfCurrentAPAddress CurrentAPAddress;
+ tDot11fIESSID SSID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIEPowerCaps PowerCaps;
+ tDot11fIESuppChannels SuppChannels;
+ tDot11fIERSNOpaque RSNOpaque;
+ tDot11fIEQOSCapsStation QOSCapsStation;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEFTInfo FTInfo;
+ uint16_t num_RICDataDesc;
+ tDot11fIERICDataDesc RICDataDesc[2];
+ tDot11fIEWPAOpaque WPAOpaque;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEWMMCaps WMMCaps;
+ tDot11fIEWMMInfoStation WMMInfoStation;
+ tDot11fIEWscIEOpaque WscIEOpaque;
+ tDot11fIEWAPIOpaque WAPIOpaque;
+ tDot11fIEWAPI WAPI;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESEVersion ESEVersion;
+ tDot11fIEESECckmOpaque ESECckmOpaque;
+ uint16_t num_WMMTSPEC;
+ tDot11fIEWMMTSPEC WMMTSPEC[4];
+ tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet;
+ tDot11fIEP2PIEOpaque P2PIEOpaque;
+ tDot11fIEWFDIEOpaque WFDIEOpaque;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOperatingMode OperatingMode;
+ tDot11fIEQosMapSet QosMapSet;
+ tDot11fIEvendor2_ie vendor2_ie;
+} tDot11fReAssocRequest;
+
+#define DOT11F_REASSOCREQUEST (26)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_re_assoc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fReAssocRequest * pFrm);
+uint32_t dot11f_pack_re_assoc_request(tpAniSirGlobal pCtx,
+ tDot11fReAssocRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_re_assoc_request_size(tpAniSirGlobal pCtx,
+ tDot11fReAssocRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fReAssocResponse{
+ tDot11fFfCapabilities Capabilities;
+ tDot11fFfStatus Status;
+ tDot11fFfAID AID;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIERCPIIE RCPIIE;
+ tDot11fIERSNIIE RSNIIE;
+ tDot11fIERRMEnabledCap RRMEnabledCap;
+ tDot11fIERSNOpaque RSNOpaque;
+ tDot11fIEMobilityDomain MobilityDomain;
+ tDot11fIEFTInfo FTInfo;
+ uint16_t num_RICDataDesc;
+ tDot11fIERICDataDesc RICDataDesc[2];
+ tDot11fIEWPA WPA;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEESERadMgmtCap ESERadMgmtCap;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+ tDot11fIEESETxmitPower ESETxmitPower;
+ uint16_t num_WMMTSPEC;
+ tDot11fIEWMMTSPEC WMMTSPEC[4];
+ tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet;
+ tDot11fIEWscReassocRes WscReassocRes;
+ tDot11fIEP2PAssocRes P2PAssocRes;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEOBSSScanParameters OBSSScanParameters;
+ tDot11fIEQosMapSet QosMapSet;
+ tDot11fIEvendor2_ie vendor2_ie;
+} tDot11fReAssocResponse;
+
+#define DOT11F_REASSOCRESPONSE (27)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_re_assoc_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fReAssocResponse * pFrm);
+uint32_t dot11f_pack_re_assoc_response(tpAniSirGlobal pCtx,
+ tDot11fReAssocResponse *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_re_assoc_response_size(tpAniSirGlobal pCtx,
+ tDot11fReAssocResponse *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fSMPowerSave{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfSMPowerModeSet SMPowerModeSet;
+} tDot11fSMPowerSave;
+
+#define DOT11F_SMPOWERSAVE (28)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_sm_power_save(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fSMPowerSave * pFrm);
+uint32_t dot11f_pack_sm_power_save(tpAniSirGlobal pCtx,
+ tDot11fSMPowerSave *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_sm_power_save_size(tpAniSirGlobal pCtx,
+ tDot11fSMPowerSave *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fSaQueryReq{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfTransactionId TransactionId;
+} tDot11fSaQueryReq;
+
+#define DOT11F_SAQUERYREQ (29)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_sa_query_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fSaQueryReq * pFrm);
+uint32_t dot11f_pack_sa_query_req(tpAniSirGlobal pCtx,
+ tDot11fSaQueryReq *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_sa_query_req_size(tpAniSirGlobal pCtx,
+ tDot11fSaQueryReq *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fSaQueryRsp{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfTransactionId TransactionId;
+} tDot11fSaQueryRsp;
+
+#define DOT11F_SAQUERYRSP (30)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_sa_query_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fSaQueryRsp * pFrm);
+uint32_t dot11f_pack_sa_query_rsp(tpAniSirGlobal pCtx,
+ tDot11fSaQueryRsp *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_sa_query_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fSaQueryRsp *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSDisReq{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIELinkIdentifier LinkIdentifier;
+} tDot11fTDLSDisReq;
+
+#define DOT11F_TDLSDISREQ (31)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_dis_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSDisReq * pFrm);
+uint32_t dot11f_pack_tdls_dis_req(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisReq *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_dis_req_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisReq *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSDisRsp{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIESuppChannels SuppChannels;
+ tDot11fIESuppOperatingClasses SuppOperatingClasses;
+ tDot11fIERSN RSN;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEFTInfo FTInfo;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ tDot11fIERICData RICData;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEht2040_bss_coexistence ht2040_bss_coexistence;
+ tDot11fIELinkIdentifier LinkIdentifier;
+ tDot11fIEVHTCaps VHTCaps;
+} tDot11fTDLSDisRsp;
+
+#define DOT11F_TDLSDISRSP (32)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSDisRsp * pFrm);
+uint32_t dot11f_pack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisRsp *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_dis_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisRsp *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSPeerTrafficInd{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIELinkIdentifier LinkIdentifier;
+ tDot11fIEPTIControl PTIControl;
+ tDot11fIEPUBufferStatus PUBufferStatus;
+} tDot11fTDLSPeerTrafficInd;
+
+#define DOT11F_TDLSPEERTRAFFICIND (33)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSPeerTrafficInd * pFrm);
+uint32_t dot11f_pack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficInd *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_peer_traffic_ind_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficInd *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSPeerTrafficRsp{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIELinkIdentifier LinkIdentifier;
+} tDot11fTDLSPeerTrafficRsp;
+
+#define DOT11F_TDLSPEERTRAFFICRSP (34)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSPeerTrafficRsp * pFrm);
+uint32_t dot11f_pack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficRsp *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_peer_traffic_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficRsp *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSSetupCnf{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfStatus Status;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIERSN RSN;
+ tDot11fIEEDCAParamSet EDCAParamSet;
+ tDot11fIEFTInfo FTInfo;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIELinkIdentifier LinkIdentifier;
+ tDot11fIEWMMParams WMMParams;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEOperatingMode OperatingMode;
+} tDot11fTDLSSetupCnf;
+
+#define DOT11F_TDLSSETUPCNF (35)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSSetupCnf * pFrm);
+uint32_t dot11f_pack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupCnf *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_setup_cnf_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupCnf *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSSetupReq{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIECountry Country;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIESuppChannels SuppChannels;
+ tDot11fIERSN RSN;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIESuppOperatingClasses SuppOperatingClasses;
+ tDot11fIEQOSCapsStation QOSCapsStation;
+ tDot11fIEFTInfo FTInfo;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ tDot11fIERICData RICData;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEht2040_bss_coexistence ht2040_bss_coexistence;
+ tDot11fIELinkIdentifier LinkIdentifier;
+ tDot11fIEWMMInfoStation WMMInfoStation;
+ tDot11fIEAID AID;
+ tDot11fIEVHTCaps VHTCaps;
+} tDot11fTDLSSetupReq;
+
+#define DOT11F_TDLSSETUPREQ (36)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_setup_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSSetupReq * pFrm);
+uint32_t dot11f_pack_tdls_setup_req(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupReq *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_setup_req_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupReq *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSSetupRsp{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfStatus Status;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIESuppRates SuppRates;
+ tDot11fIECountry Country;
+ tDot11fIEExtSuppRates ExtSuppRates;
+ tDot11fIESuppChannels SuppChannels;
+ tDot11fIERSN RSN;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIESuppOperatingClasses SuppOperatingClasses;
+ tDot11fIEQOSCapsStation QOSCapsStation;
+ tDot11fIEFTInfo FTInfo;
+ tDot11fIETimeoutInterval TimeoutInterval;
+ tDot11fIERICData RICData;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEht2040_bss_coexistence ht2040_bss_coexistence;
+ tDot11fIELinkIdentifier LinkIdentifier;
+ tDot11fIEWMMInfoStation WMMInfoStation;
+ tDot11fIEAID AID;
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEOperatingMode OperatingMode;
+} tDot11fTDLSSetupRsp;
+
+#define DOT11F_TDLSSETUPRSP (37)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSSetupRsp * pFrm);
+uint32_t dot11f_pack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupRsp *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_setup_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupRsp *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTDLSTeardown{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfReason Reason;
+ tDot11fIEFTInfo FTInfo;
+ tDot11fIELinkIdentifier LinkIdentifier;
+} tDot11fTDLSTeardown;
+
+#define DOT11F_TDLSTEARDOWN (38)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tdls_teardown(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSTeardown * pFrm);
+uint32_t dot11f_pack_tdls_teardown(tpAniSirGlobal pCtx,
+ tDot11fTDLSTeardown *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tdls_teardown_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSTeardown *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTPCReport{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIETPCReport TPCReport;
+} tDot11fTPCReport;
+
+#define DOT11F_TPCREPORT (39)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tpc_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTPCReport * pFrm);
+uint32_t dot11f_pack_tpc_report(tpAniSirGlobal pCtx,
+ tDot11fTPCReport *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tpc_report_size(tpAniSirGlobal pCtx,
+ tDot11fTPCReport *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTPCRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fIETPCRequest TPCRequest;
+} tDot11fTPCRequest;
+
+#define DOT11F_TPCREQUEST (40)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_tpc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTPCRequest * pFrm);
+uint32_t dot11f_pack_tpc_request(tpAniSirGlobal pCtx,
+ tDot11fTPCRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_tpc_request_size(tpAniSirGlobal pCtx,
+ tDot11fTPCRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fTimingAdvertisementFrame{
+ tDot11fFfTimeStamp TimeStamp;
+ tDot11fFfCapabilities Capabilities;
+ tDot11fIECountry Country;
+ tDot11fIEPowerConstraints PowerConstraints;
+ tDot11fIETimeAdvertisement TimeAdvertisement;
+ tDot11fIEExtCap ExtCap;
+ tDot11fIEVendor1IE Vendor1IE;
+ tDot11fIEVendor3IE Vendor3IE;
+} tDot11fTimingAdvertisementFrame;
+
+#define DOT11F_TIMINGADVERTISEMENTFRAME (41)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTimingAdvertisementFrame * pFrm);
+uint32_t dot11f_pack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+ tDot11fTimingAdvertisementFrame *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_timing_advertisement_frame_size(tpAniSirGlobal pCtx,
+ tDot11fTimingAdvertisementFrame *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fVHTGidManagementActionFrame{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfVhtMembershipStatusArray VhtMembershipStatusArray;
+ tDot11fFfVhtUserPositionArray VhtUserPositionArray;
+} tDot11fVHTGidManagementActionFrame;
+
+#define DOT11F_VHTGIDMANAGEMENTACTIONFRAME (42)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fVHTGidManagementActionFrame * pFrm);
+uint32_t dot11f_pack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+ tDot11fVHTGidManagementActionFrame *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_vht_gid_management_action_frame_size(tpAniSirGlobal pCtx,
+ tDot11fVHTGidManagementActionFrame *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fWMMAddTSRequest{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfStatusCode StatusCode;
+ tDot11fIEWMMTSPEC WMMTSPEC;
+ tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet;
+} tDot11fWMMAddTSRequest;
+
+#define DOT11F_WMMADDTSREQUEST (43)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fWMMAddTSRequest * pFrm);
+uint32_t dot11f_pack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSRequest *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_wmm_add_ts_request_size(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSRequest *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fWMMAddTSResponse{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfStatusCode StatusCode;
+ tDot11fIEWMMTSPEC WMMTSPEC;
+ tDot11fIEESETrafStrmMet ESETrafStrmMet;
+} tDot11fWMMAddTSResponse;
+
+#define DOT11F_WMMADDTSRESPONSE (44)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fWMMAddTSResponse * pFrm);
+uint32_t dot11f_pack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSResponse *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_wmm_add_ts_response_size(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSResponse *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fWMMDelTS{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fFfDialogToken DialogToken;
+ tDot11fFfStatusCode StatusCode;
+ tDot11fIEWMMTSPEC WMMTSPEC;
+} tDot11fWMMDelTS;
+
+#define DOT11F_WMMDELTS (45)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_wmm_del_ts(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fWMMDelTS * pFrm);
+uint32_t dot11f_pack_wmm_del_ts(tpAniSirGlobal pCtx,
+ tDot11fWMMDelTS *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_wmm_del_ts_size(tpAniSirGlobal pCtx,
+ tDot11fWMMDelTS *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+typedef struct sDot11fht2040_bss_coexistence_mgmt_action_frame{
+ tDot11fFfCategory Category;
+ tDot11fFfAction Action;
+ tDot11fIEht2040_bss_coexistence ht2040_bss_coexistence;
+ tDot11fIEht2040_bss_intolerant_report ht2040_bss_intolerant_report;
+} tDot11fht2040_bss_coexistence_mgmt_action_frame;
+
+#define DOT11F_HT2040_BSS_COEXISTENCE_MGMT_ACTION_FRAME (46)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* C++ */
+
+uint32_t dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fht2040_bss_coexistence_mgmt_action_frame * pFrm);
+uint32_t dot11f_pack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+ tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm, uint8_t *pBuf,
+ uint32_t nBuf, uint32_t *pnConsumed);
+uint32_t dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize(tpAniSirGlobal pCtx,
+ tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm,
+ uint32_t *pnNeeded);
+
+#ifdef __cplusplus
+} /* End extern "C". */
+#endif /* C++ */
+
+#endif /* DOT11F_H */
diff --git a/core/mac/src/include/dph_global.h b/core/mac/src/include/dph_global.h
new file mode 100644
index 0000000..ae590db
--- /dev/null
+++ b/core/mac/src/include/dph_global.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+
+ *
+
+ * Author: Sandesh Goel
+
+ * Date: 02/25/02
+
+ * History:-
+
+ * Date Modified by Modification Information
+
+ * --------------------------------------------------------------------
+
+ *
+
+ */
+
+#ifndef __DPH_GLOBAL_H__
+#define __DPH_GLOBAL_H__
+
+#include "lim_global.h"
+#include "sir_mac_prot_def.h"
+#include "sir_mac_prop_exts.h"
+#include "sir_api.h"
+
+/* Following determines whether statistics are maintained or not */
+#define DPH_STATS
+
+/* STAID for Management frames */
+#define DPH_USE_MGMT_STAID -1
+
+/* Keep Alive frames */
+#define DPH_NON_KEEPALIVE_FRAME 0
+#define DPH_KEEPALIVE_FRAME 1
+
+/* DPH Hash Index for BSS(STA's Peer) on station. */
+#define DPH_STA_HASH_INDEX_PEER 1
+
+#ifdef WLAN_FEATURE_11W
+/* DPH PMF SA Query state for station */
+#define DPH_SA_QUERY_NOT_IN_PROGRESS 1
+#define DPH_SA_QUERY_IN_PROGRESS 2
+#define DPH_SA_QUERY_TIMED_OUT 3
+#endif
+
+typedef struct sDphRateBasedCtr {
+ uint32_t hi;
+ uint32_t lo;
+} tDphRateBasedCtr;
+
+typedef struct sDphPhyRates {
+ uint8_t dataRateX2;
+ uint8_t ackRateX2;
+ uint8_t rtsRateX2;
+} tDphPhyRates;
+
+typedef struct sDphIFSValues {
+ uint8_t sifs;
+ uint8_t pifs;
+ uint8_t difs;
+ uint8_t preamble;
+} tDphIFSValues;
+
+typedef struct sDphQosParams {
+ uint8_t addtsPresent;
+ tSirAddtsReqInfo addts;
+ tSirMacQosCapabilityStaIE capability;
+} tDphQosParams;
+
+/* Queue attribute structure */
+typedef struct sDphQueueAttr {
+ uint16_t valid:1;
+ uint16_t seqNum:12;
+ uint16_t ackPolicy:2;
+ uint16_t rsvd:1;
+} tDphQueueAttr, *tpDphQueueAttr;
+
+/* STA state node */
+typedef struct sDphHashNode {
+ /*
+ * BYTE 0
+ * HASH ENTRY FIELDS NOT NEEDED IN HAL.
+ * This STA valid or not
+ */
+ uint8_t valid:1;
+ uint8_t encPolicy:3;
+ uint8_t defaultKey:1;
+ uint8_t defaultKeyId:2;
+ uint8_t qosMode:1;
+ /* BYTE 1 */
+ uint8_t erpEnabled:1;
+ /* This has been added to the dph hash table */
+ uint8_t added:1;
+ uint8_t linkTestOn:1;
+ uint8_t shortPreambleEnabled:1;
+ uint8_t shortSlotTimeEnabled:1;
+ uint8_t stopTx:1;
+ /* set if both ap and sta are wme capable */
+ uint8_t wmeEnabled:1;
+ /* set if both ap and sta are 11e capable */
+ uint8_t lleEnabled:1;
+ /* BYTE 2 */
+ /* set if both ap and sta are wsm capable */
+ uint8_t wsmEnabled:1;
+ /* station gave version info */
+ uint8_t versionPresent:1;
+ /* allow bursting regardless of qosMode */
+ uint8_t burstEnableForce:1;
+ uint8_t staAuthenticated:1;
+ uint8_t fAniCount:1;
+ uint8_t rmfEnabled:1;
+ /* Fragmentation size */
+ uint16_t fragSize;
+ /* LIM state */
+ tLimMlmStaContext mlmStaContext;
+ /* Number of Tim to wait if the STA doesn't respond / fetch data */
+ uint8_t timWaitCount;
+ /* Number of Successful MPDU's being sent */
+ uint32_t curTxMpduCnt;
+ /* number of consecutive TIMs sent without response */
+ uint8_t numTimSent;
+ /* qos parameter info */
+ tDphQosParams qos;
+ /* station version info - valid only if versionPresent is set */
+ tSirMacPropVersion version;
+#ifdef PLM_WDS
+ uint8_t wdsIndex;
+ uint8_t wdsPeerBeaconSeen;
+#endif
+ /* Taurus capabilities */
+ uint16_t baPolicyFlag; /* BA Policy for each TID. */
+ /*
+ * All the legacy and airgo supported rates.
+ */
+ tSirSupportedRates supportedRates;
+ uint8_t htGreenfield:1;
+ uint8_t htShortGI40Mhz:1;
+ uint8_t htShortGI20Mhz:1;
+ /* DSSS/CCK at 40 MHz: Enabled 1 or Disabled */
+ uint8_t htDsssCckRate40MHzSupport:1;
+ /* L-SIG TXOP Protection used only if peer support available */
+ uint8_t htLsigTXOPProtection:1;
+ /*
+ * A-MPDU Density
+ * 000 - No restriction
+ * 001 - 1/8 usec
+ * 010 - 1/4 usec
+ * 011 - 1/2 usec
+ * 100 - 1 usec
+ * 101 - 2 usec
+ * 110 - 4 usec
+ * 111 - 8 usec
+ */
+ uint8_t htAMpduDensity:3;
+ /* Set to 0 for 3839 octets */
+ /* Set to 1 for 7935 octets */
+ uint8_t htMaxAmsduLength;
+ /* MIMO Power Save */
+ tSirMacHTMIMOPowerSaveState htMIMOPSState;
+ /* */
+ /* Maximum Rx A-MPDU factor */
+ uint8_t htMaxRxAMpduFactor:3;
+ /*
+ * Recommended Tx Width Set
+ * 0 - use 20 MHz channel (control channel)
+ * 1 - use 40 Mhz channel
+ */
+ uint8_t htSupportedChannelWidthSet:1;
+ uint8_t htSecondaryChannelOffset:2;
+ uint8_t rsvd1:2;
+ /* DPH HASH ENTRY FIELDS NEEDED IN HAL ONLY */
+ uint8_t dpuSig:4; /* DPU signiture */
+ uint8_t staSig:4; /* STA signature */
+ uint8_t staType;
+ uint16_t bssId; /* BSSID */
+ uint16_t assocId; /* Association ID */
+ /* This is the real sta index generated by HAL */
+ uint16_t staIndex;
+ uint8_t staAddr[6];
+ /*
+ * The DPU signatures will be sent eventually to TL to help
+ * it determine the association to which a packet belongs to
+ */
+ /*Unicast DPU signature */
+ uint8_t ucUcastSig;
+ /*Broadcast DPU signature */
+ uint8_t ucBcastSig;
+
+ uint8_t vhtSupportedChannelWidthSet;
+ uint8_t vhtSupportedRxNss;
+ uint8_t vhtBeamFormerCapable;
+ uint8_t vht_su_bfee_capable;
+#ifdef WLAN_FEATURE_11W
+ uint8_t pmfSaQueryState;
+ uint8_t pmfSaQueryRetryCount;
+ uint16_t pmfSaQueryCurrentTransId;
+ uint16_t pmfSaQueryStartTransId;
+ TX_TIMER pmfSaQueryTimer;
+ v_TIME_t last_unprot_deauth_disassoc;
+ uint8_t proct_deauh_disassoc_cnt;
+ v_TIME_t last_assoc_received_time;
+#endif
+ uint8_t htLdpcCapable;
+ uint8_t vhtLdpcCapable;
+#ifdef FEATURE_WLAN_TDLS
+ uint16_t ht_caps;
+ uint32_t vht_caps;
+#endif
+ uint8_t timingMeasCap;
+ /* key installed for this STA or not in the firmware */
+ uint8_t is_key_installed;
+ uint8_t is_disassoc_deauth_in_progress;
+ /*
+ * When a station with already an existing dph entry tries to
+ * associate again, the old dph entry will be zeroed out except
+ * for the next pointer. The next pointer must be defined at the
+ * end of the structure.
+ */
+ struct sDphHashNode *next;
+} tDphHashNode, *tpDphHashNode;
+
+#include "dph_hash_table.h"
+
+/* ------------------------------------------------------------------- */
+typedef struct sAniSirDph {
+ /* The hash table object */
+ dphHashTableClass dphHashTable;
+} tAniSirDph, *tpAniSirDph;
+
+#endif
diff --git a/core/mac/src/include/parser_api.h b/core/mac/src/include/parser_api.h
new file mode 100644
index 0000000..afbfd5e
--- /dev/null
+++ b/core/mac/src/include/parser_api.h
@@ -0,0 +1,965 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file parser_api.h contains the definitions used
+ * for parsing received 802.11 frames
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __PARSE_H__
+#define __PARSE_H__
+
+#include <stdarg.h>
+#include "sir_mac_prop_exts.h"
+#include "dot11f.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+
+#define COUNTRY_STRING_LENGTH (3)
+#define COUNTRY_INFO_MAX_CHANNEL (84)
+#define MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE (COUNTRY_STRING_LENGTH * \
+ COUNTRY_INFO_MAX_CHANNEL)
+#define HIGHEST_24GHZ_CHANNEL_NUM (14)
+
+#define IS_24G_CH(__chNum) ((__chNum > 0) && (__chNum < 15))
+#define IS_5G_CH(__chNum) ((__chNum >= 36) && (__chNum <= 165))
+#define IS_2X2_CHAIN(__chain) ((__chain & 0x3) == 0x3)
+#define DISABLE_NSS2_MCS 0xC
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#define QCOM_VENDOR_IE_MCC_AVOID_CH 0x01
+
+struct sAvoidChannelIE {
+ /* following must be 0xDD (221) */
+ uint8_t tag_number;
+ uint8_t length;
+ /* following must be 00-A0-C6 */
+ uint8_t oui[3];
+ /* following must be 0x01 */
+ uint8_t type;
+ uint8_t channel;
+};
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+typedef struct sSirCountryInformation {
+ uint8_t countryString[COUNTRY_STRING_LENGTH];
+ uint8_t numIntervals; /* number of channel intervals */
+ struct channelPowerLim {
+ uint8_t channelNumber;
+ uint8_t numChannel;
+ uint8_t maxTransmitPower;
+ } channelTransmitPower[COUNTRY_INFO_MAX_CHANNEL];
+} tSirCountryInformation, *tpSirCountryInformation;
+
+/* Structure common to Beacons & Probe Responses */
+typedef struct sSirProbeRespBeacon {
+ tSirMacTimeStamp timeStamp;
+ uint16_t beaconInterval;
+ tSirMacCapabilityInfo capabilityInfo;
+
+ tSirMacSSid ssId;
+ tSirMacRateSet supportedRates;
+ tSirMacRateSet extendedRates;
+ tSirMacChanNum channelNumber;
+ tSirMacCfParamSet cfParamSet;
+ tSirMacTim tim;
+ tSirMacEdcaParamSetIE edcaParams;
+ tSirMacQosCapabilityIE qosCapability;
+
+ tSirCountryInformation countryInfoParam;
+ tSirMacWpaInfo wpa;
+ tSirMacRsnInfo rsn;
+
+ tSirMacErpInfo erpIEInfo;
+
+ tSirPropIEStruct propIEinfo;
+ tDot11fIEPowerConstraints localPowerConstraint;
+ tDot11fIETPCReport tpcReport;
+ tDot11fIEChanSwitchAnn channelSwitchIE;
+ tDot11fIEsec_chan_offset_ele sec_chan_offset;
+ tDot11fIEext_chan_switch_ann ext_chan_switch;
+ tSirMacAddr bssid;
+ tDot11fIEQuiet quietIE;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+ tDot11fIEP2PProbeRes P2PProbeRes;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ uint8_t mdie[SIR_MDIE_SIZE];
+#endif
+#ifdef FEATURE_WLAN_ESE
+ tDot11fIEESETxmitPower eseTxPwr;
+ tDot11fIEQBSSLoad QBSSLoad;
+#endif
+ uint8_t ssidPresent;
+ uint8_t suppRatesPresent;
+ uint8_t extendedRatesPresent;
+ uint8_t cfPresent;
+ uint8_t dsParamsPresent;
+ uint8_t timPresent;
+
+ uint8_t edcaPresent;
+ uint8_t qosCapabilityPresent;
+ uint8_t wmeEdcaPresent;
+ uint8_t wmeInfoPresent;
+ uint8_t wsmCapablePresent;
+
+ uint8_t countryInfoPresent;
+ uint8_t wpaPresent;
+ uint8_t rsnPresent;
+ uint8_t erpPresent;
+ uint8_t channelSwitchPresent;
+ uint8_t sec_chan_offset_present;
+ uint8_t ext_chan_switch_present;
+ uint8_t quietIEPresent;
+ uint8_t tpcReportPresent;
+ uint8_t powerConstraintPresent;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ uint8_t mdiePresent;
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+ tDot11fIEVHTExtBssLoad VHTExtBssLoad;
+ tDot11fIEOperatingMode OperatingMode;
+ uint8_t WiderBWChanSwitchAnnPresent;
+ tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn;
+#endif
+ uint8_t Vendor1IEPresent;
+ tDot11fIEvendor2_ie vendor2_ie;
+ uint8_t Vendor3IEPresent;
+ tDot11fIEIBSSParams IBSSParams;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ tDot11fIEQComVendorIE AvoidChannelIE;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#ifdef FEATURE_WLAN_ESE
+ uint8_t is_ese_ver_ie_present;
+#endif
+} tSirProbeRespBeacon, *tpSirProbeRespBeacon;
+
+/* probe Request structure */
+typedef struct sSirProbeReq {
+ tSirMacSSid ssId;
+ tSirMacRateSet supportedRates;
+ tSirMacRateSet extendedRates;
+ tDot11fIEWscProbeReq probeReqWscIeInfo;
+ tDot11fIEHTCaps HTCaps;
+ uint8_t ssidPresent;
+ uint8_t suppRatesPresent;
+ uint8_t extendedRatesPresent;
+ uint8_t wscIePresent;
+ uint8_t p2pIePresent;
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEVHTCaps VHTCaps;
+#endif
+
+} tSirProbeReq, *tpSirProbeReq;
+
+/* / Association Request structure (one day to be replaced by */
+/* / tDot11fAssocRequest) */
+typedef struct sSirAssocReq {
+
+ tSirMacCapabilityInfo capabilityInfo;
+ uint16_t listenInterval;
+ tSirMacAddr currentApAddr; /* only in reassoc frames */
+ tSirMacSSid ssId;
+ tSirMacRateSet supportedRates;
+ tSirMacRateSet extendedRates;
+
+ tSirAddtsReqInfo addtsReq;
+ tSirMacQosCapabilityStaIE qosCapability;
+
+ tSirMacWapiInfo wapi;
+ tSirMacWpaInfo wpa;
+ tSirMacRsnInfo rsn;
+ tSirAddie addIE;
+
+ tSirPropIEStruct propIEinfo;
+ tSirMacPowerCapabilityIE powerCapability;
+ tSirMacSupportedChannelIE supportedChannels;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEWMMInfoStation WMMInfoStation;
+ /* / This is set if the frame is a reassoc request: */
+ uint8_t reassocRequest;
+ uint8_t ssidPresent;
+ uint8_t suppRatesPresent;
+ uint8_t extendedRatesPresent;
+
+ uint8_t wmeInfoPresent;
+ uint8_t qosCapabilityPresent;
+ uint8_t addtsPresent;
+ uint8_t wsmCapablePresent;
+
+ uint8_t wapiPresent;
+ uint8_t wpaPresent;
+ uint8_t rsnPresent;
+ uint8_t addIEPresent;
+
+ uint8_t powerCapabilityPresent;
+ uint8_t supportedChannelsPresent;
+ /* keeping copy of association request received, this is
+ required for indicating the frame to upper layers */
+ uint32_t assocReqFrameLength;
+ uint8_t *assocReqFrame;
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEOperatingMode operMode;
+#endif
+ tDot11fIEExtCap ExtCap;
+} tSirAssocReq, *tpSirAssocReq;
+
+/* / Association Response structure (one day to be replaced by */
+/* / tDot11fAssocRequest) */
+typedef struct sSirAssocRsp {
+
+ tSirMacCapabilityInfo capabilityInfo;
+ uint16_t aid;
+ uint16_t statusCode;
+ tSirMacRateSet supportedRates;
+ tSirMacRateSet extendedRates;
+ tSirPropIEStruct propIEinfo;
+ tSirMacEdcaParamSetIE edca;
+ tSirAddtsRspInfo addtsRsp;
+ tDot11fIEHTCaps HTCaps;
+ tDot11fIEHTInfo HTInfo;
+#if defined WLAN_FEATURE_VOWIFI_11R
+ tDot11fIEFTInfo FTInfo;
+ uint8_t mdie[SIR_MDIE_SIZE];
+ uint8_t num_RICData;
+ tDot11fIERICDataDesc RICData[2];
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ uint8_t num_tspecs;
+ tDot11fIEWMMTSPEC TSPECInfo[SIR_ESE_MAX_TSPEC_IES];
+ tSirMacESETSMIE tsmIE;
+#endif
+
+ uint8_t suppRatesPresent;
+ uint8_t extendedRatesPresent;
+
+ uint8_t edcaPresent;
+ uint8_t wmeEdcaPresent;
+ uint8_t addtsPresent;
+ uint8_t wsmCapablePresent;
+#if defined WLAN_FEATURE_VOWIFI_11R
+ uint8_t ftinfoPresent;
+ uint8_t mdiePresent;
+ uint8_t ricPresent;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ uint8_t tspecPresent;
+ uint8_t tsmPresent;
+#endif
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEVHTCaps VHTCaps;
+ tDot11fIEVHTOperation VHTOperation;
+#endif
+ tDot11fIEExtCap ExtCap;
+ tSirQosMapSet QosMapSet;
+#ifdef WLAN_FEATURE_11W
+ tDot11fIETimeoutInterval TimeoutInterval;
+#endif
+ tDot11fIEvendor2_ie vendor2_ie;
+} tSirAssocRsp, *tpSirAssocRsp;
+
+#if defined(FEATURE_WLAN_ESE_UPLOAD)
+/* Structure to hold ESE Beacon report mandatory IEs */
+typedef struct sSirEseBcnReportMandatoryIe {
+ tSirMacSSid ssId;
+ tSirMacRateSet supportedRates;
+ tSirMacFHParamSet fhParamSet;
+ tSirMacDsParamSetIE dsParamSet;
+ tSirMacCfParamSet cfParamSet;
+ tSirMacIBSSParams ibssParamSet;
+ tSirMacTim tim;
+ tSirMacRRMEnabledCap rmEnabledCapabilities;
+
+ uint8_t ssidPresent;
+ uint8_t suppRatesPresent;
+ uint8_t fhParamPresent;
+ uint8_t dsParamsPresent;
+ uint8_t cfPresent;
+ uint8_t ibssParamPresent;
+ uint8_t timPresent;
+ uint8_t rrmPresent;
+} tSirEseBcnReportMandatoryIe, *tpSirEseBcnReportMandatoryIe;
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+
+/**
+ * struct s_ext_cap - holds bitfields of extended capability IE
+ *
+ * s_ext_cap holds bitfields of extended capability IE. In dot11f files
+ * extended capability IE information is stored as an array of bytes.
+ * This structure is used to encode/decode the byte array present in
+ * dot11f IE structure.
+ */
+
+struct s_ext_cap {
+ uint8_t bss_coexist_mgmt_support:1;
+ uint8_t reserved1:1;
+ uint8_t ext_chan_switch:1;
+ uint8_t reserved2:1;
+ uint8_t psmp_cap:1;
+ uint8_t reserved3:1;
+ uint8_t spsmp_cap:1;
+ uint8_t event:1;
+ uint8_t diagnostics:1;
+ uint8_t multi_diagnostics:1;
+ uint8_t loc_tracking:1;
+ uint8_t fms:1;
+ uint8_t proxy_arp_service:1;
+ uint8_t co_loc_intf_reporting:1;
+ uint8_t civic_loc:1;
+ uint8_t geospatial_loc:1;
+ uint8_t tfs:1;
+ uint8_t wnm_sleep_mode:1;
+ uint8_t tim_broadcast:1;
+ uint8_t bss_transition:1;
+ uint8_t qos_traffic_cap:1;
+ uint8_t ac_sta_cnt:1;
+ uint8_t multi_bssid:1;
+ uint8_t timing_meas:1;
+ uint8_t chan_usage:1;
+ uint8_t ssid_list:1;
+ uint8_t dms:1;
+ uint8_t utctsf_offset:1;
+ uint8_t tdls_peer_uapsd_buffer_sta:1;
+ uint8_t tdls_peer_psm_supp:1;
+ uint8_t tdls_channel_switching:1;
+ uint8_t interworking_service:1;
+ uint8_t qos_map:1;
+ uint8_t ebr:1;
+ uint8_t sspn_interface:1;
+ uint8_t reserved4:1;
+ uint8_t msg_cf_cap:1;
+ uint8_t tdls_support:1;
+ uint8_t tdls_prohibited:1;
+ uint8_t tdls_chan_swit_prohibited:1;
+ uint8_t reject_unadmitted_traffic:1;
+ uint8_t service_interval_granularity:3;
+ uint8_t identifier_loc:1;
+ uint8_t uapsd_coexistence:1;
+ uint8_t wnm_notification:1;
+ uint8_t qa_bcapbility:1;
+ uint8_t utf8_ssid:1;
+ uint8_t qmf_activated:1;
+ uint8_t qm_frecon_act:1;
+ uint8_t robust_av_streaming:1;
+ uint8_t advanced_gcr:1;
+ uint8_t mesh_gcr:1;
+ uint8_t scs:1;
+ uint8_t q_load_report:1;
+ uint8_t alternate_edca:1;
+ uint8_t unprot_txo_pneg:1;
+ uint8_t prot_txo_pneg:1;
+ uint8_t reserved6:1;
+ uint8_t prot_q_load_report:1;
+ uint8_t tdls_wider_bw:1;
+ uint8_t oper_mode_notification:1;
+ uint8_t max_num_of_msdu_bit1:1;
+ uint8_t max_num_of_msdu_bit2:1;
+ uint8_t chan_sch_mgmt:1;
+ uint8_t geo_db_inband_en_signal:1;
+ uint8_t nw_chan_control:1;
+ uint8_t white_space_map:1;
+ uint8_t chan_avail_query:1;
+ uint8_t fine_time_meas_responder:1;
+ uint8_t fine_time_meas_initiator:1;
+};
+
+uint8_t sirIsPropCapabilityEnabled(struct sAniSirGlobal *pMac, uint32_t bitnum);
+
+void dot11f_log(tpAniSirGlobal pMac, int nSev, const char *lpszFormat, ...);
+
+#define CFG_GET_INT(nStatus, pMac, nItem, cfg) do { \
+ (nStatus) = wlan_cfg_get_int((pMac), (nItem), &(cfg)); \
+ if (eSIR_SUCCESS != (nStatus)) { \
+ dot11f_log((pMac), LOGP, FL("Failed to retrieve nItem from CFG (%d)."), (nStatus)); \
+ return nStatus; \
+ } \
+} while (0)
+
+#define CFG_GET_INT_NO_STATUS(nStatus, pMac, nItem, cfg) do { \
+ (nStatus) = wlan_cfg_get_int((pMac), (nItem), &(cfg)); \
+ if (eSIR_SUCCESS != (nStatus)) { \
+ dot11f_log((pMac), LOGP, FL("Failed to retrieve nItem from CFG (%d)."), (nStatus)); \
+ return; \
+ } \
+} while (0)
+
+#define CFG_GET_STR(nStatus, pMac, nItem, cfg, nCfg, nMaxCfg) do { \
+ (nCfg) = (nMaxCfg); \
+ (nStatus) = wlan_cfg_get_str((pMac), (nItem), (cfg), &(nCfg)); \
+ if (eSIR_SUCCESS != (nStatus)) { \
+ dot11f_log((pMac), LOGP, FL("Failed to retrieve nItem from CFG (%d)."), (nStatus)); \
+ return nStatus; \
+ } \
+} while (0)
+
+#define CFG_GET_STR_NO_STATUS(nStatus, pMac, nItem, cfg, nCfg, nMaxCfg) do { \
+ (nCfg) = (nMaxCfg); \
+ (nStatus) = wlan_cfg_get_str((pMac), (nItem), (cfg), &(nCfg)); \
+ if (eSIR_SUCCESS != (nStatus)) { \
+ dot11f_log((pMac), LOGP, FL("Failed to retrieve nItem from CFG (%d)."), (nStatus)); \
+ return; \
+ } \
+} while (0)
+
+void swap_bit_field16(uint16_t in, uint16_t *out);
+
+/* Currently implemented as "shims" between callers & the new framesc- */
+/* generated code: */
+
+tSirRetStatus
+sir_convert_probe_req_frame2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tpSirProbeReq probe);
+
+tSirRetStatus
+sir_convert_probe_frame2_struct(struct sAniSirGlobal *pMac, uint8_t *frame,
+ uint32_t len, tpSirProbeRespBeacon probe);
+
+tSirRetStatus
+sir_convert_assoc_req_frame2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tpSirAssocReq assoc);
+
+tSirRetStatus
+sir_convert_assoc_resp_frame2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tpSirAssocRsp assoc);
+
+tSirRetStatus
+sir_convert_reassoc_req_frame2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tpSirAssocReq assoc);
+
+tSirRetStatus
+sir_parse_beacon_ie(struct sAniSirGlobal *pMac,
+ tpSirProbeRespBeacon pBeaconStruct,
+ uint8_t *pPayload, uint32_t payloadLength);
+
+#if defined(FEATURE_WLAN_ESE_UPLOAD)
+tSirRetStatus
+sir_beacon_ie_ese_bcn_report(tpAniSirGlobal pMac,
+ uint8_t *pPayload, const uint32_t payloadLength,
+ uint8_t **outIeBuf, uint32_t *pOutIeLen);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+
+tSirRetStatus
+sir_convert_beacon_frame2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *pBeaconFrame,
+ tpSirProbeRespBeacon pBeaconStruct);
+
+tSirRetStatus
+sir_convert_auth_frame2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tpSirMacAuthFrameBody auth);
+
+tSirRetStatus
+sir_convert_addts_req2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tSirAddtsReqInfo *addTs);
+
+tSirRetStatus
+sir_convert_addts_rsp2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tSirAddtsRspInfo *addts);
+
+tSirRetStatus
+sir_convert_delts_req2_struct(struct sAniSirGlobal *pMac,
+ uint8_t *frame, uint32_t len,
+ tSirDeltsReqInfo *delTs);
+tSirRetStatus
+sir_convert_qos_map_configure_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame, uint32_t nFrame,
+ tSirQosMapSet *pQosMapSet);
+
+#ifdef ANI_SUPPORT_11H
+tSirRetStatus
+sir_convert_tpc_req_frame2_struct(struct sAniSirGlobal *, uint8_t *,
+ tpSirMacTpcReqActionFrame, uint32_t);
+
+tSirRetStatus
+sir_convert_meas_req_frame2_struct(struct sAniSirGlobal *, uint8_t *,
+ tpSirMacMeasReqActionFrame, uint32_t);
+#endif
+
+/**
+ * \brief Populated a tDot11fFfCapabilities
+ *
+ * \sa PopulatedDot11fCapabilities2
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param pDot11f Address of a tDot11fFfCapabilities to be filled in
+ *
+ *
+ * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled, we'll clear the QOS
+ * bit in pDot11f
+ *
+ *
+ */
+
+tSirRetStatus
+populate_dot11f_capabilities(tpAniSirGlobal pMac,
+ tDot11fFfCapabilities *pDot11f,
+ tpPESession psessionEntry);
+
+/**
+ * \brief Populated a tDot11fFfCapabilities
+ *
+ * \sa PopulatedDot11fCapabilities2
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param pDot11f Address of a tDot11fFfCapabilities to be filled in
+ *
+ * \param pSta Pointer to a tDphHashNode representing a peer
+ *
+ *
+ * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled on our peer, we'll
+ * clear the QOS bit in pDot11f
+ *
+ *
+ */
+
+struct sDphHashNode;
+
+tSirRetStatus
+populate_dot11f_capabilities2(tpAniSirGlobal pMac,
+ tDot11fFfCapabilities *pDot11f,
+ struct sDphHashNode *pSta,
+ tpPESession psessionEntry);
+
+/* / Populate a tDot11fIEChanSwitchAnn */
+void
+populate_dot11f_chan_switch_ann(tpAniSirGlobal pMac,
+ tDot11fIEChanSwitchAnn *pDot11f,
+ tpPESession psessionEntry);
+
+void
+populate_dot_11_f_ext_chann_switch_ann(tpAniSirGlobal mac_ptr,
+ tDot11fIEext_chan_switch_ann *dot_11_ptr,
+ tpPESession session_entry);
+
+/* / Populate a tDot11fIEChannelSwitchWrapper */
+void
+populate_dot11f_chan_switch_wrapper(tpAniSirGlobal pMac,
+ tDot11fIEChannelSwitchWrapper *pDot11f,
+ tpPESession psessionEntry);
+
+/* / Populate a tDot11fIECountry */
+tSirRetStatus
+populate_dot11f_country(tpAniSirGlobal pMac,
+ tDot11fIECountry *pDot11f, tpPESession psessionEntry);
+
+/* Populated a populate_dot11f_ds_params */
+tSirRetStatus
+populate_dot11f_ds_params(tpAniSirGlobal pMac,
+ tDot11fIEDSParams *pDot11f, uint8_t channel);
+
+/* / Populated a tDot11fIEEDCAParamSet */
+void
+populate_dot11f_edca_param_set(tpAniSirGlobal pMac,
+ tDot11fIEEDCAParamSet *pDot11f,
+ tpPESession psessionEntry);
+
+tSirRetStatus
+populate_dot11f_erp_info(tpAniSirGlobal pMac,
+ tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry);
+
+tSirRetStatus
+populate_dot11f_ext_supp_rates(tpAniSirGlobal pMac,
+ uint8_t nChannelNum, tDot11fIEExtSuppRates *pDot11f,
+ tpPESession psessionEntry);
+
+#if defined WLAN_FEATURE_VOWIFI
+tSirRetStatus
+populate_dot11f_beacon_report(tpAniSirGlobal pMac,
+ tDot11fIEMeasurementReport *pDot11f,
+ tSirMacBeaconReport *pBeaconReport);
+#endif
+
+/**
+ * \brief Populate a tDot11fIEExtSuppRates
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param nChannelNum Channel on which the enclosing frame will be going out
+ *
+ * \param pDot11f Address of a tDot11fIEExtSuppRates struct to be filled in.
+ *
+ *
+ * This method is a NOP if the channel is greater than 14.
+ *
+ *
+ */
+
+tSirRetStatus
+populate_dot11f_ext_supp_rates1(tpAniSirGlobal pMac,
+ uint8_t nChannelNum,
+ tDot11fIEExtSuppRates *pDot11f);
+
+tSirRetStatus
+populate_dot11f_ht_caps(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, tDot11fIEHTCaps *pDot11f);
+
+tSirRetStatus
+populate_dot11f_ht_info(tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pDot11f, tpPESession psessionEntry);
+
+void populate_dot11f_ibss_params(tpAniSirGlobal pMac,
+ tDot11fIEIBSSParams *pDot11f,
+ tpPESession psessionEntry);
+
+#ifdef ANI_SUPPORT_11H
+tSirRetStatus
+populate_dot11f_measurement_report0(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pReq,
+ tDot11fIEMeasurementReport *pDot11f);
+
+/* / Populate a tDot11fIEMeasurementReport when the report type is CCA */
+tSirRetStatus
+populate_dot11f_measurement_report1(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pReq,
+ tDot11fIEMeasurementReport *pDot11f);
+
+/* / Populate a tDot11fIEMeasurementReport when the report type is RPI Hist */
+tSirRetStatus
+populate_dot11f_measurement_report2(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pReq,
+ tDot11fIEMeasurementReport *pDot11f);
+#endif /* ANI_SUPPORT_11H */
+
+/* / Populate a tDot11fIEPowerCaps */
+void
+populate_dot11f_power_caps(tpAniSirGlobal pMac,
+ tDot11fIEPowerCaps *pCaps,
+ uint8_t nAssocType, tpPESession psessionEntry);
+
+/* / Populate a tDot11fIEPowerConstraints */
+tSirRetStatus
+populate_dot11f_power_constraints(tpAniSirGlobal pMac,
+ tDot11fIEPowerConstraints *pDot11f);
+
+void
+populate_dot11f_qos_caps_ap(tpAniSirGlobal pMac,
+ tDot11fIEQOSCapsAp *pDot11f,
+ tpPESession psessionEntry);
+
+void
+populate_dot11f_qos_caps_station(tpAniSirGlobal pMac,
+ tDot11fIEQOSCapsStation *pDot11f);
+
+tSirRetStatus
+populate_dot11f_rsn(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIERSN *pDot11f);
+
+tSirRetStatus
+populate_dot11f_rsn_opaque(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIERSNOpaque *pDot11f);
+
+#if defined(FEATURE_WLAN_WAPI)
+
+tSirRetStatus
+populate_dot11f_wapi(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f);
+
+tSirRetStatus populate_dot11f_wapi_opaque(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe,
+ tDot11fIEWAPIOpaque *pDot11f);
+
+#endif /* defined(FEATURE_WLAN_WAPI) */
+
+/* / Populate a tDot11fIESSID given a tSirMacSSid */
+void
+populate_dot11f_ssid(tpAniSirGlobal pMac,
+ tSirMacSSid *pInternal, tDot11fIESSID *pDot11f);
+
+/* / Populate a tDot11fIESSID from CFG */
+tSirRetStatus populate_dot11f_ssid2(tpAniSirGlobal pMac,
+ tDot11fIESSID *pDot11f);
+
+/**
+ * \brief Populate a tDot11fIESchedule
+ *
+ * \sa populate_dot11f_wmm_schedule
+ *
+ *
+ * \param pSchedule Address of a tSirMacScheduleIE struct
+ *
+ * \param pDot11f Address of a tDot11fIESchedule to be filled in
+ *
+ *
+ */
+
+void
+populate_dot11f_schedule(tSirMacScheduleIE *pSchedule,
+ tDot11fIESchedule *pDot11f);
+
+void
+populate_dot11f_supp_channels(tpAniSirGlobal pMac,
+ tDot11fIESuppChannels *pDot11f,
+ uint8_t nAssocType, tpPESession psessionEntry);
+
+/**
+ * \brief Populated a tDot11fIESuppRates
+ *
+ *
+ * \param pMac Pointer to the global MAC data structure
+ *
+ * \param nChannelNum Channel the enclosing frame will be going out on; see
+ * below
+ *
+ * \param pDot11f Address of a tDot11fIESuppRates struct to be filled in.
+ *
+ *
+ * If nChannelNum is greater than 13, the supported rates will be
+ * WNI_CFG_SUPPORTED_RATES_11B. If it is less than or equal to 13, the
+ * supported rates will be WNI_CFG_SUPPORTED_RATES_11A. If nChannelNum is
+ * set to the sentinel value POPULATE_DOT11F_RATES_OPERATIONAL, the struct
+ * will be populated with WNI_CFG_OPERATIONAL_RATE_SET.
+ *
+ *
+ */
+
+#define POPULATE_DOT11F_RATES_OPERATIONAL (0xff)
+
+tSirRetStatus
+populate_dot11f_supp_rates(tpAniSirGlobal pMac,
+ uint8_t nChannelNum,
+ tDot11fIESuppRates *pDot11f, tpPESession);
+
+tSirRetStatus
+populate_dot11f_rates_tdls(tpAniSirGlobal p_mac,
+ tDot11fIESuppRates *p_supp_rates,
+ tDot11fIEExtSuppRates *p_ext_supp_rates);
+
+tSirRetStatus populate_dot11f_tpc_report(tpAniSirGlobal pMac,
+ tDot11fIETPCReport *pDot11f,
+ tpPESession psessionEntry);
+
+/* / Populate a tDot11FfTSInfo */
+void populate_dot11f_ts_info(tSirMacTSInfo *pInfo, tDot11fFfTSInfo *pDot11f);
+
+void populate_dot11f_wmm(tpAniSirGlobal pMac,
+ tDot11fIEWMMInfoAp *pInfo,
+ tDot11fIEWMMParams *pParams,
+ tDot11fIEWMMCaps *pCaps, tpPESession psessionEntry);
+
+void populate_dot11f_wmm_caps(tDot11fIEWMMCaps *pCaps);
+
+#if defined(FEATURE_WLAN_ESE)
+/* Fill the ESE version IE */
+void populate_dot11f_ese_version(tDot11fIEESEVersion *pESEVersion);
+/* Fill the Radio Management Capability */
+void populate_dot11f_ese_rad_mgmt_cap(tDot11fIEESERadMgmtCap *pESERadMgmtCap);
+/* Fill the CCKM IE */
+tSirRetStatus populate_dot11f_ese_cckm_opaque(tpAniSirGlobal pMac,
+ tpSirCCKMie pCCKMie,
+ tDot11fIEESECckmOpaque *pDot11f);
+
+void populate_dot11_tsrsie(tpAniSirGlobal pMac,
+ tSirMacESETSRSIE *pOld,
+ tDot11fIEESETrafStrmRateSet *pDot11f,
+ uint8_t rate_length);
+void populate_dot11f_re_assoc_tspec(tpAniSirGlobal pMac,
+ tDot11fReAssocRequest *pReassoc,
+ tpPESession psessionEntry);
+#endif
+
+void populate_dot11f_wmm_info_ap(tpAniSirGlobal pMac,
+ tDot11fIEWMMInfoAp *pInfo,
+ tpPESession psessionEntry);
+
+void populate_dot11f_wmm_info_station_per_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIEWMMInfoStation *pInfo);
+
+void populate_dot11f_wmm_params(tpAniSirGlobal pMac,
+ tDot11fIEWMMParams *pParams,
+ tpPESession psessionEntry);
+
+/**
+ * \brief Populate a tDot11fIEWMMSchedule
+ *
+ * \sa PopulatedDot11fSchedule
+ *
+ *
+ * \param pSchedule Address of a tSirMacScheduleIE struct
+ *
+ * \param pDot11f Address of a tDot11fIEWMMSchedule to be filled in
+ *
+ *
+ */
+
+void
+populate_dot11f_wmm_schedule(tSirMacScheduleIE *pSchedule,
+ tDot11fIEWMMSchedule *pDot11f);
+
+tSirRetStatus
+populate_dot11f_wpa(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIEWPA *pDot11f);
+
+tSirRetStatus
+populate_dot11f_wpa_opaque(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIEWPAOpaque *pDot11f);
+
+void populate_dot11f_tspec(tSirMacTspecIE *pOld, tDot11fIETSPEC *pDot11f);
+
+void populate_dot11f_wmmtspec(tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pDot11f);
+
+tSirRetStatus
+populate_dot11f_tclas(tpAniSirGlobal pMac,
+ tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f);
+
+tSirRetStatus
+populate_dot11f_wmmtclas(tpAniSirGlobal pMac,
+ tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pDot11f);
+
+tSirRetStatus populate_dot11f_wsc(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f);
+
+tSirRetStatus populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f);
+
+tSirRetStatus de_populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f);
+
+tSirRetStatus populate_dot11f_probe_res_wpsi_es(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *pDot11f,
+ tpPESession psessionEntry);
+tSirRetStatus populate_dot11f_assoc_res_wpsi_es(tpAniSirGlobal pMac,
+ tDot11fIEWscAssocRes *pDot11f,
+ tpPESession psessionEntry);
+tSirRetStatus populate_dot11f_beacon_wpsi_es(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f,
+ tpPESession psessionEntry);
+
+tSirRetStatus populate_dot11f_wsc_in_probe_res(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *pDot11f);
+
+tSirRetStatus
+populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *pDot11f);
+
+tSirRetStatus
+de_populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *pDot11f);
+
+tSirRetStatus populate_dot11f_assoc_res_wsc_ie(tpAniSirGlobal pMac,
+ tDot11fIEWscAssocRes *pDot11f,
+ tpSirAssocReq pRcvdAssocReq);
+
+tSirRetStatus populate_dot11_assoc_res_p2p_ie(tpAniSirGlobal pMac,
+ tDot11fIEP2PAssocRes *pDot11f,
+ tpSirAssocReq pRcvdAssocReq);
+
+tSirRetStatus populate_dot11f_wscInAssocRes(tpAniSirGlobal pMac,
+ tDot11fIEWscAssocRes *pDot11f);
+
+#if defined WLAN_FEATURE_VOWIFI
+tSirRetStatus populate_dot11f_wfatpc(tpAniSirGlobal pMac,
+ tDot11fIEWFATPC *pDot11f, uint8_t txPower,
+ uint8_t linkMargin);
+
+tSirRetStatus populate_dot11f_rrm_ie(tpAniSirGlobal pMac,
+ tDot11fIERRMEnabledCap *pDot11f,
+ tpPESession psessionEntry);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+void populate_mdie(tpAniSirGlobal pMac,
+ tDot11fIEMobilityDomain * pDot11f, uint8_t mdie[]);
+void populate_ft_info(tpAniSirGlobal pMac, tDot11fIEFTInfo *pDot11f);
+#endif
+
+void populate_dot11f_assoc_rsp_rates(tpAniSirGlobal pMac,
+ tDot11fIESuppRates *pSupp,
+ tDot11fIEExtSuppRates *pExt,
+ uint16_t *_11bRates, uint16_t *_11aRates);
+
+int find_ie_location(tpAniSirGlobal pMac, tpSirRSNie pRsnIe, uint8_t EID);
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus
+populate_dot11f_vht_caps(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ tDot11fIEVHTCaps *pDot11f);
+
+tSirRetStatus
+populate_dot11f_vht_operation(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIEVHTOperation *pDot11f);
+
+tSirRetStatus
+populate_dot11f_vht_ext_bss_load(tpAniSirGlobal pMac,
+ tDot11fIEVHTExtBssLoad *pDot11f);
+
+tSirRetStatus
+populate_dot11f_ext_cap(tpAniSirGlobal pMac, bool isVHTEnabled,
+ tDot11fIEExtCap *pDot11f, tpPESession psessionEntry);
+
+tSirRetStatus
+populate_dot11f_operating_mode(tpAniSirGlobal pMac,
+ tDot11fIEOperatingMode *pDot11f,
+ tpPESession psessionEntry);
+
+void
+populate_dot11f_wider_bw_chan_switch_ann(tpAniSirGlobal pMac,
+ tDot11fIEWiderBWChanSwitchAnn *pDot11f,
+ tpPESession psessionEntry);
+#endif
+
+void populate_dot11f_timeout_interval(tpAniSirGlobal pMac,
+ tDot11fIETimeoutInterval *pDot11f,
+ uint8_t type, uint32_t value);
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/* Populate a tDot11fIEQComVendorIE */
+void
+populate_dot11f_avoid_channel_ie(tpAniSirGlobal mac_ctx,
+ tDot11fIEQComVendorIE *dot11f,
+ tpPESession session_entry);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+tSirRetStatus populate_dot11f_timing_advert_frame(tpAniSirGlobal pMac,
+ tDot11fTimingAdvertisementFrame *frame);
+
+#endif /* __PARSE_H__ */
diff --git a/core/mac/src/include/sir_common.h b/core/mac/src/include/sir_common.h
new file mode 100644
index 0000000..f699772
--- /dev/null
+++ b/core/mac/src/include/sir_common.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sir_common.h contains the common definitions used by all
+ * Firmware modules.
+ *
+ * Author: V. K. Kandarpa
+ * Date: 04/12/2002
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SIRCOMMON_H
+#define __SIRCOMMON_H
+
+#include "sir_api.h"
+#include "sir_params.h"
+#include "sys_wrapper.h"
+
+/* ********************************************* *
+* *
+* SIRIUS SYSTEM EXTERNAL GLOBALS *
+* *
+* ********************************************* */
+
+/* All the following are resource definitions */
+
+#endif /* __SIRCOMMON_H */
diff --git a/core/mac/src/include/sir_debug.h b/core/mac/src/include/sir_debug.h
new file mode 100644
index 0000000..674855d
--- /dev/null
+++ b/core/mac/src/include/sir_debug.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ */
+
+#ifndef __POL_DEBUG_H__
+#define __POL_DEBUG_H__
+
+#define LOGOFF 0
+#define LOGP 1
+#define LOGE 2
+#define LOGW 3
+#define LOG1 4
+#define LOG2 5
+#define LOG3 6
+#define LOG4 7
+
+#ifdef WLAN_MDM_CODE_REDUCTION_OPT
+#ifdef PE_DEBUG_LOGE
+#define PELOGE(p) { p }
+#else
+#define PELOGE(p) { }
+#endif
+
+#ifdef PE_DEBUG_LOGW
+#define PELOGW(p) { p }
+#else
+#define PELOGW(p) { }
+#endif
+
+#define PELOG1(p) { }
+#define PELOG2(p) { }
+#define PELOG3(p) { }
+#define PELOG4(p) { }
+
+#else /* WLAN_MDM_CODE_REDUCTION_OPT */
+
+#ifdef PE_DEBUG_LOGE
+#define PELOGE(p) { p }
+#else
+#define PELOGE(p) { }
+#endif
+
+#ifdef PE_DEBUG_LOGW
+#define PELOGW(p) { p }
+#else
+#define PELOGW(p) { }
+#endif
+
+#ifdef PE_DEBUG_LOG1
+#define PELOG1(p) { p }
+#else
+#define PELOG1(p) { }
+#endif
+
+#ifdef PE_DEBUG_LOG2
+#define PELOG2(p) { p }
+#else
+#define PELOG2(p) { }
+#endif
+
+#ifdef PE_DEBUG_LOG3
+#define PELOG3(p) { p }
+#else
+#define PELOG3(p) { }
+#endif
+
+#ifdef PE_DEBUG_LOG4
+#define PELOG4(p) { p }
+#else
+#define PELOG4(p) { }
+#endif
+
+#endif /* WLAN_MDM_CODE_REDUCTION_OPT */
+
+#define FL(x) "%s: %d: " \
+ x, __func__, __LINE__
+
+#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+#endif
diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h
new file mode 100644
index 0000000..78513a3
--- /dev/null
+++ b/core/mac/src/include/sir_params.h
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file sir_params.h contains the common parameter definitions, which
+ * are not dependent on threadX API. These can be used by all Firmware
+ * modules.
+ *
+ * Author: Sandesh Goel
+ * Date: 04/13/2002
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SIRPARAMS_H
+#define __SIRPARAMS_H
+
+#include "sir_types.h"
+
+/* defines for WPS config states */
+#define SAP_WPS_DISABLED 0
+#define SAP_WPS_ENABLED_UNCONFIGURED 1
+#define SAP_WPS_ENABLED_CONFIGURED 2
+
+
+/* Firmware wide constants */
+
+#define SIR_MAX_PACKET_SIZE 512
+#define SIR_MAX_NUM_CHANNELS 64
+#define SIR_MAX_NUM_STA_IN_IBSS 16
+#define SIR_ESE_MAX_MEAS_IE_REQS 8
+
+typedef enum {
+ PHY_SINGLE_CHANNEL_CENTERED = 0, /* 20MHz IF bandwidth centered on IF carrier */
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, /* 40MHz IF bandwidth with lower 20MHz supporting the primary channel */
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, /* 40MHz IF bandwidth with higher 20MHz supporting the primary channel */
+#ifdef WLAN_FEATURE_11AC
+ PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, /* 20/40MHZ offset LOW 40/80MHZ offset CENTERED */
+ PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, /* 20/40MHZ offset CENTERED 40/80MHZ offset CENTERED */
+ PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, /* 20/40MHZ offset HIGH 40/80MHZ offset CENTERED */
+ PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7, /* 20/40MHZ offset LOW 40/80MHZ offset LOW */
+ PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, /* 20/40MHZ offset HIGH 40/80MHZ offset LOW */
+ PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, /* 20/40MHZ offset LOW 40/80MHZ offset HIGH */
+ PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10, /* 20/40MHZ offset-HIGH 40/80MHZ offset HIGH */
+#endif
+ PHY_CHANNEL_BONDING_STATE_MAX = 11
+} ePhyChanBondState;
+
+#define MAX_BONDED_CHANNELS 4
+
+typedef enum {
+ MCC = 0,
+ P2P = 1,
+ DOT11AC = 2,
+ SLM_SESSIONIZATION = 3,
+ DOT11AC_OPMODE = 4,
+ SAP32STA = 5,
+ TDLS = 6,
+ P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7,
+ WLANACTIVE_OFFLOAD = 8,
+#ifdef FEATURE_WLAN_EXTSCAN
+ EXTENDED_SCAN = 9,
+#endif
+#ifdef FEATURE_WLAN_SCAN_PNO
+ PNO = 10,
+#endif
+#ifdef WLAN_FEATURE_NAN
+ NAN = 11,
+#endif
+ RTT = 12,
+ WOW = 22,
+ WLAN_ROAM_SCAN_OFFLOAD = 23,
+ IBSS_HEARTBEAT_OFFLOAD = 26,
+ WLAN_PERIODIC_TX_PTRN = 28,
+#ifdef FEATURE_WLAN_TDLS
+ ADVANCE_TDLS = 29,
+ TDLS_OFF_CHANNEL = 30,
+#endif
+
+ /* MAX_FEATURE_SUPPORTED = 128 */
+} placeHolderInCapBitmap;
+
+typedef enum eSriLinkState {
+ eSIR_LINK_IDLE_STATE = 0,
+ eSIR_LINK_PREASSOC_STATE = 1,
+ eSIR_LINK_POSTASSOC_STATE = 2,
+ eSIR_LINK_AP_STATE = 3,
+ eSIR_LINK_IBSS_STATE = 4,
+ /* BT-AMP Case */
+ eSIR_LINK_BTAMP_PREASSOC_STATE = 5,
+ eSIR_LINK_BTAMP_POSTASSOC_STATE = 6,
+ eSIR_LINK_BTAMP_AP_STATE = 7,
+ eSIR_LINK_BTAMP_STA_STATE = 8,
+
+ /* Reserved for HAL internal use */
+ eSIR_LINK_LEARN_STATE = 9,
+ eSIR_LINK_SCAN_STATE = 10,
+ eSIR_LINK_FINISH_SCAN_STATE = 11,
+ eSIR_LINK_INIT_CAL_STATE = 12,
+ eSIR_LINK_FINISH_CAL_STATE = 13,
+ eSIR_LINK_LISTEN_STATE = 14,
+ eSIR_LINK_SEND_ACTION_STATE = 15,
+ eSIR_LINK_DOWN_STATE = 16,
+} tSirLinkState;
+
+/* / Message queue structure used across Sirius project. */
+/* / NOTE: this structure should be multiples of a word size (4bytes) */
+/* / as this is used in tx_queue where it expects to be multiples of 4 bytes. */
+typedef struct sSirMsgQ {
+ uint16_t type;
+ /*
+ * This field can be used as sequence number/dialog token for matching
+ * requests and responses.
+ */
+ uint16_t reserved;
+ /**
+ * Based on the type either a bodyptr pointer into
+ * memory or bodyval as a 32 bit data is used.
+ * bodyptr: is always a freeable pointer, one should always
+ * make sure that bodyptr is always freeable.
+ *
+ * Messages should use either bodyptr or bodyval; not both !!!.
+ */
+ void *bodyptr;
+ uint32_t bodyval;
+
+ /*
+ * Some messages provide a callback function. The function signature
+ * must be agreed upon between the two entities exchanging the message
+ */
+ void *callback;
+
+} tSirMsgQ, *tpSirMsgQ;
+
+/* / Mailbox Message Structure Define */
+typedef struct sSirMbMsg {
+ uint16_t type;
+
+ /**
+ * This length includes 4 bytes of header, that is,
+ * 2 bytes type + 2 bytes msgLen + n*4 bytes of data.
+ * This field is byte length.
+ */
+ uint16_t msgLen;
+
+ /**
+ * This is the first data word in the mailbox message.
+ * It is followed by n words of data.
+ * NOTE: data[1] is not a place holder to store data
+ * instead to dereference the message body.
+ */
+ uint32_t data[1];
+} tSirMbMsg, *tpSirMbMsg;
+
+/* / Mailbox Message Structure for P2P */
+typedef struct sSirMbMsgP2p {
+ uint16_t type;
+
+ /**
+ * This length includes 4 bytes of header, that is,
+ * 2 bytes type + 2 bytes msgLen + n*4 bytes of data.
+ * This field is byte length.
+ */
+ uint16_t msgLen;
+
+ uint8_t sessionId;
+ uint8_t noack;
+ uint16_t wait;
+ uint16_t channel_freq;
+ uint32_t scan_id;
+
+ /**
+ * This is the first data word in the mailbox message.
+ * It is followed by n words of data.
+ * NOTE: data[1] is not a place holder to store data
+ * instead to dereference the message body.
+ */
+ uint32_t data[1];
+} tSirMbMsgP2p, *tpSirMbMsgP2p;
+
+/* ******************************************* *
+* *
+* SIRIUS MESSAGE TYPES *
+* *
+* ******************************************* */
+
+/*
+ * The following message types have bounds defined for each module for
+ * inter thread/module communications.
+ * Each module will get 256 message types in total.
+ * Note that message type definitions for mailbox messages for
+ * communication with Host are in wni_api.h file.
+ *
+ * Any addition/deletion to this message list should also be
+ * reflected in the halUtil_getMsgString() routine.
+ */
+
+/* HAL message types */
+#define SIR_HAL_MSG_TYPES_BEGIN (SIR_HAL_MODULE_ID << 8)
+#define SIR_HAL_ITC_MSG_TYPES_BEGIN (SIR_HAL_MSG_TYPES_BEGIN+0x20)
+#define SIR_HAL_RADAR_DETECTED_IND SIR_HAL_ITC_MSG_TYPES_BEGIN
+
+/*
+ * New Taurus related messages
+ */
+#define SIR_HAL_ADD_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 1)
+#define SIR_HAL_ADD_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 2)
+#define SIR_HAL_DELETE_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 3)
+#define SIR_HAL_DELETE_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 4)
+#define SIR_HAL_ADD_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 5)
+#define SIR_HAL_ADD_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 6)
+#define SIR_HAL_DELETE_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 7)
+#define SIR_HAL_DELETE_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 8)
+#define SIR_HAL_INIT_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 9)
+#define SIR_HAL_INIT_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 10)
+#define SIR_HAL_START_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 11)
+#define SIR_HAL_START_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 12)
+#define SIR_HAL_END_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 13)
+#define SIR_HAL_END_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 14)
+#define SIR_HAL_FINISH_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 15)
+#define SIR_HAL_FINISH_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 16)
+#define SIR_HAL_SEND_BEACON_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 17)
+
+#define SIR_HAL_SET_BSSKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 18)
+#define SIR_HAL_SET_BSSKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 19)
+#define SIR_HAL_SET_STAKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 20)
+#define SIR_HAL_SET_STAKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 21)
+#define SIR_HAL_UPDATE_EDCA_PROFILE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 22)
+
+#define SIR_HAL_UPDATE_BEACON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 23)
+#define SIR_HAL_UPDATE_CF_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 24)
+#define SIR_HAL_CHNL_SWITCH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 25)
+#define SIR_HAL_ADD_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 26)
+#define SIR_HAL_DEL_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 27)
+
+#define SIR_HAL_MISSED_BEACON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 34)
+
+#define SIR_HAL_SWITCH_CHANNEL_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 35)
+#define SIR_HAL_PWR_SAVE_CFG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 36)
+
+#define SIR_HAL_REGISTER_PE_CALLBACK (SIR_HAL_ITC_MSG_TYPES_BEGIN + 37)
+
+#define SIR_HAL_IBSS_STA_ADD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 43)
+#define SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 44)
+#define SIR_HAL_SET_LINK_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 45)
+
+/*
+ * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 46) to
+ * (SIR_HAL_ITC_MSG_TYPES_BEGIN + 57) are unused
+ */
+
+#define SIR_HAL_SET_STA_BCASTKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 58)
+#define SIR_HAL_SET_STA_BCASTKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 59)
+#define SIR_HAL_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 60)
+#define SIR_HAL_DPU_MIC_ERROR (SIR_HAL_ITC_MSG_TYPES_BEGIN + 61)
+#define SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 63)
+#define SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 64)
+#define SIR_HAL_TIMER_ADC_RSSI_STATS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 65)
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 66) is unused */
+#define SIR_HAL_SET_MIMOPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 67)
+#define SIR_HAL_SET_MIMOPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 68)
+#define SIR_HAL_SYS_READY_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 69)
+#define SIR_HAL_SET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 70)
+#define SIR_HAL_SET_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 71)
+#define SIR_HAL_GET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 72)
+#define SIR_HAL_GET_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 73)
+#define SIR_HAL_GET_NOISE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 74)
+
+/* Messages to support transmit_halt and transmit_resume */
+#define SIR_HAL_TRANSMISSION_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 75)
+
+#define SIR_HAL_LOW_RSSI_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 80)
+#define SIR_HAL_BEACON_FILTER_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 81)
+/* / PE <-> HAL WOWL messages */
+#define SIR_HAL_WOW_ADD_PTRN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 82)
+#define SIR_HAL_WOW_DEL_PTRN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 83)
+#define SIR_HAL_WOWL_ENTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 84)
+#define SIR_HAL_WOWL_ENTER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 85)
+#define SIR_HAL_WOWL_EXIT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 86)
+#define SIR_HAL_WOWL_EXIT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 87)
+/* / PE <-> HAL statistics messages */
+#define SIR_HAL_GET_STATISTICS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 88)
+#define SIR_HAL_GET_STATISTICS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 89)
+#define SIR_HAL_SET_KEY_DONE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 90)
+
+/* / PE <-> HAL BTC messages */
+#define SIR_HAL_BTC_SET_CFG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 91)
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 92) is unused */
+#define SIR_HAL_HANDLE_FW_MBOX_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 93)
+#define SIR_HAL_SEND_PROBE_RSP_TMPL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 94)
+
+/* PE <-> HAL addr2 mismatch message */
+#define SIR_LIM_ADDR2_MISS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 95)
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/* PE <-> HAL OEM_DATA RELATED MESSAGES */
+#define SIR_HAL_START_OEM_DATA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 96)
+#define SIR_HAL_START_OEM_DATA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 97)
+#endif
+
+#define SIR_HAL_SET_MAX_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 98)
+#define SIR_HAL_SET_MAX_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 99)
+
+/* / PE <-> HAL Host Offload message */
+#define SIR_HAL_SET_HOST_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 100)
+
+#define SIR_HAL_ADD_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 101)
+#define SIR_HAL_ADD_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 102)
+#define SIR_HAL_DEL_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 103)
+#define SIR_HAL_DEL_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 104)
+
+#define SIR_HAL_CFG_RXP_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 106)
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#define SIR_HAL_AGGR_ADD_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 107)
+#define SIR_HAL_AGGR_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 108)
+#define SIR_HAL_AGGR_QOS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 109)
+#define SIR_HAL_AGGR_QOS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 110)
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+/* P2P <-> HAL P2P msg */
+#define SIR_HAL_SET_P2P_GO_NOA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 111)
+#define SIR_HAL_P2P_NOA_ATTR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 112)
+#define SIR_HAL_P2P_NOA_START_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 113)
+
+#define SIR_HAL_SET_LINK_STATE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 114)
+
+#define SIR_HAL_WLAN_SUSPEND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 115)
+#define SIR_HAL_WLAN_RESUME_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 116)
+
+/* / PE <-> HAL Keep Alive message */
+#define SIR_HAL_SET_KEEP_ALIVE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 117)
+
+#ifdef WLAN_NS_OFFLOAD
+#define SIR_HAL_SET_NS_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 118)
+#endif /* WLAN_NS_OFFLOAD */
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+#define SIR_HAL_SET_PNO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 119)
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 120) is unused */
+#endif /* FEATURE_WLAN_SCAN_PNO */
+
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 122) is unused */
+
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+#define SIR_HAL_8023_MULTICAST_LIST_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 123)
+#define SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 124)
+#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 125)
+#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 126)
+#define SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 127)
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+
+/* (SIR_HAL_ITC_MSG_TYPES_BEGIN + 128) is unused */
+
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+#define SIR_HAL_GTK_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 129)
+#define SIR_HAL_GTK_OFFLOAD_GETINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 130)
+#define SIR_HAL_GTK_OFFLOAD_GETINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 131)
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+
+#ifdef FEATURE_WLAN_ESE
+#define SIR_HAL_TSM_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 132)
+#define SIR_HAL_TSM_STATS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 133)
+#endif
+
+#define SIR_HAL_SET_TM_LEVEL_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 134)
+
+#ifdef WLAN_FEATURE_11AC
+#define SIR_HAL_UPDATE_OP_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 135)
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+/* / PE <-> HAL TDLS messages */
+#define SIR_HAL_TDLS_LINK_ESTABLISH (SIR_HAL_ITC_MSG_TYPES_BEGIN + 136)
+#define SIR_HAL_TDLS_LINK_TEARDOWN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 137)
+#endif
+#define SIR_HAL_ROAM_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 138)
+
+#define SIR_HAL_TRAFFIC_STATS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 141)
+
+#ifdef WLAN_FEATURE_11W
+#define SIR_HAL_EXCLUDE_UNENCRYPTED_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 142)
+#endif
+#ifdef FEATURE_WLAN_TDLS
+/* / PE <-> HAL TDLS messages */
+#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 143)
+#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 144)
+#define SIR_HAL_TDLS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 145)
+#endif
+
+#define SIR_HAL_STOP_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 146)
+#define SIR_HAL_RX_SCAN_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 147)
+#define SIR_HAL_DHCP_START_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 148)
+#define SIR_HAL_DHCP_STOP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 149)
+#define SIR_HAL_IBSS_PEER_INACTIVITY_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 150)
+
+#define SIR_HAL_LPHB_CONF_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 151)
+
+#define SIR_HAL_ADD_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 152)
+#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 153)
+
+/* Messages between 156 to 157 are not used */
+#define SIR_HAL_SOC_DUAL_MAC_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154)
+#define SIR_HAL_SOC_DUAL_MAC_CFG_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155)
+
+#define SIR_HAL_RATE_UPDATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 159)
+
+#define SIR_HAL_FLUSH_LOG_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160)
+
+#define SIR_HAL_SOC_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161)
+
+/* 162 unused */
+
+#define SIR_HAL_CLI_SET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 163)
+#ifndef REMOVE_PKT_LOG
+#define SIR_HAL_PKTLOG_ENABLE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 164)
+#endif
+#ifdef FEATURE_WLAN_SCAN_PNO
+#define SIR_HAL_SME_SCAN_CACHE_UPDATED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 165)
+#endif
+#define SIR_HAL_START_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 166)
+#define SIR_HAL_UPDATE_CHAN_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 167)
+#define SIR_CSA_OFFLOAD_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 169)
+
+#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 170)
+
+#ifdef WLAN_FEATURE_11AC
+#define SIR_HAL_UPDATE_MEMBERSHIP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 172)
+#define SIR_HAL_UPDATE_USERPOS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 173)
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+#define SIR_HAL_UPDATE_FW_TDLS_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 174)
+#define SIR_HAL_UPDATE_TDLS_PEER_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 175)
+#define SIR_HAL_TDLS_SHOULD_DISCOVER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 176)
+#define SIR_HAL_TDLS_SHOULD_TEARDOWN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 177)
+#define SIR_HAL_TDLS_PEER_DISCONNECTED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 178)
+#endif
+
+/* Handling of beacon tx indication from FW */
+#define SIR_HAL_BEACON_TX_SUCCESS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 179)
+#define SIR_HAL_DFS_RADAR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 180)
+
+#define SIR_HAL_INIT_THERMAL_INFO_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 185)
+#define SIR_HAL_SET_THERMAL_LEVEL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 186)
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+#define SIR_HAL_SET_PLM_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 187)
+#endif
+
+#define SIR_HAL_SET_TX_POWER_LIMIT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 188)
+#define SIR_HAL_SET_SAP_INTRABSS_DIS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 189)
+
+#define SIR_HAL_MODEM_POWER_STATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 190)
+
+#define SIR_HAL_DISASSOC_TX_COMP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 191)
+#define SIR_HAL_DEAUTH_TX_COMP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 192)
+
+#ifdef WLAN_FEATURE_11AC
+#define SIR_HAL_UPDATE_RX_NSS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 193)
+#endif
+
+#ifdef WLAN_FEATURE_STATS_EXT
+#define SIR_HAL_STATS_EXT_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 194)
+#define SIR_HAL_STATS_EXT_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 195)
+#endif /* WLAN_FEATURE_STATS_EXT */
+
+#define SIR_HAL_HIDE_SSID_VDEV_RESTART (SIR_HAL_ITC_MSG_TYPES_BEGIN + 196)
+
+#define SIR_HAL_GET_LINK_SPEED (SIR_HAL_ITC_MSG_TYPES_BEGIN + 197)
+
+#ifdef FEATURE_WLAN_EXTSCAN
+#define SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 198)
+#define SIR_HAL_EXTSCAN_START_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 199)
+#define SIR_HAL_EXTSCAN_STOP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 200)
+#define SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 201)
+#define SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 202)
+#define SIR_HAL_EXTSCAN_SET_SIGNF_CHANGE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 203)
+#define SIR_HAL_EXTSCAN_RESET_SIGNF_CHANGE_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 204)
+#define SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ \
+ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 205)
+#endif /* FEATURE_WLAN_EXTSCAN */
+
+#ifdef FEATURE_WLAN_CH_AVOID
+#define SIR_HAL_CH_AVOID_UPDATE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 206)
+#endif
+
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+#define SIR_HAL_LL_STATS_CLEAR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207)
+#define SIR_HAL_LL_STATS_SET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 208)
+#define SIR_HAL_LL_STATS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 209)
+#define SIR_HAL_LL_STATS_RESULTS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 210)
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define SIR_HAL_ROAM_OFFLOAD_SYNCH_CNF (SIR_HAL_ITC_MSG_TYPES_BEGIN + 211)
+#endif
+#ifdef WLAN_FEATURE_NAN
+#define SIR_HAL_NAN_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 212)
+#endif /* WLAN_FEATURE_NAN */
+
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+#define SIR_HAL_SET_AUTO_SHUTDOWN_TIMER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 213)
+#endif
+
+#define SIR_HAL_SET_BASE_MACADDR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 214)
+
+#define SIR_HAL_UNIT_TEST_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 215)
+
+#define SIR_HAL_LINK_STATUS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 216)
+
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+#define SIR_HAL_CONFIG_EXT_WOW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 217)
+#define SIR_HAL_CONFIG_APP_TYPE1_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 218)
+#define SIR_HAL_CONFIG_APP_TYPE2_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 219)
+#endif
+
+#define SIR_HAL_GET_TEMPERATURE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220)
+#define SIR_HAL_SET_SCAN_MAC_OUI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221)
+#ifdef DHCP_SERVER_OFFLOAD
+#define SIR_HAL_SET_DHCP_SERVER_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 222)
+#endif /* DHCP_SERVER_OFFLOAD */
+#define SIR_HAL_LED_FLASHING_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 223)
+#define SIR_HAL_PROCESS_FW_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 224)
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+#define SIR_HAL_ROAM_OFFLOAD_SYNCH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 225)
+#define SIR_HAL_ROAM_OFFLOAD_SYNCH_FAIL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 226)
+#define SIR_HAL_ROAM_INVOKE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 227)
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+#define SIR_HAL_TDLS_SET_OFFCHAN_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 228)
+#endif
+
+#define SIR_HAL_SET_MAS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 229)
+#define SIR_HAL_SET_MIRACAST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 230)
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+#define SIR_HAL_UPDATE_Q2Q_IE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 231)
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#define SIR_HAL_CONFIG_STATS_FACTOR (SIR_HAL_ITC_MSG_TYPES_BEGIN + 232)
+#define SIR_HAL_CONFIG_GUARD_TIME (SIR_HAL_ITC_MSG_TYPES_BEGIN + 233)
+#define SIR_HAL_IPA_OFFLOAD_ENABLE_DISABLE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 234)
+
+#define SIR_HAL_ENTER_PS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 235)
+#define SIR_HAL_EXIT_PS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 236)
+#define SIR_HAL_ENABLE_UAPSD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 237)
+#define SIR_HAL_DISABLE_UAPSD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 238)
+
+#define SIR_HAL_SET_EPNO_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 313)
+#define SIR_HAL_SET_PASSPOINT_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 316)
+#define SIR_HAL_RESET_PASSPOINT_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 317)
+#define SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 318)
+
+#define SIR_HAL_OCB_SET_CONFIG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 319)
+#define SIR_HAL_OCB_SET_UTC_TIME_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 320)
+#define SIR_HAL_OCB_START_TIMING_ADVERT_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 321)
+#define SIR_HAL_OCB_STOP_TIMING_ADVERT_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 322)
+#define SIR_HAL_OCB_GET_TSF_TIMER_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 323)
+#define SIR_HAL_DCC_GET_STATS_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 324)
+#define SIR_HAL_DCC_CLEAR_STATS_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 325)
+#define SIR_HAL_DCC_UPDATE_NDL_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 326)
+
+#define SIR_HAL_FW_MEM_DUMP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 327)
+#define SIR_HAL_START_STOP_LOGGING (SIR_HAL_ITC_MSG_TYPES_BEGIN + 328)
+#define SIR_HAL_SOC_SET_HW_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 329)
+#define SIR_HAL_SOC_SET_HW_MODE_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 330)
+#define SIR_HAL_SOC_HW_MODE_TRANS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 331)
+
+#define SIR_HAL_SET_RSSI_MONITOR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 333)
+#define SIR_HAL_SET_IE_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 334)
+
+#define SIR_HAL_LRO_CONFIG_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 335)
+
+#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
+
+/* CFG message types */
+#define SIR_CFG_MSG_TYPES_BEGIN (SIR_CFG_MODULE_ID << 8)
+#define SIR_CFG_ITC_MSG_TYPES_BEGIN (SIR_CFG_MSG_TYPES_BEGIN+0xB0)
+#define SIR_CFG_PARAM_UPDATE_IND (SIR_CFG_ITC_MSG_TYPES_BEGIN)
+#define SIR_CFG_DOWNLOAD_COMPLETE_IND (SIR_CFG_ITC_MSG_TYPES_BEGIN + 1)
+#define SIR_CFG_MSG_TYPES_END (SIR_CFG_MSG_TYPES_BEGIN+0xFF)
+
+/* LIM message types */
+#define SIR_LIM_MSG_TYPES_BEGIN (SIR_LIM_MODULE_ID << 8)
+#define SIR_LIM_ITC_MSG_TYPES_BEGIN (SIR_LIM_MSG_TYPES_BEGIN+0xB0)
+
+/* Messages to/from HAL */
+/* Removed as part of moving HAL down to FW */
+
+/* Message from ISR upon TFP retry interrupt */
+#define SIR_LIM_RETRY_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 3)
+/* Message from BB Transport */
+#define SIR_BB_XPORT_MGMT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 4)
+/* UNUSED SIR_LIM_ITC_MSG_TYPES_BEGIN + 6 */
+/* Message from ISR upon SP's Invalid session key interrupt */
+#define SIR_LIM_INV_KEY_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 7)
+/* Message from ISR upon SP's Invalid key ID interrupt */
+#define SIR_LIM_KEY_ID_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 8)
+/* Message from ISR upon SP's Replay threshold reached interrupt */
+#define SIR_LIM_REPLAY_THRES_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 9)
+/* Message from HDD after the TD dummy packet is cleaned up */
+#define SIR_LIM_TD_DUMMY_CALLBACK_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xA)
+/* Message from SCH when the STA is ready to be deleted */
+#define SIR_LIM_SCH_CLEAN_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xB)
+/* Message from ISR upon Radar Detection */
+#define SIR_LIM_RADAR_DETECT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xC)
+
+/* /////////////////////////////////// */
+/* message id Available */
+/* ////////////////////////////////// */
+
+/* Message from Hal to send out a DEL-TS indication */
+#define SIR_LIM_DEL_TS_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xE)
+/* Indication from HAL to delete Station context */
+#define SIR_LIM_DELETE_STA_CONTEXT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x11)
+/* Indication from HAL to delete BA */
+#define SIR_LIM_UPDATE_BEACON (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x13)
+
+/* LIM Timeout messages */
+#define SIR_LIM_TIMEOUT_MSG_START ((SIR_LIM_MODULE_ID << 8) + 0xD0)
+#define SIR_LIM_JOIN_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 2)
+#define SIR_LIM_AUTH_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 3)
+#define SIR_LIM_AUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 4)
+#define SIR_LIM_ASSOC_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 5)
+#define SIR_LIM_REASSOC_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 6)
+#define SIR_LIM_HEART_BEAT_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 7)
+/* currently unused SIR_LIM_TIMEOUT_MSG_START + 0x8 */
+/* Link Monitoring Messages */
+#define SIR_LIM_PROBE_HB_FAILURE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xB)
+#define SIR_LIM_ADDTS_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xC)
+#define SIR_LIM_LINK_TEST_DURATION_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x13)
+#define SIR_LIM_HASH_MISS_THRES_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x16)
+#define SIR_LIM_CNF_WAIT_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x17)
+/* currently unused (SIR_LIM_TIMEOUT_MSG_START + 0x18) */
+#define SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x19)
+#define SIR_LIM_CHANNEL_SWITCH_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1A)
+#define SIR_LIM_QUIET_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1B)
+#define SIR_LIM_QUIET_BSS_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1C)
+
+#define SIR_LIM_WPS_OVERLAP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1D)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#define SIR_LIM_FT_PREAUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1E)
+#endif
+#define SIR_LIM_REMAIN_CHN_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1F)
+#define SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x20)
+
+#define SIR_LIM_BEACON_GEN_IND (SIR_LIM_TIMEOUT_MSG_START + 0x23)
+#define SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x24)
+#ifdef FEATURE_WLAN_ESE
+#define SIR_LIM_ESE_TSM_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x25)
+#endif
+
+#define SIR_LIM_DISASSOC_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x26)
+#define SIR_LIM_DEAUTH_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x27)
+#define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT \
+ (SIR_LIM_TIMEOUT_MSG_START + 0x28)
+
+#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE \
+ (SIR_LIM_TIMEOUT_MSG_START + 0x2C)
+
+#define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF)
+
+/* SCH message types */
+#define SIR_SCH_MSG_TYPES_BEGIN (SIR_SCH_MODULE_ID << 8)
+#define SIR_SCH_CHANNEL_SWITCH_REQUEST (SIR_SCH_MSG_TYPES_BEGIN)
+#define SIR_SCH_START_SCAN_REQ (SIR_SCH_MSG_TYPES_BEGIN + 1)
+#define SIR_SCH_START_SCAN_RSP (SIR_SCH_MSG_TYPES_BEGIN + 2)
+#define SIR_SCH_END_SCAN_NTF (SIR_SCH_MSG_TYPES_BEGIN + 3)
+#define SIR_SCH_MSG_TYPES_END (SIR_SCH_MSG_TYPES_BEGIN+0xFF)
+
+/* PMM message types */
+#define SIR_PMM_MSG_TYPES_BEGIN (SIR_PMM_MODULE_ID << 8)
+#define SIR_PMM_CHANGE_PM_MODE (SIR_PMM_MSG_TYPES_BEGIN)
+#define SIR_PMM_MSG_TYPES_END (SIR_PMM_MSG_TYPES_BEGIN+0xFF)
+
+/* MNT message types */
+#define SIR_MNT_MSG_TYPES_BEGIN (SIR_MNT_MODULE_ID << 8)
+#define SIR_MNT_RELEASE_BD (SIR_MNT_MSG_TYPES_BEGIN + 0)
+#define SIR_MNT_MSG_TYPES_END (SIR_MNT_MSG_TYPES_BEGIN + 0xFF)
+
+/* PTT message types */
+#define SIR_PTT_MSG_TYPES_BEGIN 0x3000
+#define SIR_PTT_MSG_TYPES_END 0x3300
+
+/* ****************************************** *
+* *
+* EVENT TYPE Defintions *
+* *
+* ****************************************** */
+
+/* MMH Events that are used in other modules to post events to MMH */
+#define SIR_HSTEMUL_TXMB_DONE_EVT 0x00000100
+#define SIR_HSTEMUL_RXMB_READY_EVT 0x00000200
+#define SIR_HSTEMUL_MSGQ_NE_EVT 0x00000400
+
+#define SIR_TST_XMIT_MSG_QS_EMPTY_EVT 0x00000080
+
+/* added for OBSS */
+
+/* Param Change Bitmap sent to HAL */
+#define PARAM_BCN_INTERVAL_CHANGED (1 << 0)
+#define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1)
+#define PARAM_SHORT_SLOT_TIME_CHANGED (1 << 2)
+#define PARAM_llACOEXIST_CHANGED (1 << 3)
+#define PARAM_llBCOEXIST_CHANGED (1 << 4)
+#define PARAM_llGCOEXIST_CHANGED (1 << 5)
+#define PARAM_HT20MHZCOEXIST_CHANGED (1<<6)
+#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7)
+#define PARAM_RIFS_MODE_CHANGED (1<<8)
+#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9)
+#define PARAM_OBSS_MODE_CHANGED (1<<10)
+#define PARAM_BEACON_UPDATE_MASK (PARAM_BCN_INTERVAL_CHANGED | \
+ PARAM_SHORT_PREAMBLE_CHANGED | \
+ PARAM_SHORT_SLOT_TIME_CHANGED | \
+ PARAM_llACOEXIST_CHANGED | \
+ PARAM_llBCOEXIST_CHANGED | \
+ PARAM_llGCOEXIST_CHANGED | \
+ PARAM_HT20MHZCOEXIST_CHANGED | \
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED | \
+ PARAM_RIFS_MODE_CHANGED | \
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED | \
+ PARAM_OBSS_MODE_CHANGED)
+
+#endif
diff --git a/core/mac/src/include/sys_global.h b/core/mac/src/include/sys_global.h
new file mode 100644
index 0000000..2f76ddf
--- /dev/null
+++ b/core/mac/src/include/sys_global.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __SYS_GLOBAL_H__
+#define __SYS_GLOBAL_H__
+
+typedef struct sAniSirSys {
+
+ uint32_t gSysFrameCount[4][16];
+ uint32_t gSysBbtReceived;
+ uint32_t gSysBbtPostedToLim;
+ uint32_t gSysBbtPostedToSch;
+ uint32_t gSysBbtPostedToPmm;
+ uint32_t gSysBbtPostedToHal;
+ uint32_t gSysBbtDropped;
+ uint32_t gSysBbtNonLearnFrameInv;
+ uint32_t gSysBbtLearnFrameInv;
+ uint32_t gSysBbtCrcFail;
+ uint32_t gSysBbtDuplicates;
+ uint32_t gSysReleaseCount;
+ uint32_t probeError, probeBadSsid, probeIgnore, probeRespond;
+
+ uint32_t gSysEnableLearnMode;
+ uint32_t gSysEnableScanMode;
+ uint32_t gSysEnableLinkMonitorMode;
+} tAniSirSys, *tpAniSirSys;
+
+#endif
diff --git a/core/mac/src/include/utils_api.h b/core/mac/src/include/utils_api.h
new file mode 100644
index 0000000..6a344be
--- /dev/null
+++ b/core/mac/src/include/utils_api.h
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __UTILSAPI_H
+#define __UTILSAPI_H
+
+#include <stdarg.h>
+#include <sir_common.h>
+#include "ani_global.h"
+#include "utils_global.h"
+#include "sys_wrapper.h"
+
+/* / System role definition on a per BSS */
+typedef enum eBssSystemRole {
+ eSYSTEM_UNKNOWN_ROLE,
+ eSYSTEM_AP_ROLE,
+ eSYSTEM_STA_IN_IBSS_ROLE,
+ eSYSTEM_STA_ROLE,
+ eSYSTEM_BTAMP_STA_ROLE,
+ eSYSTEM_BTAMP_AP_ROLE,
+
+ eSYSTEM_LAST_ROLE,
+ eSYSTEM_MULTI_BSS_ROLE = eSYSTEM_LAST_ROLE
+} tBssSystemRole;
+
+#define LOG_INDEX_FOR_MODULE(modId) ((modId) - LOG_FIRST_MODULE_ID)
+#define GET_MIN_VALUE(__val1, __val2) ((__val1 < __val2) ? __val1 : __val2)
+
+/* The caller must check loglevel. This API assumes loglevel is good */
+extern void log_debug(tpAniSirGlobal pMac, uint8_t modId, uint32_t debugLevel,
+ const char *pStr, va_list marker);
+
+extern void log_dbg(tpAniSirGlobal pMac, uint8_t modId, uint32_t debugLevel,
+ const char *pStr, ...);
+
+extern uint32_t gPktAllocCnt, gPktFreeCnt;
+
+extern CDF_TRACE_LEVEL get_vos_debug_level(uint32_t debugLevel);
+
+/* / Log initialization */
+extern tSirRetStatus log_init(tpAniSirGlobal);
+
+extern void log_deinit(tpAniSirGlobal);
+
+extern tSirRetStatus cfg_init(tpAniSirGlobal);
+extern void cfg_de_init(tpAniSirGlobal);
+
+void sir_dump_buf(tpAniSirGlobal pMac, uint8_t modId, uint32_t level,
+ uint8_t *buf, uint32_t size);
+
+/**
+ * sir_swap_u16()
+ *
+ * FUNCTION:
+ * This function is called to swap two U8s of an uint16_t value
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param val uint16_t value to be uint8_t swapped
+ * @return Swapped uint16_t value
+ */
+
+static inline uint16_t sir_swap_u16(uint16_t val)
+{
+ return ((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8);
+} /*** end sir_swap_u16() ***/
+
+/**
+ * sir_swap_u16if_needed()
+ *
+ * FUNCTION:
+ * This function is called to swap two U8s of an uint16_t value depending
+ * on endiannes of the target processor/compiler the software is
+ * running on
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param val uint16_t value to be uint8_t swapped
+ * @return Swapped uint16_t value
+ */
+
+static inline uint16_t sir_swap_u16if_needed(uint16_t val)
+{
+#ifndef ANI_LITTLE_BYTE_ENDIAN
+ return sir_swap_u16(val);
+#else
+ return val;
+#endif
+} /*** end sir_swap_u16if_needed() ***/
+
+/**
+ * sir_swap_u32()
+ *
+ * FUNCTION:
+ * This function is called to swap four U8s of an uint32_t value
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param val uint32_t value to be uint8_t swapped
+ * @return Swapped uint32_t value
+ */
+
+static inline uint32_t sir_swap_u32(uint32_t val)
+{
+ return (val << 24) |
+ (val >> 24) |
+ ((val & 0x0000FF00) << 8) | ((val & 0x00FF0000) >> 8);
+} /*** end sir_swap_u32() ***/
+
+/**
+ * sir_swap_u32if_needed()
+ *
+ * FUNCTION:
+ * This function is called to swap U8s of an uint32_t value depending
+ * on endiannes of the target processor/compiler the software is
+ * running on
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param val uint32_t value to be uint8_t swapped
+ * @return Swapped uint32_t value
+ */
+
+static inline uint32_t sir_swap_u32if_needed(uint32_t val)
+{
+#ifndef ANI_LITTLE_BYTE_ENDIAN
+ return sir_swap_u32(val);
+#else
+ return val;
+#endif
+} /*** end sir_swap_u32if_needed() ***/
+
+/**
+ * sir_swap_u32_buf
+ *
+ * FUNCTION:
+ * It swaps N dwords into the same buffer
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of uint32_t array
+ * @return void
+ *
+ */
+
+static inline void sir_swap_u32_buf(uint32_t *ptr, uint32_t nWords)
+{
+ uint32_t i;
+
+ for (i = 0; i < nWords; i++)
+ ptr[i] = sir_swap_u32(ptr[i]);
+}
+
+/**
+ * sir_swap_u32_buf_if_needed()
+ *
+ * FUNCTION:
+ * This function is called to swap U8s of U32s in the buffer depending
+ * on endiannes of the target processor/compiler the software is
+ * running on
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param pBuf Buffer that will get swapped
+ * @param nWords Number DWORDS will be swapped
+ * @return void
+ */
+
+static inline void sir_swap_u32_buf_if_needed(uint32_t *pBuf, uint32_t nWords)
+{
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+ sir_swap_u32_buf(pBuf, nWords);
+#endif
+} /*** end sir_swap_u32if_needed() ***/
+
+/**
+ * sir_swap_bd_if_needed
+ *
+ * FUNCTION:
+ * Byte swap all the dwords in the BD, except the PHY/MAC headers
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param pBd BD that will get swapped
+ * @return void
+ */
+
+static inline void sir_swap_bd_if_needed(uint32_t *pBd)
+{
+ sir_swap_u32_buf_if_needed(pBd, 6);
+ sir_swap_u32_buf_if_needed(pBd + 18, 14);
+}
+
+/**
+ * sir_store_u16_n
+ *
+ * FUNCTION:
+ * It stores a 16 bit number into the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of destination byte array
+ * @param val value to store
+ * @return None
+ */
+
+static inline void sir_store_u16_n(uint8_t *ptr, uint16_t val)
+{
+ *ptr++ = (val >> 8) & 0xff;
+ *ptr = val & 0xff;
+}
+
+/**
+ * sir_store_u32_n
+ *
+ * FUNCTION:
+ * It stores a 32 bit number into the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of destination byte array
+ * @param val value to store
+ * @return None
+ */
+
+static inline void sir_store_u32_n(uint8_t *ptr, uint32_t val)
+{
+ *ptr++ = (uint8_t) (val >> 24) & 0xff;
+ *ptr++ = (uint8_t) (val >> 16) & 0xff;
+ *ptr++ = (uint8_t) (val >> 8) & 0xff;
+ *ptr = (uint8_t) (val) & 0xff;
+}
+
+/**
+ * sir_store_u16
+ *
+ * FUNCTION:
+ * It stores a 16 bit number into the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of destination byte array
+ * @param val value to store
+ * @return None
+ */
+
+static inline void sir_store_u16(uint8_t *ptr, uint16_t val)
+{
+ *ptr++ = val & 0xff;
+ *ptr = (val >> 8) & 0xff;
+}
+
+/**
+ * sir_store_u32
+ *
+ * FUNCTION:
+ * It stores a 32 bit number into the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of destination byte array
+ * @param val value to store
+ * @return None
+ */
+
+static inline void sir_store_u32(uint8_t *ptr, uint32_t val)
+{
+ *ptr++ = (uint8_t) val & 0xff;
+ *ptr++ = (uint8_t) (val >> 8) & 0xff;
+ *ptr++ = (uint8_t) (val >> 16) & 0xff;
+ *ptr = (uint8_t) (val >> 24) & 0xff;
+}
+
+/**
+ * sir_store_u32BufN
+ *
+ * FUNCTION:
+ * It stores a 32 bit number into the byte array in network byte order
+ * i.e. the least significant byte first. It performs the above operation
+ * on entire buffer and writes to the dst buffer
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * Assumes that the pSrc buffer is of all uint32_t data type fields.
+ *
+ * NOTE:
+ * Must be used if all the fields in the buffer must be of uint32_t types.
+ *
+ * @param pDst address of destination byte array
+ * @param pSrc address of the source DWORD array
+ * @param length number of DWORDs
+ * @return None
+ */
+
+static inline void
+sir_store_buf_n(uint8_t *pDst, uint32_t *pSrc, uint32_t length)
+{
+ while (length) {
+ sir_store_u32_n(pDst, *pSrc);
+ pDst += 4;
+ pSrc++;
+ length--;
+ }
+}
+
+/**
+ * sir_read_u16_n
+ *
+ * FUNCTION:
+ * It reads a 16 bit number from the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of byte array
+ * @return 16 bit value
+ */
+
+static inline uint16_t sir_read_u16_n(uint8_t *ptr)
+{
+ return ((*ptr) << 8) | (*(ptr + 1));
+}
+
+/**
+ * sir_swap_u32_buf
+ *
+ * FUNCTION:
+ * It swaps N dwords into the same buffer
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of uint32_t array
+ * @return void
+ *
+ */
+
+static inline void
+sir_swap_n_store(uint32_t *src, uint32_t *dst, uint32_t nWords)
+{
+ uint32_t i;
+
+ for (i = 0; i < nWords; i++)
+ dst[i] = sir_swap_u32(src[i]);
+}
+
+/**
+ * sir_read_u32_n
+ *
+ * FUNCTION:
+ * It reads a 32 bit number from the byte array in network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of byte array
+ * @return 32 bit value
+ */
+
+static inline uint32_t sir_read_u32_n(uint8_t *ptr)
+{
+ return (*(ptr) << 24) |
+ (*(ptr + 1) << 16) | (*(ptr + 2) << 8) | (*(ptr + 3));
+}
+
+/**
+ * sir_read_u16
+ *
+ * FUNCTION:
+ * It reads a 16 bit number from the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of byte array
+ * @return 16 bit value
+ */
+
+static inline uint16_t sir_read_u16(uint8_t *ptr)
+{
+ return (*ptr) | (*(ptr + 1) << 8);
+}
+
+/**
+ * sir_read_u32
+ *
+ * FUNCTION:
+ * It reads a 32 bit number from the byte array in NON-network byte order
+ * i.e. the least significant byte first
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param ptr address of byte array
+ * @return 32 bit value
+ */
+
+static inline uint32_t sir_read_u32(uint8_t *ptr)
+{
+ return (*(ptr)) |
+ (*(ptr + 1) << 8) | (*(ptr + 2) << 16) | (*(ptr + 3) << 24);
+}
+
+/* / Copy a MAC address from 'from' to 'to' */
+static inline void sir_copy_mac_addr(uint8_t to[], uint8_t from[])
+{
+#if defined(_X86_)
+ uint32_t align = (0x3 & ((uint32_t) to | (uint32_t) from));
+ if (align == 0) {
+ *((uint16_t *) &(to[4])) = *((uint16_t *) &(from[4]));
+ *((uint32_t *) to) = *((uint32_t *) from);
+ } else if (align == 2) {
+ *((uint16_t *) &to[4]) = *((uint16_t *) &from[4]);
+ *((uint16_t *) &to[2]) = *((uint16_t *) &from[2]);
+ *((uint16_t *) &to[0]) = *((uint16_t *) &from[0]);
+ } else {
+ to[5] = from[5];
+ to[4] = from[4];
+ to[3] = from[3];
+ to[2] = from[2];
+ to[1] = from[1];
+ to[0] = from[0];
+ }
+#else
+ to[0] = from[0];
+ to[1] = from[1];
+ to[2] = from[2];
+ to[3] = from[3];
+ to[4] = from[4];
+ to[5] = from[5];
+#endif
+}
+
+static inline uint8_t sir_compare_mac_addr(uint8_t addr1[], uint8_t addr2[])
+{
+#if defined(_X86_)
+ uint32_t align = (0x3 & ((uint32_t) addr1 | (uint32_t) addr2));
+
+ if (align == 0) {
+ return (*((uint16_t *) &(addr1[4])) ==
+ *((uint16_t *) &(addr2[4])))
+ && (*((uint32_t *) addr1) == *((uint32_t *) addr2));
+ } else if (align == 2) {
+ return (*((uint16_t *) &addr1[4]) ==
+ *((uint16_t *) &addr2[4]))
+ && (*((uint16_t *) &addr1[2]) ==
+ *((uint16_t *) &addr2[2]))
+ && (*((uint16_t *) &addr1[0]) ==
+ *((uint16_t *) &addr2[0]));
+ } else {
+ return (addr1[5] == addr2[5]) &&
+ (addr1[4] == addr2[4]) &&
+ (addr1[3] == addr2[3]) &&
+ (addr1[2] == addr2[2]) &&
+ (addr1[1] == addr2[1]) && (addr1[0] == addr2[0]);
+ }
+#else
+ return (addr1[0] == addr2[0]) &&
+ (addr1[1] == addr2[1]) &&
+ (addr1[2] == addr2[2]) &&
+ (addr1[3] == addr2[3]) &&
+ (addr1[4] == addr2[4]) && (addr1[5] == addr2[5]);
+#endif
+}
+
+/*
+ * converts uint16_t CW value to 4 bit value to be inserted in IE
+ */
+static inline uint8_t convert_cw(uint16_t cw)
+{
+ uint8_t val = 0;
+ while (cw > 0) {
+ val++;
+ cw >>= 1;
+ }
+ if (val > 15)
+ return 0xF;
+ return val;
+}
+
+/* The user priority to AC mapping is such:
+ * UP(1, 2) ---> AC_BK(1)
+ * UP(0, 3) ---> AC_BE(0)
+ * UP(4, 5) ---> AC_VI(2)
+ * UP(6, 7) ---> AC_VO(3)
+ */
+#define WLAN_UP_TO_AC_MAP 0x33220110
+#define upToAc(up) ((WLAN_UP_TO_AC_MAP >> ((up) << 2)) & 0x03)
+
+/* ------------------------------------------------------------------- */
+
+/* / Parse the next IE in a message */
+extern tSirRetStatus sirParseNextIE(tpAniSirGlobal, uint8_t *pPayload,
+ uint16_t payloadLength, int16_t lastType,
+ uint8_t *pType, uint8_t *pLength);
+
+/* / Check if the given channel is 11b channel */
+#define SIR_IS_CHANNEL_11B(chId) (chId <= 14)
+
+/**
+ * hal_round_s32
+ *
+ * FUNCTION:
+ * Performs integer rounding like returns 12346 for 123456 or -12346 for -123456
+ * Note that a decimal place is lost.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param int32_t input
+ * @return rounded number
+ */
+static inline int32_t hal_round_s32(int32_t p)
+{
+ int32_t k, i, j;
+
+ i = p / 10;
+ j = p % 10;
+ if (p > 0)
+ k = i + (j > 4 ? 1 : 0);
+ else if (p < 0)
+ k = i + (j < -5 ? -1 : 0);
+ else
+ k = p;
+
+ return k;
+}
+
+/* New functions for endianess conversion */
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+#define ani_cpu_to_be16(x) sir_swap_u16((x))
+#define ani_cpu_to_le16(x) (x)
+#define ani_cpu_to_be32(x) sir_swap_u32((x))
+#define ani_cpu_to_le32(x) (x)
+#else /* ANI_LITTLE_BYTE_ENDIAN */
+#define ani_cpu_to_be16(x) (x)
+#define ani_cpu_to_le16(x) sir_swap_u16((x))
+#define ani_cpu_to_be32(x) (x)
+#define ani_cpu_to_le32(x) sir_swap_u32((x))
+#endif /* ANI_LITTLE_BYTE_ENDIAN */
+
+#define ani_le16_to_cpu(x) ani_cpu_to_le16(x)
+#define ani_le32_to_cpu(x) ani_cpu_to_le32(x)
+#define ani_be16_to_cpu(x) ani_cpu_to_be16(x)
+#define ani_be32_to_cpu(x) ani_cpu_to_be32(x)
+
+void convertto_big_endian(void *ptr, uint16_t size);
+void create_scan_cts_frame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
+ tSirMacAddr selfMac);
+void create_scan_data_null_frame(tpAniSirGlobal pMac,
+ tSirMacMgmtHdr *macMgmtHdr, uint8_t pwrMgmt, tSirMacAddr bssid,
+ tSirMacAddr selfMacAddr);
+void create_init_scan_raw_frame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
+ tBssSystemRole role);
+void create_finish_scan_raw_frame(tpAniSirGlobal pMac,
+ tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role);
+
+#endif /* __UTILSAPI_H */
diff --git a/core/mac/src/include/utils_global.h b/core/mac/src/include/utils_global.h
new file mode 100644
index 0000000..db2f854
--- /dev/null
+++ b/core/mac/src/include/utils_global.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __UTILS_GLOBAL_H__
+#define __UTILS_GLOBAL_H__
+
+#include "sir_params.h"
+
+/*
+ * Current debug and event log level
+ */
+#define LOG_FIRST_MODULE_ID SIR_FIRST_MODULE_ID
+#define LOG_LAST_MODULE_ID SIR_LAST_MODULE_ID
+#define LOG_ENTRY_NUM (LOG_LAST_MODULE_ID - LOG_FIRST_MODULE_ID + 1)
+
+typedef struct sAniSirUtils {
+ uint32_t gLogEvtLevel[LOG_ENTRY_NUM];
+ uint32_t gLogDbgLevel[LOG_ENTRY_NUM];
+
+} tAniSirUtils, *tpAniSirUtils;
+
+#endif
diff --git a/core/mac/src/pe/include/lim_admit_control.h b/core/mac/src/pe/include/lim_admit_control.h
new file mode 100644
index 0000000..90eae86
--- /dev/null
+++ b/core/mac/src/pe/include/lim_admit_control.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Author: Dinesh Upadhyay
+ * Date: 10/24/06
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_ADMIT_CONTROL_H__
+#define __LIM_ADMIT_CONTROL_H__
+
+#include "sir_common.h"
+#include "sir_mac_prot_def.h"
+
+#include "ani_global.h"
+
+tSirRetStatus
+lim_tspec_find_by_assoc_id(tpAniSirGlobal, uint16_t, tSirMacTspecIE *,
+ tpLimTspecInfo, tpLimTspecInfo *);
+
+/* Add TSPEC in lim local table */
+tSirRetStatus lim_tspec_add(tpAniSirGlobal pMac,
+ uint8_t *pAddr,
+ uint16_t assocId,
+ tSirMacTspecIE *pTspec,
+ uint32_t interval, tpLimTspecInfo *ppInfo);
+
+/* admit control interface */
+extern tSirRetStatus lim_admit_control_add_ts(tpAniSirGlobal pMac,
+ uint8_t *pAddr, tSirAddtsReqInfo *addts,
+ tSirMacQosCapabilityStaIE *qos,
+ uint16_t assocId, uint8_t alloc,
+ tSirMacScheduleIE *pSch,
+ /* index to the lim tspec table. */
+ uint8_t *pTspecIdx,
+ tpPESession psessionEntry);
+
+static inline tSirRetStatus
+lim_admit_control_add_sta(tpAniSirGlobal pMac, uint8_t *staAddr, uint8_t alloc)
+{
+ return eSIR_SUCCESS;
+}
+
+extern tSirRetStatus
+lim_admit_control_delete_sta(tpAniSirGlobal pMac, uint16_t assocId);
+
+extern tSirRetStatus
+lim_admit_control_delete_ts(tpAniSirGlobal pMac,
+ uint16_t assocId,
+ tSirMacTSInfo *tsinfo,
+ uint8_t *tsStatus, uint8_t *tspecIdx);
+
+extern tSirRetStatus lim_update_admit_policy(tpAniSirGlobal pMac);
+
+tSirRetStatus lim_admit_control_init(tpAniSirGlobal pMac);
+#ifdef FEATURE_WLAN_ESE
+tSirRetStatus lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+ uint16_t staIdx,
+ uint8_t tspecIdx,
+ tSirMacTspecIE tspecIE,
+ uint8_t sessionId, uint16_t tsm_interval);
+#else
+tSirRetStatus lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+ uint16_t staIdx,
+ uint8_t tspecIdx,
+ tSirMacTspecIE tspecIE,
+ uint8_t sessionId);
+#endif
+
+tSirRetStatus lim_send_hal_msg_del_ts(tpAniSirGlobal pMac,
+ uint16_t staIdx,
+ uint8_t tspecIdx,
+ tSirDeltsReqInfo delts,
+ uint8_t sessionId, uint8_t *bssId);
+void lim_process_hal_add_ts_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+
+#endif
diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h
new file mode 100644
index 0000000..99e2fc7
--- /dev/null
+++ b/core/mac/src/pe/include/lim_api.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_api.h contains the definitions exported by
+ * LIM module.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_API_H
+#define __LIM_API_H
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "sch_global.h"
+#include "utils_api.h"
+#include "lim_global.h"
+#include "wma_if.h"
+#include "wma_types.h"
+
+/* Macro to count heartbeat */
+#define limResetHBPktCount(psessionEntry) (psessionEntry->LimRxedBeaconCntDuringHB = 0)
+
+/* Useful macros for fetching various states in pMac->lim */
+/* gLimSystemRole */
+#define GET_LIM_SYSTEM_ROLE(psessionEntry) (psessionEntry->limSystemRole)
+#define LIM_IS_AP_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_AP_ROLE)
+#define LIM_IS_STA_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_ROLE)
+#define LIM_IS_IBSS_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)
+#define LIM_IS_UNKNOWN_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_UNKNOWN_ROLE)
+#define LIM_IS_BT_AMP_AP_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_BT_AMP_AP_ROLE)
+#define LIM_IS_BT_AMP_STA_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_BT_AMP_STA_ROLE)
+#define LIM_IS_P2P_DEVICE_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_P2P_DEVICE_ROLE)
+#define LIM_IS_P2P_DEVICE_GO(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_P2P_DEVICE_GO)
+/* gLimSmeState */
+#define GET_LIM_SME_STATE(pMac) (pMac->lim.gLimSmeState)
+#define SET_LIM_SME_STATE(pMac, state) (pMac->lim.gLimSmeState = state)
+/* gLimMlmState */
+#define GET_LIM_MLM_STATE(pMac) (pMac->lim.gLimMlmState)
+#define SET_LIM_MLM_STATE(pMac, state) (pMac->lim.gLimMlmState = state)
+/*tpdphHashNode mlmStaContext*/
+#define GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs) (pStaDs->mlmStaContext.mlmState)
+#define SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, state) (pStaDs->mlmStaContext.mlmState = state)
+/* gLimQuietState */
+#define GET_LIM_QUIET_STATE(pMac) (pMac->lim.gLimSpecMgmt.quietState)
+#define SET_LIM_QUIET_STATE(pMac, state) (pMac->lim.gLimSpecMgmt.quietState = state)
+#define LIM_IS_CONNECTION_ACTIVE(psessionEntry) (psessionEntry->LimRxedBeaconCntDuringHB)
+/*pMac->lim.gLimProcessDefdMsgs*/
+#define GET_LIM_PROCESS_DEFD_MESGS(pMac) (pMac->lim.gLimProcessDefdMsgs)
+#define SET_LIM_PROCESS_DEFD_MESGS(pMac, val) (pMac->lim.gLimProcessDefdMsgs = val)
+/* LIM exported function templates */
+#define LIM_IS_RADAR_DETECTED(pMac) (pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan)
+#define LIM_SET_RADAR_DETECTED(pMac, val) (pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan = val)
+#define LIM_MIN_BCN_PR_LENGTH 12
+#define LIM_BCN_PR_CAPABILITY_OFFSET 10
+typedef enum eMgmtFrmDropReason {
+ eMGMT_DROP_NO_DROP,
+ eMGMT_DROP_NOT_LAST_IBSS_BCN,
+ eMGMT_DROP_INFRA_BCN_IN_IBSS,
+ eMGMT_DROP_SCAN_MODE_FRAME,
+ eMGMT_DROP_NON_SCAN_MODE_FRAME,
+ eMGMT_DROP_INVALID_SIZE,
+ eMGMT_DROP_SPURIOUS_FRAME,
+} tMgmtFrmDropReason;
+
+/**
+ * Function to initialize LIM state machines.
+ * This called upon LIM thread creation.
+ */
+extern tSirRetStatus lim_initialize(tpAniSirGlobal);
+tSirRetStatus pe_open(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam);
+tSirRetStatus pe_close(tpAniSirGlobal pMac);
+void pe_register_tl_handle(tpAniSirGlobal pMac);
+tSirRetStatus lim_start(tpAniSirGlobal pMac);
+tSirRetStatus pe_start(tpAniSirGlobal pMac);
+void pe_stop(tpAniSirGlobal pMac);
+tSirRetStatus pe_post_msg_api(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
+tSirRetStatus peProcessMsg(tpAniSirGlobal pMac, tSirMsgQ *limMsg);
+/**
+ * Function to cleanup LIM state.
+ * This called upon reset/persona change etc
+ */
+extern void lim_cleanup(tpAniSirGlobal);
+/* / Function to post messages to LIM thread */
+extern uint32_t lim_post_msg_api(tpAniSirGlobal, tSirMsgQ *);
+/**
+ * Function to process messages posted to LIM thread
+ * and dispatch to various sub modules within LIM module.
+ */
+extern void lim_message_processor(tpAniSirGlobal, tpSirMsgQ);
+extern void lim_process_messages(tpAniSirGlobal, tpSirMsgQ); /* DT test alt deferred 2 */
+/**
+ * Function to check the LIM state if system is in Scan/Learn state.
+ */
+extern uint8_t lim_is_system_in_scan_state(tpAniSirGlobal);
+/**
+ * Function to handle IBSS coalescing.
+ * Beacon Processing module to call this.
+ */
+extern tSirRetStatus lim_handle_ibss_coalescing(tpAniSirGlobal,
+ tpSchBeaconStruct,
+ uint8_t *, tpPESession);
+/* / Function used by other Sirius modules to read global SME state */
+static inline tLimSmeStates lim_get_sme_state(tpAniSirGlobal pMac)
+{
+ return pMac->lim.gLimSmeState;
+}
+
+extern void lim_received_hb_handler(tpAniSirGlobal, uint8_t, tpPESession);
+extern void limCheckAndQuietBSS(tpAniSirGlobal);
+/* / Function that triggers STA context deletion */
+extern void lim_trigger_sta_deletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry);
+
+#ifdef FEATURE_WLAN_TDLS
+/* Function that sends TDLS Del Sta indication to SME */
+extern void lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry,
+ uint16_t reasonCode);
+#endif
+
+/* / Function that checks for change in AP's capabilties on STA */
+extern void lim_detect_change_in_ap_capabilities(tpAniSirGlobal,
+ tpSirProbeRespBeacon, tpPESession);
+tSirRetStatus lim_update_short_slot(tpAniSirGlobal pMac,
+ tpSirProbeRespBeacon pBeacon,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession);
+
+void lim_ps_offload_handle_missed_beacon_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+void lim_send_heart_beat_timeout_ind(tpAniSirGlobal pMac, tpPESession psessionEntry);
+tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ uint32_t subType);
+bool lim_is_deauth_diassoc_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info);
+#ifdef WLAN_FEATURE_11W
+bool lim_is_assoc_req_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info);
+#endif
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+void lim_roam_offload_synch_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+#endif
+#define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled)
+#define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled)
+#define limGetWsmMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWsmEnabled)
+#define limGet11dMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->lim11dEnabled)
+#define limGetAckPolicy(pMac, pVal) (*(pVal) = pMac->lim.ackPolicy)
+/* ----------------------------------------------------------------------- */
+static inline void lim_get_phy_mode(tpAniSirGlobal pMac, uint32_t *phyMode,
+ tpPESession psessionEntry)
+{
+ *phyMode =
+ psessionEntry ? psessionEntry->gLimPhyMode : pMac->lim.gLimPhyMode;
+}
+
+/* ----------------------------------------------------------------------- */
+static inline void lim_get_rf_band_new(tpAniSirGlobal pMac, tSirRFBand *band,
+ tpPESession psessionEntry)
+{
+ *band = psessionEntry ? psessionEntry->limRFBand : SIR_BAND_UNKNOWN;
+}
+
+/*--------------------------------------------------------------------------
+
+ \brief pe_process_messages() - Message Processor for PE
+
+ Voss calls this function to dispatch the message to PE
+
+ \param pMac - Pointer to Global MAC structure
+ \param pMsg - Pointer to the message structure
+
+ \return uint32_t - TX_SUCCESS for success.
+
+ --------------------------------------------------------------------------*/
+tSirRetStatus pe_process_messages(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
+/** -------------------------------------------------------------
+ \fn pe_free_msg
+ \brief Called by CDS scheduler (function cds_sched_flush_mc_mqs)
+ \ to free a given PE message on the TX and MC thread.
+ \ This happens when there are messages pending in the PE
+ \ queue when system is being stopped and reset.
+ \param tpAniSirGlobal pMac
+ \param tSirMsgQ pMsg
+ \return none
+ -----------------------------------------------------------------*/
+void pe_free_msg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
+
+/*--------------------------------------------------------------------------
+
+ \brief lim_remain_on_chn_rsp() - API for sending remain on channel response.
+
+ LIM calls this api to send the remain on channel response to SME.
+
+ \param pMac - Pointer to Global MAC structure
+ \param status - status of the response
+ \param data - pointer to msg
+
+ \return void
+
+ --------------------------------------------------------------------------*/
+void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, CDF_STATUS status, uint32_t *data);
+
+/*--------------------------------------------------------------------------
+
+ \brief lim_process_abort_scan_ind() - function for sending abort scan indication.
+
+ LIM calls this function for sending abort scan indication.
+
+ \param pMac - Pointer to Global MAC structure
+
+ \return void
+
+ --------------------------------------------------------------------------*/
+void lim_process_abort_scan_ind(tpAniSirGlobal pMac, uint8_t sessionId,
+ uint32_t scan_id);
+
+void __lim_process_sme_assoc_cnf_new(tpAniSirGlobal, uint32_t, uint32_t *);
+
+/************************************************************/
+#endif /* __LIM_API_H */
diff --git a/core/mac/src/pe/include/lim_ft.h b/core/mac/src/pe/include/lim_ft.h
new file mode 100644
index 0000000..a0be848
--- /dev/null
+++ b/core/mac/src/pe/include/lim_ft.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+/**=========================================================================
+
+ Macros and Function prototypes FT and 802.11R purposes
+
+ ========================================================================*/
+
+#ifndef __LIMFT_H__
+#define __LIMFT_H__
+
+#include <cds_api.h>
+#include <lim_global.h>
+#include <ani_global.h>
+#include <lim_debug.h>
+#include <lim_ser_des_utils.h>
+
+/*-------------------------------------------------------------------------
+ Function declarations and documenation
+ ------------------------------------------------------------------------*/
+void lim_ft_open(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_ft_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac, tpPESession psessionEntry);
+int lim_process_ft_pre_auth_req(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry);
+void limPerformPostFTPreAuth(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry);
+void limFTResumeLinkCb(tpAniSirGlobal pMac, CDF_STATUS status, uint32_t *data);
+void lim_post_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status,
+ uint8_t *auth_rsp, uint16_t auth_rsp_length,
+ tpPESession psessionEntry);
+void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status,
+ uint8_t *auth_rsp, uint16_t auth_rsp_len,
+ tpPESession psessionEntry);
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
+ tpPESession psessionEntry);
+void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal pMac);
+
+bool lim_process_ft_update_key(tpAniSirGlobal pMac, uint32_t *pMsgBuf);
+tSirRetStatus lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf);
+void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+void lim_ft_cleanup_all_ft_sessions(tpAniSirGlobal pMac);
+void lim_fill_ft_session(tpAniSirGlobal pMac,
+ tpSirBssDescription pbssDescription,
+ tpPESession pftSessionEntry,
+ tpPESession psessionEntry);
+tSirRetStatus lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac,
+ uint8_t updateEntry,
+ tpPESession pftSessionEntry,
+ tpSirBssDescription bssDescription);
+#endif /* __LIMFT_H__ */
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
diff --git a/core/mac/src/pe/include/lim_ft_defs.h b/core/mac/src/pe/include/lim_ft_defs.h
new file mode 100644
index 0000000..da4f11f
--- /dev/null
+++ b/core/mac/src/pe/include/lim_ft_defs.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+/**=========================================================================
+
+ Macros and Function prototypes FT and 802.11R purposes
+
+ ========================================================================*/
+
+#ifndef __LIMFTDEFS_H__
+#define __LIMFTDEFS_H__
+
+#include <cds_api.h>
+#include "wma_if.h"
+
+/*--------------------------------------------------------------------------
+ Preprocessor definitions and constants
+ ------------------------------------------------------------------------*/
+#define SIR_MDIE_SIZE 3 /* MD ID(2 bytes), Capability(1 byte) */
+#define MAX_FTIE_SIZE 384 /* Max size limited to 384, on acct. of IW custom events */
+
+/*--------------------------------------------------------------------------
+ Type declarations
+ ------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------
+ FT Pre Auth Req SME<->PE
+ ------------------------------------------------------------------------*/
+typedef struct sSirFTPreAuthReq {
+ uint16_t messageType; /* eWNI_SME_FT_PRE_AUTH_REQ */
+ uint16_t length;
+ /*
+ * Track if response is processed for this request
+ * We expect only one response per request.
+ */
+ bool bPreAuthRspProcessed;
+ uint8_t preAuthchannelNum;
+ /* BSSID currently associated to suspend the link */
+ tSirMacAddr currbssId;
+ tSirMacAddr preAuthbssId; /* BSSID to preauth to */
+ uint16_t ft_ies_length;
+ uint8_t ft_ies[MAX_FTIE_SIZE];
+ tpSirBssDescription pbssDescription;
+} tSirFTPreAuthReq, *tpSirFTPreAuthReq;
+
+/*-------------------------------------------------------------------------
+ FT Pre Auth Rsp PE<->SME
+ ------------------------------------------------------------------------*/
+typedef struct sSirFTPreAuthRsp {
+ uint16_t messageType; /* eWNI_SME_FT_PRE_AUTH_RSP */
+ uint16_t length;
+ uint8_t smeSessionId;
+ tSirMacAddr preAuthbssId; /* BSSID to preauth to */
+ tSirRetStatus status;
+ uint16_t ft_ies_length;
+ uint8_t ft_ies[MAX_FTIE_SIZE];
+ uint16_t ric_ies_length;
+ uint8_t ric_ies[MAX_FTIE_SIZE];
+} tSirFTPreAuthRsp, *tpSirFTPreAuthRsp;
+
+/*--------------------------------------------------------------------------
+ FT Pre Auth Rsp Key SME<->PE
+ ------------------------------------------------------------------------*/
+typedef struct sSirFTUpdateKeyInfo {
+ uint16_t messageType;
+ uint16_t length;
+ uint32_t smeSessionId;
+ tSirMacAddr bssId;
+ tSirKeyMaterial keyMaterial;
+} tSirFTUpdateKeyInfo, *tpSirFTUpdateKeyInfo;
+
+/*--------------------------------------------------------------------------
+ FT Pre Auth Rsp Key SME<->PE
+ ------------------------------------------------------------------------*/
+typedef struct sSirFTPreAuthKeyInfo {
+ uint8_t extSetStaKeyParamValid; /* Ext Bss Config Msg if set */
+ /* SetStaKeyParams for ext bss msg */
+ tLimMlmSetKeysReq extSetStaKeyParam;
+} tSirFTPreAuthKeyInfo, *tpSirFTPreAuthKeyInfo;
+
+/*-------------------------------------------------------------------------
+ Global FT Information
+ ------------------------------------------------------------------------*/
+typedef struct sFTPEContext {
+ tpSirFTPreAuthReq pFTPreAuthReq; /* Saved FT Pre Auth Req */
+ tSirRetStatus ftPreAuthStatus;
+ uint16_t saved_auth_rsp_length;
+ uint8_t saved_auth_rsp[MAX_FTIE_SIZE];
+ tSirFTPreAuthKeyInfo PreAuthKeyInfo;
+ /* Items created for the new FT, session */
+ void *pAddBssReq; /* Save add bss req */
+ void *pAddStaReq; /*Save add sta req */
+ uint32_t peSessionId;
+ uint32_t smeSessionId;
+
+ /* This flag is required to indicate on which session the preauth
+ * has taken place, since the auth reponse for preauth will come
+ * for a new BSSID for which there is no session yet. This flag
+ * will be used to extract the session from the session preauth
+ * has been initiated
+ */
+ bool ftPreAuthSession;
+} tftPEContext, *tpftPEContext;
+
+#endif /* __LIMFTDEFS_H__ */
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h
new file mode 100644
index 0000000..5ddb01c
--- /dev/null
+++ b/core/mac/src/pe/include/lim_global.h
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_global.h contains the definitions exported by
+ * LIM module.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_GLOBAL_H
+#define __LIM_GLOBAL_H
+
+#include "wni_api.h"
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+#include "sir_mac_prop_exts.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "wni_cfg.h"
+#include "csr_api.h"
+#include "sap_api.h"
+#include "dot11f.h"
+#include "wma_if.h"
+
+/* / Maximum number of scan hash table entries */
+#define LIM_MAX_NUM_OF_SCAN_RESULTS 256
+
+/* Sending Disassociate frames threshold */
+#define LIM_SEND_DISASSOC_FRAME_THRESHOLD 2
+#define LIM_HASH_MISS_TIMER_MS 10000
+
+/* Deferred Message Queue Length */
+#define MAX_DEFERRED_QUEUE_LEN 80
+
+/* Maximum number of PS - TIM's to be sent with out wakeup from STA */
+#define LIM_TIM_WAIT_COUNT_FACTOR 5
+
+/*
+ * Use this count if (LIM_TIM_WAIT_FACTOR * ListenInterval)
+ * is less than LIM_MIN_TIM_WAIT_CNT
+ */
+#define LIM_MIN_TIM_WAIT_COUNT 50
+
+#define GET_TIM_WAIT_COUNT(LIntrvl) \
+ ((LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) > LIM_MIN_TIM_WAIT_COUNT ? \
+ (LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) : LIM_MIN_TIM_WAIT_COUNT)
+
+#define IS_5G_BAND(__rfBand) ((__rfBand & 0x3) == 0x2)
+#define IS_24G_BAND(__rfBand) ((__rfBand & 0x3) == 0x1)
+
+#define LIM_MAX_CSA_IE_UPDATES (5)
+
+/* enums exported by LIM are as follows */
+
+/*System role definition */
+typedef enum eLimSystemRole {
+ eLIM_UNKNOWN_ROLE,
+ eLIM_AP_ROLE,
+ eLIM_STA_IN_IBSS_ROLE,
+ eLIM_STA_ROLE,
+ eLIM_BT_AMP_STA_ROLE,
+ eLIM_BT_AMP_AP_ROLE,
+ eLIM_P2P_DEVICE_ROLE,
+ eLIM_P2P_DEVICE_GO,
+ eLIM_P2P_DEVICE_CLIENT
+} tLimSystemRole;
+
+/*
+ * SME state definition accessible across all Sirius modules.
+ * AP only states are LIM_SME_CHANNEL_SCAN_STATE &
+ * LIM_SME_NORMAL_CHANNEL_SCAN_STATE.
+ * Note that these states may also be present in STA
+ * side too when DFS support is present for a STA in IBSS mode.
+ */
+typedef enum eLimSmeStates {
+ eLIM_SME_OFFLINE_STATE,
+ eLIM_SME_IDLE_STATE,
+ eLIM_SME_SUSPEND_STATE,
+ eLIM_SME_WT_SCAN_STATE,
+ eLIM_SME_WT_JOIN_STATE,
+ eLIM_SME_WT_AUTH_STATE,
+ eLIM_SME_WT_ASSOC_STATE,
+ eLIM_SME_WT_REASSOC_STATE,
+ eLIM_SME_WT_REASSOC_LINK_FAIL_STATE,
+ eLIM_SME_JOIN_FAILURE_STATE,
+ eLIM_SME_ASSOCIATED_STATE,
+ eLIM_SME_REASSOCIATED_STATE,
+ eLIM_SME_LINK_EST_STATE,
+ eLIM_SME_LINK_EST_WT_SCAN_STATE,
+ eLIM_SME_WT_PRE_AUTH_STATE,
+ eLIM_SME_WT_DISASSOC_STATE,
+ eLIM_SME_WT_DEAUTH_STATE,
+ eLIM_SME_WT_START_BSS_STATE,
+ eLIM_SME_WT_STOP_BSS_STATE,
+ eLIM_SME_NORMAL_STATE,
+ eLIM_SME_CHANNEL_SCAN_STATE,
+ eLIM_SME_NORMAL_CHANNEL_SCAN_STATE
+} tLimSmeStates;
+
+/*
+ * MLM state definition.
+ * While these states are present on AP too when it is
+ * STA mode, per-STA MLM state exclusive to AP is:
+ * eLIM_MLM_WT_AUTH_FRAME3.
+ */
+typedef enum eLimMlmStates {
+ eLIM_MLM_OFFLINE_STATE,
+ eLIM_MLM_IDLE_STATE,
+ eLIM_MLM_WT_PROBE_RESP_STATE,
+ eLIM_MLM_PASSIVE_SCAN_STATE,
+ eLIM_MLM_WT_JOIN_BEACON_STATE,
+ eLIM_MLM_JOINED_STATE,
+ eLIM_MLM_BSS_STARTED_STATE,
+ eLIM_MLM_WT_AUTH_FRAME2_STATE,
+ eLIM_MLM_WT_AUTH_FRAME3_STATE,
+ eLIM_MLM_WT_AUTH_FRAME4_STATE,
+ eLIM_MLM_AUTH_RSP_TIMEOUT_STATE,
+ eLIM_MLM_AUTHENTICATED_STATE,
+ eLIM_MLM_WT_ASSOC_RSP_STATE,
+ eLIM_MLM_WT_REASSOC_RSP_STATE,
+ eLIM_MLM_ASSOCIATED_STATE,
+ eLIM_MLM_REASSOCIATED_STATE,
+ eLIM_MLM_LINK_ESTABLISHED_STATE,
+ eLIM_MLM_WT_ASSOC_CNF_STATE,
+ eLIM_MLM_LEARN_STATE,
+ eLIM_MLM_WT_ADD_BSS_RSP_STATE,
+ eLIM_MLM_WT_DEL_BSS_RSP_STATE,
+ eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE,
+ eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE,
+ eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE,
+ eLIM_MLM_WT_ADD_STA_RSP_STATE,
+ eLIM_MLM_WT_DEL_STA_RSP_STATE,
+ /*
+ * MLM goes to this state when LIM initiates DELETE_STA
+ * as processing of Assoc req because the entry already exists.
+ * LIM comes out of this state when DELETE_STA response from
+ * HAL is received. LIM needs to maintain this state so that ADD_STA
+ * can be issued while processing DELETE_STA response from HAL.
+ */
+ eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE,
+ eLIM_MLM_WT_SET_BSS_KEY_STATE,
+ eLIM_MLM_WT_SET_STA_KEY_STATE,
+ eLIM_MLM_WT_SET_STA_BCASTKEY_STATE,
+ eLIM_MLM_WT_SET_MIMOPS_STATE,
+#if defined WLAN_FEATURE_VOWIFI_11R
+ eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE,
+ eLIM_MLM_WT_FT_REASSOC_RSP_STATE,
+#endif
+ eLIM_MLM_P2P_LISTEN_STATE,
+} tLimMlmStates;
+
+/* 11h channel quiet states */
+
+/*
+ * This enum indicates in which state the device is in
+ * when it receives quiet element in beacon or probe-response.
+ * The default quiet state of the device is always INIT
+ * eLIM_QUIET_BEGIN - When Quiet period is started
+ * eLIM_QUIET_CHANGED - When Quiet period is updated
+ * eLIM_QUIET_RUNNING - Between two successive Quiet updates
+ * eLIM_QUIET_END - When quiet period ends
+ */
+typedef enum eLimQuietStates {
+ eLIM_QUIET_INIT,
+ eLIM_QUIET_BEGIN,
+ eLIM_QUIET_CHANGED,
+ eLIM_QUIET_RUNNING,
+ eLIM_QUIET_END
+} tLimQuietStates;
+
+/* 11h channel switch states */
+
+/*
+ * This enum indicates in which state the channel-swith
+ * is presently operating.
+ * eLIM_11H_CHANSW_INIT - Default state
+ * eLIM_11H_CHANSW_RUNNING - When channel switch is running
+ * eLIM_11H_CHANSW_END - After channel switch is complete
+ */
+typedef enum eLimDot11hChanSwStates {
+ eLIM_11H_CHANSW_INIT,
+ eLIM_11H_CHANSW_RUNNING,
+ eLIM_11H_CHANSW_END
+} tLimDot11hChanSwStates;
+
+
+/* WLAN_SUSPEND_LINK Related */
+typedef void (*SUSPEND_RESUME_LINK_CALLBACK)(tpAniSirGlobal pMac,
+ CDF_STATUS status,
+ uint32_t *data);
+
+/* LIM to HAL SCAN Management Message Interface states */
+typedef enum eLimHalScanState {
+ eLIM_HAL_IDLE_SCAN_STATE,
+ eLIM_HAL_INIT_SCAN_WAIT_STATE,
+ eLIM_HAL_START_SCAN_WAIT_STATE,
+ eLIM_HAL_END_SCAN_WAIT_STATE,
+ eLIM_HAL_FINISH_SCAN_WAIT_STATE,
+ eLIM_HAL_INIT_LEARN_WAIT_STATE,
+ eLIM_HAL_START_LEARN_WAIT_STATE,
+ eLIM_HAL_END_LEARN_WAIT_STATE,
+ eLIM_HAL_FINISH_LEARN_WAIT_STATE,
+ eLIM_HAL_SCANNING_STATE,
+/* WLAN_SUSPEND_LINK Related */
+ eLIM_HAL_SUSPEND_LINK_WAIT_STATE,
+ eLIM_HAL_SUSPEND_LINK_STATE,
+ eLIM_HAL_RESUME_LINK_WAIT_STATE,
+/* end WLAN_SUSPEND_LINK Related */
+} tLimLimHalScanState;
+
+/* MLM Req/Cnf structure definitions */
+typedef struct sLimMlmAuthReq {
+ tSirMacAddr peerMacAddr;
+ tAniAuthType authType;
+ uint32_t authFailureTimeout;
+ uint8_t sessionId;
+} tLimMlmAuthReq, *tpLimMlmAuthReq;
+
+typedef struct sLimMlmJoinReq {
+ uint32_t joinFailureTimeout;
+ tSirMacRateSet operationalRateSet;
+ uint8_t sessionId;
+ tSirBssDescription bssDescription;
+} tLimMlmJoinReq, *tpLimMlmJoinReq;
+
+typedef struct sLimMlmScanReq {
+ tSirBssType bssType;
+ tSirMacAddr bssId;
+ tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID];
+ tSirScanType scanType;
+ uint32_t minChannelTime;
+ uint32_t maxChannelTime;
+ uint32_t dot11mode;
+ /* Number of SSIDs to scan(send Probe request) */
+ uint8_t numSsid;
+
+ bool p2pSearch;
+ uint16_t uIEFieldLen;
+ uint16_t uIEFieldOffset;
+
+ uint8_t sessionId;
+ /* channelList MUST be the last field of this structure */
+ tSirChannelList channelList;
+ /*-----------------------------
+ tLimMlmScanReq....
+ -----------------------------
+ uIEFiledLen
+ -----------------------------
+ uIEFiledOffset ----+
+ ----------------------------- |
+ channelList.numChannels |
+ ----------------------------- |
+ ... variable size up to |
+ channelNumber[numChannels-1] |
+ This can be zero, if |
+ numChannel is zero. |
+ ----------------------------- <--+
+ ... variable size uIEFiled
+ up to uIEFieldLen (can be 0)
+ -----------------------------*/
+} tLimMlmScanReq, *tpLimMlmScanReq;
+
+typedef struct tLimScanResultNode tLimScanResultNode;
+struct tLimScanResultNode {
+ tLimScanResultNode *next;
+ tSirBssDescription bssDescription;
+};
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+#ifndef OEM_DATA_REQ_SIZE
+#define OEM_DATA_REQ_SIZE 280
+#endif
+#ifndef OEM_DATA_RSP_SIZE
+#define OEM_DATA_RSP_SIZE 1724
+#endif
+
+/* OEM Data related structure definitions */
+typedef struct sLimMlmOemDataReq {
+ tSirMacAddr selfMacAddr;
+ uint8_t oemDataReq[OEM_DATA_REQ_SIZE];
+} tLimMlmOemDataReq, *tpLimMlmOemDataReq;
+
+typedef struct sLimMlmOemDataRsp {
+ uint8_t oemDataRsp[OEM_DATA_RSP_SIZE];
+} tLimMlmOemDataRsp, *tpLimMlmOemDataRsp;
+#endif
+
+/* Pre-authentication structure definition */
+typedef struct tLimPreAuthNode {
+ struct tLimPreAuthNode *next;
+ tSirMacAddr peerMacAddr;
+ tAniAuthType authType;
+ tLimMlmStates mlmState;
+ uint8_t authNodeIdx;
+ uint8_t challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH];
+ uint8_t fTimerStarted:1;
+ uint8_t fSeen:1;
+ uint8_t fFree:1;
+ uint8_t rsvd:5;
+ TX_TIMER timer;
+ uint16_t seq_num;
+ v_TIME_t timestamp;
+} tLimPreAuthNode, *tpLimPreAuthNode;
+
+/* Pre-authentication table definition */
+typedef struct tLimPreAuthTable {
+ uint32_t numEntry;
+ tpLimPreAuthNode pTable;
+} tLimPreAuthTable, *tpLimPreAuthTable;
+
+/* / Per STA context structure definition */
+typedef struct sLimMlmStaContext {
+ tLimMlmStates mlmState;
+ tAniAuthType authType;
+ uint16_t listenInterval;
+ tSirMacCapabilityInfo capabilityInfo;
+ tSirMacPropRateSet propRateSet;
+ tSirMacReasonCodes disassocReason;
+ uint16_t cleanupTrigger;
+
+ tSirResultCodes resultCode;
+ uint16_t protStatusCode;
+
+ uint8_t subType:1; /* Indicates ASSOC (0) or REASSOC (1) */
+ uint8_t updateContext:1;
+ uint8_t schClean:1;
+ /* 802.11n HT Capability in Station: Enabled 1 or DIsabled 0 */
+ uint8_t htCapability:1;
+#ifdef WLAN_FEATURE_11AC
+ uint8_t vhtCapability:1;
+#endif
+} tLimMlmStaContext, *tpLimMlmStaContext;
+
+/* Structure definition to hold deferred messages queue parameters */
+typedef struct sLimDeferredMsgQParams {
+ tSirMsgQ deferredQueue[MAX_DEFERRED_QUEUE_LEN];
+ uint16_t size;
+ uint16_t read;
+ uint16_t write;
+} tLimDeferredMsgQParams, *tpLimDeferredMsgQParams;
+
+typedef struct sCfgProtection {
+ uint32_t overlapFromlla:1;
+ uint32_t overlapFromllb:1;
+ uint32_t overlapFromllg:1;
+ uint32_t overlapHt20:1;
+ uint32_t overlapNonGf:1;
+ uint32_t overlapLsigTxop:1;
+ uint32_t overlapRifs:1;
+ uint32_t overlapOBSS:1; /* added for obss */
+ uint32_t fromlla:1;
+ uint32_t fromllb:1;
+ uint32_t fromllg:1;
+ uint32_t ht20:1;
+ uint32_t nonGf:1;
+ uint32_t lsigTxop:1;
+ uint32_t rifs:1;
+ uint32_t obss:1; /* added for Obss */
+} tCfgProtection, *tpCfgProtection;
+
+typedef enum eLimProtStaCacheType {
+ eLIM_PROT_STA_CACHE_TYPE_INVALID,
+ eLIM_PROT_STA_CACHE_TYPE_llB,
+ eLIM_PROT_STA_CACHE_TYPE_llG,
+ eLIM_PROT_STA_CACHE_TYPE_HT20
+} tLimProtStaCacheType;
+
+typedef struct sCacheParams {
+ uint8_t active;
+ tSirMacAddr addr;
+ tLimProtStaCacheType protStaCacheType;
+
+} tCacheParams, *tpCacheParams;
+
+#define LIM_PROT_STA_OVERLAP_CACHE_SIZE HAL_NUM_ASSOC_STA
+#define LIM_PROT_STA_CACHE_SIZE HAL_NUM_ASSOC_STA
+
+typedef struct sLimProtStaParams {
+ uint8_t numSta;
+ uint8_t protectionEnabled;
+} tLimProtStaParams, *tpLimProtStaParams;
+
+typedef struct sLimNoShortParams {
+ uint8_t numNonShortPreambleSta;
+ tCacheParams staNoShortCache[LIM_PROT_STA_CACHE_SIZE];
+} tLimNoShortParams, *tpLimNoShortParams;
+
+typedef struct sLimNoShortSlotParams {
+ uint8_t numNonShortSlotSta;
+ tCacheParams staNoShortSlotCache[LIM_PROT_STA_CACHE_SIZE];
+} tLimNoShortSlotParams, *tpLimNoShortSlotParams;
+
+typedef struct tLimIbssPeerNode tLimIbssPeerNode;
+struct tLimIbssPeerNode {
+ tLimIbssPeerNode *next;
+ tSirMacAddr peerMacAddr;
+ uint8_t extendedRatesPresent:1;
+ uint8_t edcaPresent:1;
+ uint8_t wmeEdcaPresent:1;
+ uint8_t wmeInfoPresent:1;
+ uint8_t htCapable:1;
+ uint8_t vhtCapable:1;
+ uint8_t rsvd:2;
+ uint8_t htSecondaryChannelOffset;
+ tSirMacCapabilityInfo capabilityInfo;
+ tSirMacRateSet supportedRates;
+ tSirMacRateSet extendedRates;
+ uint8_t supportedMCSSet[SIZE_OF_SUPPORTED_MCS_SET];
+ tSirMacEdcaParamSetIE edcaParams;
+ uint8_t erpIePresent;
+
+ /* HT Capabilities of IBSS Peer */
+ uint8_t htGreenfield;
+ uint8_t htShortGI40Mhz;
+ uint8_t htShortGI20Mhz;
+
+ /* DSSS/CCK at 40 MHz: Enabled 1 or Disabled */
+ uint8_t htDsssCckRate40MHzSupport;
+
+ /* MIMO Power Save */
+ tSirMacHTMIMOPowerSaveState htMIMOPSState;
+
+ /* */
+ /* A-MPDU Density */
+ /* 000 - No restriction */
+ /* 001 - 1/8 usec */
+ /* 010 - 1/4 usec */
+ /* 011 - 1/2 usec */
+ /* 100 - 1 usec */
+ /* 101 - 2 usec */
+ /* 110 - 4 usec */
+ /* 111 - 8 usec */
+ /* */
+ uint8_t htAMpduDensity;
+
+ /* Maximum Rx A-MPDU factor */
+ uint8_t htMaxRxAMpduFactor;
+
+ /* Set to 0 for 3839 octets */
+ /* Set to 1 for 7935 octets */
+ uint8_t htMaxAmsduLength;
+
+ /* */
+ /* Recommended Tx Width Set */
+ /* 0 - use 20 MHz channel (control channel) */
+ /* 1 - use 40 Mhz channel */
+ /* */
+ uint8_t htSupportedChannelWidthSet;
+
+ uint8_t htLdpcCapable;
+
+ uint8_t beaconHBCount;
+ uint8_t heartbeatFailure;
+
+ uint8_t *beacon; /* Hold beacon to be sent to HDD/CSR */
+ uint16_t beaconLen;
+
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEVHTCaps VHTCaps;
+ uint8_t vhtSupportedChannelWidthSet;
+ uint8_t vhtBeamFormerCapable;
+#endif
+ /*
+ * Peer Atim Info
+ */
+ uint8_t atimIePresent;
+ uint32_t peerAtimWindowLength;
+};
+
+/* Enums used for channel switching. */
+typedef enum eLimChannelSwitchState {
+ eLIM_CHANNEL_SWITCH_IDLE,
+ eLIM_CHANNEL_SWITCH_PRIMARY_ONLY,
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY
+} tLimChannelSwitchState;
+
+/* Channel Switch Info */
+typedef struct sLimChannelSwitchInfo {
+ tLimChannelSwitchState state;
+ uint8_t primaryChannel;
+ uint8_t ch_center_freq_seg0;
+ uint8_t ch_center_freq_seg1;
+ phy_ch_width ch_width;
+ int8_t switchCount;
+ uint32_t switchTimeoutValue;
+ uint8_t switchMode;
+} tLimChannelSwitchInfo, *tpLimChannelSwitchInfo;
+
+#ifdef WLAN_FEATURE_11AC
+typedef struct sLimOperatingModeInfo {
+ uint8_t present;
+ uint8_t chanWidth:2;
+ uint8_t reserved:2;
+ uint8_t rxNSS:3;
+ uint8_t rxNSSType:1;
+} tLimOperatingModeInfo, *tpLimOperatingModeInfo;
+#endif
+
+typedef struct sLimWiderBWChannelSwitch {
+ uint8_t newChanWidth;
+ uint8_t newCenterChanFreq0;
+ uint8_t newCenterChanFreq1;
+} tLimWiderBWChannelSwitchInfo, *tpLimWiderBWChannelSwitchInfo;
+
+/* Enums used when stopping the Tx. */
+typedef enum eLimQuietTxMode {
+ /* Stop/resume transmission of all stations,Uses the global flag */
+ eLIM_TX_ALL = 0,
+ /*
+ * Stops/resumes the transmission of specific stations identified
+ * by staId.
+ */
+ eLIM_TX_STA,
+ /* Stops/resumes the transmission of all the packets in BSS */
+ eLIM_TX_BSS,
+ /*
+ * Stops/resumes the transmission of all packets except beacons in BSS
+ * This is used when radar is detected in the current operating channel.
+ * Beacon has to be sent to notify the stations associated about the
+ * scheduled channel switch
+ */
+ eLIM_TX_BSS_BUT_BEACON
+} tLimQuietTxMode;
+
+typedef enum eLimControlTx {
+ eLIM_RESUME_TX = 0,
+ eLIM_STOP_TX
+} tLimControlTx;
+
+/* -------------------------------------------------------------------- */
+
+typedef struct sLimTspecInfo {
+ /* 0==free, else used */
+ uint8_t inuse;
+ /* index in list */
+ uint8_t idx;
+ tSirMacAddr staAddr;
+ uint16_t assocId;
+ tSirMacTspecIE tspec;
+ /* number of Tclas elements */
+ uint8_t numTclas;
+ tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM];
+ uint8_t tclasProc;
+ /* tclassProc is valid only if this is set to 1. */
+ uint8_t tclasProcPresent:1;
+} cdf_packed tLimTspecInfo, *tpLimTspecInfo;
+
+typedef struct sLimAdmitPolicyInfo {
+ /* admit control policy type */
+ uint8_t type;
+ /* oversubscription factor : 0 means nothing is allowed */
+ uint8_t bw_factor;
+ /* valid only when 'type' is set BW_FACTOR */
+} tLimAdmitPolicyInfo, *tpLimAdmitPolicyInfo;
+
+typedef enum eLimWscEnrollState {
+ eLIM_WSC_ENROLL_NOOP,
+ eLIM_WSC_ENROLL_BEGIN,
+ eLIM_WSC_ENROLL_IN_PROGRESS,
+ eLIM_WSC_ENROLL_END
+} tLimWscEnrollState;
+
+#define WSC_PASSWD_ID_PUSH_BUTTON (0x0004)
+
+typedef struct sLimWscIeInfo {
+ bool apSetupLocked;
+ bool selectedRegistrar;
+ uint16_t selectedRegistrarConfigMethods;
+ tLimWscEnrollState wscEnrollmentState;
+ tLimWscEnrollState probeRespWscEnrollmentState;
+ uint8_t reqType;
+ uint8_t respType;
+} tLimWscIeInfo, *tpLimWscIeInfo;
+
+/* maximum number of tspec's supported */
+#define LIM_NUM_TSPEC_MAX 15
+
+/* structure to hold all 11h specific data */
+typedef struct sLimSpecMgmtInfo {
+ tLimQuietStates quietState;
+ uint32_t quietCount;
+ /* This is in units of system TICKS */
+ uint32_t quietDuration;
+ /* This is in units of TU, for over the air transmission */
+ uint32_t quietDuration_TU;
+ /* After this timeout, actual quiet starts */
+ uint32_t quietTimeoutValue;
+ /* Used on AP, if quiet is enabled during learning */
+ bool fQuietEnabled;
+ tLimDot11hChanSwStates dot11hChanSwState;
+ /* Radar detected in cur oper chan on AP */
+ bool fRadarDetCurOperChan;
+ /* Whether radar interrupt has been configured */
+ bool fRadarIntrConfigured;
+} tLimSpecMgmtInfo, *tpLimSpecMgmtInfo;
+
+#ifdef FEATURE_WLAN_TDLS
+/*
+ * Peer info needed for TDLS setup..
+ */
+typedef struct tLimTDLSPeerSta {
+ struct tLimTDLSPeerSta *next;
+ uint8_t dialog;
+ tSirMacAddr peerMac;
+ tSirMacCapabilityInfo capabilityInfo;
+ tSirMacRateSet supportedRates;
+ tSirMacRateSet extendedRates;
+ tSirMacQosCapabilityStaIE qosCaps;
+ tSirMacEdcaParamSetIE edcaParams;
+ uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
+ uint8_t tdls_bIsResponder;
+ /* HT Capabilties */
+ tDot11fIEHTCaps tdlsPeerHTCaps;
+ tDot11fIEExtCap tdlsPeerExtCaps;
+ uint8_t tdls_flags;
+ uint8_t tdls_link_state;
+ uint8_t tdls_prev_link_state;
+ uint8_t tdls_sessionId;
+ uint8_t ExtRatesPresent;
+ TX_TIMER gLimTdlsLinkSetupRspTimeoutTimer;
+ TX_TIMER gLimTdlsLinkSetupCnfTimeoutTimer;
+} tLimTdlsLinkSetupPeer, *tpLimTdlsLinkSetupPeer;
+
+typedef struct tLimTdlsLinkSetupInfo {
+ tLimTdlsLinkSetupPeer *tdlsLinkSetupList;
+ uint8_t num_tdls_peers;
+ uint8_t tdls_flags;
+ uint8_t tdls_state;
+ uint8_t tdls_prev_state;
+} tLimTdlsLinkSetupInfo, *tpLimTdlsLinkSetupInfo;
+
+typedef enum tdlsLinkMode {
+ TDLS_LINK_MODE_BG,
+ TDLS_LINK_MODE_N,
+ TDLS_LINK_MODE_AC,
+ TDLS_LINK_MODE_NONE
+} eLimTdlsLinkMode;
+#endif /* FEATURE_WLAN_TDLS */
+
+#endif
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
new file mode 100644
index 0000000..f027fa0
--- /dev/null
+++ b/core/mac/src/pe/include/lim_session.h
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if !defined(__LIM_SESSION_H)
+#define __LIM_SESSION_H
+
+/**=========================================================================
+
+ \file lim_session.h
+
+ \brief prototype for lim Session related APIs
+
+ \author Sunit Bhatia
+
+ ========================================================================*/
+
+/* Powersave Offload Implementation */
+typedef enum ePowersaveState {
+ PMM_FULL_POWER,
+ PMM_POWER_SAVE
+} tPowersaveState;
+
+/* Master Structure: This will be part of PE Session Entry */
+typedef struct sPowersaveoffloadInfo {
+ tPowersaveState psstate;
+ uint8_t bcnmiss;
+} tPowersaveoffloadInfo, tpPowersaveoffloadInfo;
+
+#ifdef WLAN_FEATURE_11W
+typedef struct tagComebackTimerInfo {
+ tpAniSirGlobal pMac;
+ uint8_t sessionID;
+ tLimMlmStates limPrevMlmState; /* Previous MLM State */
+ tLimSmeStates limMlmState; /* MLM State */
+} tComebackTimerInfo;
+#endif /* WLAN_FEATURE_11W */
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------
+ Preprocessor definitions and constants
+ ------------------------------------------------------------------------*/
+#define NUM_WEP_KEYS 4
+
+/* Maximum allowable size of a beacon frame */
+#define SCH_MAX_BEACON_SIZE 512
+
+#define SCH_MAX_PROBE_RESP_SIZE 512
+#define SCH_PROTECTION_RESET_TIME 4000
+
+/*--------------------------------------------------------------------------
+ Type declarations
+ ------------------------------------------------------------------------*/
+typedef struct {
+ tSirMacBeaconInterval beaconInterval;
+ uint8_t fShortPreamble;
+ uint8_t llaCoexist;
+ uint8_t llbCoexist;
+ uint8_t llgCoexist;
+ uint8_t ht20Coexist;
+ uint8_t llnNonGFCoexist;
+ uint8_t fRIFSMode;
+ uint8_t fLsigTXOPProtectionFullSupport;
+ uint8_t gHTObssMode;
+} tBeaconParams, *tpBeaconParams;
+
+typedef struct sPESession /* Added to Support BT-AMP */
+{
+ /* To check session table is in use or free */
+ uint8_t available;
+ uint16_t peSessionId;
+ uint8_t smeSessionId;
+ uint16_t transactionId;
+
+ /* In AP role: BSSID and selfMacAddr will be the same. */
+ /* In STA role: they will be different */
+ tSirMacAddr bssId;
+ tSirMacAddr selfMacAddr;
+ tSirMacSSid ssId;
+ uint8_t bssIdx;
+ uint8_t valid;
+ tLimMlmStates limMlmState; /* MLM State */
+ tLimMlmStates limPrevMlmState; /* Previous MLM State */
+ tLimSmeStates limSmeState; /* SME State */
+ tLimSmeStates limPrevSmeState; /* Previous SME State */
+ tLimSystemRole limSystemRole;
+ tSirBssType bssType;
+ uint8_t operMode; /* AP - 0; STA - 1 ; */
+ tSirNwType nwType;
+ tpSirSmeStartBssReq pLimStartBssReq; /* handle to smestart bss req */
+ tpSirSmeJoinReq pLimJoinReq; /* handle to sme join req */
+ tpSirSmeJoinReq pLimReAssocReq; /* handle to sme reassoc req */
+ tpLimMlmJoinReq pLimMlmJoinReq; /* handle to MLM join Req */
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ void *pLimMlmReassocRetryReq; /* keep reasoc req for retry */
+#endif
+ void *pLimMlmReassocReq; /* handle to MLM reassoc Req */
+ uint16_t channelChangeReasonCode;
+ uint8_t dot11mode;
+ uint8_t htCapability;
+ /* Supported Channel Width Set: 0-20MHz 1 - 40MHz */
+ uint8_t htSupportedChannelWidthSet;
+ /* Recommended Tx Width Set
+ * 0 - use 20 MHz channel (control channel)
+ * 1 - use channel width enabled under Supported Channel Width Set
+ */
+ uint8_t htRecommendedTxWidthSet;
+ /* Identifies the 40 MHz extension channel */
+ ePhyChanBondState htSecondaryChannelOffset;
+ tSirRFBand limRFBand;
+ uint8_t limIbssActive; /* TO SUPPORT CONCURRENCY */
+
+ /* These global varibales moved to session Table to support BT-AMP : Oct 9th review */
+ tAniAuthType limCurrentAuthType;
+ uint16_t limCurrentBssCaps;
+ uint8_t limCurrentBssQosCaps;
+ uint16_t limCurrentBssPropCap;
+ uint8_t limSentCapsChangeNtf;
+ uint16_t limAID;
+
+ /* Parameters For Reassociation */
+ tSirMacAddr limReAssocbssId;
+ tSirMacChanNum limReassocChannelId;
+ /* CB paramaters required/duplicated for Reassoc since re-assoc mantains its own params in lim */
+ uint8_t reAssocHtSupportedChannelWidthSet;
+ uint8_t reAssocHtRecommendedTxWidthSet;
+ ePhyChanBondState reAssocHtSecondaryChannelOffset;
+ tSirMacSSid limReassocSSID;
+ uint16_t limReassocBssCaps;
+ uint8_t limReassocBssQosCaps;
+ uint16_t limReassocBssPropCap;
+
+ /* Assoc or ReAssoc Response Data/Frame */
+ void *limAssocResponseData;
+
+ /** BSS Table parameters **/
+
+ /*
+ * staId: Start BSS: this is the Sta Id for the BSS.
+ * Join: this is the selfStaId
+ * In both cases above, the peer STA ID wll be stored in dph hash table.
+ */
+ uint16_t staId;
+ uint16_t statypeForBss; /* to know session is for PEER or SELF */
+ uint8_t shortSlotTimeSupported;
+ uint8_t dtimPeriod;
+ tSirMacRateSet rateSet;
+ tSirMacRateSet extRateSet;
+ tSirMacHTOperatingMode htOperMode;
+ uint8_t currentOperChannel;
+ uint8_t currentReqChannel;
+ uint8_t LimRxedBeaconCntDuringHB;
+
+ /* Time stamp of the last beacon received from the BSS to which STA is connected. */
+ uint64_t lastBeaconTimeStamp;
+ /* RX Beacon count for the current BSS to which STA is connected. */
+ uint32_t currentBssBeaconCnt;
+ uint8_t lastBeaconDtimCount;
+ uint8_t lastBeaconDtimPeriod;
+
+ uint32_t bcnLen;
+ uint8_t *beacon; /* Used to store last beacon / probe response before assoc. */
+
+ uint32_t assocReqLen;
+ uint8_t *assocReq; /* Used to store association request frame sent out while associating. */
+
+ uint32_t assocRspLen;
+ uint8_t *assocRsp; /* Used to store association response received while associating */
+ tAniSirDph dph;
+ void **parsedAssocReq; /* Used to store parsed assoc req from various requesting station */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ uint32_t RICDataLen; /* Used to store the Ric data received in the assoc response */
+ uint8_t *ricData;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ uint32_t tspecLen; /* Used to store the TSPEC IEs received in the assoc response */
+ uint8_t *tspecIes;
+#endif
+ uint32_t encryptType;
+
+ bool bTkipCntrMeasActive; /* Used to keep record of TKIP counter measures start/stop */
+
+ uint8_t gLimProtectionControl; /* used for 11n protection */
+
+ uint8_t gHTNonGFDevicesPresent;
+
+ /* protection related config cache */
+ tCfgProtection cfgProtection;
+
+ /* Number of legacy STAs associated */
+ tLimProtStaParams gLim11bParams;
+
+ /* Number of 11A STAs associated */
+ tLimProtStaParams gLim11aParams;
+
+ /* Number of non-ht non-legacy STAs associated */
+ tLimProtStaParams gLim11gParams;
+
+ /* Number of nonGf STA associated */
+ tLimProtStaParams gLimNonGfParams;
+
+ /* Number of HT 20 STAs associated */
+ tLimProtStaParams gLimHt20Params;
+
+ /* Number of Lsig Txop not supported STAs associated */
+ tLimProtStaParams gLimLsigTxopParams;
+
+ /* Number of STAs that do not support short preamble */
+ tLimNoShortParams gLimNoShortParams;
+
+ /* Number of STAs that do not support short slot time */
+ tLimNoShortSlotParams gLimNoShortSlotParams;
+
+ /* OLBC parameters */
+ tLimProtStaParams gLimOlbcParams;
+
+ /* OLBC parameters */
+ tLimProtStaParams gLimOverlap11gParams;
+
+ tLimProtStaParams gLimOverlap11aParams;
+ tLimProtStaParams gLimOverlapHt20Params;
+ tLimProtStaParams gLimOverlapNonGfParams;
+
+ /* cache for each overlap */
+ tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE];
+
+ uint8_t privacy;
+ tAniAuthType authType;
+ tSirKeyMaterial WEPKeyMaterial[NUM_WEP_KEYS];
+
+ tDot11fIERSN gStartBssRSNIe;
+ tDot11fIEWPA gStartBssWPAIe;
+ tSirAPWPSIEs APWPSIEs;
+ uint8_t apUapsdEnable;
+ tSirWPSPBCSession *pAPWPSPBCSession;
+ uint32_t DefProbeRspIeBitmap[8];
+ uint32_t proxyProbeRspEn;
+ tDot11fProbeResponse probeRespFrame;
+ uint8_t ssidHidden;
+ bool fwdWPSPBCProbeReq;
+ uint8_t wps_state;
+
+ uint8_t limQosEnabled:1; /* 11E */
+ uint8_t limWmeEnabled:1; /* WME */
+ uint8_t limWsmEnabled:1; /* WSM */
+ uint8_t limHcfEnabled:1;
+ uint8_t lim11dEnabled:1;
+#ifdef WLAN_FEATURE_11W
+ uint8_t limRmfEnabled:1; /* 11W */
+#endif
+ uint32_t lim11hEnable;
+
+ tPowerdBm maxTxPower; /* MIN (Regulatory and local power constraint) */
+ tCDF_CON_MODE pePersona;
+#if defined WLAN_FEATURE_VOWIFI
+ tPowerdBm txMgmtPower;
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ tAniBool is11Rconnection;
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ tAniBool isESEconnection;
+ tEsePEContext eseContext;
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ tAniBool isFastTransitionEnabled;
+#endif
+#ifdef FEATURE_WLAN_LFR
+ tAniBool isFastRoamIniFeatureEnabled;
+#endif
+ tSirNoAParam p2pNoA;
+ tSirP2PNoaAttr p2pGoPsUpdate;
+ uint32_t defaultAuthFailureTimeout;
+ tSirP2PNoaStart p2pGoPsNoaStartInd;
+
+ /* EDCA QoS parameters
+ * gLimEdcaParams - These EDCA parameters are used locally on AP or STA.
+ * If STA, then these are values taken from the Assoc Rsp when associating,
+ * or Beacons/Probe Response after association. If AP, then these are
+ * values originally set locally on AP.
+ *
+ * gLimEdcaParamsBC - These EDCA parameters are use by AP to broadcast
+ * to other STATIONs in the BSS.
+ *
+ * gLimEdcaParamsActive: These EDCA parameters are what's actively being
+ * used on station. Specific AC values may be downgraded depending on
+ * admission control for that particular AC.
+ */
+ tSirMacEdcaParamRecord gLimEdcaParams[MAX_NUM_AC]; /* used locally */
+ tSirMacEdcaParamRecord gLimEdcaParamsBC[MAX_NUM_AC]; /* used for broadcast */
+ tSirMacEdcaParamRecord gLimEdcaParamsActive[MAX_NUM_AC];
+
+ uint8_t gLimEdcaParamSetCount;
+
+ tBeaconParams beaconParams;
+ uint8_t vhtCapability;
+ uint8_t vhtTxChannelWidthSet;
+ tLimOperatingModeInfo gLimOperatingMode;
+ uint8_t vhtCapabilityPresentInBeacon;
+ uint8_t ch_center_freq_seg0;
+ phy_ch_width ch_width;
+ uint8_t ch_center_freq_seg1;
+ uint8_t txBFIniFeatureEnabled;
+ uint8_t txMuBformee;
+ uint8_t enableVhtpAid;
+ uint8_t enableVhtGid;
+ uint8_t enable_su_tx_bformer;
+ tLimWiderBWChannelSwitchInfo gLimWiderBWChannelSwitch;
+ uint8_t enableAmpduPs;
+ uint8_t enableHtSmps;
+ uint8_t htSmpsvalue;
+ uint8_t spectrumMgtEnabled;
+ /* *********************11H related**************************** */
+ tLimSpecMgmtInfo gLimSpecMgmt;
+ /* CB Primary/Secondary Channel Switch Info */
+ tLimChannelSwitchInfo gLimChannelSwitch;
+ /* *********************End 11H related**************************** */
+
+ /*Flag to Track Status/Indicate HBFailure on this session */
+ bool LimHBFailureStatus;
+ uint32_t gLimPhyMode;
+ uint8_t amsduSupportedInBA;
+ uint8_t txLdpcIniFeatureEnabled;
+ /**
+ * Following is the place holder for free peer index pool.
+ * A non-zero value indicates that peer index is available
+ * for assignment.
+ */
+ uint8_t *gpLimPeerIdxpool;
+ uint8_t freePeerIdxHead;
+ uint8_t freePeerIdxTail;
+ uint16_t gLimNumOfCurrentSTAs;
+#ifdef FEATURE_WLAN_TDLS
+ uint32_t peerAIDBitmap[2];
+ bool tdls_prohibited;
+ bool tdls_chan_swit_prohibited;
+#endif
+ bool fWaitForProbeRsp;
+ bool fIgnoreCapsChange;
+ bool fDeauthReceived;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ int8_t rssi;
+#endif
+ uint8_t isAmsduSupportInAMPDU;
+ uint8_t isCoalesingInIBSSAllowed;
+
+ tSirHTConfig htConfig;
+
+ /*
+ * Place holder for StartBssReq message
+ * received by SME state machine
+ */
+ uint8_t gLimCurrentBssUapsd;
+
+ /* Used on STA, this is a static UAPSD mask setting
+ * derived from SME_JOIN_REQ and SME_REASSOC_REQ. If a
+ * particular AC bit is set, it means the AC is both
+ * trigger enabled and delivery enabled.
+ */
+ uint8_t gUapsdPerAcBitmask;
+
+ /* Used on STA, this is a dynamic UPASD mask setting
+ * derived from AddTS Rsp and DelTS frame. If a
+ * particular AC bit is set, it means AC is trigger
+ * enabled.
+ */
+ uint8_t gUapsdPerAcTriggerEnableMask;
+
+ /* Used on STA, dynamic UPASD mask setting
+ * derived from AddTS Rsp and DelTs frame. If
+ * a particular AC bit is set, it means AC is
+ * delivery enabled.
+ */
+ uint8_t gUapsdPerAcDeliveryEnableMask;
+
+ /* Flag to skip CSA IE processing when CSA
+ * offload is enabled.
+ */
+ uint8_t csaOffloadEnable;
+
+ /* Used on STA for AC downgrade. This is a dynamic mask
+ * setting which keep tracks of ACs being admitted.
+ * If bit is set to 0: That partiular AC is not admitted
+ * If bit is set to 1: That particular AC is admitted
+ */
+ uint8_t gAcAdmitMask[SIR_MAC_DIRECTION_DIRECT];
+
+ /* Power Save Off load Parameters */
+ tPowersaveoffloadInfo pmmOffloadInfo;
+ /* SMPS mode */
+ uint8_t smpsMode;
+
+ uint8_t chainMask;
+
+ /* Flag to indicate Chan Sw announcement is required */
+ uint8_t dfsIncludeChanSwIe;
+
+ /* Flag to indicate Chan Wrapper Element is required */
+ uint8_t dfsIncludeChanWrapperIe;
+
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ uint8_t cc_switch_mode;
+#endif
+
+ bool isCiscoVendorAP;
+
+ tSirAddIeParams addIeParams;
+
+ uint8_t *pSchProbeRspTemplate;
+ /* Beginning portion of the beacon frame to be written to TFP */
+ uint8_t *pSchBeaconFrameBegin;
+ /* Trailing portion of the beacon frame to be written to TFP */
+ uint8_t *pSchBeaconFrameEnd;
+ /* Size of the beginning portion */
+ uint16_t schBeaconOffsetBegin;
+ /* Size of the trailing portion */
+ uint16_t schBeaconOffsetEnd;
+ bool isOSENConnection;
+ /* DSCP to UP mapping for HS 2.0 */
+ tSirQosMapSet QosMapSet;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ bool bRoamSynchInProgress;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ /* Fast Transition (FT) */
+ tftPEContext ftPEContext;
+#endif
+ bool isNonRoamReassoc;
+#ifdef WLAN_FEATURE_11W
+ cdf_mc_timer_t pmfComebackTimer;
+ tComebackTimerInfo pmfComebackTimerInfo;
+#endif /* WLAN_FEATURE_11W */
+ uint8_t is_key_installed;
+ /* timer for reseting protection fileds at regular intervals */
+ cdf_mc_timer_t protection_fields_reset_timer;
+ void *mac_ctx;
+ /*
+ * variable to store state of various protection struct like
+ * gLimOlbcParams, gLimOverlap11gParams, gLimOverlapHt20Params etc
+ */
+ uint16_t old_protection_state;
+ tSirMacAddr prev_ap_bssid;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ /* tells if Q2Q IE, from another MDM device in AP MCC mode was recvd */
+ bool sap_advertise_avoid_ch_ie;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+#ifdef FEATURE_WLAN_ESE
+ uint8_t is_ese_version_ie_present;
+#endif
+ uint8_t sap_dot11mc;
+ bool is_vendor_specific_vhtcaps;
+ uint8_t vendor_specific_vht_ie_type;
+ uint8_t vendor_specific_vht_ie_sub_type;
+ /* flag to indicate country code in beacon */
+ uint8_t country_info_present;
+ uint8_t nss;
+} tPESession, *tpPESession;
+
+/*-------------------------------------------------------------------------
+ Function declarations and documenation
+ ------------------------------------------------------------------------*/
+
+/**
+ * pe_create_session() - creates a new PE session given the BSSID
+ *
+ * @pMac: pointer to global adapter context
+ * @bssid: BSSID of the new session
+ * @sessionId: session ID is returned here, if session is created.
+ * @numSta: number of stations
+ * @bssType: bss type of new session to do conditional memory allocation.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the passed BSSID is found in the PE session table.
+ *
+ * Return: ptr to the session context or NULL if session can not be created.
+ */
+tpPESession pe_create_session(tpAniSirGlobal pMac,
+ uint8_t *bssid,
+ uint8_t *sessionId,
+ uint16_t numSta, tSirBssType bssType);
+
+/**
+ * pe_find_session_by_bssid() - looks up the PE session given the BSSID.
+ *
+ * @pMac: pointer to global adapter context
+ * @bssid: BSSID of the new session
+ * @sessionId: session ID is returned here, if session is created.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given BSSID is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_bssid(tpAniSirGlobal pMac, uint8_t *bssid,
+ uint8_t *sessionId);
+
+/**
+ * pe_find_session_by_bss_idx() - looks up the PE session given the bssIdx.
+ *
+ * @pMac: pointer to global adapter context
+ * @bssIdx: bss index of the session
+ *
+ * This function returns the session context if the session
+ * corresponding to the given bssIdx is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_bss_idx(tpAniSirGlobal pMac, uint8_t bssIdx);
+
+/**
+ * pe_find_session_by_peer_sta() - looks up the PE session given the Peer
+ * Station Address.
+ *
+ * @pMac: pointer to global adapter context
+ * @sa: Peer STA Address of the session
+ * @sessionId: session ID is returned here, if session is found.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given destination address is found in the PE session
+ * table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_peer_sta(tpAniSirGlobal pMac, uint8_t *sa,
+ uint8_t *sessionId);
+
+/**
+ * pe_find_session_by_session_id() - looks up the PE session given the session
+ * ID.
+ *
+ * @pMac: pointer to global adapter context
+ * @sessionId: session ID for which session context needs to be looked up.
+ *
+ * This function returns the session context if the session corresponding to
+ * the given session ID is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_session_id(tpAniSirGlobal pMac,
+ uint8_t sessionId);
+
+/**
+ * pe_find_session_by_bssid() - looks up the PE session given staid.
+ *
+ * @pMac: pointer to global adapter context
+ * @staid: StaId of the session
+ * @sessionId: session ID is returned here, if session is found.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given StaId is found in the PE session table.
+ *
+ * Return: pointer to the session context or NULL if session is not found.
+ */
+tpPESession pe_find_session_by_sta_id(tpAniSirGlobal pMac, uint8_t staid,
+ uint8_t *sessionId);
+
+/**
+ * pe_delete_session() - deletes the PE session given the session ID.
+ *
+ * @pMac: pointer to global adapter context
+ * @sessionId: session ID to delete.
+ *
+ * Return: void
+ */
+void pe_delete_session(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+/**
+ * pe_find_session_by_sme_session_id() - looks up the PE session for given sme
+ * session id
+ * @mac_ctx: pointer to global adapter context
+ * @sme_session_id: sme session id
+ *
+ * looks up the PE session for given sme session id
+ *
+ * Return: pe session entry for given sme session if found else NULL
+ */
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+ uint8_t sme_session_id);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+uint8_t pe_get_active_session_count(tpAniSirGlobal mac_ctx);
+#endif /* #if !defined( __LIM_SESSION_H ) */
diff --git a/core/mac/src/pe/include/lim_trace.h b/core/mac/src/pe/include/lim_trace.h
new file mode 100644
index 0000000..494edc8
--- /dev/null
+++ b/core/mac/src/pe/include/lim_trace.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ * \file lim_trace.h
+
+ * \brief definition for trace related APIs
+
+ * \author Sunit Bhatia
+
+ ========================================================================*/
+
+#ifndef __LIM_TRACE_H
+#define __LIM_TRACE_H
+
+#include "lim_global.h"
+#include "mac_trace.h"
+#include "cdf_trace.h"
+#ifdef LIM_TRACE_RECORD
+
+#define LIM_TRACE_GET_SSN(data) (((data) >> 16) & 0xff)
+#define LIM_TRACE_GET_SUBTYPE(data) (data & 0xff)
+#define LIM_TRACE_GET_DEFERRED(data) (data & 0x80000000)
+#define LIM_TRACE_GET_DEFRD_OR_DROPPED(data) (data & 0xc0000000)
+
+#define LIM_MSG_PROCESSED 0
+#define LIM_MSG_DEFERRED 1
+#define LIM_MSG_DROPPED 2
+
+#define LIM_TRACE_MAKE_RXMGMT(type, ssn) \
+ ((ssn << 16) | (type))
+#define LIM_TRACE_MAKE_RXMSG(msg, action) \
+ ((msg) | (action << 30))
+
+enum {
+ TRACE_CODE_MLM_STATE,
+ TRACE_CODE_SME_STATE,
+ TRACE_CODE_TX_MGMT,
+ TRACE_CODE_RX_MGMT,
+ TRACE_CODE_RX_MGMT_TSF,
+ TRACE_CODE_TX_COMPLETE,
+ TRACE_CODE_TX_SME_MSG,
+ TRACE_CODE_RX_SME_MSG,
+ TRACE_CODE_TX_WMA_MSG,
+ TRACE_CODE_RX_WMA_MSG,
+ TRACE_CODE_TX_LIM_MSG,
+ TRACE_CODE_RX_LIM_MSG,
+ TRACE_CODE_TX_CFG_MSG,
+ TRACE_CODE_RX_CFG_MSG,
+ TRACE_CODE_RX_MGMT_DROP,
+
+ TRACE_CODE_TIMER_ACTIVATE,
+ TRACE_CODE_TIMER_DEACTIVATE,
+ TRACE_CODE_INFO_LOG
+};
+
+void lim_trace_init(tpAniSirGlobal pMac);
+void limTraceReset(tpAniSirGlobal pMac);
+void limTraceUpdateMgmtStat(tpAniSirGlobal pMac, uint8_t subtype);
+void lim_trace_dumpMgmtStat(tpAniSirGlobal pMac, uint8_t subtype);
+uint8_t *lim_trace_get_mlm_state_string(uint32_t mlmState);
+uint8_t *lim_trace_get_sme_state_string(uint32_t smeState);
+void lim_trace_dump(tpAniSirGlobal pMac, tp_cdf_trace_record pRecord,
+ uint16_t recIndex);
+void mac_trace_msg_tx(tpAniSirGlobal pMac, uint8_t session, uint32_t data);
+void mac_trace_msg_rx(tpAniSirGlobal pMac, uint8_t session, uint32_t data);
+
+void mac_trace_msg_rx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+ uint32_t data);
+void mac_trace_msg_tx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+ uint32_t data);
+#endif /* endof LIM_TRACE_RECORD MACRO */
+
+#endif
diff --git a/core/mac/src/pe/include/rrm_api.h b/core/mac/src/pe/include/rrm_api.h
new file mode 100644
index 0000000..05466c0
--- /dev/null
+++ b/core/mac/src/pe/include/rrm_api.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file rrm_api.h
+
+ \brief RRM APIs
+
+ ========================================================================*/
+
+/* $Header$ */
+
+#ifndef __RRM_API_H__
+#define __RRM_API_H__
+
+#define RRM_MIN_TX_PWR_CAP 13
+#define RRM_MAX_TX_PWR_CAP 19
+
+#define RRM_BCN_RPT_NO_BSS_INFO 0
+#define RRM_BCN_RPT_MIN_RPT 1
+
+uint8_t rrm_get_min_of_max_tx_power(tpAniSirGlobal pMac, tPowerdBm regMax,
+ tPowerdBm apTxPower);
+
+extern tSirRetStatus rrm_initialize(tpAniSirGlobal pMac);
+
+extern tSirRetStatus rrm_cleanup(tpAniSirGlobal pMac);
+
+extern tSirRetStatus rrm_process_link_measurement_request(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ tDot11fLinkMeasurementRequest
+ *pLinkReq,
+ tpPESession
+ pSessionEntry);
+
+extern tSirRetStatus rrm_process_radio_measurement_request(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ tDot11fRadioMeasurementRequest
+ *pRRMReq,
+ tpPESession
+ pSessionEntry);
+
+extern tSirRetStatus rrm_process_neighbor_report_response(tpAniSirGlobal pMac,
+ tDot11fNeighborReportResponse
+ *pNeighborRep,
+ tpPESession
+ pSessionEntry);
+
+extern void rrm_process_message(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+
+extern tSirRetStatus rrm_send_set_max_tx_power_req(tpAniSirGlobal pMac,
+ tPowerdBm txPower,
+ tpPESession pSessionEntry);
+
+extern tPowerdBm rrm_get_mgmt_tx_power(tpAniSirGlobal pMac,
+ tpPESession pSessionEntry);
+
+extern void rrm_cache_mgmt_tx_power(tpAniSirGlobal pMac,
+ tPowerdBm txPower, tpPESession pSessionEntry);
+
+extern tpRRMCaps rrm_get_capabilities(tpAniSirGlobal pMac,
+ tpPESession pSessionEntry);
+
+extern void rrm_update_config(tpAniSirGlobal pMac, tpPESession pSessionEntry);
+
+extern void rrm_get_start_tsf(tpAniSirGlobal pMac, uint32_t *pStartTSF);
+
+extern void rrm_update_start_tsf(tpAniSirGlobal pMac, uint32_t startTSF[2]);
+
+extern tSirRetStatus rrm_set_max_tx_power_rsp(tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ);
+
+extern tSirRetStatus
+rrm_process_neighbor_report_req(tpAniSirGlobal pMac,
+ tpSirNeighborReportReqInd pNeighborReq);
+extern tSirRetStatus
+rrm_process_beacon_report_xmit(tpAniSirGlobal pMac,
+ tpSirBeaconReportXmitInd pBcnReport);
+#endif
diff --git a/core/mac/src/pe/include/rrm_global.h b/core/mac/src/pe/include/rrm_global.h
new file mode 100644
index 0000000..053848d
--- /dev/null
+++ b/core/mac/src/pe/include/rrm_global.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if !defined(__RRMGLOBAL_H)
+#define __RRMGLOBAL_H
+
+/**=========================================================================
+
+ \file rrm_global.h
+
+ \brief Definitions for SME APIs
+
+ ========================================================================*/
+
+typedef enum eRrmRetStatus {
+ eRRM_SUCCESS,
+ eRRM_INCAPABLE,
+ eRRM_REFUSED,
+ eRRM_FAILURE
+} tRrmRetStatus;
+
+typedef enum eRrmMsgReqSource {
+ eRRM_MSG_SOURCE_LEGACY_ESE = 1, /* legacy ese */
+ eRRM_MSG_SOURCE_11K = 2, /* 11k */
+ eRRM_MSG_SOURCE_ESE_UPLOAD = 3, /* ese upload approach */
+} tRrmMsgReqSource;
+
+typedef struct sSirChannelInfo {
+ uint8_t regulatoryClass;
+ uint8_t channelNum;
+} tSirChannelInfo, *tpSirChannelInfo;
+
+typedef struct sSirBeaconReportReqInd {
+ uint16_t messageType; /* eWNI_SME_BEACON_REPORT_REQ_IND */
+ uint16_t length;
+ tSirMacAddr bssId;
+ uint16_t measurementDuration[SIR_ESE_MAX_MEAS_IE_REQS]; /* ms */
+ uint16_t randomizationInterval; /* ms */
+ tSirChannelInfo channelInfo;
+ /* 0: wildcard */
+ tSirMacAddr macaddrBssid;
+ /* 0:Passive, 1: Active, 2: table mode */
+ uint8_t fMeasurementtype[SIR_ESE_MAX_MEAS_IE_REQS];
+ tAniSSID ssId; /* May be wilcard. */
+ uint16_t uDialogToken;
+ tSirChannelList channelList; /* From AP channel report. */
+ tRrmMsgReqSource msgSource;
+} tSirBeaconReportReqInd, *tpSirBeaconReportReqInd;
+
+typedef struct sSirBeaconReportXmitInd {
+ uint16_t messageType; /* eWNI_SME_BEACON_REPORT_RESP_XMIT_IND */
+ uint16_t length;
+ tSirMacAddr bssId;
+ uint16_t uDialogToken;
+ uint8_t fMeasureDone;
+ uint16_t duration;
+ uint8_t regClass;
+ uint8_t numBssDesc;
+ tpSirBssDescription pBssDescription[SIR_BCN_REPORT_MAX_BSS_DESC];
+} tSirBeaconReportXmitInd, *tpSirBeaconReportXmitInd;
+
+typedef struct sSirNeighborReportReqInd {
+ /* eWNI_SME_NEIGHBOR_REPORT_REQ_IND */
+ uint16_t messageType;
+ uint16_t length;
+ /* For the session. */
+ tSirMacAddr bssId;
+ /* true - dont include SSID in the request. */
+ uint16_t noSSID;
+ /* false include the SSID. It may be null (wildcard) */
+ tSirMacSSid ucSSID;
+} tSirNeighborReportReqInd, *tpSirNeighborReportReqInd;
+
+typedef struct sSirNeighborBssDescription {
+ uint16_t length;
+ tSirMacAddr bssId;
+ uint8_t regClass;
+ uint8_t channel;
+ uint8_t phyType;
+ union sSirNeighborBssidInfo {
+ struct _rrmInfo {
+ /* see IEEE 802.11k Table 7-43a */
+ uint32_t fApPreauthReachable:2;
+ uint32_t fSameSecurityMode:1;
+ uint32_t fSameAuthenticator:1;
+ /* see IEEE 802.11k Table 7-95d */
+ uint32_t fCapSpectrumMeasurement:1;
+ uint32_t fCapQos:1;
+ uint32_t fCapApsd:1;
+ uint32_t fCapRadioMeasurement:1;
+ uint32_t fCapDelayedBlockAck:1;
+ uint32_t fCapImmediateBlockAck:1;
+ uint32_t fMobilityDomain:1;
+ uint32_t reserved:21;
+ } rrmInfo;
+ struct _eseInfo {
+ uint32_t channelBand:8;
+ uint32_t minRecvSigPower:8;
+ uint32_t apTxPower:8;
+ uint32_t roamHysteresis:8;
+ uint32_t adaptScanThres:8;
+
+ uint32_t transitionTime:8;
+ uint32_t tsfOffset:16;
+
+ uint32_t beaconInterval:16;
+ uint32_t reserved:16;
+ } eseInfo;
+ } bssidInfo;
+
+ /* Optional sub IEs....ignoring for now. */
+} tSirNeighborBssDescription, *tpSirNeighborBssDescripton;
+
+typedef struct sSirNeighborReportInd {
+ uint16_t messageType; /* eWNI_SME_NEIGHBOR_REPORT_IND */
+ uint16_t length;
+ uint8_t sessionId;
+ uint16_t numNeighborReports;
+ tSirMacAddr bssId; /* For the session. */
+ tSirNeighborBssDescription sNeighborBssDescription[1];
+} tSirNeighborReportInd, *tpSirNeighborReportInd;
+
+typedef struct sRRMBeaconReportRequestedIes {
+ uint8_t num;
+ uint8_t *pElementIds;
+} tRRMBeaconReportRequestedIes, *tpRRMBeaconReportRequestedIes;
+
+/* Reporting detail defines. */
+/* Reference - IEEE Std 802.11k-2008 section 7.3.2.21.6 Table 7-29h */
+#define BEACON_REPORTING_DETAIL_NO_FF_IE 0
+#define BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE 1
+#define BEACON_REPORTING_DETAIL_ALL_FF_IE 2
+
+typedef struct sRRMReq {
+ uint8_t dialog_token; /* In action frame; */
+ uint8_t token; /* Within individual request; */
+ uint8_t type;
+ union {
+ struct {
+ uint8_t reportingDetail;
+ tRRMBeaconReportRequestedIes reqIes;
+ } Beacon;
+ } request;
+ uint8_t sendEmptyBcnRpt;
+} tRRMReq, *tpRRMReq;
+
+typedef struct sRRMCaps {
+ uint8_t LinkMeasurement:1;
+ uint8_t NeighborRpt:1;
+ uint8_t parallel:1;
+ uint8_t repeated:1;
+ uint8_t BeaconPassive:1;
+ uint8_t BeaconActive:1;
+ uint8_t BeaconTable:1;
+ uint8_t BeaconRepCond:1;
+ uint8_t FrameMeasurement:1;
+ uint8_t ChannelLoad:1;
+ uint8_t NoiseHistogram:1;
+ uint8_t statistics:1;
+ uint8_t LCIMeasurement:1;
+ uint8_t LCIAzimuth:1;
+ uint8_t TCMCapability:1;
+ uint8_t triggeredTCM:1;
+ uint8_t APChanReport:1;
+ uint8_t RRMMIBEnabled:1;
+ uint8_t operatingChanMax:3;
+ uint8_t nonOperatingChanMax:3;
+ uint8_t MeasurementPilot:3;
+ uint8_t MeasurementPilotEnabled:1;
+ uint8_t NeighborTSFOffset:1;
+ uint8_t RCPIMeasurement:1;
+ uint8_t RSNIMeasurement:1;
+ uint8_t BssAvgAccessDelay:1;
+ uint8_t BSSAvailAdmission:1;
+ uint8_t AntennaInformation:1;
+ uint8_t fine_time_meas_rpt:1;
+ uint8_t lci_capability:1;
+ uint8_t reserved:4;
+} tRRMCaps, *tpRRMCaps;
+
+typedef struct sRrmPEContext {
+ uint8_t rrmEnable;
+ /*
+ * Used during scan/measurement to store the start TSF.
+ * this is not used directly in beacon reports.
+ */
+ uint32_t startTSF[2];
+ /*
+ * This value is stored into bssdescription and beacon report
+ * gets it from bss decsription.
+ */
+ tRRMCaps rrmEnabledCaps;
+ tPowerdBm txMgmtPower;
+ /* Dialog token for the request initiated from station. */
+ uint8_t DialogToken;
+ tpRRMReq pCurrentReq;
+} tRrmPEContext, *tpRrmPEContext;
+
+/* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */
+#define RCPI_LOW_RSSI_VALUE (-110)
+#define RCPI_MAX_VALUE (220)
+#define CALCULATE_RCPI(rssi) (((rssi) + 110) * 2)
+
+#endif /* #if defined __RRMGLOBAL_H */
diff --git a/core/mac/src/pe/include/sch_api.h b/core/mac/src/pe/include/sch_api.h
new file mode 100644
index 0000000..04db805
--- /dev/null
+++ b/core/mac/src/pe/include/sch_api.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_API_H__
+#define __SCH_API_H__
+
+#include "sir_common.h"
+#include "sir_mac_prot_def.h"
+
+#include "ani_global.h"
+
+/* / Send start scan response message */
+extern void sch_send_start_scan_rsp(tpAniSirGlobal pMac);
+
+/* update only the broadcast qos params */
+extern void sch_qos_update_broadcast(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+
+/* fill in the default local edca parameter into gLimEdcaParams[] */
+extern void sch_set_default_edca_params(tpAniSirGlobal pMac, tpPESession psessionE);
+
+/* update only local qos params */
+extern void sch_qos_update_local(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+/* update the edca profile parameters */
+extern void sch_edca_profile_update(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+
+/* / Set the fixed fields in a beacon frame */
+extern tSirRetStatus sch_set_fixed_beacon_fields(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+
+/* / Initialize globals */
+extern void sch_init_globals(tpAniSirGlobal pMac);
+
+/* / Initialize CF Poll template */
+extern void sch_initializeCfPollTemplate(tpAniSirGlobal pMac);
+
+/* / Initialize CF End template */
+extern void sch_initializeCfEndTemplate(tpAniSirGlobal pMac);
+
+/* / Process the scheduler messages */
+extern void sch_process_message(tpAniSirGlobal pMac, tpSirMsgQ pSchMsg);
+
+/* / The beacon Indication handler function */
+extern void sch_process_pre_beacon_ind(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+
+/* / Post a message to the scheduler message queue */
+extern tSirRetStatus sch_post_message(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+
+extern void sch_beacon_process(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry);
+extern tSirRetStatus sch_beacon_edca_process(tpAniSirGlobal pMac,
+ tSirMacEdcaParamSetIE *edca,
+ tpPESession psessionEntry);
+
+void sch_generate_tim(tpAniSirGlobal, uint8_t **, uint16_t *, uint8_t);
+#define SCH_RR_TIMEOUT (SCH_RR_TIMEOUT_MS / SYS_TICK_DUR_MS)
+
+void sch_set_beacon_interval(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+tSirRetStatus sch_send_beacon_req(tpAniSirGlobal, uint8_t *, uint16_t,
+ tpPESession psessionEntry);
+
+tSirRetStatus lim_update_probe_rsp_template_ie_bitmap_beacon1(tpAniSirGlobal,
+ tDot11fBeacon1 *,
+ tpPESession
+ psessionEntry);
+void lim_update_probe_rsp_template_ie_bitmap_beacon2(tpAniSirGlobal, tDot11fBeacon2 *,
+ uint32_t *,
+ tDot11fProbeResponse *);
+void set_probe_rsp_ie_bitmap(uint32_t *, uint32_t);
+uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal, tpPESession, uint32_t *);
+
+int sch_gen_timing_advert_frame(tpAniSirGlobal pMac, tSirMacAddr self_addr,
+ uint8_t **buf, uint32_t *timestamp_offset, uint32_t *time_value_offset);
+
+#endif
diff --git a/core/mac/src/pe/include/sch_global.h b/core/mac/src/pe/include/sch_global.h
new file mode 100644
index 0000000..baebe98
--- /dev/null
+++ b/core/mac/src/pe/include/sch_global.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_GLOBAL_H__
+#define __SCH_GLOBAL_H__
+
+#include "sir_mac_prop_exts.h"
+#include "lim_global.h"
+
+#include "parser_api.h"
+
+#ifdef WLAN_SOFTAP_VSTA_FEATURE
+#define TIM_IE_SIZE 0xB
+#else
+#define TIM_IE_SIZE 0x7
+#endif
+
+/* ----------------------- Beacon processing ------------------------ */
+
+/* / Beacon structure */
+#define tSchBeaconStruct tSirProbeRespBeacon
+#define tpSchBeaconStruct struct sSirProbeRespBeacon *
+
+/* ------------------------------------------------------------------- */
+
+/* ****************** MISC defs ********************************* */
+
+struct schMisc {
+ uint16_t gSchBeaconInterval;
+
+ /* / Current CFP count */
+ uint8_t gSchCFPCount;
+
+ /* / CFP Duration remaining */
+ uint8_t gSchCFPDurRemaining;
+
+ /* / CFP Maximum Duration */
+ uint8_t gSchCFPMaxDuration;
+
+ /* / Current DTIM count */
+ uint8_t gSchDTIMCount;
+
+ /* / Whether we have initiated a CFP or not */
+ uint8_t gSchCFPInitiated;
+
+ /* / Whether we have initiated a CFB or not */
+ uint8_t gSchCFBInitiated;
+
+ /* / CFP is enabled and AP is configured as HCF */
+ uint8_t gSchCFPEnabled;
+
+ /* / CFB is enabled and AP is configured as HCF */
+ uint8_t gSchCFBEnabled;
+
+ /* --------- STA ONLY state ----------- */
+
+ /* / Indicates whether RR timer is running or not */
+ uint8_t rrTimer[8];
+
+ /* / Indicates the remaining RR timeout value if the RR timer is running */
+ uint16_t rrTimeout[8];
+
+ /* / Number of RRs transmitted */
+ uint16_t numRR[8];
+ uint16_t numRRtimeouts[8];
+
+ /* / flag to indicate that beacon template has been updated */
+ uint8_t fBeaconChanged;
+
+ uint16_t p2pIeOffset;
+
+};
+
+/* ****************** MISC defs ********************************* */
+
+typedef struct schStaWaitList {
+ uint16_t staId;
+ uint16_t count;
+} tStaWaitList, *tpStaWaitList;
+
+/* / Global SCH structure */
+typedef struct sAniSirSch {
+ /* / The scheduler object */
+ struct schMisc schObject;
+
+ /* schQoSClass unsolicited; */
+
+ /* / Whether HCF is enabled or not */
+ uint8_t gSchHcfEnabled;
+
+ /* / Whether scan is requested by LIM or not */
+ uint8_t gSchScanRequested;
+
+ /* / Whether scan request is received by SCH or not */
+ uint8_t gSchScanReqRcvd;
+
+ /* / Debug flag to disable beacon generation */
+ uint32_t gSchGenBeacon;
+
+#define SCH_MAX_ARR 100
+ uint32_t gSchBeaconsWritten;
+ uint32_t gSchBeaconsSent;
+ uint32_t gSchBBXportRcvCnt;
+ uint32_t gSchRRRcvCnt, qosNullCnt;
+ uint32_t gSchBcnRcvCnt;
+ uint32_t gSchUnknownRcvCnt;
+
+ uint32_t gSchBcnParseErrorCnt;
+ uint32_t gSchBcnIgnored;
+
+ uint32_t numPoll, numData, numCorrupt;
+ uint32_t numBogusInt, numTxAct0;
+
+#define SCH_MAX_NUM_SCH 21
+ uint32_t lastBeaconLength;
+ uint16_t rrTimeout;
+ uint32_t pollPeriod;
+ uint32_t multipleSched;
+ uint32_t pollFeedbackHist[8];
+ uint32_t dataFeedbackHist[8];
+ uint32_t maxPollTimeouts;
+ uint32_t checkCfbFlagStuck;
+
+ /* / Sta Wait list */
+ tpStaWaitList pStaWaitList;
+
+ /* / Pointer to next available entry in sta wait list */
+ uint16_t staWaitListIn;
+ /* / Pointer to first waiting sta in sta wait list */
+ uint16_t staWaitListOut;
+ /* / Total number of waiting STAs in sta wait list */
+ uint16_t staWaitListCount;
+ /* / Total number of schedules to be waited */
+ uint16_t staWaitListTotalWait;
+
+ /* / Number of entries in DPH activity queue that were ignored */
+ uint32_t ignoreDph;
+
+} tAniSirSch, *tpAniSirSch;
+
+#endif
diff --git a/core/mac/src/pe/include/wmm_apsd.h b/core/mac/src/pe/include/wmm_apsd.h
new file mode 100644
index 0000000..9b5d5d4
--- /dev/null
+++ b/core/mac/src/pe/include/wmm_apsd.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef __WMMAPSD_H__
+#define __WMMAPSD_H__
+
+#include "ani_global.h"
+
+/* UAPSD Flag for each AC (WMM spec 2.2.1) */
+#define LIM_UAPSD_BITOFFSET_ACVO 0
+#define LIM_UAPSD_BITOFFSET_ACVI 1
+#define LIM_UAPSD_BITOFFSET_ACBK 2
+#define LIM_UAPSD_BITOFFSET_ACBE 3
+
+#define LIM_UAPSD_FLAG_ACVO (1 << LIM_UAPSD_BITOFFSET_ACVO)
+#define LIM_UAPSD_FLAG_ACVI (1 << LIM_UAPSD_BITOFFSET_ACVI)
+#define LIM_UAPSD_FLAG_ACBK (1 << LIM_UAPSD_BITOFFSET_ACBK)
+#define LIM_UAPSD_FLAG_ACBE (1 << LIM_UAPSD_BITOFFSET_ACBE)
+
+#define LIM_UAPSD_GET(ac, mask) (((mask) & (LIM_UAPSD_FLAG_ ## ac)) >> LIM_UAPSD_BITOFFSET_ ## ac)
+
+/* Definition for setting/clearing Uapsd Mask */
+#define SET_UAPSD_MASK 1
+#define CLEAR_UAPSD_MASK 0
+
+#endif /* __WMMAPSD_H__ */
diff --git a/core/mac/src/pe/lim/lim_admit_control.c b/core/mac/src/pe/lim/lim_admit_control.c
new file mode 100644
index 0000000..b217c40
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_admit_control.c
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file contains TSPEC and STA admit control related functions
+ * NOTE: applies only to AP builds
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "lim_debug.h"
+#include "sys_def.h"
+#include "lim_api.h"
+#include "cfg_api.h" /* wlan_cfg_get_int() */
+#include "lim_trace.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "lim_types.h"
+
+#define ADMIT_CONTROL_LOGLEVEL LOG1
+#define ADMIT_CONTROL_POLICY_LOGLEVEL LOG1
+
+/* total available bandwidth in bps in each phy mode
+ * these should be defined in hal or dph - replace these later
+ */
+#define LIM_TOTAL_BW_11A 54000000
+#define LIM_MIN_BW_11A 6000000
+#define LIM_TOTAL_BW_11B 11000000
+#define LIM_MIN_BW_11B 1000000
+#define LIM_TOTAL_BW_11G LIM_TOTAL_BW_11A
+#define LIM_MIN_BW_11G LIM_MIN_BW_11B
+
+/* conversion factors */
+#define LIM_CONVERT_SIZE_BITS(numBytes) ((numBytes) * 8)
+#define LIM_CONVERT_RATE_MBPS(rate) ((rate)/1000000)
+
+/* ------------------------------------------------------------------------------ */
+/* local protos */
+
+static tSirRetStatus
+lim_calculate_svc_int(tpAniSirGlobal, tSirMacTspecIE *, uint32_t *);
+static tSirRetStatus
+lim_validate_tspec_edca(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
+static tSirRetStatus
+lim_validate_tspec(tpAniSirGlobal, tSirMacTspecIE *, tpPESession);
+static void
+lim_compute_mean_bw_used(tpAniSirGlobal, uint32_t *, uint32_t, tpLimTspecInfo,
+ tpPESession);
+static void lim_get_available_bw(tpAniSirGlobal, uint32_t *, uint32_t *, uint32_t,
+ uint32_t);
+static tSirRetStatus lim_admit_policy_oversubscription(tpAniSirGlobal,
+ tSirMacTspecIE *,
+ tpLimAdmitPolicyInfo,
+ tpLimTspecInfo,
+ tpPESession);
+static tSirRetStatus lim_tspec_find_by_sta_addr(tpAniSirGlobal, uint8_t *,
+ tSirMacTspecIE *, tpLimTspecInfo,
+ tpLimTspecInfo *);
+static tSirRetStatus lim_validate_access_policy(tpAniSirGlobal, uint8_t, uint16_t,
+ tpPESession);
+
+/** -------------------------------------------------------------
+ \fn lim_calculate_svc_int
+ \brief TSPEC validation and servcie interval determination
+ \param tpAniSirGlobal pMac
+ \param tSirMacTspecIE *pTspec
+ \param uint32_t *pSvcInt
+ \return eSirRetStatus - status of the comparison
+ -------------------------------------------------------------*/
+
+static tSirRetStatus
+lim_calculate_svc_int(tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec, uint32_t *pSvcInt)
+{
+ uint32_t msduSz, dataRate;
+ *pSvcInt = 0;
+
+ /* if a service interval is already specified, we are done */
+ if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0)) {
+ *pSvcInt = (pTspec->maxSvcInterval != 0)
+ ? pTspec->maxSvcInterval : pTspec->minSvcInterval;
+ return eSIR_SUCCESS;
+ }
+
+ /* Masking off the fixed bits according to definition of MSDU size
+ * in IEEE 802.11-2007 spec (section 7.3.2.30). Nominal MSDU size
+ * is defined as: Bit[0:14]=Size, Bit[15]=Fixed
+ */
+ if (pTspec->nomMsduSz != 0)
+ msduSz = (pTspec->nomMsduSz & 0x7fff);
+ else if (pTspec->maxMsduSz != 0)
+ msduSz = pTspec->maxMsduSz;
+ else {
+ PELOGE(lim_log(pMac, LOGE, FL("MsduSize not specified"));)
+ return eSIR_FAILURE;
+ }
+
+ /* need to calculate a reasonable service interval
+ * this is simply the msduSz/meanDataRate
+ */
+ if (pTspec->meanDataRate != 0)
+ dataRate = pTspec->meanDataRate;
+ else if (pTspec->peakDataRate != 0)
+ dataRate = pTspec->peakDataRate;
+ else if (pTspec->minDataRate != 0)
+ dataRate = pTspec->minDataRate;
+ else {
+ PELOGE(lim_log(pMac, LOGE, FL("DataRate not specified"));)
+ return eSIR_FAILURE;
+ }
+
+ *pSvcInt =
+ LIM_CONVERT_SIZE_BITS(msduSz) / LIM_CONVERT_RATE_MBPS(dataRate);
+ return eSIR_FAILURE;
+}
+
+/**
+ * lim_validate_tspec_edca() - Validate the parameters
+ * @mac_ctx: Global MAC context
+ * @tspec: Pointer to the TSPEC
+ * @session_entry: Session Entry
+ *
+ * validate the parameters in the edca tspec
+ * mandatory fields are derived from 11e Annex I (Table I.1)
+ *
+ * Return: Status
+ **/
+static tSirRetStatus
+lim_validate_tspec_edca(tpAniSirGlobal mac_ctx,
+ tSirMacTspecIE *tspec, tpPESession session_entry)
+{
+ uint32_t max_phy_rate, min_phy_rate;
+ uint32_t phy_mode;
+ tSirRetStatus retval = eSIR_SUCCESS;
+
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+ lim_get_available_bw(mac_ctx, &max_phy_rate, &min_phy_rate, phy_mode,
+ 1 /* bandwidth mult factor */);
+ /* mandatory fields are derived from 11e Annex I (Table I.1) */
+ if ((tspec->nomMsduSz == 0) ||
+ (tspec->meanDataRate == 0) ||
+ (tspec->surplusBw == 0) ||
+ (tspec->minPhyRate == 0) ||
+ (tspec->minPhyRate > max_phy_rate)) {
+ lim_log(mac_ctx, LOGW,
+ FL
+ ("Invalid EDCA Tspec: NomMsdu %d, meanDataRate %d, surplusBw %d, min_phy_rate %d"),
+ tspec->nomMsduSz, tspec->meanDataRate,
+ tspec->surplusBw, tspec->minPhyRate);
+ retval = eSIR_FAILURE;
+ }
+
+ lim_log(mac_ctx, ADMIT_CONTROL_LOGLEVEL,
+ FL("return status %d"), retval);
+ return retval;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_validate_tspec
+ \brief validate the offered tspec
+ \param tpAniSirGlobal pMac
+ \param tSirMacTspecIE *pTspec
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static tSirRetStatus
+lim_validate_tspec(tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec, tpPESession psessionEntry)
+{
+ tSirRetStatus retval = eSIR_SUCCESS;
+ switch (pTspec->tsinfo.traffic.accessPolicy) {
+ case SIR_MAC_ACCESSPOLICY_EDCA:
+ retval = lim_validate_tspec_edca(pMac, pTspec, psessionEntry);
+ if (retval != eSIR_SUCCESS)
+ PELOGW(lim_log(pMac, LOGW, FL("EDCA tspec invalid"));)
+ break;
+
+ case SIR_MAC_ACCESSPOLICY_HCCA:
+ case SIR_MAC_ACCESSPOLICY_BOTH:
+ /* TBD: should we support hybrid tspec as well?? for now, just fall through */
+ default:
+ lim_log(pMac, LOGW, FL("AccessType %d not supported"),
+ pTspec->tsinfo.traffic.accessPolicy);
+ retval = eSIR_FAILURE;
+ break;
+ }
+ return retval;
+}
+
+/* ----------------------------------------------------------------------------- */
+/* Admit Control Policy */
+
+/** -------------------------------------------------------------
+ \fn lim_compute_mean_bw_used
+ \brief determime the used/allocated bandwidth
+ \param tpAniSirGlobal pMac
+ \param uint32_t *pBw
+ \param uint32_t phyMode
+ \param tpLimTspecInfo pTspecInfo
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static void
+lim_compute_mean_bw_used(tpAniSirGlobal pMac,
+ uint32_t *pBw,
+ uint32_t phyMode,
+ tpLimTspecInfo pTspecInfo, tpPESession psessionEntry)
+{
+ uint32_t ctspec;
+ *pBw = 0;
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) {
+ if (pTspecInfo->inuse) {
+ tpDphHashNode pSta =
+ dph_get_hash_entry(pMac, pTspecInfo->assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL) {
+ /* maybe we should delete the tspec?? */
+ lim_log(pMac, LOGE,
+ FL
+ ("Tspec %d (assocId %d): dphNode not found"),
+ ctspec, pTspecInfo->assocId);
+ continue;
+ }
+ *pBw += pTspecInfo->tspec.meanDataRate;
+ }
+ }
+}
+
+/** -------------------------------------------------------------
+ \fn lim_get_available_bw
+ \brief based on the phy mode and the bw_factor, determine the total bandwidth that
+ can be supported
+ \param tpAniSirGlobal pMac
+ \param uint32_t *pMaxBw
+ \param uint32_t *pMinBw
+ \param uint32_t phyMode
+ \param uint32_t bw_factor
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static void
+lim_get_available_bw(tpAniSirGlobal pMac,
+ uint32_t *pMaxBw,
+ uint32_t *pMinBw, uint32_t phyMode, uint32_t bw_factor)
+{
+ switch (phyMode) {
+ case WNI_CFG_PHY_MODE_11B:
+ *pMaxBw = LIM_TOTAL_BW_11B;
+ *pMinBw = LIM_MIN_BW_11B;
+ break;
+
+ case WNI_CFG_PHY_MODE_11A:
+ *pMaxBw = LIM_TOTAL_BW_11A;
+ *pMinBw = LIM_MIN_BW_11A;
+ break;
+
+ case WNI_CFG_PHY_MODE_11G:
+ case WNI_CFG_PHY_MODE_NONE:
+ default:
+ *pMaxBw = LIM_TOTAL_BW_11G;
+ *pMinBw = LIM_MIN_BW_11G;
+ break;
+ }
+ *pMaxBw *= bw_factor;
+}
+
+/**
+ * lim_admit_policy_oversubscription() - Admission control policy
+ * @mac_ctx: Global MAC Context
+ * @tspec: Pointer to the tspec
+ * @admit_policy: Admission policy
+ * @tspec_info: TSPEC information
+ * @session_entry: Session Entry
+ *
+ * simple admission control policy based on oversubscription
+ * if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then
+ * reject the tspec, else admit it. The phy-bw is the peak available bw in the
+ * current phy mode. The 'factor' is the configured oversubscription factor.
+ *
+ * Return: Status
+ **/
+static tSirRetStatus
+lim_admit_policy_oversubscription(tpAniSirGlobal mac_ctx,
+ tSirMacTspecIE *tspec,
+ tpLimAdmitPolicyInfo admit_policy,
+ tpLimTspecInfo tspec_info,
+ tpPESession session_entry)
+{
+ uint32_t totalbw, minbw, usedbw;
+ uint32_t phy_mode;
+
+ /* determine total bandwidth used so far */
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+ lim_compute_mean_bw_used(mac_ctx, &usedbw, phy_mode,
+ tspec_info, session_entry);
+
+ /* determine how much bw is available based on the current phy mode */
+ lim_get_available_bw(mac_ctx, &totalbw, &minbw, phy_mode,
+ admit_policy->bw_factor);
+
+ if (usedbw > totalbw) /* this can't possibly happen */
+ return eSIR_FAILURE;
+
+ if ((totalbw - usedbw) < tspec->meanDataRate) {
+ lim_log(mac_ctx, ADMIT_CONTROL_POLICY_LOGLEVEL,
+ FL
+ ("Total BW %d, Used %d, Tspec request %d not possible"),
+ totalbw, usedbw, tspec->meanDataRate);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_admit_policy
+ \brief determine the current admit control policy and apply it for the offered tspec
+ \param tpAniSirGlobal pMac
+ \param tSirMacTspecIE *pTspec
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus lim_admit_policy(tpAniSirGlobal pMac,
+ tSirMacTspecIE *pTspec, tpPESession psessionEntry)
+{
+ tSirRetStatus retval = eSIR_FAILURE;
+ tpLimAdmitPolicyInfo pAdmitPolicy = &pMac->lim.admitPolicyInfo;
+
+ switch (pAdmitPolicy->type) {
+ case WNI_CFG_ADMIT_POLICY_ADMIT_ALL:
+ retval = eSIR_SUCCESS;
+ break;
+
+ case WNI_CFG_ADMIT_POLICY_BW_FACTOR:
+ retval = lim_admit_policy_oversubscription(pMac, pTspec,
+ &pMac->lim.
+ admitPolicyInfo,
+ &pMac->lim.tspecInfo[0],
+ psessionEntry);
+ if (retval != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE, FL("rejected by BWFactor policy"));
+ )
+ break;
+
+ case WNI_CFG_ADMIT_POLICY_REJECT_ALL:
+ retval = eSIR_FAILURE;
+ break;
+
+ default:
+ retval = eSIR_SUCCESS;
+ lim_log(pMac, LOGE,
+ FL("Admit Policy %d unknown, admitting all traffic"),
+ pAdmitPolicy->type);
+ break;
+ }
+ return retval;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_tspec_delete
+ \brief delete the specified tspec
+ \param tpAniSirGlobal pMac
+ \param tpLimTspecInfo pInfo
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+/* ----------------------------------------------------------------------------- */
+/* delete the specified tspec */
+void lim_tspec_delete(tpAniSirGlobal pMac, tpLimTspecInfo pInfo)
+{
+ if (pInfo == NULL)
+ return;
+ /* pierre */
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tspec entry = %d"),
+ pInfo->idx);
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL, FL("delete tspec %p"), pInfo);
+ pInfo->inuse = 0;
+
+ return;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_tspec_find_by_sta_addr
+ \brief Send halMsg_AddTs to HAL
+ \param tpAniSirGlobal pMac
+ \param \param uint8_t *pAddr
+ \param tSirMacTspecIE *pTspecIE
+ \param tpLimTspecInfo pTspecList
+ \param tpLimTspecInfo *ppInfo
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+/* find the specified tspec in the list */
+static tSirRetStatus
+lim_tspec_find_by_sta_addr(tpAniSirGlobal pMac,
+ uint8_t *pAddr,
+ tSirMacTspecIE *pTspecIE,
+ tpLimTspecInfo pTspecList, tpLimTspecInfo *ppInfo)
+{
+ int ctspec;
+
+ *ppInfo = NULL;
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) {
+ if ((pTspecList->inuse)
+ &&
+ (cdf_mem_compare
+ (pAddr, pTspecList->staAddr, sizeof(pTspecList->staAddr)))
+ &&
+ (cdf_mem_compare
+ ((uint8_t *) pTspecIE, (uint8_t *) &pTspecList->tspec,
+ sizeof(tSirMacTspecIE)))) {
+ *ppInfo = pTspecList;
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_tspec_find_by_assoc_id
+ \brief find tspec with matchin staid and Tspec
+ \param tpAniSirGlobal pMac
+ \param uint32_t staid
+ \param tSirMacTspecIE *pTspecIE
+ \param tpLimTspecInfo pTspecList
+ \param tpLimTspecInfo *ppInfo
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+lim_tspec_find_by_assoc_id(tpAniSirGlobal pMac,
+ uint16_t assocId,
+ tSirMacTspecIE *pTspecIE,
+ tpLimTspecInfo pTspecList, tpLimTspecInfo *ppInfo)
+{
+ int ctspec;
+
+ *ppInfo = NULL;
+
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("Trying to find tspec entry for assocId = %d"), assocId);
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL
+ ("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d"),
+ pTspecIE->tsinfo.traffic.direction,
+ pTspecIE->tsinfo.traffic.tsid);
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) {
+ if ((pTspecList->inuse)
+ && (assocId == pTspecList->assocId)
+ &&
+ (cdf_mem_compare
+ ((uint8_t *) pTspecIE, (uint8_t *) &pTspecList->tspec,
+ sizeof(tSirMacTspecIE)))) {
+ *ppInfo = pTspecList;
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_find_tspec
+ \brief finding a TSPEC entry with assocId, tsinfo.direction and tsinfo.tsid
+ \param uint16_t assocId
+ \param tpAniSirGlobal pMac
+ \param tSirMacTSInfo *pTsInfo
+ \param tpLimTspecInfo pTspecList
+ \param tpLimTspecInfo *ppInfo
+ \return eSirRetStatus - status of the comparison
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+lim_find_tspec(tpAniSirGlobal pMac,
+ uint16_t assocId,
+ tSirMacTSInfo *pTsInfo,
+ tpLimTspecInfo pTspecList, tpLimTspecInfo *ppInfo)
+{
+ int ctspec;
+
+ *ppInfo = NULL;
+
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("Trying to find tspec entry for assocId = %d"), assocId);
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL
+ ("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d"),
+ pTsInfo->traffic.direction, pTsInfo->traffic.tsid);
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) {
+ if ((pTspecList->inuse)
+ && (assocId == pTspecList->assocId)
+ && (pTsInfo->traffic.direction ==
+ pTspecList->tspec.tsinfo.traffic.direction)
+ && (pTsInfo->traffic.tsid ==
+ pTspecList->tspec.tsinfo.traffic.tsid)) {
+ *ppInfo = pTspecList;
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_tspec_add
+ \brief add or update the specified tspec to the tspec list
+ \param tpAniSirGlobal pMac
+ \param uint8_t *pAddr
+ \param uint16_t assocId
+ \param tSirMacTspecIE *pTspec
+ \param uint32_t interval
+ \param tpLimTspecInfo *ppInfo
+
+ \return eSirRetStatus - status of the comparison
+ -------------------------------------------------------------*/
+
+tSirRetStatus lim_tspec_add(tpAniSirGlobal pMac,
+ uint8_t *pAddr,
+ uint16_t assocId,
+ tSirMacTspecIE *pTspec,
+ uint32_t interval, tpLimTspecInfo *ppInfo)
+{
+ tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0];
+ *ppInfo = NULL;
+
+ /* validate the assocId */
+ if (assocId >= pMac->lim.maxStation) {
+ PELOGE(lim_log(pMac, LOGE, FL("Invalid assocId 0x%x"), assocId);)
+ return eSIR_FAILURE;
+ }
+ /* decide whether to add/update */
+ {
+ *ppInfo = NULL;
+
+ if (eSIR_SUCCESS ==
+ lim_find_tspec(pMac, assocId, &pTspec->tsinfo, pTspecList,
+ ppInfo)) {
+ /* update this entry. */
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("updating TSPEC table entry = %d"),
+ (*ppInfo)->idx);
+ } else {
+ /* We didn't find one to update. So find a free slot in the
+ * LIM TSPEC list and add this new entry
+ */
+ uint8_t ctspec = 0;
+ for (ctspec = 0, pTspecList = &pMac->lim.tspecInfo[0];
+ ctspec < LIM_NUM_TSPEC_MAX;
+ ctspec++, pTspecList++) {
+ if (!pTspecList->inuse) {
+ lim_log(pMac, LOG1,
+ FL
+ ("Found free slot in TSPEC list. Add to TSPEC table entry %d"),
+ ctspec);
+ break;
+ }
+ }
+
+ if (ctspec >= LIM_NUM_TSPEC_MAX)
+ return eSIR_FAILURE;
+
+ /* Record the new index entry */
+ pTspecList->idx = ctspec;
+ }
+ }
+
+ /* update the tspec info */
+ pTspecList->tspec = *pTspec;
+ pTspecList->assocId = assocId;
+ cdf_mem_copy(pTspecList->staAddr, pAddr, sizeof(pTspecList->staAddr));
+
+ /* for edca tspec's, we are all done */
+ if (pTspec->tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
+ pTspecList->inuse = 1;
+ *ppInfo = pTspecList;
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("added entry for EDCA AccessPolicy"));
+ return eSIR_SUCCESS;
+ }
+
+ /*
+ * for hcca tspec's, must set the parameterized bit in the queues
+ * the 'ts' bit in the queue data structure indicates that the queue is
+ * parameterized (hcca). When the schedule is written this bit is used
+ * in the tsid field (bit 3) and the other three bits (0-2) are simply
+ * filled in as the user priority (or qid). This applies only to uplink
+ * polls where the qos control field must contain the tsid specified in the
+ * tspec.
+ */
+ pTspecList->inuse = 1;
+ *ppInfo = pTspecList;
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("added entry for HCCA AccessPolicy"));
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_validate_access_policy
+ \brief Validates Access policy
+ \param tpAniSirGlobal pMac
+ \param uint8_t accessPolicy
+ \param uint16_t assocId
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+static tSirRetStatus
+lim_validate_access_policy(tpAniSirGlobal pMac,
+ uint8_t accessPolicy,
+ uint16_t assocId, tpPESession psessionEntry)
+{
+ tSirRetStatus retval = eSIR_FAILURE;
+ tpDphHashNode pSta =
+ dph_get_hash_entry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+ if ((pSta == NULL) || (!pSta->valid)) {
+ PELOGE(lim_log(pMac, LOGE, FL("invalid station address passed"));)
+ return eSIR_FAILURE;
+ }
+
+ switch (accessPolicy) {
+ case SIR_MAC_ACCESSPOLICY_EDCA:
+ if (pSta->wmeEnabled || pSta->lleEnabled)
+ retval = eSIR_SUCCESS;
+ break;
+
+ case SIR_MAC_ACCESSPOLICY_HCCA:
+ case SIR_MAC_ACCESSPOLICY_BOTH:
+ default:
+ PELOGE(lim_log
+ (pMac, LOGE, FL("Invalid accessPolicy %d"),
+ accessPolicy);
+ )
+ break;
+ }
+
+ if (retval != eSIR_SUCCESS)
+ lim_log(pMac, LOGW,
+ FL
+ ("failed (accPol %d, staId %d, lle %d, wme %d, wsm %d)"),
+ accessPolicy, pSta->staIndex, pSta->lleEnabled,
+ pSta->wmeEnabled, pSta->wsmEnabled);
+
+ return retval;
+}
+
+/**
+ * lim_admit_control_add_ts() - Check if STA can be admitted
+ * @pMac: Global MAC context
+ * @pAddr: Address
+ * @pAddts: ADD TS
+ * @pQos: QOS fields
+ * @assocId: Association ID
+ * @alloc: Allocate bandwidth for this tspec
+ * @pSch: Schedule IE
+ * @pTspecIdx: TSPEC index
+ * @psessionEntry: PE Session Entry
+ *
+ * Determine if STA with the specified TSPEC can be admitted. If it can,
+ * a schedule element is provided
+ *
+ * Return: status
+ **/
+tSirRetStatus lim_admit_control_add_ts(tpAniSirGlobal pMac, uint8_t *pAddr,
+ tSirAddtsReqInfo *pAddts, tSirMacQosCapabilityStaIE *pQos,
+ uint16_t assocId, uint8_t alloc, tSirMacScheduleIE *pSch,
+ uint8_t *pTspecIdx, tpPESession psessionEntry)
+{
+ tpLimTspecInfo pTspecInfo;
+ tSirRetStatus retval;
+ uint32_t svcInterval;
+ (void)pQos;
+
+ /* TBD: modify tspec as needed */
+ /* EDCA: need to fill in the medium time and the minimum phy rate */
+ /* to be consistent with the desired traffic parameters. */
+
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL
+ ("tsid %d, directn %d, start %d, intvl %d, accPolicy %d, up %d"),
+ pAddts->tspec.tsinfo.traffic.tsid,
+ pAddts->tspec.tsinfo.traffic.direction,
+ pAddts->tspec.svcStartTime, pAddts->tspec.minSvcInterval,
+ pAddts->tspec.tsinfo.traffic.accessPolicy,
+ pAddts->tspec.tsinfo.traffic.userPrio);
+
+ /* check for duplicate tspec */
+ retval = (alloc)
+ ? lim_tspec_find_by_assoc_id(pMac, assocId, &pAddts->tspec,
+ &pMac->lim.tspecInfo[0], &pTspecInfo)
+ : lim_tspec_find_by_sta_addr(pMac, pAddr, &pAddts->tspec,
+ &pMac->lim.tspecInfo[0], &pTspecInfo);
+
+ if (retval == eSIR_SUCCESS) {
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("duplicate tspec (index %d)!"), pTspecInfo->idx);
+ return eSIR_FAILURE;
+ }
+ /* check that the tspec's are well formed and acceptable */
+ if (lim_validate_tspec(pMac, &pAddts->tspec, psessionEntry) !=
+ eSIR_SUCCESS) {
+ PELOGW(lim_log(pMac, LOGW, FL("tspec validation failed"));)
+ return eSIR_FAILURE;
+ }
+ /* determine a service interval for the tspec */
+ if (lim_calculate_svc_int(pMac, &pAddts->tspec, &svcInterval) !=
+ eSIR_SUCCESS) {
+ PELOGW(lim_log(pMac, LOGW, FL("SvcInt calculate failed"));)
+ return eSIR_FAILURE;
+ }
+ /* determine if the tspec can be admitted or not based on current policy */
+ if (lim_admit_policy(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("tspec rejected by admit control policy"));
+ )
+ return eSIR_FAILURE;
+ }
+ /* fill in a schedule if requested */
+ if (pSch != NULL) {
+ cdf_mem_set((uint8_t *) pSch, sizeof(*pSch), 0);
+ pSch->svcStartTime = pAddts->tspec.svcStartTime;
+ pSch->svcInterval = svcInterval;
+ pSch->maxSvcDuration = (uint16_t) pSch->svcInterval; /* use SP = SI */
+ pSch->specInterval = 0x1000; /* fixed for now: TBD */
+
+ pSch->info.direction = pAddts->tspec.tsinfo.traffic.direction;
+ pSch->info.tsid = pAddts->tspec.tsinfo.traffic.tsid;
+ pSch->info.aggregation = 0; /* no support for aggregation for now: TBD */
+ }
+ /* if no allocation is requested, done */
+ if (!alloc)
+ return eSIR_SUCCESS;
+
+ /* check that we are in the proper mode to deal with the tspec type */
+ if (lim_validate_access_policy
+ (pMac, (uint8_t) pAddts->tspec.tsinfo.traffic.accessPolicy, assocId,
+ psessionEntry) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGW,
+ FL("AccessPolicy %d is not valid in current mode"),
+ pAddts->tspec.tsinfo.traffic.accessPolicy);
+ return eSIR_FAILURE;
+ }
+ /* add tspec to list */
+ if (lim_tspec_add
+ (pMac, pAddr, assocId, &pAddts->tspec, svcInterval, &pTspecInfo)
+ != eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("no space in tspec list"));)
+ return eSIR_FAILURE;
+ }
+ /* passing lim tspec table index to the caller */
+ *pTspecIdx = pTspecInfo->idx;
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_admit_control_delete_ts
+ \brief Delete the specified Tspec for the specified STA
+ \param tpAniSirGlobal pMac
+ \param uint16_t assocId
+ \param tSirMacTSInfo *pTsInfo
+ \param uint8_t *pTsStatus
+ \param uint8_t *ptspecIdx
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+lim_admit_control_delete_ts(tpAniSirGlobal pMac,
+ uint16_t assocId,
+ tSirMacTSInfo *pTsInfo,
+ uint8_t *pTsStatus, uint8_t *ptspecIdx)
+{
+ tpLimTspecInfo pTspecInfo = NULL;
+
+ if (pTsStatus != NULL)
+ *pTsStatus = 0;
+
+ if (lim_find_tspec
+ (pMac, assocId, pTsInfo, &pMac->lim.tspecInfo[0],
+ &pTspecInfo) == eSIR_SUCCESS) {
+ if (pTspecInfo != NULL) {
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("Tspec entry %d found"), pTspecInfo->idx);
+
+ *ptspecIdx = pTspecInfo->idx;
+ lim_tspec_delete(pMac, pTspecInfo);
+ return eSIR_SUCCESS;
+ }
+ }
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_admit_control_delete_sta
+ \brief Delete all TSPEC for the specified STA
+ \param tpAniSirGlobal pMac
+ \param uint16_t assocId
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus lim_admit_control_delete_sta(tpAniSirGlobal pMac, uint16_t assocId)
+{
+ tpLimTspecInfo pTspecInfo = &pMac->lim.tspecInfo[0];
+ int ctspec;
+
+ for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) {
+ if (assocId == pTspecInfo->assocId) {
+ lim_tspec_delete(pMac, pTspecInfo);
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL,
+ FL("Deleting TSPEC %d for assocId %d"), ctspec,
+ assocId);
+ }
+ }
+ lim_log(pMac, ADMIT_CONTROL_LOGLEVEL, FL("assocId %d done"), assocId);
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_admit_control_init
+ \brief init tspec table
+ \param tpAniSirGlobal pMac
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+tSirRetStatus lim_admit_control_init(tpAniSirGlobal pMac)
+{
+ cdf_mem_set(pMac->lim.tspecInfo,
+ LIM_NUM_TSPEC_MAX * sizeof(tLimTspecInfo), 0);
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_update_admit_policy
+ \brief Set the admit control policy based on CFG parameters
+ \param tpAniSirGlobal pMac
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus lim_update_admit_policy(tpAniSirGlobal pMac)
+{
+ uint32_t val;
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ADMIT_POLICY, &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("Unable to get CFG_ADMIT_POLICY"));
+ return eSIR_FAILURE;
+ }
+ pMac->lim.admitPolicyInfo.type = (uint8_t) val;
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ADMIT_BWFACTOR, &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("Unable to get CFG_ADMIT_BWFACTOR"));
+ return eSIR_FAILURE;
+ }
+ pMac->lim.admitPolicyInfo.bw_factor = (uint8_t) val;
+
+ PELOG1(lim_log(pMac, LOG1, FL("LIM: AdmitPolicy %d, bw_factor %d"),
+ pMac->lim.admitPolicyInfo.type,
+ pMac->lim.admitPolicyInfo.bw_factor);
+ )
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_send_hal_msg_add_ts
+ \brief Send halMsg_AddTs to HAL
+ \param tpAniSirGlobal pMac
+ \param uint16_t staIdx
+ \param uint8_t tspecIdx
+ \param tSirMacTspecIE tspecIE
+ \param tSirTclasInfo *tclasInfo
+ \param uint8_t tclasProc
+ \param uint16_t tsm_interval
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+#ifdef FEATURE_WLAN_ESE
+tSirRetStatus
+lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+ uint16_t staIdx,
+ uint8_t tspecIdx,
+ tSirMacTspecIE tspecIE,
+ uint8_t sessionId, uint16_t tsm_interval)
+#else
+tSirRetStatus
+lim_send_hal_msg_add_ts(tpAniSirGlobal pMac,
+ uint16_t staIdx,
+ uint8_t tspecIdx, tSirMacTspecIE tspecIE, uint8_t sessionId)
+#endif
+{
+ tSirMsgQ msg;
+ tpAddTsParams pAddTsParam;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ tpPESession psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Unable to get Session for session Id %d"),
+ sessionId);
+ return eSIR_FAILURE;
+ }
+#endif
+ pAddTsParam = cdf_mem_malloc(sizeof(tAddTsParams));
+ if (NULL == pAddTsParam) {
+ PELOGW(lim_log(pMac, LOGW, FL("AllocateMemory() failed"));)
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set((uint8_t *) pAddTsParam, sizeof(tAddTsParams), 0);
+ pAddTsParam->staIdx = staIdx;
+ pAddTsParam->tspecIdx = tspecIdx;
+ cdf_mem_copy(&pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE));
+ pAddTsParam->sessionId = sessionId;
+ pAddTsParam->sme_session_id = psessionEntry->smeSessionId;
+
+#ifdef FEATURE_WLAN_ESE
+ pAddTsParam->tsm_interval = tsm_interval;
+#endif
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (pMac->roam.configParam.isRoamOffloadEnabled &&
+ psessionEntry->is11Rconnection)
+ pAddTsParam->setRICparams = 1;
+#endif
+
+ msg.type = WMA_ADD_TS_REQ;
+ msg.bodyptr = pAddTsParam;
+ msg.bodyval = 0;
+
+ /* We need to defer any incoming messages until we get a
+ * WMA_ADD_TS_RSP from HAL.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(mac_trace_msg_tx(pMac, sessionId, msg.type));
+
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+ lim_log(pMac, LOGW, FL("wma_post_ctrl_msg() failed"));
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ cdf_mem_free(pAddTsParam);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_send_hal_msg_del_ts
+ \brief Send halMsg_AddTs to HAL
+ \param tpAniSirGlobal pMac
+ \param uint16_t staIdx
+ \param uint8_t tspecIdx
+ \param tSirAddtsReqInfo addts
+ \return eSirRetStatus - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus
+lim_send_hal_msg_del_ts(tpAniSirGlobal pMac,
+ uint16_t staIdx,
+ uint8_t tspecIdx,
+ tSirDeltsReqInfo delts, uint8_t sessionId, uint8_t *bssId)
+{
+ tSirMsgQ msg;
+ tpDelTsParams pDelTsParam;
+ tpPESession psessionEntry = NULL;
+
+ pDelTsParam = cdf_mem_malloc(sizeof(tDelTsParams));
+ if (NULL == pDelTsParam) {
+ lim_log(pMac, LOGP, FL("AllocateMemory() failed"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ msg.type = WMA_DEL_TS_REQ;
+ msg.bodyptr = pDelTsParam;
+ msg.bodyval = 0;
+ cdf_mem_set((uint8_t *) pDelTsParam, sizeof(tDelTsParams), 0);
+
+ /* filling message parameters. */
+ pDelTsParam->staIdx = staIdx;
+ pDelTsParam->tspecIdx = tspecIdx;
+ cdf_mem_copy(&pDelTsParam->bssId, bssId, sizeof(tSirMacAddr));
+
+ psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("Session does Not exist with given sessionId :%d "),
+ sessionId);
+ )
+ goto err;
+ }
+ pDelTsParam->sessionId = psessionEntry->smeSessionId;
+ pDelTsParam->userPrio = delts.wmeTspecPresent ?
+ delts.tspec.tsinfo.traffic.userPrio :
+ delts.tsinfo.traffic.userPrio;
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (pMac->roam.configParam.isRoamOffloadEnabled &&
+ psessionEntry->is11Rconnection) {
+ cdf_mem_copy(&pDelTsParam->delTsInfo, &delts,
+ sizeof(tSirDeltsReqInfo));
+ pDelTsParam->setRICparams = 1;
+ }
+#endif
+
+ lim_log(pMac, LOGW, FL("calling wma_post_ctrl_msg()"));
+ MTRACE(mac_trace_msg_tx(pMac, sessionId, msg.type));
+
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+ lim_log(pMac, LOGW, FL("wma_post_ctrl_msg() failed"));
+ goto err;
+ }
+ return eSIR_SUCCESS;
+
+err:
+ cdf_mem_free(pDelTsParam);
+ return eSIR_FAILURE;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_process_hal_add_ts_rsp
+ \brief This function process the WMA_ADD_TS_RSP from HAL.
+ \ If response is successful, then send back SME_ADDTS_RSP.
+ \ Otherwise, send DELTS action frame to peer and then
+ \ then send back SME_ADDTS_RSP.
+ \
+ \param tpAniSirGlobal pMac
+ \param tpSirMsgQ limMsg
+ -------------------------------------------------------------*/
+void lim_process_hal_add_ts_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpAddTsParams pAddTsRspMsg = NULL;
+ tpDphHashNode pSta = NULL;
+ uint16_t assocId = 0;
+ tSirMacAddr peerMacAddr;
+ uint8_t rspReqd = 1;
+ tpPESession psessionEntry = NULL;
+
+ /* Need to process all the deferred messages enqueued
+ * since sending the WMA_ADD_TS_REQ.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+ if (NULL == limMsg->bodyptr) {
+ lim_log(pMac, LOGP, FL("Received WMA_ADD_TS_RSP with NULL "));
+ goto end;
+ }
+
+ pAddTsRspMsg = (tpAddTsParams) (limMsg->bodyptr);
+
+ /* 090803: Use pe_find_session_by_session_id() to obtain the PE session context */
+ /* from the sessionId in the Rsp Msg from HAL */
+ psessionEntry = pe_find_session_by_session_id(pMac, pAddTsRspMsg->sessionId);
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Session does Not exist with given sessionId :%d "),
+ pAddTsRspMsg->sessionId);
+ )
+ lim_send_sme_addts_rsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED,
+ psessionEntry, pAddTsRspMsg->tspec,
+ pMac->lim.gLimAddtsReq.sessionId,
+ pMac->lim.gLimAddtsReq.transactionId);
+ goto end;
+ }
+
+ if (pAddTsRspMsg->status == CDF_STATUS_SUCCESS) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Received successful ADDTS response from HAL "));
+ )
+ /* Use the smesessionId and smetransactionId from the PE session context */
+ lim_send_sme_addts_rsp(pMac, rspReqd, eSIR_SME_SUCCESS,
+ psessionEntry, pAddTsRspMsg->tspec,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+ goto end;
+ } else {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Received failure ADDTS response from HAL "));
+ )
+ /* Send DELTS action frame to AP */
+ /* 090803: Get peer MAC addr from session */
+ sir_copy_mac_addr(peerMacAddr, psessionEntry->bssId);
+
+ /* 090803: Add the SME Session ID */
+ lim_send_delts_req_action_frame(pMac, peerMacAddr, rspReqd,
+ &pAddTsRspMsg->tspec.tsinfo,
+ &pAddTsRspMsg->tspec, psessionEntry);
+
+ /* Delete TSPEC */
+ /* 090803: Pull the hash table from the session */
+ pSta = dph_lookup_assoc_id(pMac, pAddTsRspMsg->staIdx, &assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta != NULL)
+ lim_admit_control_delete_ts(pMac, assocId,
+ &pAddTsRspMsg->tspec.tsinfo,
+ NULL,
+ (uint8_t *) &pAddTsRspMsg->
+ tspecIdx);
+
+ /* Send SME_ADDTS_RSP */
+ /* 090803: Use the smesessionId and smetransactionId from the PE session context */
+ lim_send_sme_addts_rsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED,
+ psessionEntry, pAddTsRspMsg->tspec,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+ goto end;
+ }
+
+end:
+ if (pAddTsRspMsg != NULL)
+ cdf_mem_free(pAddTsRspMsg);
+ return;
+}
diff --git a/core/mac/src/pe/lim/lim_aid_mgmt.c b/core/mac/src/pe/lim/lim_aid_mgmt.c
new file mode 100644
index 0000000..253543d
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_aid_mgmt.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_aid_mgmt.c contains the functions related to
+ * AID pool management like initialization, assignment etc.
+ * Author: Chandra Modumudi
+ * Date: 03/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "sir_params.h"
+#include "lim_utils.h"
+#include "lim_timer_utils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "lim_session_utils.h"
+
+#define LIM_START_PEER_IDX 1
+
+/**
+ * lim_init_peer_idxpool()
+ *
+ ***FUNCTION:
+ * This function is called while starting a BSS at AP
+ * to initialize AID pool. This may also be called while
+ * starting/joining an IBSS if 'Association' is allowed
+ * in IBSS.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_init_peer_idxpool(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+ uint8_t i;
+ uint8_t maxAssocSta = pMac->lim.gLimAssocStaLimit;
+
+ pSessionEntry->gpLimPeerIdxpool[0] = 0;
+
+#ifdef FEATURE_WLAN_TDLS
+ /* In station role, DPH_STA_HASH_INDEX_PEER (index 1) is reserved for peer */
+ /* station index corresponding to AP. Avoid choosing that index and get index */
+ /* starting from (DPH_STA_HASH_INDEX_PEER + 1) (index 2) for TDLS stations; */
+ if (LIM_IS_STA_ROLE(pSessionEntry)) {
+ pSessionEntry->freePeerIdxHead = DPH_STA_HASH_INDEX_PEER + 1;
+ } else
+#endif
+#ifdef QCA_IBSS_SUPPORT
+ if (LIM_IS_IBSS_ROLE(pSessionEntry)) {
+ pSessionEntry->freePeerIdxHead = LIM_START_PEER_IDX;
+ maxAssocSta = pMac->lim.gLimIbssStaLimit;
+ } else
+#endif
+ {
+ pSessionEntry->freePeerIdxHead = LIM_START_PEER_IDX;
+ }
+
+ for (i = pSessionEntry->freePeerIdxHead; i < maxAssocSta; i++) {
+ pSessionEntry->gpLimPeerIdxpool[i] = i + 1;
+ }
+ pSessionEntry->gpLimPeerIdxpool[i] = 0;
+
+ pSessionEntry->freePeerIdxTail = i;
+
+}
+
+/**
+ * lim_assign_peer_idx()
+ *
+ ***FUNCTION:
+ * This function is called to get a peer station index. This index is
+ * used during Association/Reassociation
+ * frame handling to assign association ID (aid) to a STA.
+ * In case of TDLS, this is used to assign a index into the Dph hash entry.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return peerIdx - assigned peer Station IDx for STA
+ */
+
+uint16_t lim_assign_peer_idx(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+ uint16_t peerId;
+
+ /* make sure we haven't exceeded the configurable limit on associations */
+ /* This count is global to ensure that it doesnt exceed the hardware limits. */
+ if (pe_get_current_stas_count(pMac) >= pMac->lim.gLimAssocStaLimit) {
+ /* too many associations already active */
+ return 0;
+ }
+
+ /* return head of free list */
+
+ if (pSessionEntry->freePeerIdxHead) {
+ peerId = pSessionEntry->freePeerIdxHead;
+ pSessionEntry->freePeerIdxHead =
+ pSessionEntry->gpLimPeerIdxpool[pSessionEntry->
+ freePeerIdxHead];
+ if (pSessionEntry->freePeerIdxHead == 0)
+ pSessionEntry->freePeerIdxTail = 0;
+ pSessionEntry->gLimNumOfCurrentSTAs++;
+ return peerId;
+ }
+
+ return 0; /* no more free peer index */
+}
+
+/**
+ * lim_release_peer_idx()
+ *
+ ***FUNCTION:
+ * This function is called when a STA context is removed
+ * at AP (or at a STA in IBSS mode or TDLS) to return peer Index
+ * to free pool.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param peerIdx - peer station index that need to return to free pool
+ *
+ * @return None
+ */
+
+void
+lim_release_peer_idx(tpAniSirGlobal pMac, uint16_t peerIdx,
+ tpPESession pSessionEntry)
+{
+ pSessionEntry->gLimNumOfCurrentSTAs--;
+
+ /* insert at tail of free list */
+ if (pSessionEntry->freePeerIdxTail) {
+ pSessionEntry->gpLimPeerIdxpool[pSessionEntry->
+ freePeerIdxTail] =
+ (uint8_t) peerIdx;
+ pSessionEntry->freePeerIdxTail = (uint8_t) peerIdx;
+ } else {
+ pSessionEntry->freePeerIdxTail =
+ pSessionEntry->freePeerIdxHead = (uint8_t) peerIdx;
+ }
+ pSessionEntry->gpLimPeerIdxpool[(uint8_t) peerIdx] = 0;
+}
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
new file mode 100644
index 0000000..1d0dc07
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -0,0 +1,2202 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_api.cc contains the functions that are
+ * exported by LIM to other modules.
+ *
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "wni_api.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_api.h"
+#include "lim_global.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_admit_control.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "wmm_apsd.h"
+#include "lim_trace.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "wma_types.h"
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+#include <lim_ft.h>
+#include "cdf_types.h"
+#include "cds_packet.h"
+#include "cds_utils.h"
+#include "sys_startup.h"
+
+static void __lim_init_scan_vars(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimUseScanModeForLearnMode = 1;
+
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+
+ /* Scan related globals on STA */
+ pMac->lim.gLimReturnAfterFirstMatch = 0;
+ pMac->lim.gLim24Band11dScanDone = 0;
+ pMac->lim.gLim50Band11dScanDone = 0;
+ pMac->lim.gLimReturnUniqueResults = 0;
+
+ pMac->lim.gLimCurrentScanChannelId = 0;
+ pMac->lim.gpLimMlmScanReq = NULL;
+ pMac->lim.gDeferMsgTypeForNOA = 0;
+ pMac->lim.gpDefdSmeMsgForNOA = NULL;
+
+ pMac->lim.gLimRestoreCBNumScanInterval =
+ LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT;
+ pMac->lim.gLimRestoreCBCount = 0;
+ cdf_mem_set(pMac->lim.gLimLegacyBssidList,
+ sizeof(pMac->lim.gLimLegacyBssidList), 0);
+
+ /* Fill in default values */
+
+ /* abort scan is used to abort an on-going scan */
+ pMac->lim.abortScan = 0;
+ cdf_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0);
+ cdf_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);
+
+/* WLAN_SUSPEND_LINK Related */
+ pMac->lim.gpLimSuspendCallback = NULL;
+ pMac->lim.gpLimResumeCallback = NULL;
+/* end WLAN_SUSPEND_LINK Related */
+}
+
+static void __lim_init_bss_vars(tpAniSirGlobal pMac)
+{
+ cdf_mem_set((void *)pMac->lim.gpSession,
+ sizeof(*pMac->lim.gpSession) * pMac->lim.maxBssId, 0);
+
+ /* This is for testing purposes only, be default should always be off */
+ pMac->lim.gLimForceNoPropIE = 0;
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+}
+
+static void __lim_init_stats_vars(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimNumBeaconsRcvd = 0;
+ pMac->lim.gLimNumBeaconsIgnored = 0;
+
+ pMac->lim.gLimNumDeferredMsgs = 0;
+
+ /* / Variable to keep track of number of currently associated STAs */
+ pMac->lim.gLimNumOfAniSTAs = 0; /* count of ANI peers */
+
+ /* Heart-Beat interval value */
+ pMac->lim.gLimHeartBeatCount = 0;
+
+ cdf_mem_zero(pMac->lim.gLimHeartBeatApMac[0],
+ sizeof(tSirMacAddr));
+ cdf_mem_zero(pMac->lim.gLimHeartBeatApMac[1],
+ sizeof(tSirMacAddr));
+ pMac->lim.gLimHeartBeatApMacIndex = 0;
+
+ /* Statistics to keep track of no. beacons rcvd in heart beat interval */
+ cdf_mem_set(pMac->lim.gLimHeartBeatBeaconStats,
+ sizeof(pMac->lim.gLimHeartBeatBeaconStats), 0);
+
+#ifdef WLAN_DEBUG
+ /* Debug counters */
+ pMac->lim.numTot = 0;
+ pMac->lim.numBbt = 0;
+ pMac->lim.numProtErr = 0;
+ pMac->lim.numLearn = 0;
+ pMac->lim.numLearnIgnore = 0;
+ pMac->lim.numSme = 0;
+ cdf_mem_set(pMac->lim.numMAC, sizeof(pMac->lim.numMAC), 0);
+ pMac->lim.gLimNumAssocReqDropInvldState = 0;
+ pMac->lim.gLimNumAssocReqDropACRejectTS = 0;
+ pMac->lim.gLimNumAssocReqDropACRejectSta = 0;
+ pMac->lim.gLimNumReassocReqDropInvldState = 0;
+ pMac->lim.gLimNumHashMissIgnored = 0;
+ pMac->lim.gLimUnexpBcnCnt = 0;
+ pMac->lim.gLimBcnSSIDMismatchCnt = 0;
+ pMac->lim.gLimNumLinkEsts = 0;
+ pMac->lim.gLimNumRxCleanup = 0;
+ pMac->lim.gLim11bStaAssocRejectCount = 0;
+#endif
+}
+
+static void __lim_init_states(tpAniSirGlobal pMac)
+{
+ /* Counts Heartbeat failures */
+ pMac->lim.gLimHBfailureCntInLinkEstState = 0;
+ pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0;
+ pMac->lim.gLimHBfailureCntInOtherStates = 0;
+ pMac->lim.gLimRspReqd = 0;
+ pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE;
+
+ /* / MLM State visible across all Sirius modules */
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, NO_SESSION, eLIM_MLM_IDLE_STATE));
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+
+ /* / Previous MLM State */
+ pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE;
+
+ /* LIM to HAL SCAN Management Message Interface states */
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+
+ /**
+ * Initialize state to eLIM_SME_OFFLINE_STATE
+ */
+ pMac->lim.gLimSmeState = eLIM_SME_OFFLINE_STATE;
+
+ /**
+ * By default assume 'unknown' role. This will be updated
+ * when SME_START_BSS_REQ is received.
+ */
+
+ cdf_mem_set(&pMac->lim.gLimOverlap11gParams, sizeof(tLimProtStaParams),
+ 0);
+ cdf_mem_set(&pMac->lim.gLimOverlap11aParams, sizeof(tLimProtStaParams),
+ 0);
+ cdf_mem_set(&pMac->lim.gLimOverlapHt20Params, sizeof(tLimProtStaParams),
+ 0);
+ cdf_mem_set(&pMac->lim.gLimOverlapNonGfParams,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set(&pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams), 0);
+ cdf_mem_set(&pMac->lim.gLimNoShortSlotParams,
+ sizeof(tLimNoShortSlotParams), 0);
+
+ pMac->lim.gLimPhyMode = 0;
+ pMac->lim.scanStartTime = 0; /* used to measure scan time */
+
+ cdf_mem_set(pMac->lim.gLimMyMacAddr, sizeof(pMac->lim.gLimMyMacAddr),
+ 0);
+ pMac->lim.ackPolicy = 0;
+
+ pMac->lim.gLimProbeRespDisableFlag = 0; /* control over probe resp */
+}
+
+static void __lim_init_vars(tpAniSirGlobal pMac)
+{
+ /* Place holder for Measurement Req/Rsp/Ind related info */
+
+
+ /* Deferred Queue Paramters */
+ cdf_mem_set(&pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq), 0);
+
+ /* addts request if any - only one can be outstanding at any time */
+ cdf_mem_set(&pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq), 0);
+ pMac->lim.gLimAddtsSent = 0;
+ pMac->lim.gLimAddtsRspTimerCount = 0;
+
+ /* protection related config cache */
+ cdf_mem_set(&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0);
+ pMac->lim.gLimProtectionControl = 0;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+ /* WMM Related Flag */
+ pMac->lim.gUapsdEnable = 0;
+ pMac->lim.gUapsdPerAcBitmask = 0;
+
+ /* QoS-AC Downgrade: Initially, no AC is admitted */
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0;
+ pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0;
+
+ /* dialogue token List head/tail for Action frames request sent. */
+ pMac->lim.pDialogueTokenHead = NULL;
+ pMac->lim.pDialogueTokenTail = NULL;
+
+ cdf_mem_set(&pMac->lim.tspecInfo,
+ sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX, 0);
+
+ /* admission control policy information */
+ cdf_mem_set(&pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo), 0);
+
+ pMac->lim.gLastBeaconDtimCount = 0;
+ pMac->lim.gLastBeaconDtimPeriod = 0;
+
+ /* Scan in Power Save Flag */
+ pMac->lim.gScanInPowersave = 0;
+ pMac->lim.probeCounter = 0;
+ pMac->lim.maxProbe = 0;
+}
+
+static void __lim_init_assoc_vars(tpAniSirGlobal pMac)
+{
+ uint32_t val;
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val)
+ != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get assoc sta limit failed"));
+ pMac->lim.gLimAssocStaLimit = val;
+ pMac->lim.gLimIbssStaLimit = val;
+ /* Place holder for current authentication request */
+ /* being handled */
+ pMac->lim.gpLimMlmAuthReq = NULL;
+
+ /* / MAC level Pre-authentication related globals */
+ pMac->lim.gLimPreAuthChannelNumber = 0;
+ pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM;
+ cdf_mem_set(&pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr), 0);
+ pMac->lim.gLimNumPreAuthContexts = 0;
+ cdf_mem_set(&pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable),
+ 0);
+
+ /* Placed holder to deauth reason */
+ pMac->lim.gLimDeauthReasonCode = 0;
+
+ /* Place holder for Pre-authentication node list */
+ pMac->lim.pLimPreAuthList = NULL;
+
+ /* Send Disassociate frame threshold parameters */
+ pMac->lim.gLimDisassocFrameThreshold =
+ LIM_SEND_DISASSOC_FRAME_THRESHOLD;
+ pMac->lim.gLimDisassocFrameCredit = 0;
+
+ /* One cache for each overlap and associated case. */
+ cdf_mem_set(pMac->lim.protStaOverlapCache,
+ sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE, 0);
+ cdf_mem_set(pMac->lim.protStaCache,
+ sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE, 0);
+
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ pMac->lim.pSessionEntry = NULL;
+ pMac->lim.reAssocRetryAttempt = 0;
+#endif
+
+}
+
+static void __lim_init_ht_vars(tpAniSirGlobal pMac)
+{
+ pMac->lim.htCapabilityPresentInBeacon = 0;
+ pMac->lim.gHTGreenfield = 0;
+ pMac->lim.gHTShortGI40Mhz = 0;
+ pMac->lim.gHTShortGI20Mhz = 0;
+ pMac->lim.gHTMaxAmsduLength = 0;
+ pMac->lim.gHTDsssCckRate40MHzSupport = 0;
+ pMac->lim.gHTPSMPSupport = 0;
+ pMac->lim.gHTLsigTXOPProtection = 0;
+ pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC;
+ pMac->lim.gHTAMpduDensity = 0;
+
+ pMac->lim.gMaxAmsduSizeEnabled = false;
+ pMac->lim.gHTMaxRxAMpduFactor = 0;
+ pMac->lim.gHTServiceIntervalGranularity = 0;
+ pMac->lim.gHTControlledAccessOnly = 0;
+ pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ pMac->lim.gHTPCOActive = 0;
+
+ pMac->lim.gHTPCOPhase = 0;
+ pMac->lim.gHTSecondaryBeacon = 0;
+ pMac->lim.gHTDualCTSProtection = 0;
+ pMac->lim.gHTSTBCBasicMCS = 0;
+}
+
+static tSirRetStatus __lim_init_config(tpAniSirGlobal pMac)
+{
+ uint32_t val1, val2, val3;
+ uint16_t val16;
+ uint8_t val8;
+ tSirMacHTCapabilityInfo *pHTCapabilityInfo;
+ tSirMacHTInfoField1 *pHTInfoField1;
+ tSirMacHTParametersInfo *pAmpduParamInfo;
+
+ /* Read all the CFGs here that were updated before pe_start is called */
+ /* All these CFG READS/WRITES are only allowed in init, at start when there is no session
+ * and they will be used throughout when there is no session
+ */
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("could not retrieve HT Cap CFG"));)
+ return eSIR_FAILURE;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve Channel Bonding CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+
+ /* channel bonding mode could be set to anything from 0 to 4(Titan had these */
+ /* modes But for Taurus we have only two modes: enable(>0) or disable(=0) */
+ pHTCapabilityInfo->supportedChannelWidthSet = val2 ?
+ WNI_CFG_CHANNEL_BONDING_MODE_ENABLE :
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO, *(uint16_t *) pHTCapabilityInfo)
+ != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not update HT Cap Info CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT INFO Field1 CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ val8 = (uint8_t) val1;
+ pHTInfoField1 = (tSirMacHTInfoField1 *) &val8;
+ pHTInfoField1->recommendedTxWidthSet =
+ (uint8_t) pHTCapabilityInfo->supportedChannelWidthSet;
+ if (cfg_set_int(pMac, WNI_CFG_HT_INFO_FIELD1, *(uint8_t *) pHTInfoField1)
+ != eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("could not update HT Info Field"));)
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_HEART_BEAT_THRESHOLD */
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+ if (!val1) {
+ pMac->sys.gSysEnableLinkMonitorMode = 0;
+ } else {
+ /* No need to activate the timer during init time. */
+ pMac->sys.gSysEnableLinkMonitorMode = 1;
+ }
+
+ /* WNI_CFG_SHORT_GI_20MHZ */
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("could not retrieve HT Cap CFG"));)
+ return eSIR_FAILURE;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_40MHZ, &val3) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+ pHTCapabilityInfo->shortGI20MHz = (uint16_t) val2;
+ pHTCapabilityInfo->shortGI40MHz = (uint16_t) val3;
+
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO,
+ *(uint16_t *) pHTCapabilityInfo) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not update HT Cap Info CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_MAX_RX_AMPDU_FACTOR */
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT AMPDU Param CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not retrieve AMPDU Factor CFG"));
+ )
+ return eSIR_FAILURE;
+ }
+ val16 = (uint16_t) val1;
+ pAmpduParamInfo = (tSirMacHTParametersInfo *) &val16;
+ pAmpduParamInfo->maxRxAMPDUFactor = (uint8_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_AMPDU_PARAMS,
+ *(uint8_t *) pAmpduParamInfo) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, FL("cfg get short preamble failed"));
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_SHORT_PREAMBLE - this one is not updated in
+ lim_handle_cf_gparam_update do we want to update this? */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val1) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("cfg get short preamble failed"));
+ return eSIR_FAILURE;
+ }
+
+ /* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */
+
+ /* This was initially done after resume notification from HAL. Now, DAL is
+ started before PE so this can be done here */
+ handle_ht_capabilityand_ht_info(pMac, NULL);
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,
+ (uint32_t *) &pMac->lim.disableLDPCWithTxbfAP)) {
+ lim_log(pMac, LOGP, FL("cfg get disableLDPCWithTxbfAP failed"));
+ return eSIR_FAILURE;
+ }
+#ifdef FEATURE_WLAN_TDLS
+ if (eSIR_SUCCESS != wlan_cfg_get_int(pMac, WNI_CFG_TDLS_BUF_STA_ENABLED,
+ (uint32_t *) &pMac->lim.
+ gLimTDLSBufStaEnabled)) {
+ lim_log(pMac, LOGP, FL("cfg get LimTDLSBufStaEnabled failed"));
+ return eSIR_FAILURE;
+ }
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK,
+ (uint32_t *) &pMac->lim.gLimTDLSUapsdMask)) {
+ lim_log(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed"));
+ return eSIR_FAILURE;
+ }
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED,
+ (uint32_t *) &pMac->lim.
+ gLimTDLSOffChannelEnabled)) {
+ lim_log(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed"));
+ return eSIR_FAILURE;
+ }
+
+ if (eSIR_SUCCESS != wlan_cfg_get_int(pMac, WNI_CFG_TDLS_WMM_MODE_ENABLED,
+ (uint32_t *) &pMac->lim.
+ gLimTDLSWmmMode)) {
+ lim_log(pMac, LOGP, FL("cfg get LimTDLSWmmMode failed"));
+ return eSIR_FAILURE;
+ }
+#endif
+ return eSIR_SUCCESS;
+}
+
+/*
+ lim_start
+ This function is to replace the __lim_process_sme_start_req since there is no
+ eWNI_SME_START_REQ post to PE.
+ */
+tSirRetStatus lim_start(tpAniSirGlobal pMac)
+{
+ tSirResultCodes retCode = eSIR_SUCCESS;
+
+ PELOG1(lim_log(pMac, LOG1, FL(" enter"));)
+
+ if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) {
+ pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, NO_SESSION,
+ pMac->lim.gLimSmeState));
+
+ /* By default do not return after first scan match */
+ pMac->lim.gLimReturnAfterFirstMatch = 0;
+
+ /* Initialize MLM state machine */
+ lim_init_mlm(pMac);
+
+ /* By default return unique scan results */
+ pMac->lim.gLimReturnUniqueResults = true;
+ } else {
+ /**
+ * Should not have received eWNI_SME_START_REQ in states
+ * other than OFFLINE. Return response to host and
+ * log error
+ */
+ lim_log(pMac, LOGE, FL("Invalid SME state %X"),
+ pMac->lim.gLimSmeState);
+ retCode = eSIR_FAILURE;
+ }
+
+ return retCode;
+}
+
+/**
+ * lim_initialize()
+ *
+ ***FUNCTION:
+ * This function is called from LIM thread entry function.
+ * LIM related global data structures are initialized in this function.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @return None
+ */
+
+tSirRetStatus lim_initialize(tpAniSirGlobal pMac)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ __lim_init_assoc_vars(pMac);
+ __lim_init_vars(pMac);
+ __lim_init_states(pMac);
+ __lim_init_stats_vars(pMac);
+ __lim_init_bss_vars(pMac);
+ __lim_init_scan_vars(pMac);
+ __lim_init_ht_vars(pMac);
+
+ status = lim_start(pMac);
+ if (eSIR_SUCCESS != status) {
+ return status;
+ }
+ /* Initializations for maintaining peers in IBSS */
+ lim_ibss_init(pMac);
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrm_initialize(pMac);
+#endif
+
+ cdf_mutex_init(&pMac->lim.lim_frame_register_lock);
+ cdf_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue, 0);
+
+ /* Initialize the configurations needed by PE */
+ if (eSIR_FAILURE == __lim_init_config(pMac)) {
+ /* We need to undo everything in lim_start */
+ lim_cleanup_mlm(pMac);
+ return eSIR_FAILURE;
+ }
+ /* initialize the TSPEC admission control table. */
+ /* Note that this was initially done after resume notification from HAL. */
+ /* Now, DAL is started before PE so this can be done here */
+ lim_admit_control_init(pMac);
+ lim_register_hal_ind_call_back(pMac);
+
+ return status;
+
+} /*** end lim_initialize() ***/
+
+/**
+ * lim_cleanup()
+ *
+ ***FUNCTION:
+ * This function is called upon reset or persona change
+ * to cleanup LIM state
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_cleanup(tpAniSirGlobal pMac)
+{
+ void *p_cds_gctx;
+ CDF_STATUS retStatus;
+
+ /*Before destroying the list making sure all the nodes have been deleted
+ *Which should be the normal case, but a memory leak has been reported
+ */
+
+ struct mgmt_frm_reg_info *pLimMgmtRegistration = NULL;
+
+ if (CDF_FTM_MODE != cds_get_conparam()) {
+ cdf_mutex_acquire(&pMac->lim.lim_frame_register_lock);
+ while (cdf_list_remove_front(
+ &pMac->lim.gLimMgmtFrameRegistratinQueue,
+ (cdf_list_node_t **) &pLimMgmtRegistration) ==
+ CDF_STATUS_SUCCESS) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("Fixing leak! Deallocating pLimMgmtRegistration node"));
+ cdf_mem_free(pLimMgmtRegistration);
+ }
+ cdf_mutex_release(&pMac->lim.lim_frame_register_lock);
+ cdf_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue);
+ }
+
+ lim_cleanup_mlm(pMac);
+ lim_cleanup_lmm(pMac);
+
+ /* free up preAuth table */
+ if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL) {
+ cdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
+ pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
+ pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
+ }
+
+ if (NULL != pMac->lim.pDialogueTokenHead) {
+ lim_delete_dialogue_token_list(pMac);
+ }
+
+ if (NULL != pMac->lim.pDialogueTokenTail) {
+ cdf_mem_free(pMac->lim.pDialogueTokenTail);
+ pMac->lim.pDialogueTokenTail = NULL;
+ }
+
+ if (pMac->lim.gpLimMlmSetKeysReq != NULL) {
+ cdf_mem_free(pMac->lim.gpLimMlmSetKeysReq);
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+ }
+
+ if (pMac->lim.gpLimMlmAuthReq != NULL) {
+ cdf_mem_free(pMac->lim.gpLimMlmAuthReq);
+ pMac->lim.gpLimMlmAuthReq = NULL;
+ }
+
+ if (pMac->lim.gpDefdSmeMsgForNOA != NULL) {
+ cdf_mem_free(pMac->lim.gpDefdSmeMsgForNOA);
+ pMac->lim.gpDefdSmeMsgForNOA = NULL;
+ }
+
+ if (pMac->lim.gpLimMlmScanReq != NULL) {
+ cdf_mem_free(pMac->lim.gpLimMlmScanReq);
+ pMac->lim.gpLimMlmScanReq = NULL;
+ }
+ /* Now, finally reset the deferred message queue pointers */
+ lim_reset_deferred_msg_q(pMac);
+
+ p_cds_gctx = cds_get_global_context();
+ retStatus = wma_de_register_mgmt_frm_client(p_cds_gctx);
+
+ if (retStatus != CDF_STATUS_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("DeRegistering the PE Handle with wma has failed bailing out..."));
+ )
+#if defined WLAN_FEATURE_VOWIFI
+ rrm_cleanup(pMac);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ lim_ft_cleanup_all_ft_sessions(pMac);
+#endif
+
+} /*** end lim_cleanup() ***/
+
+/** -------------------------------------------------------------
+ \fn pe_open
+ \brief will be called in Open sequence from mac_open
+ \param tpAniSirGlobal pMac
+ \param tHalOpenParameters *pHalOpenParam
+ \return tSirRetStatus
+ -------------------------------------------------------------*/
+
+tSirRetStatus pe_open(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ if (eDRIVER_TYPE_MFG == pMacOpenParam->driverType)
+ return eSIR_SUCCESS;
+
+ pMac->lim.maxBssId = pMacOpenParam->maxBssId;
+ pMac->lim.maxStation = pMacOpenParam->maxStation;
+
+ if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0)) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("max number of Bssid or Stations cannot be zero!"));)
+ return eSIR_FAILURE;
+ }
+
+ pMac->lim.limTimers.gpLimCnfWaitTimer =
+ cdf_mem_malloc(sizeof(TX_TIMER) * (pMac->lim.maxStation + 1));
+ if (NULL == pMac->lim.limTimers.gpLimCnfWaitTimer) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("gpLimCnfWaitTimer memory allocate failed!"));)
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ pMac->lim.gpSession =
+ cdf_mem_malloc(sizeof(tPESession) * pMac->lim.maxBssId);
+ if (NULL == pMac->lim.gpSession) {
+ lim_log(pMac, LOGE,
+ FL("gpSession memory allocate failed!"));
+ status = eSIR_MEM_ALLOC_FAILED;
+ goto pe_open_psession_fail;
+ }
+
+ cdf_mem_set(pMac->lim.gpSession,
+ sizeof(tPESession) * pMac->lim.maxBssId, 0);
+
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ pMac->lim.deferredMsgCnt = 0;
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_mutex_init(&pMac->lim.lkPeGlobalLock))) {
+ PELOGE(lim_log(pMac, LOGE, FL("pe lock init failed!"));)
+ status = eSIR_FAILURE;
+ goto pe_open_lock_fail;
+ }
+ pMac->lim.deauthMsgCnt = 0;
+ pMac->lim.retry_packet_cnt = 0;
+ pMac->lim.ibss_retry_cnt = 0;
+
+ /*
+ * pe_open is successful by now, so it is right time to initialize
+ * MTRACE for PE module. if LIM_TRACE_RECORD is not defined in build
+ * file then nothing will be logged for PE module.
+ */
+#ifdef LIM_TRACE_RECORD
+ MTRACE(lim_trace_init(pMac));
+#endif
+ return status; /* status here will be eSIR_SUCCESS */
+
+pe_open_lock_fail:
+ cdf_mem_free(pMac->lim.gpSession);
+ pMac->lim.gpSession = NULL;
+pe_open_psession_fail:
+ cdf_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer);
+ pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
+
+ return status;
+}
+
+/** -------------------------------------------------------------
+ \fn pe_close
+ \brief will be called in close sequence from mac_close
+ \param tpAniSirGlobal pMac
+ \return tSirRetStatus
+ -------------------------------------------------------------*/
+
+tSirRetStatus pe_close(tpAniSirGlobal pMac)
+{
+ uint8_t i;
+
+ if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG)
+ return eSIR_SUCCESS;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if (pMac->lim.gpSession[i].valid == true) {
+ pe_delete_session(pMac, &pMac->lim.gpSession[i]);
+ }
+ }
+ cdf_mem_free(pMac->lim.limTimers.gpLimCnfWaitTimer);
+ pMac->lim.limTimers.gpLimCnfWaitTimer = NULL;
+
+ if (pMac->lim.gpLimMlmOemDataReq) {
+ cdf_mem_free(pMac->lim.gpLimMlmOemDataReq);
+ pMac->lim.gpLimMlmOemDataReq = NULL;
+ }
+
+ cdf_mem_free(pMac->lim.gpSession);
+ pMac->lim.gpSession = NULL;
+ if (!CDF_IS_STATUS_SUCCESS
+ (cdf_mutex_destroy(&pMac->lim.lkPeGlobalLock))) {
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn pe_start
+ \brief will be called in start sequence from mac_start
+ \param tpAniSirGlobal pMac
+ \return none
+ -------------------------------------------------------------*/
+
+tSirRetStatus pe_start(tpAniSirGlobal pMac)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ status = lim_initialize(pMac);
+ return status;
+}
+
+/** -------------------------------------------------------------
+ \fn pe_stop
+ \brief will be called in stop sequence from mac_stop
+ \param tpAniSirGlobal pMac
+ \return none
+ -------------------------------------------------------------*/
+
+void pe_stop(tpAniSirGlobal pMac)
+{
+ lim_cleanup(pMac);
+ SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE);
+ return;
+}
+
+/** -------------------------------------------------------------
+ \fn pe_free_msg
+ \brief Called by CDS scheduler (function cds_sched_flush_mc_mqs)
+ \ to free a given PE message on the TX and MC thread.
+ \ This happens when there are messages pending in the PE
+ \ queue when system is being stopped and reset.
+ \param tpAniSirGlobal pMac
+ \param tSirMsgQ pMsg
+ \return none
+ -----------------------------------------------------------------*/
+void pe_free_msg(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ if (pMsg != NULL) {
+ if (NULL != pMsg->bodyptr) {
+ if (SIR_BB_XPORT_MGMT_MSG == pMsg->type) {
+ cds_pkt_return_packet((cds_pkt_t *) pMsg->
+ bodyptr);
+ } else {
+ cdf_mem_free((void *)pMsg->bodyptr);
+ }
+ }
+ pMsg->bodyptr = 0;
+ pMsg->bodyval = 0;
+ pMsg->type = 0;
+ }
+ return;
+}
+
+/**
+ * lim_post_msg_api()
+ *
+ ***FUNCTION:
+ * This function is called from other thread while posting a
+ * message to LIM message Queue gSirLimMsgQ.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMsg - Pointer to the message structure
+ * @return None
+ */
+
+uint32_t lim_post_msg_api(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ return cds_mq_post_message(CDS_MQ_ID_PE, (cds_msg_t *) pMsg);
+
+} /*** end lim_post_msg_api() ***/
+
+/*--------------------------------------------------------------------------
+
+ \brief pe_post_msg_api() - A wrapper function to post message to Voss msg queues
+
+ This function can be called by legacy code to post message to cds queues OR
+ legacy code may keep on invoking 'lim_post_msg_api' to post the message to cds queue
+ for dispatching it later.
+
+ \param pMac - Pointer to Global MAC structure
+ \param pMsg - Pointer to the message structure
+
+ \return uint32_t - TX_SUCCESS for success.
+
+ --------------------------------------------------------------------------*/
+
+tSirRetStatus pe_post_msg_api(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ return (tSirRetStatus) lim_post_msg_api(pMac, pMsg);
+}
+
+/*--------------------------------------------------------------------------
+
+ \brief pe_process_messages() - Message Processor for PE
+
+ Voss calls this function to dispatch the message to PE
+
+ \param pMac - Pointer to Global MAC structure
+ \param pMsg - Pointer to the message structure
+
+ \return uint32_t - TX_SUCCESS for success.
+
+ --------------------------------------------------------------------------*/
+
+tSirRetStatus pe_process_messages(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG) {
+ return eSIR_SUCCESS;
+ }
+ /**
+ * If the Message to be handled is for CFG Module call the CFG Msg
+ * Handler and for all the other cases post it to LIM
+ */
+ if (SIR_CFG_PARAM_UPDATE_IND != pMsg->type && IS_CFG_MSG(pMsg->type))
+ cfg_process_mb_msg(pMac, (tSirMbMsg *) pMsg->bodyptr);
+ else
+ lim_message_processor(pMac, pMsg);
+ return eSIR_SUCCESS;
+}
+
+/* --------------------------------------------------------------------------- */
+/**
+ * pe_handle_mgmt_frame
+ *
+ * FUNCTION:
+ * Process the Management frames from TL
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS: TL sends the packet along with the CDS GlobalContext
+ *
+ * NOTE:
+ *
+ * @param p_cds_gctx Global Vos Context
+ * @param cds_buff Packet
+ * @return None
+ */
+
+CDF_STATUS pe_handle_mgmt_frame(void *p_cds_gctx, void *cds_buff)
+{
+ tpAniSirGlobal pMac;
+ tpSirMacMgmtHdr mHdr;
+ tSirMsgQ msg;
+ cds_pkt_t *pVosPkt;
+ CDF_STATUS cdf_status;
+ uint8_t *pRxPacketInfo;
+
+ pVosPkt = (cds_pkt_t *) cds_buff;
+ if (NULL == pVosPkt) {
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ pMac = cds_get_context(CDF_MODULE_ID_PE);
+ if (NULL == pMac) {
+ /* cannot log a failure without a valid pMac */
+ cds_pkt_return_packet(pVosPkt);
+ pVosPkt = NULL;
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ cdf_status =
+ wma_ds_peek_rx_packet_info(pVosPkt, (void *)&pRxPacketInfo, false);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ cds_pkt_return_packet(pVosPkt);
+ pVosPkt = NULL;
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ /*
+ * The MPDU header is now present at a certain "offset" in
+ * the BD and is specified in the BD itself
+ */
+
+ mHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ if (mHdr->fc.type == SIR_MAC_MGMT_FRAME) {
+ lim_log(pMac, LOG1, FL
+ ("RxBd=%p mHdr=%p Type: %d Subtype: %d Sizes:FC%zu Mgmt%zu"),
+ pRxPacketInfo, mHdr, mHdr->fc.type, mHdr->fc.subType,
+ sizeof(tSirMacFrameCtl), sizeof(tSirMacMgmtHdr));
+
+ lim_log(pMac, LOG1, FL("mpdu_len:%d hdr_len:%d data_len:%d"),
+ WMA_GET_RX_MPDU_LEN(pRxPacketInfo),
+ WMA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo),
+ WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo));
+
+ MTRACE(mac_trace(pMac, TRACE_CODE_RX_MGMT,
+ WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo),
+ LIM_TRACE_MAKE_RXMGMT(mHdr->fc.subType,
+ (uint16_t) (((uint16_t)
+ (mHdr->seqControl.seqNumHi << 4)) |
+ mHdr->seqControl.seqNumLo)));)
+
+ if (WMA_GET_ROAMCANDIDATEIND(pRxPacketInfo))
+ lim_log(pMac, LOG1, FL("roamCandidateInd %d"),
+ WMA_GET_ROAMCANDIDATEIND(pRxPacketInfo));
+
+ if (WMA_GET_OFFLOADSCANLEARN(pRxPacketInfo))
+ lim_log(pMac, LOG1, FL("offloadScanLearn %d"),
+ WMA_GET_OFFLOADSCANLEARN(pRxPacketInfo));
+ }
+
+ /* Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG */
+ msg.type = SIR_BB_XPORT_MGMT_MSG;
+ msg.bodyptr = cds_buff;
+ msg.bodyval = 0;
+
+ if (eSIR_SUCCESS != sys_bbt_process_message_core(pMac,
+ &msg,
+ mHdr->fc.type,
+ mHdr->fc.subType)) {
+ cds_pkt_return_packet(pVosPkt);
+ pVosPkt = NULL;
+ lim_log(pMac, LOGW,
+ FL
+ ("sys_bbt_process_message_core failed to process SIR_BB_XPORT_MGMT_MSG"));
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * pe_register_wma_handle() - register management frame handler to WMA
+ * @pMac: mac global ctx
+ *
+ * Return: None
+ */
+void pe_register_wma_handle(tpAniSirGlobal pMac)
+{
+ void *p_cds_gctx;
+ CDF_STATUS retStatus;
+
+ p_cds_gctx = cds_get_global_context();
+
+ retStatus = wma_register_mgmt_frm_client(p_cds_gctx,
+ pe_handle_mgmt_frame);
+ if (retStatus != CDF_STATUS_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("Registering the PE Handle with WMA has failed"));
+
+}
+
+/**
+ * lim_is_system_in_scan_state()
+ *
+ ***FUNCTION:
+ * This function is called by various MAC software modules to
+ * determine if System is in Scan/Learn state
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return true - System is in Scan/Learn state
+ * false - System is NOT in Scan/Learn state
+ */
+
+uint8_t lim_is_system_in_scan_state(tpAniSirGlobal pMac)
+{
+ switch (pMac->lim.gLimSmeState) {
+ case eLIM_SME_CHANNEL_SCAN_STATE:
+ case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+ case eLIM_SME_LINK_EST_WT_SCAN_STATE:
+ case eLIM_SME_WT_SCAN_STATE:
+ /* System is in Learn mode */
+ return true;
+
+ default:
+ /* System is NOT in Learn mode */
+ return false;
+ }
+} /*** end lim_is_system_in_scan_state() ***/
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_is_assoc_req_for_drop()- function to decides to drop assoc\reassoc
+ * frames.
+ * @mac: pointer to global mac structure
+ * @rx_pkt_info: rx packet meta information
+ *
+ * This function is called before enqueuing the frame to PE queue to
+ * drop flooded assoc/reassoc frames getting into PE Queue.
+ *
+ * Return: true for dropping the frame otherwise false
+ */
+
+bool lim_is_assoc_req_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info)
+{
+ uint8_t session_id;
+ uint16_t aid;
+ tpPESession session_entry;
+ tpSirMacMgmtHdr mac_hdr;
+ tpDphHashNode sta_ds;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ session_entry = pe_find_session_by_bssid(mac, mac_hdr->bssId,
+ &session_id);
+ if (!session_entry) {
+ PELOG1(limLog(pMac, LOG1,
+ FL("session does not exist for given STA [%pM]"),
+ mac_hdr->sa););
+ return false;
+ }
+
+ sta_ds = dph_lookup_hash_entry(mac, mac_hdr->sa, &aid,
+ &session_entry->dph.dphHashTable);
+ if (!sta_ds) {
+ PELOG1(limLog(pMac, LOG1, FL("pStaDs is NULL")););
+ return false;
+ }
+
+ if (!sta_ds->rmfEnabled)
+ return false;
+
+ if (sta_ds->pmfSaQueryState == DPH_SA_QUERY_IN_PROGRESS)
+ return true;
+
+ if (sta_ds->last_assoc_received_time &&
+ ((cdf_mc_timer_get_system_ticks() -
+ sta_ds->last_assoc_received_time) < 1000))
+ return true;
+
+ sta_ds->last_assoc_received_time = cdf_mc_timer_get_system_ticks();
+ return false;
+}
+#endif
+
+/**
+ * lim_is_deauth_diassoc_for_drop()- function to decides to drop deauth\diassoc
+ * frames.
+ * @mac: pointer to global mac structure
+ * @rx_pkt_info: rx packet meta information
+ *
+ * This function is called before enqueuing the frame to PE queue to
+ * drop flooded deauth/diassoc frames getting into PE Queue.
+ *
+ * Return: true for dropping the frame otherwise false
+ */
+
+bool lim_is_deauth_diassoc_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info)
+{
+ uint8_t session_id;
+ uint16_t aid;
+ tpPESession session_entry;
+ tpSirMacMgmtHdr mac_hdr;
+ tpDphHashNode sta_ds;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ session_entry = pe_find_session_by_bssid(mac, mac_hdr->bssId,
+ &session_id);
+ if (!session_entry) {
+ PELOG1(limLog(mac, LOG1,
+ FL("session does not exist for given STA [%pM]"),
+ mac_hdr->sa););
+ return true;
+ }
+
+ sta_ds = dph_lookup_hash_entry(mac, mac_hdr->sa, &aid,
+ &session_entry->dph.dphHashTable);
+ if (!sta_ds) {
+ PELOG1(limLog(mac, LOG1, FL("pStaDs is NULL")););
+ return true;
+ }
+
+#ifdef WLAN_FEATURE_11W
+ if (session_entry->limRmfEnabled) {
+ if ((WMA_GET_RX_DPU_FEEDBACK(rx_pkt_info) &
+ DPU_FEEDBACK_UNPROTECTED_ERROR)) {
+ /* It may be possible that deauth/diassoc frames from a
+ * spoofy AP is received. So if all further
+ * deauth/diassoc frmaes are dropped, then it may
+ * result in lossing deauth/diassoc frames from genuine
+ * AP. So process all deauth/diassoc frames with
+ * a time difference of 1 sec.
+ */
+ if ((cdf_mc_timer_get_system_ticks() -
+ sta_ds->last_unprot_deauth_disassoc) < 1000)
+ return true;
+
+ sta_ds->last_unprot_deauth_disassoc =
+ cdf_mc_timer_get_system_ticks();
+ } else {
+ /* PMF enabed, Management frames are protected */
+ if (sta_ds->proct_deauh_disassoc_cnt)
+ return true;
+ else
+ sta_ds->proct_deauh_disassoc_cnt++;
+ }
+ } else
+#endif
+ /* PMF disabled */
+ {
+ if (sta_ds->is_disassoc_deauth_in_progress)
+ return true;
+ else
+ sta_ds->is_disassoc_deauth_in_progress++;
+ }
+
+ return false;
+}
+
+/**
+ *\brief lim_received_hb_handler()
+ *
+ * This function is called by sch_beacon_process() upon
+ * receiving a Beacon on STA. This also gets called upon
+ * receiving Probe Response after heat beat failure is
+ * detected.
+ *
+ * param pMac - global mac structure
+ * param channel - channel number indicated in Beacon, Probe Response
+ * return - none
+ */
+
+void
+lim_received_hb_handler(tpAniSirGlobal pMac, uint8_t channelId,
+ tpPESession psessionEntry)
+{
+ if ((channelId == 0)
+ || (channelId == psessionEntry->currentOperChannel))
+ psessionEntry->LimRxedBeaconCntDuringHB++;
+
+ psessionEntry->pmmOffloadInfo.bcnmiss = false;
+} /*** lim_init_wds_info_params() ***/
+
+/** -------------------------------------------------------------
+ \fn lim_update_overlap_sta_param
+ \brief Updates overlap cache and param data structure
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr bssId
+ \param tpLimProtStaParams pStaParams
+ \return None
+ -------------------------------------------------------------*/
+void
+lim_update_overlap_sta_param(tpAniSirGlobal pMac, tSirMacAddr bssId,
+ tpLimProtStaParams pStaParams)
+{
+ int i;
+ if (!pStaParams->numSta) {
+ cdf_mem_copy(pMac->lim.protStaOverlapCache[0].addr,
+ bssId, sizeof(tSirMacAddr));
+ pMac->lim.protStaOverlapCache[0].active = true;
+
+ pStaParams->numSta = 1;
+
+ return;
+ }
+
+ for (i = 0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++) {
+ if (pMac->lim.protStaOverlapCache[i].active) {
+ if (cdf_mem_compare
+ (pMac->lim.protStaOverlapCache[i].addr, bssId,
+ sizeof(tSirMacAddr))) {
+ return;
+ }
+ } else
+ break;
+ }
+
+ if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE) {
+ PELOG1(lim_log(pMac, LOGW, FL("Overlap cache is full"));)
+ } else {
+ cdf_mem_copy(pMac->lim.protStaOverlapCache[i].addr,
+ bssId, sizeof(tSirMacAddr));
+ pMac->lim.protStaOverlapCache[i].active = true;
+
+ pStaParams->numSta++;
+ }
+}
+
+/**
+ * lim_ibss_enc_type_matched
+ *
+ ***FUNCTION:
+ * This function compares the encryption type of the peer with self
+ * while operating in IBSS mode and detects mismatch.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pSession - Pointer to the PE session
+ *
+ * @return eSIR_TRUE if encryption type is matched; eSIR_FALSE otherwise
+ */
+static tAniBool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon,
+ tpPESession pSession)
+{
+ if (!pBeacon || !pSession)
+ return eSIR_FALSE;
+
+ /* Open case */
+ if (pBeacon->capabilityInfo.privacy == 0
+ && pSession->encryptType == eSIR_ED_NONE)
+ return eSIR_TRUE;
+
+ /* WEP case */
+ if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 0
+ && pBeacon->rsnPresent == 0
+ && (pSession->encryptType == eSIR_ED_WEP40
+ || pSession->encryptType == eSIR_ED_WEP104))
+ return eSIR_TRUE;
+
+ /* WPA-None case */
+ if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 1
+ && pBeacon->rsnPresent == 0
+ && ((pSession->encryptType == eSIR_ED_CCMP) ||
+ (pSession->encryptType == eSIR_ED_TKIP)))
+ return eSIR_TRUE;
+
+ return eSIR_FALSE;
+}
+
+/**
+ * lim_handle_ibs_scoalescing()
+ *
+ ***FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * while operating in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pRxPacketInfo - Pointer to RX packet info structure
+ *
+ * @return Status whether to process or ignore received Beacon Frame
+ */
+
+tSirRetStatus
+lim_handle_ibss_coalescing(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeacon,
+ uint8_t *pRxPacketInfo, tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tSirRetStatus retCode;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ /* Ignore the beacon when any of the conditions below is met:
+ 1. The beacon claims no IBSS network
+ 2. SSID in the beacon does not match SSID of self station
+ 3. Operational channel in the beacon does not match self station
+ 4. Encyption type in the beacon does not match with self station
+ */
+ if ((!pBeacon->capabilityInfo.ibss) ||
+ (lim_cmp_s_sid(pMac, &pBeacon->ssId, psessionEntry) != true) ||
+ (psessionEntry->currentOperChannel != pBeacon->channelNumber))
+ retCode = eSIR_LIM_IGNORE_BEACON;
+ else if (lim_ibss_enc_type_matched(pBeacon, psessionEntry) != eSIR_TRUE) {
+ PELOG3(lim_log(pMac, LOG3,
+ FL
+ ("peer privacy %d peer wpa %d peer rsn %d self encType %d"),
+ pBeacon->capabilityInfo.privacy,
+ pBeacon->wpaPresent, pBeacon->rsnPresent,
+ psessionEntry->encryptType);
+ )
+ retCode = eSIR_LIM_IGNORE_BEACON;
+ } else {
+ uint32_t ieLen;
+ uint16_t tsfLater;
+ uint8_t *pIEs;
+ ieLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ tsfLater = WMA_GET_RX_TSF_LATER(pRxPacketInfo);
+ pIEs = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ PELOG3(lim_log
+ (pMac, LOG3, FL("BEFORE Coalescing tsfLater val :%d"),
+ tsfLater);
+ )
+ retCode =
+ lim_ibss_coalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,
+ psessionEntry);
+ }
+ return retCode;
+} /*** end lim_handle_ibs_scoalescing() ***/
+
+/**
+ * lim_enc_type_matched() - matches security type of incoming beracon with
+ * current
+ * @mac_ctx Pointer to Global MAC structure
+ * @bcn Pointer to parsed Beacon structure
+ * @session PE session entry
+ *
+ * This function matches security type of incoming beracon with current
+ *
+ * @return true if matched, false otherwise
+ */
+static bool
+lim_enc_type_matched(tpAniSirGlobal mac_ctx,
+ tpSchBeaconStruct bcn,
+ tpPESession session)
+{
+ if (!bcn || !session)
+ return false;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Beacon/Probe:: Privacy :%d WPA Present:%d RSN Present: %d"),
+ bcn->capabilityInfo.privacy, bcn->wpaPresent, bcn->rsnPresent);
+ lim_log(mac_ctx, LOG1,
+ FL("session:: Privacy :%d EncyptionType: %d"),
+ SIR_MAC_GET_PRIVACY(session->limCurrentBssCaps),
+ session->encryptType);
+
+ /*
+ * This is handled by sending probe req due to IOT issues so
+ * return TRUE
+ */
+ if ((bcn->capabilityInfo.privacy) !=
+ SIR_MAC_GET_PRIVACY(session->limCurrentBssCaps)) {
+ lim_log(mac_ctx, LOGW, FL("Privacy bit miss match\n"));
+ return true;
+ }
+
+ /* Open */
+ if ((bcn->capabilityInfo.privacy == 0) &&
+ (session->encryptType == eSIR_ED_NONE))
+ return true;
+
+ /* WEP */
+ if ((bcn->capabilityInfo.privacy == 1) &&
+ (bcn->wpaPresent == 0) && (bcn->rsnPresent == 0) &&
+ ((session->encryptType == eSIR_ED_WEP40) ||
+ (session->encryptType == eSIR_ED_WEP104)
+#ifdef FEATURE_WLAN_WAPI
+ || (session->encryptType == eSIR_ED_WPI)
+#endif
+ ))
+ return true;
+
+ /* WPA OR RSN*/
+ if ((bcn->capabilityInfo.privacy == 1) &&
+ ((bcn->wpaPresent == 1) || (bcn->rsnPresent == 1)) &&
+ ((session->encryptType == eSIR_ED_TKIP) ||
+ (session->encryptType == eSIR_ED_CCMP) ||
+ (session->encryptType == eSIR_ED_AES_128_CMAC)))
+ return true;
+
+ return false;
+}
+
+/**
+ * lim_detect_change_in_ap_capabilities()
+ *
+ ***FUNCTION:
+ * This function is called while SCH is processing
+ * received Beacon from AP on STA to detect any
+ * change in AP's capabilities. If there any change
+ * is detected, Roaming is informed of such change
+ * so that it can trigger reassociation.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * Notification is enabled for STA product only since
+ * it is not a requirement on BP side.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pBeacon Pointer to parsed Beacon structure
+ * @return None
+ */
+
+void
+lim_detect_change_in_ap_capabilities(tpAniSirGlobal pMac,
+ tpSirProbeRespBeacon pBeacon,
+ tpPESession psessionEntry)
+{
+ uint8_t len;
+ tSirSmeApNewCaps apNewCaps;
+ uint8_t newChannel;
+ tSirRetStatus status = eSIR_SUCCESS;
+ bool security_caps_matched = true;
+
+ apNewCaps.capabilityInfo =
+ lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
+ newChannel = (uint8_t) pBeacon->channelNumber;
+
+ security_caps_matched = lim_enc_type_matched(pMac, pBeacon,
+ psessionEntry);
+ if ((false == psessionEntry->limSentCapsChangeNtf) &&
+ (((!lim_is_null_ssid(&pBeacon->ssId)) &&
+ (false == lim_cmp_s_sid(pMac, &pBeacon->ssId, psessionEntry))) ||
+ ((SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) !=
+ SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps)) ||
+ (SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) !=
+ SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps)) ||
+ (SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) !=
+ SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps)) ||
+ (SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) !=
+ SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps)) ||
+ ((newChannel != psessionEntry->currentOperChannel) &&
+ (newChannel != 0)) ||
+ (false == security_caps_matched)
+ ))) {
+ if (false == psessionEntry->fWaitForProbeRsp) {
+ /* If Beacon capabilities is not matching with the current capability,
+ * then send unicast probe request to AP and take decision after
+ * receiving probe response */
+ if (true == psessionEntry->fIgnoreCapsChange) {
+ lim_log(pMac, LOGW,
+ FL
+ ("Ignoring the Capability change as it is false alarm"));
+ return;
+ }
+ psessionEntry->fWaitForProbeRsp = true;
+ lim_log(pMac, LOGW,
+ FL("AP capabilities are not matching,"
+ "sending directed probe request.. "));
+ status =
+ lim_send_probe_req_mgmt_frame(pMac, &psessionEntry->ssId,
+ psessionEntry->bssId,
+ psessionEntry->
+ currentOperChannel,
+ psessionEntry->selfMacAddr,
+ psessionEntry->dot11mode,
+ 0, NULL);
+
+ if (eSIR_SUCCESS != status) {
+ lim_log(pMac, LOGE, FL("send ProbeReq failed"));
+ psessionEntry->fWaitForProbeRsp = false;
+ }
+ return;
+ }
+ /**
+ * BSS capabilities have changed.
+ * Inform Roaming.
+ */
+ len = sizeof(tSirMacCapabilityInfo) + sizeof(tSirMacAddr) + sizeof(uint8_t) + 3 * sizeof(uint8_t) + /* reserved fields */
+ pBeacon->ssId.length + 1;
+
+ cdf_mem_copy(apNewCaps.bssId,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+ if (newChannel != psessionEntry->currentOperChannel) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Channel Change from %d --> %d - "
+ "Ignoring beacon!"),
+ psessionEntry->currentOperChannel, newChannel);
+ )
+ return;
+ }
+
+ /**
+ * When Cisco 1262 Enterprise APs are configured with WPA2-PSK with
+ * AES+TKIP Pairwise ciphers and WEP-40 Group cipher, they do not set
+ * the privacy bit in Beacons (wpa/rsnie is still present in beacons),
+ * the privacy bit is set in Probe and association responses.
+ * Due to this anomaly, we detect a change in
+ * AP capabilities when we receive a beacon after association and
+ * disconnect from the AP. The following check makes sure that we can
+ * connect to such APs
+ */
+ else if ((SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) == 0) &&
+ (pBeacon->rsnPresent || pBeacon->wpaPresent)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("BSS Caps (Privacy) bit 0 in beacon,"
+ " but WPA or RSN IE present, Ignore Beacon!"));
+ )
+ return;
+ } else
+ apNewCaps.channelId = psessionEntry->currentOperChannel;
+ cdf_mem_copy((uint8_t *) &apNewCaps.ssId,
+ (uint8_t *) &pBeacon->ssId,
+ pBeacon->ssId.length + 1);
+
+ psessionEntry->fIgnoreCapsChange = false;
+ psessionEntry->fWaitForProbeRsp = false;
+ psessionEntry->limSentCapsChangeNtf = true;
+ lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_AP_CAPS_CHANGED,
+ (uint32_t *) &apNewCaps,
+ len, psessionEntry->smeSessionId);
+ } else if (true == psessionEntry->fWaitForProbeRsp) {
+ /* Only for probe response frames and matching capabilities the control
+ * will come here. If beacon is with broadcast ssid then fWaitForProbeRsp
+ * will be false, the control will not come here*/
+
+ lim_log(pMac, LOG1, FL("capabilities in probe response are"
+ "matching with the current setting,"
+ "Ignoring subsequent capability"
+ "mismatch"));
+ psessionEntry->fIgnoreCapsChange = true;
+ psessionEntry->fWaitForProbeRsp = false;
+ }
+
+} /*** lim_detect_change_in_ap_capabilities() ***/
+
+/* --------------------------------------------------------------------- */
+/**
+ * lim_update_short_slot
+ *
+ * FUNCTION:
+ * Enable/Disable short slot
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param enable Flag to enable/disable short slot
+ * @return None
+ */
+
+tSirRetStatus lim_update_short_slot(tpAniSirGlobal pMac,
+ tpSirProbeRespBeacon pBeacon,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+
+ tSirSmeApNewCaps apNewCaps;
+ uint32_t nShortSlot;
+ uint32_t val = 0;
+ uint32_t phyMode;
+
+ /* Check Admin mode first. If it is disabled just return */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val)
+ != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed"));
+ return eSIR_FAILURE;
+ }
+ if (val == false)
+ return eSIR_SUCCESS;
+
+ /* Check for 11a mode or 11b mode. In both cases return since slot time is constant and cannot/should not change in beacon */
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+ if ((phyMode == WNI_CFG_PHY_MODE_11A)
+ || (phyMode == WNI_CFG_PHY_MODE_11B))
+ return eSIR_SUCCESS;
+
+ apNewCaps.capabilityInfo =
+ lim_get_u16((uint8_t *) &pBeacon->capabilityInfo);
+
+ /* Earlier implementation: determine the appropriate short slot mode based on AP advertised modes */
+ /* when erp is present, apply short slot always unless, prot=on && shortSlot=off */
+ /* if no erp present, use short slot based on current ap caps */
+
+ /* Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4); */
+
+ /* Resolution : always use the shortSlot setting the capability info to decide slot time. */
+ /* The difference between the earlier implementation and the new one is only Case4. */
+ /*
+ ERP IE Present | useProtection | shortSlot = QC STA Short Slot
+ Case1 1 1 1 1 //AP should not advertise this combination.
+ Case2 1 1 0 0
+ Case3 1 0 1 1
+ Case4 1 0 0 0
+ Case5 0 1 1 1
+ Case6 0 1 0 0
+ Case7 0 0 1 1
+ Case8 0 0 0 0
+ */
+ nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo);
+
+ if (nShortSlot != psessionEntry->shortSlotTimeSupported) {
+ /* Short slot time capability of AP has changed. Adopt to it. */
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Shortslot capability of AP changed: %d"),
+ nShortSlot);
+ )
+ ((tpSirMacCapabilityInfo) & psessionEntry->
+ limCurrentBssCaps)->shortSlotTime = (uint16_t) nShortSlot;
+ psessionEntry->shortSlotTimeSupported = nShortSlot;
+ pBeaconParams->fShortSlotTime = (uint8_t) nShortSlot;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_SHORT_SLOT_TIME_CHANGED;
+ }
+ return eSIR_SUCCESS;
+}
+
+
+void lim_send_heart_beat_timeout_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ uint32_t statusCode;
+ tSirMsgQ msg;
+
+ /* Prepare and post message to LIM Message Queue */
+ msg.type = (uint16_t) SIR_LIM_HEART_BEAT_TIMEOUT;
+ msg.bodyptr = psessionEntry;
+ msg.bodyval = 0;
+ lim_log(pMac, LOGE, FL("Heartbeat failure from Fw"));
+
+ statusCode = lim_post_msg_api(pMac, &msg);
+
+ if (statusCode != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("posting message %X to LIM failed, reason=%d"),
+ msg.type, statusCode);
+ }
+}
+
+/**
+ * lim_ps_offload_handle_missed_beacon_ind(): handles missed beacon indication
+ * @pMac : global mac context
+ * @pMsg: message
+ *
+ * This function process the SIR_HAL_MISSED_BEACON_IND
+ * message from HAL, to do active AP probing.
+ *
+ * Return: void
+ */
+void lim_ps_offload_handle_missed_beacon_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ tpSirSmeMissedBeaconInd pSirMissedBeaconInd =
+ (tpSirSmeMissedBeaconInd) pMsg->bodyptr;
+ tpPESession psessionEntry =
+ pe_find_session_by_bss_idx(pMac, pSirMissedBeaconInd->bssIdx);
+
+ if (!psessionEntry) {
+ lim_log(pMac, LOGE,
+ FL("session does not exist for given BSSId"));
+ return;
+ }
+
+ /* Set Beacon Miss in Powersave Offload */
+ psessionEntry->pmmOffloadInfo.bcnmiss = true;
+ PELOGE(lim_log(pMac, LOGE,
+ FL("Received Heart Beat Failure"));)
+
+ /* Do AP probing immediately */
+ lim_send_heart_beat_timeout_ind(pMac, psessionEntry);
+ return;
+}
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+CDF_STATUS lim_roam_fill_bss_descr(tpAniSirGlobal pMac,
+ roam_offload_synch_ind *roam_offload_synch_ind_ptr)
+{
+ uint32_t ie_len = 0;
+ tpSirProbeRespBeacon parsed_frm_ptr;
+ tpSirMacMgmtHdr mac_hdr;
+ uint8_t *bcn_proberesp_ptr;
+ tSirBssDescription *bss_desc_ptr = NULL;
+
+ bcn_proberesp_ptr = (uint8_t *)roam_offload_synch_ind_ptr +
+ roam_offload_synch_ind_ptr->beaconProbeRespOffset;
+ mac_hdr = (tpSirMacMgmtHdr)bcn_proberesp_ptr;
+ parsed_frm_ptr =
+ (tpSirProbeRespBeacon) cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+ if (NULL == parsed_frm_ptr) {
+ lim_log(pMac, LOGE, "fail to allocate memory for frame");
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ if (roam_offload_synch_ind_ptr->beaconProbeRespLength <=
+ SIR_MAC_HDR_LEN_3A) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR, "%s: very"
+ "few bytes in synchInd beacon / probe resp frame! length=%d",
+ __func__, roam_offload_synch_ind_ptr->beaconProbeRespLength);
+ cdf_mem_free(parsed_frm_ptr);
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ "LFR3: Beacon/Prb Rsp:");
+ CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ bcn_proberesp_ptr, roam_offload_synch_ind_ptr->beaconProbeRespLength);
+ if (roam_offload_synch_ind_ptr->isBeacon) {
+ if (sir_parse_beacon_ie(pMac, parsed_frm_ptr,
+ &bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A +
+ SIR_MAC_B_PR_SSID_OFFSET],
+ roam_offload_synch_ind_ptr->beaconProbeRespLength -
+ SIR_MAC_HDR_LEN_3A) != eSIR_SUCCESS ||
+ !parsed_frm_ptr->ssidPresent) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "Parse error Beacon, length=%d",
+ roam_offload_synch_ind_ptr->beaconProbeRespLength);
+ cdf_mem_free(parsed_frm_ptr);
+ return CDF_STATUS_E_FAILURE;
+ }
+ } else {
+ if (sir_convert_probe_frame2_struct(pMac,
+ &bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A],
+ roam_offload_synch_ind_ptr->beaconProbeRespLength -
+ SIR_MAC_HDR_LEN_3A, parsed_frm_ptr) != eSIR_SUCCESS ||
+ !parsed_frm_ptr->ssidPresent) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "Parse error ProbeResponse, length=%d",
+ roam_offload_synch_ind_ptr->beaconProbeRespLength);
+ cdf_mem_free(parsed_frm_ptr);
+ return CDF_STATUS_E_FAILURE;
+ }
+ }
+ /* 24 byte MAC header and 12 byte to ssid IE */
+ if (roam_offload_synch_ind_ptr->beaconProbeRespLength >
+ (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) {
+ ie_len = roam_offload_synch_ind_ptr->beaconProbeRespLength -
+ (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET);
+ }
+ /*
+ * Memory allocated below is freed up in csrProcessRoamOffloadSynchInd
+ */
+ roam_offload_synch_ind_ptr->bss_desc_ptr =
+ cdf_mem_malloc(sizeof (tSirBssDescription) + ie_len);
+ bss_desc_ptr = roam_offload_synch_ind_ptr->bss_desc_ptr;
+ if (NULL == bss_desc_ptr) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "LFR3:Failed to allocate memory");
+ CDF_ASSERT(bss_desc_ptr != NULL);
+ return CDF_STATUS_E_NOMEM;
+ }
+ cdf_mem_zero(bss_desc_ptr, sizeof(tSirBssDescription));
+
+ /*
+ * Length of BSS desription is without length of
+ * length itself and length of pointer
+ * that holds ieFields
+ *
+ * tSirBssDescription
+ * +--------+---------------------------------+---------------+
+ * | length | other fields | pointer to IEs|
+ * +--------+---------------------------------+---------------+
+ * ^
+ * ieFields
+ */
+ bss_desc_ptr->length = (uint16_t) (offsetof(tSirBssDescription,
+ ieFields[0]) -
+ sizeof(bss_desc_ptr->length) + ie_len);
+
+ if (parsed_frm_ptr->dsParamsPresent) {
+ bss_desc_ptr->channelId = parsed_frm_ptr->channelNumber;
+ } else if (parsed_frm_ptr->HTInfo.present) {
+ bss_desc_ptr->channelId = parsed_frm_ptr->HTInfo.primaryChannel;
+ } else {
+ /*
+ * If DS Params or HTIE is not present in the probe resp or
+ * beacon, then use the channel frequency provided by firmware
+ * to fill the channel in the BSS descriptor.*/
+ bss_desc_ptr->channelId =
+ cds_freq_to_chan(roam_offload_synch_ind_ptr->chan_freq);
+ }
+ bss_desc_ptr->channelIdSelf = bss_desc_ptr->channelId;
+
+ if ((bss_desc_ptr->channelId > 0) && (bss_desc_ptr->channelId < 15)) {
+ int i;
+ /* *
+ * 11b or 11g packet
+ * 11g if extended Rate IE is present or
+ * if there is an A rate in suppRate IE
+ * */
+ for (i = 0; i < parsed_frm_ptr->supportedRates.numRates; i++) {
+ if (sirIsArate(parsed_frm_ptr->supportedRates.rate[i] &
+ 0x7f)) {
+ bss_desc_ptr->nwType = eSIR_11G_NW_TYPE;
+ break;
+ }
+ }
+ if (parsed_frm_ptr->extendedRatesPresent) {
+ bss_desc_ptr->nwType = eSIR_11G_NW_TYPE;
+ }
+ } else {
+ /* 11a packet */
+ bss_desc_ptr->nwType = eSIR_11A_NW_TYPE;
+ }
+
+ bss_desc_ptr->sinr = 0;
+ bss_desc_ptr->beaconInterval = parsed_frm_ptr->beaconInterval;
+ bss_desc_ptr->timeStamp[0] = parsed_frm_ptr->timeStamp[0];
+ bss_desc_ptr->timeStamp[1] = parsed_frm_ptr->timeStamp[1];
+ cdf_mem_copy(&bss_desc_ptr->capabilityInfo,
+ &bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_CAPAB_OFFSET], 2);
+ cdf_mem_copy((uint8_t *) &bss_desc_ptr->bssId,
+ (uint8_t *) mac_hdr->bssId,
+ sizeof(tSirMacAddr));
+ bss_desc_ptr->nReceivedTime =
+ (uint32_t)cdf_mc_timer_get_system_ticks();
+ if (parsed_frm_ptr->mdiePresent) {
+ bss_desc_ptr->mdiePresent = parsed_frm_ptr->mdiePresent;
+ cdf_mem_copy((uint8_t *)bss_desc_ptr->mdie,
+ (uint8_t *)parsed_frm_ptr->mdie,
+ SIR_MDIE_SIZE);
+ }
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:%s:BssDescr Info:", __func__);
+ CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ bss_desc_ptr->bssId, sizeof(tSirMacAddr));
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "chan=%d, rssi=%d", bss_desc_ptr->channelId,
+ bss_desc_ptr->rssi);
+ if (ie_len) {
+ cdf_mem_copy(&bss_desc_ptr->ieFields,
+ bcn_proberesp_ptr +
+ (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET),
+ ie_len);
+ }
+ cdf_mem_free(parsed_frm_ptr);
+ return CDF_STATUS_SUCCESS;
+}
+
+/**-----------------------------------------------------------------
+ * brief lim_roam_offload_synch_ind() - Handles Roam Synch Indication
+ * param pMac - global mac structure
+ * return - none
+ *-----------------------------------------------------------------
+ **/
+void lim_roam_offload_synch_ind(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ tpPESession session_ptr;
+ tpPESession ft_session_ptr;
+ uint8_t session_id;
+ tSirMsgQ mmh_msg;
+ tSirBssDescription *bss_desc_ptr = NULL;
+ roam_offload_synch_ind *roam_sync_ind_ptr =
+ (roam_offload_synch_ind *)pMsg->bodyptr;
+
+ if (!roam_sync_ind_ptr) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "LFR3:%s:roam_sync_ind_ptr is NULL", __func__);
+ return;
+ }
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "LFR3: Received WMA_ROAM_OFFLOAD_SYNCH_IND");
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:%s:authStatus=%d, vdevId=%d", __func__,
+ roam_sync_ind_ptr->authStatus,
+ roam_sync_ind_ptr->roamedVdevId);
+ CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ roam_sync_ind_ptr->bssId, 6);
+ session_ptr = pe_find_session_by_bss_idx(pMac,
+ roam_sync_ind_ptr->roamedVdevId);
+ if (session_ptr == NULL) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "%s: LFR3:Unable to find session", __func__);
+ return;
+ }
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session_ptr)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "session is not in STA mode");
+ return;
+ }
+ if (!CDF_IS_STATUS_SUCCESS(lim_roam_fill_bss_descr(pMac,
+ roam_sync_ind_ptr))) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "LFR3:%s:Failed to fill Bss Descr", __func__);
+ return;
+ }
+ bss_desc_ptr = roam_sync_ind_ptr->bss_desc_ptr;
+ ft_session_ptr = pe_create_session(pMac, bss_desc_ptr->bssId,
+ &session_id, pMac->lim.maxStation,
+ eSIR_INFRASTRUCTURE_MODE);
+ if (ft_session_ptr == NULL) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "LFR3: Session Can't be created for new AP during Roam Synch");
+ lim_print_mac_addr(pMac, bss_desc_ptr->bssId, LOGE);
+ return;
+ }
+ ft_session_ptr->peSessionId = session_id;
+ sir_copy_mac_addr(ft_session_ptr->selfMacAddr, session_ptr->selfMacAddr);
+ sir_copy_mac_addr(ft_session_ptr->limReAssocbssId, bss_desc_ptr->bssId);
+ ft_session_ptr->bssType = eSIR_INFRASTRUCTURE_MODE;
+ /**
+ * Set bRoamSynchInProgress here since this session is
+ *specific to roam synch indication. This flag will
+ *later be used to differentiate LFR3 with LFR2 in LIM
+ **/
+ ft_session_ptr->bRoamSynchInProgress = true;
+
+ if (ft_session_ptr->bssType == eSIR_INFRASTRUCTURE_MODE) {
+ ft_session_ptr->limSystemRole = eLIM_STA_ROLE;
+ } else {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "LFR3:Invalid bss type");
+ return;
+ }
+ ft_session_ptr->limPrevSmeState = ft_session_ptr->limSmeState;
+ ft_session_ptr->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:%s:created session (%p) with id = %d",
+ __func__, ft_session_ptr, ft_session_ptr->peSessionId);
+ /* Update the ReAssoc BSSID of the current session */
+ sir_copy_mac_addr(session_ptr->limReAssocbssId, bss_desc_ptr->bssId);
+ lim_print_mac_addr(pMac, session_ptr->limReAssocbssId, LOG2);
+
+ /* Prepare the session right now with as much as possible */
+ lim_fill_ft_session(pMac, bss_desc_ptr, ft_session_ptr, session_ptr);
+ lim_ft_prepare_add_bss_req(pMac, false, ft_session_ptr, bss_desc_ptr);
+ mmh_msg.type =
+ roam_sync_ind_ptr->messageType;
+ /* eWNI_SME_ROAM_OFFLOAD_SYNCH_IND */
+ mmh_msg.bodyptr = roam_sync_ind_ptr;
+ mmh_msg.bodyval = 0;
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:%s:sending eWNI_SME_ROAM_OFFLOAD_SYNCH_IND", __func__);
+ lim_sys_process_mmh_msg_api(pMac, &mmh_msg, ePROT);
+}
+#endif
+
+uint8_t lim_is_beacon_miss_scenario(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo)
+{
+ tpSirMacMgmtHdr pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ uint8_t sessionId;
+ tpPESession psessionEntry =
+ pe_find_session_by_bssid(pMac, pHdr->bssId, &sessionId);
+
+ if (psessionEntry && psessionEntry->pmmOffloadInfo.bcnmiss)
+ return true;
+ return false;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_is_pkt_candidate_for_drop() - decides whether to drop the frame or not
+
+ This function is called before enqueuing the frame to PE queue for further processing.
+ This prevents unnecessary frames getting into PE Queue and drops them right away.
+ Frames will be droped in the following scenarios:
+
+ - In Scan State, drop the frames which are not marked as scan frames
+ - In non-Scan state, drop the frames which are marked as scan frames.
+ - Drop INFRA Beacons and Probe Responses in IBSS Mode
+ - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon
+
+ \param pMac - global mac structure
+ \return - none
+ \sa
+ ----------------------------------------------------------------- */
+
+tMgmtFrmDropReason lim_is_pkt_candidate_for_drop(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ uint32_t subType)
+{
+ uint32_t framelen;
+ uint8_t *pBody;
+ tSirMacCapabilityInfo capabilityInfo;
+ tpSirMacMgmtHdr pHdr = NULL;
+ tpPESession psessionEntry = NULL;
+ uint8_t sessionId;
+
+ /*
+ *
+ * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames.
+ * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames.
+ * Allow other mgmt frames, they must be from our own AP, as we don't allow
+ * other than beacons or probe responses in scan state.
+ */
+ if ((subType == SIR_MAC_MGMT_BEACON) ||
+ (subType == SIR_MAC_MGMT_PROBE_RSP)) {
+ if (lim_is_beacon_miss_scenario(pMac, pRxPacketInfo)) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_INFO_LOG, 0,
+ eLOG_NODROP_MISSED_BEACON_SCENARIO));
+ return eMGMT_DROP_NO_DROP;
+ }
+ if (lim_is_system_in_scan_state(pMac)) {
+ return eMGMT_DROP_NO_DROP;
+ } else if (WMA_IS_RX_IN_SCAN(pRxPacketInfo)) {
+ return eMGMT_DROP_SCAN_MODE_FRAME;
+ } else {
+ /* Beacons and probe responses can come in any time
+ * because of parallel scans. Don't drop them.
+ */
+ return eMGMT_DROP_NO_DROP;
+ }
+ }
+
+ if ((subType == SIR_MAC_MGMT_DEAUTH ||
+ subType == SIR_MAC_MGMT_DISASSOC) &&
+ lim_is_deauth_diassoc_for_drop(pMac, pRxPacketInfo))
+ return eMGMT_DROP_SPURIOUS_FRAME;
+
+#ifdef WLAN_FEATURE_11W
+ if ((subType == SIR_MAC_MGMT_ASSOC_REQ ||
+ subType == SIR_MAC_MGMT_REASSOC_REQ) &&
+ lim_is_assoc_req_for_drop(pMac, pRxPacketInfo))
+ return eMGMT_DROP_SPURIOUS_FRAME;
+#endif
+
+ framelen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ /* Drop INFRA Beacons and Probe Responses in IBSS Mode */
+ if ((subType == SIR_MAC_MGMT_BEACON) ||
+ (subType == SIR_MAC_MGMT_PROBE_RSP)) {
+ /* drop the frame if length is less than 12 */
+ if (framelen < LIM_MIN_BCN_PR_LENGTH)
+ return eMGMT_DROP_INVALID_SIZE;
+
+ *((uint16_t *) &capabilityInfo) =
+ sir_read_u16(pBody + LIM_BCN_PR_CAPABILITY_OFFSET);
+
+ /* Note sure if this is sufficient, basically this condition allows all probe responses and
+ * beacons from an infrastructure network
+ */
+ if (!capabilityInfo.ibss)
+ return eMGMT_DROP_NO_DROP;
+
+ /* This can be enhanced to even check the SSID before deciding to enque the frame. */
+ if (capabilityInfo.ess)
+ return eMGMT_DROP_INFRA_BCN_IN_IBSS;
+ } else if ((subType == SIR_MAC_MGMT_PROBE_REQ) &&
+ (!WMA_GET_RX_BEACON_SENT(pRxPacketInfo))) {
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ psessionEntry =
+ pe_find_session_by_bssid(pMac, pHdr->bssId, &sessionId);
+ if ((psessionEntry && !LIM_IS_IBSS_ROLE(psessionEntry)) ||
+ (!psessionEntry))
+ return eMGMT_DROP_NO_DROP;
+
+ /* Drop the Probe Request in IBSS mode, if STA did not send out the last beacon */
+ /* In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq */
+ return eMGMT_DROP_NOT_LAST_IBSS_BCN;
+ }
+
+ return eMGMT_DROP_NO_DROP;
+}
+
+CDF_STATUS pe_acquire_global_lock(tAniSirLim *psPe)
+{
+ CDF_STATUS status = CDF_STATUS_E_INVAL;
+
+ if (psPe) {
+ if (CDF_IS_STATUS_SUCCESS
+ (cdf_mutex_acquire(&psPe->lkPeGlobalLock))) {
+ status = CDF_STATUS_SUCCESS;
+ }
+ }
+ return status;
+}
+
+CDF_STATUS pe_release_global_lock(tAniSirLim *psPe)
+{
+ CDF_STATUS status = CDF_STATUS_E_INVAL;
+ if (psPe) {
+ if (CDF_IS_STATUS_SUCCESS
+ (cdf_mutex_release(&psPe->lkPeGlobalLock))) {
+ status = CDF_STATUS_SUCCESS;
+ }
+ }
+ return status;
+}
+
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c
new file mode 100644
index 0000000..a1680d6
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_assoc_utils.c
@@ -0,0 +1,5132 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_assoc_utils.cc contains the utility functions
+ * LIM uses while processing (Re) Association messages.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_api.h"
+#include "sir_common.h"
+
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_admit_control.h"
+#include "lim_send_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+
+#include "cdf_types.h"
+#include "wma_types.h"
+#include "lim_types.h"
+
+/*
+ * fill up the rate info properly based on what is actually supported by the peer
+ * TBD TBD TBD
+ */
+void
+lim_fill_supported_rates_info(tpAniSirGlobal pMac,
+ tpDphHashNode pSta,
+ tpSirSupportedRates pRates, tpPESession psessionEntry)
+{
+ /* pSta will be NULL for self entry, so get the opRateMode based on the self mode. */
+ /* For the peer entry get it from the peer Capabilities present in hash table */
+ if (pSta == NULL)
+ pRates->opRateMode =
+ lim_get_sta_rate_mode((uint8_t) psessionEntry->dot11mode);
+ else
+ pRates->opRateMode =
+ lim_get_sta_peer_type(pMac, pSta, psessionEntry);
+
+}
+
+/**
+ * lim_cmp_s_sid()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether received SSid is same as SSID in use.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param *prxSSid - pointer to SSID structure
+ *
+ * @return status - true for SSID match else false.
+ */
+
+uint8_t
+lim_cmp_s_sid(tpAniSirGlobal pMac, tSirMacSSid *prxSSid,
+ tpPESession psessionEntry)
+{
+
+ if (cdf_mem_compare
+ ((uint8_t *) prxSSid, (uint8_t *) &psessionEntry->ssId,
+ (uint8_t) (psessionEntry->ssId.length + 1)))
+ return true;
+ else
+ return false;
+
+} /****** end lim_cmp_s_sid() ******/
+
+/**
+ * lim_compare_capabilities()
+ *
+ ***FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received capabilities
+ * match with local capabilities or not.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAssocReq - Pointer to received Assoc Req frame
+ * @param pLocalCapabs - Pointer to local capabilities
+ *
+ * @return status - true for Capabilitity match else false.
+ */
+
+uint8_t
+lim_compare_capabilities(tpAniSirGlobal pMac,
+ tSirAssocReq *pAssocReq,
+ tSirMacCapabilityInfo *pLocalCapabs,
+ tpPESession psessionEntry)
+{
+ uint32_t val;
+
+ if ((LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
+ (pAssocReq->capabilityInfo.ibss)) {
+ /* Requesting STA asserting IBSS capability. */
+ lim_log(pMac, LOG1,
+ FL("Requesting STA asserting IBSS capability"));
+ return false;
+ }
+ /* Compare CF capabilities */
+ if (pAssocReq->capabilityInfo.cfPollable ||
+ pAssocReq->capabilityInfo.cfPollReq) {
+ /* AP does not support PCF functionality */
+ lim_log(pMac, LOG1,
+ FL(" AP does not support PCF functionality"));
+ return false;
+ }
+ /* Compare short preamble capability */
+ if (pAssocReq->capabilityInfo.shortPreamble &&
+ (pAssocReq->capabilityInfo.shortPreamble !=
+ pLocalCapabs->shortPreamble)) {
+ /* Allowing a STA requesting short preamble while */
+ /* AP does not support it */
+ }
+
+ lim_log(pMac, LOG1, "QoS in AssocReq: %d, local capabs qos: %d",
+ pAssocReq->capabilityInfo.qos, pLocalCapabs->qos);
+
+ /* Compare QoS capability */
+ if (pAssocReq->capabilityInfo.qos &&
+ (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos)) {
+ /*Temporary hack for UPF to skip 11e capability check in order to interop with
+ CSR - proper fix needs to be put in place */
+ lim_log(pMac, LOG1,
+ FL
+ ("Received unmatched QOS but cfg to suppress - continuing"));
+ }
+
+ /*
+ * If AP supports shortSlot and if apple user has
+ * enforced association only from shortSlot station,
+ * then AP must reject any station that does not support
+ * shortSlot
+ */
+ if ((LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
+ (pLocalCapabs->shortSlotTime == 1)) {
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY,
+ &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY "));
+ return false;
+ }
+ if (val) {
+ if (pAssocReq->capabilityInfo.shortSlotTime !=
+ pLocalCapabs->shortSlotTime) {
+ lim_log(pMac, LOGE,
+ FL
+ ("AP rejects association as station doesnt support shortslot time"));
+ return false;
+ }
+ return false;
+ }
+ }
+
+ return true;
+} /****** end lim_compare_capabilities() ******/
+
+/**
+ * lim_check_rx_basic_rates()
+ *
+ ***FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received rates in
+ * Assoc/Reassoc request frames include all BSS basic rates
+ * or not.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param rxRateSet - pointer to SSID structure
+ *
+ * @return status - true if ALL BSS basic rates are present in the
+ * received rateset else false.
+ */
+
+uint8_t
+lim_check_rx_basic_rates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,
+ tpPESession psessionEntry)
+{
+ tSirMacRateSet *pRateSet, basicRate;
+ uint8_t i, j, k, match;
+
+ pRateSet = cdf_mem_malloc(sizeof(tSirMacRateSet));
+ if (NULL == pRateSet) {
+ lim_log(pMac, LOGP,
+ FL("call to AllocateMemory failed for RATESET"));
+
+ return false;
+ }
+
+ /* Copy operational rate set from session Entry */
+ cdf_mem_copy(pRateSet->rate, (psessionEntry->rateSet.rate),
+ psessionEntry->rateSet.numRates);
+
+ pRateSet->numRates = psessionEntry->rateSet.numRates;
+
+ /* Extract BSS basic rateset from operational rateset */
+ for (i = 0, j = 0;
+ ((i < pRateSet->numRates) && (i < SIR_MAC_RATESET_EID_MAX)); i++) {
+ if ((pRateSet->rate[i] & 0x80) == 0x80) {
+ /* msb is set, so this is a basic rate */
+ basicRate.rate[j++] = pRateSet->rate[i];
+ }
+ }
+
+ /*
+ * For each BSS basic rate, find if it is present in the
+ * received rateset.
+ */
+ for (k = 0; k < j; k++) {
+ match = 0;
+ for (i = 0;
+ ((i < rxRateSet.numRates)
+ && (i < SIR_MAC_RATESET_EID_MAX)); i++) {
+ if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k])
+ match = 1;
+ }
+
+ if (!match) {
+ /* Free up memory allocated for rateset */
+ cdf_mem_free((uint8_t *) pRateSet);
+
+ return false;
+ }
+ }
+
+ /* Free up memory allocated for rateset */
+ cdf_mem_free((uint8_t *) pRateSet);
+
+ return true;
+} /****** end lim_check_rx_basic_rates() ******/
+
+/**
+ * lim_check_mcs_set()
+ *
+ ***FUNCTION:
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received MCS rates in
+ * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param supportedMCSSet - pointer to Supported MCS Rate Set
+ *
+ * @return status - true if ALL MCS Basic Rate Set rates are present in the
+ * received rateset else false.
+ */
+
+uint8_t lim_check_mcs_set(tpAniSirGlobal pMac, uint8_t *supportedMCSSet)
+{
+ uint8_t basicMCSSet[SIZE_OF_BASIC_MCS_SET] = { 0 };
+ uint32_t cfgLen = 0;
+ uint8_t i;
+ uint8_t validBytes;
+ uint8_t lastByteMCSMask = 0x1f;
+
+ cfgLen = WNI_CFG_BASIC_MCS_SET_LEN;
+ if (wlan_cfg_get_str(pMac, WNI_CFG_BASIC_MCS_SET,
+ (uint8_t *) basicMCSSet,
+ (uint32_t *) &cfgLen) != eSIR_SUCCESS) {
+ /* / Could not get Basic MCS rateset from CFG. Log error. */
+ lim_log(pMac, LOGP, FL("could not retrieve Basic MCS rateset"));
+ return false;
+ }
+
+ validBytes = VALID_MCS_SIZE / 8;
+
+ /* check if all the Basic MCS Bits are set in supported MCS bitmap */
+ for (i = 0; i < validBytes; i++) {
+ if ((basicMCSSet[i] & supportedMCSSet[i]) != basicMCSSet[i]) {
+ /* Log is avaiable in calling function in file lim_process_assoc_req_frame.c */
+ lim_log(pMac, LOGW,
+ FL
+ ("One of Basic MCS Set Rates is not supported by the Station."));
+ return false;
+ }
+ }
+
+ /* check the last 5 bits of the valid MCS bitmap */
+ if (((basicMCSSet[i] & lastByteMCSMask) &
+ (supportedMCSSet[i] & lastByteMCSMask)) !=
+ (basicMCSSet[i] & lastByteMCSMask)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("One of Basic MCS Set Rates is not supported by the Station."));
+ return false;
+ }
+
+ return true;
+}
+
+#define SECURITY_SUITE_TYPE_MASK 0xFF
+#define SECURITY_SUITE_TYPE_WEP40 0x1
+#define SECURITY_SUITE_TYPE_TKIP 0x2
+#define SECURITY_SUITE_TYPE_CCMP 0x4
+#define SECURITY_SUITE_TYPE_WEP104 0x4
+
+/**
+ * lim_check_rx_rsn_ie_match()- validate received rsn ie with supported cipher
+ * suites.
+ * @mac_ctx: pointer to global mac structure
+ * @rx_rsn_ie: received rsn IE
+ * @session_entry: pe session entry
+ * @sta_is_ht: peer station HT capability
+ * @pmf_connection: set to true if this is pmf connection
+ *
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received RSN in
+ * Assoc/Reassoc request frames include supported cipher suites or not.
+ *
+ * Return: eSIR_SUCCESS if ALL BSS basic rates are present in the
+ * received rateset else failure status.
+ */
+
+uint8_t
+lim_check_rx_rsn_ie_match(tpAniSirGlobal mac_ctx, tDot11fIERSN rx_rsn_ie,
+ tpPESession session_entry, uint8_t sta_is_ht,
+ bool *pmf_connection)
+{
+ tDot11fIERSN *rsn_ie;
+ uint8_t i, j, match, only_non_ht_cipher = 1;
+#ifdef WLAN_FEATURE_11W
+ bool we_are_pmf_capable;
+ bool we_require_pmf;
+ bool they_are_pmf_capable;
+ bool they_require_pmf;
+#endif
+
+ /* RSN IE should be received from PE */
+ rsn_ie = &session_entry->gStartBssRSNIe;
+
+ /* Check groupwise cipher suite */
+ for (i = 0; i < sizeof(rx_rsn_ie.gp_cipher_suite); i++)
+ if (rsn_ie->gp_cipher_suite[i] !=
+ rx_rsn_ie.gp_cipher_suite[i]) {
+ lim_log(mac_ctx, LOG3,
+ FL("Invalid groupwise cipher suite"));
+ return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
+ }
+
+ /*
+ * For each Pairwise cipher suite check whether we support
+ * received pairwise
+ */
+ match = 0;
+ for (i = 0; i < rx_rsn_ie.pwise_cipher_suite_count; i++) {
+ for (j = 0; j < rsn_ie->pwise_cipher_suite_count; j++) {
+ if (cdf_mem_compare(&rx_rsn_ie.pwise_cipher_suites[i],
+ &rsn_ie->pwise_cipher_suites[j],
+ sizeof(rsn_ie->pwise_cipher_suites[j]))) {
+ match = 1;
+ break;
+ }
+ }
+
+ if ((sta_is_ht)
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+ &&
+ ((rx_rsn_ie.pwise_cipher_suites[i][3] &
+ SECURITY_SUITE_TYPE_MASK) ==
+ SECURITY_SUITE_TYPE_CCMP))
+#else
+ &&
+ ((rx_rsn_ie.pwise_cipher_suites[i][0] &
+ SECURITY_SUITE_TYPE_MASK) ==
+ SECURITY_SUITE_TYPE_CCMP))
+#endif
+ only_non_ht_cipher = 0;
+
+ }
+
+ if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
+ lim_log(mac_ctx, LOG1, FL("Invalid pairwise cipher suite"));
+ return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS;
+ }
+ /*
+ * Check RSN capabilities
+ * Bit 0 of First Byte - PreAuthentication Capability
+ */
+ if (((rx_rsn_ie.RSN_Cap[0] >> 0) & 0x1) == true) {
+ /* this is supported by AP only */
+ lim_log(mac_ctx, LOG1,
+ FL("Invalid RSN information element capabilities"));
+ return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS;
+ }
+
+ *pmf_connection = false;
+
+#ifdef WLAN_FEATURE_11W
+ we_are_pmf_capable = session_entry->pLimStartBssReq->pmfCapable;
+ we_require_pmf = session_entry->pLimStartBssReq->pmfRequired;
+ they_are_pmf_capable = (rx_rsn_ie.RSN_Cap[0] >> 7) & 0x1;
+ they_require_pmf = (rx_rsn_ie.RSN_Cap[0] >> 6) & 0x1;
+
+ if ((they_require_pmf && they_are_pmf_capable && !we_are_pmf_capable) ||
+ (we_require_pmf && !they_are_pmf_capable)) {
+ lim_log(mac_ctx, LOG1,
+ FL("Association fail, robust management frames policy"
+ " violation they_require_pmf =%d"
+ " theyArePMFCapable %d weArePMFCapable %d"
+ " weRequirePMF %d theyArePMFCapable %d"),
+ they_require_pmf, they_are_pmf_capable,
+ we_are_pmf_capable, we_require_pmf,
+ they_are_pmf_capable);
+ return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION;
+ }
+
+ if (they_are_pmf_capable && we_are_pmf_capable)
+ *pmf_connection = true;
+
+ lim_log(mac_ctx, LOG1,
+ FL("weAreCapable %d, weRequire %d, theyAreCapable %d,"
+ " theyRequire %d, PMFconnection %d"),
+ we_are_pmf_capable, we_require_pmf, they_are_pmf_capable,
+ they_require_pmf, *pmf_connection);
+#endif
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_check_rx_wpa_ie_match() - to check supported cipher suites
+ *
+ * @mac: pointer to global mac structure
+ * @rx_wpaie: Received WPA IE in (Re)Assco req
+ * @session_entry: pointer to PE session
+ * @sta_is_ht: peer station is HT
+ *
+ * This function is called during Association/Reassociation
+ * frame handling to determine whether received RSN in
+ * Assoc/Reassoc request frames include supported cipher suites or not.
+ *
+ * Return: Success if ALL BSS basic rates are present in the
+ * received rateset else failure status.
+ */
+
+uint8_t
+lim_check_rx_wpa_ie_match(tpAniSirGlobal mac, tDot11fIEWPA rx_wpaie,
+ tpPESession session_entry, uint8_t sta_is_ht)
+{
+ tDot11fIEWPA *wpa_ie;
+ uint8_t i, j, match, only_non_ht_cipher = 1;
+
+ /* WPA IE should be received from PE */
+ wpa_ie = &session_entry->gStartBssWPAIe;
+
+ /* Check groupwise cipher suite */
+ for (i = 0; i < 4; i++) {
+ if (wpa_ie->multicast_cipher[i] != rx_wpaie.multicast_cipher[i]) {
+ lim_log(mac, LOG1,
+ FL("Invalid groupwise cipher suite"));
+ return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
+ }
+ }
+
+ /*
+ * For each Pairwise cipher suite check whether we support
+ * received pairwise
+ */
+ match = 0;
+ for (i = 0; i < rx_wpaie.unicast_cipher_count; i++) {
+ for (j = 0; j < wpa_ie->unicast_cipher_count; j++) {
+ if (cdf_mem_compare(rx_wpaie.unicast_ciphers[i],
+ wpa_ie->unicast_ciphers[j], 4)) {
+ match = 1;
+ break;
+ }
+ }
+
+ if ((sta_is_ht)
+#ifdef ANI_LITTLE_BYTE_ENDIAN
+ &&
+ ((rx_wpaie.
+ unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) ==
+ SECURITY_SUITE_TYPE_CCMP))
+#else
+ &&
+ ((rx_wpaie.
+ unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) ==
+ SECURITY_SUITE_TYPE_CCMP))
+#endif
+ {
+ only_non_ht_cipher = 0;
+ }
+
+ }
+
+ if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
+ lim_log(mac, LOG1, FL("Invalid pairwise cipher suite"));
+ return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_cleanup_rx_path()
+ *
+ ***FUNCTION:
+ * This function is called to cleanup STA state at SP & RFP.
+ *
+ ***LOGIC:
+ * To circumvent RFP's handling of dummy packet when it does not
+ * have an incomplete packet for the STA to be deleted, a packet
+ * with 'more framgents' bit set will be queued to RFP's WQ before
+ * queuing 'dummy packet'.
+ * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010
+ * (Disassociation frame) and routing flags in BD set to eCPU's
+ * Low Priority WQ.
+ * RFP cleans up its local context for the STA id mentioned in the
+ * BD and then pushes BD to eCPU's low priority WQ.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pStaDs Pointer to the per STA data structure
+ * initialized by LIM and maintained at DPH
+ *
+ * @return None
+ */
+
+tSirRetStatus
+lim_cleanup_rx_path(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ lim_log(pMac, LOG1, FL("Cleanup Rx Path for AID : %d"
+ "psessionEntry->limSmeState : %d, mlmState : %d"),
+ pStaDs->assocId, psessionEntry->limSmeState,
+ pStaDs->mlmStaContext.mlmState);
+
+ psessionEntry->isCiscoVendorAP = false;
+
+ if (pMac->lim.gLimAddtsSent) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER));
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer);
+ }
+
+ if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) {
+ lim_deactivate_and_change_per_sta_id_timer(pMac, eLIM_CNF_WAIT_TIMER,
+ pStaDs->assocId);
+
+ if (!pStaDs->mlmStaContext.updateContext) {
+ /**
+ * There is no context at Polaris to delete.
+ * Release our assigned AID back to the free pool
+ */
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ lim_release_peer_idx(pMac, pStaDs->assocId,
+ psessionEntry);
+ }
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
+ pStaDs->assocId, psessionEntry);
+
+ return retCode;
+ }
+ }
+ /* delete all tspecs associated with this sta. */
+ lim_admit_control_delete_sta(pMac, pStaDs->assocId);
+
+ /**
+ * Make STA hash entry invalid at eCPU so that DPH
+ * does not process any more data packets and
+ * releases those BDs
+ */
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ eLIM_MLM_WT_DEL_STA_RSP_STATE));
+ psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ /* Deactivating probe after heart beat timer */
+ lim_deactivate_and_change_timer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
+ lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
+ pMac->lim.gLastBeaconDtimCount = 0;
+ pMac->lim.gLastBeaconDtimPeriod = 0;
+
+#ifdef FEATURE_WLAN_ESE
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
+#else
+ lim_deactivate_and_change_timer(pMac, eLIM_TSM_TIMER);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+#endif
+
+ }
+#ifdef WLAN_DEBUG
+ /* increment a debug count */
+ pMac->lim.gLimNumRxCleanup++;
+#endif
+
+ if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) {
+ retCode =
+ lim_del_bss(pMac, pStaDs, psessionEntry->bssIdx,
+ psessionEntry);
+ } else
+ retCode = lim_del_sta(pMac, pStaDs, true, psessionEntry);
+
+ return retCode;
+
+} /*** end lim_cleanup_rx_path() ***/
+
+/**
+ * lim_send_del_sta_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to send appropriate CNF message to SME
+ *
+ ***LOGIC:
+ *
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tpAniSirGlobal pMac,
+ * @param tSirMacAddr staDsAddr,
+ * @param uint16_t staDsAssocId,
+ * @param tLimMlmStaContext mlmStaContext,
+ * @param tSirResultCodes statusCode
+ *
+ * @return None
+ */
+
+void
+lim_send_del_sta_cnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr,
+ uint16_t staDsAssocId, tLimMlmStaContext mlmStaContext,
+ tSirResultCodes statusCode, tpPESession psessionEntry)
+{
+
+ tLimMlmDisassocCnf mlmDisassocCnf;
+ tLimMlmDeauthCnf mlmDeauthCnf;
+ tLimMlmPurgeStaInd mlmPurgeStaInd;
+
+ lim_log(pMac, LOG1, FL("Sessionid: %d staDsAssocId: %d Trigger: %d"
+ "statusCode: %d staDsAddr: " MAC_ADDRESS_STR),
+ psessionEntry->peSessionId, staDsAssocId,
+ mlmStaContext.cleanupTrigger, statusCode,
+ MAC_ADDR_ARRAY(staDsAddr));
+
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ /* Set BSSID at CFG to null */
+ tSirMacAddr nullAddr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ sir_copy_mac_addr(nullAddr, psessionEntry->bssId);
+
+ /* Free up buffer allocated for JoinReq held by */
+ /* MLM state machine */
+ if (psessionEntry->pLimMlmJoinReq) {
+ cdf_mem_free(psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ psessionEntry->limAID = 0;
+
+ }
+
+ if ((mlmStaContext.cleanupTrigger ==
+ eLIM_HOST_DISASSOC) ||
+ (mlmStaContext.cleanupTrigger ==
+ eLIM_LINK_MONITORING_DISASSOC) ||
+ (mlmStaContext.cleanupTrigger == eLIM_PROMISCUOUS_MODE_DISASSOC)) {
+ /**
+ * Host or LMM driven Disassociation.
+ * Issue Disassoc Confirm to SME.
+ */
+ lim_log(pMac, LOGW,
+ FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %d"),
+ mlmStaContext.cleanupTrigger);
+
+ cdf_mem_copy((uint8_t *) &mlmDisassocCnf.peerMacAddr,
+ (uint8_t *) staDsAddr, sizeof(tSirMacAddr));
+ mlmDisassocCnf.resultCode = statusCode;
+ mlmDisassocCnf.disassocTrigger = mlmStaContext.cleanupTrigger;
+ /* Update PE session Id */
+ mlmDisassocCnf.sessionId = psessionEntry->peSessionId;
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_DISASSOC_CNF,
+ (uint32_t *) &mlmDisassocCnf);
+ } else if ((mlmStaContext.cleanupTrigger ==
+ eLIM_HOST_DEAUTH) ||
+ (mlmStaContext.cleanupTrigger ==
+ eLIM_LINK_MONITORING_DEAUTH)) {
+ /**
+ * Host or LMM driven Deauthentication.
+ * Issue Deauth Confirm to SME.
+ */
+ lim_log(pMac, LOGW,
+ FL("Lim Posting DEAUTH_CNF to Sme. Trigger: %d"),
+ mlmStaContext.cleanupTrigger);
+ cdf_mem_copy((uint8_t *) &mlmDeauthCnf.peerMacAddr,
+ (uint8_t *) staDsAddr, sizeof(tSirMacAddr));
+ mlmDeauthCnf.resultCode = statusCode;
+ mlmDeauthCnf.deauthTrigger = mlmStaContext.cleanupTrigger;
+ /* PE session Id */
+ mlmDeauthCnf.sessionId = psessionEntry->peSessionId;
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_DEAUTH_CNF,
+ (uint32_t *) &mlmDeauthCnf);
+ } else if ((mlmStaContext.cleanupTrigger ==
+ eLIM_PEER_ENTITY_DISASSOC) ||
+ (mlmStaContext.cleanupTrigger == eLIM_PEER_ENTITY_DEAUTH)) {
+ /**
+ * Received Disassociation/Deauthentication from peer.
+ * Issue Purge Ind to SME.
+ */
+ lim_log(pMac, LOGW,
+ FL("Lim Posting PURGE_STA_IND to Sme. Trigger: %d"),
+ mlmStaContext.cleanupTrigger);
+ cdf_mem_copy((uint8_t *) &mlmPurgeStaInd.peerMacAddr,
+ (uint8_t *) staDsAddr, sizeof(tSirMacAddr));
+ mlmPurgeStaInd.reasonCode =
+ (uint8_t) mlmStaContext.disassocReason;
+ mlmPurgeStaInd.aid = staDsAssocId;
+ mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger;
+ mlmPurgeStaInd.sessionId = psessionEntry->peSessionId;
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_PURGE_STA_IND,
+ (uint32_t *) &mlmPurgeStaInd);
+ } else if (mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE) {
+ /* PE setup the peer entry in HW upfront, right after join is completed. */
+ /* If there is a failure during rest of the assoc sequence, this context needs to be cleaned up. */
+ uint8_t smesessionId;
+ uint16_t smetransactionId;
+
+ smesessionId = psessionEntry->smeSessionId;
+ smetransactionId = psessionEntry->transactionId;
+
+ psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+
+ /* if it is a reassoc failure to join new AP */
+ if ((mlmStaContext.resultCode ==
+ eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE)
+ || (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE)
+ || (mlmStaContext.resultCode ==
+ eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE)) {
+ lim_log(pMac, LOG1,
+ FL("Lim Posting eWNI_SME_REASSOC_RSP to SME"
+ "resultCode: %d, statusCode: %d,"
+ "sessionId: %d"),
+ mlmStaContext.resultCode,
+ mlmStaContext.protStatusCode,
+ psessionEntry->peSessionId);
+
+ if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
+ pe_delete_session(pMac, psessionEntry);
+ psessionEntry = NULL;
+ }
+
+ lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP,
+ mlmStaContext.resultCode,
+ mlmStaContext.protStatusCode,
+ psessionEntry, smesessionId,
+ smetransactionId);
+ } else {
+ cdf_mem_free(psessionEntry->pLimJoinReq);
+ psessionEntry->pLimJoinReq = NULL;
+
+ lim_log(pMac, LOG1,
+ FL("Lim Posting eWNI_SME_JOIN_RSP to SME."
+ "resultCode: %d,statusCode: %d,"
+ "sessionId: %d"),
+ mlmStaContext.resultCode,
+ mlmStaContext.protStatusCode,
+ psessionEntry->peSessionId);
+
+ if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
+ pe_delete_session(pMac, psessionEntry);
+ psessionEntry = NULL;
+ }
+
+ lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_JOIN_RSP,
+ mlmStaContext.resultCode,
+ mlmStaContext.protStatusCode,
+ psessionEntry, smesessionId,
+ smetransactionId);
+ }
+
+ }
+
+ if (NULL != psessionEntry && !LIM_IS_AP_ROLE(psessionEntry)) {
+ pe_delete_session(pMac, psessionEntry);
+ psessionEntry = NULL;
+ }
+}
+
+/**
+ * lim_reject_association() - function to reject Re/Association Request
+ *
+ * @mac_ctx: pointer to global mac structure
+ * @peer_addr: mac address of the peer
+ * @sub_type: Indicates whether it is Association Request (=0) or
+ * Reassociation Request (=1) frame
+ * @add_pre_auth_context:Indicates whether pre-auth context
+ * to be added for this STA
+ * @auth_type: Indicates auth type to be added
+ * @sta_id: Indicates staId of the STA being rejected
+ * association
+ * @delete_sta: Indicates whether to delete STA context
+ * at Polaris
+ * @result_code: Indicates what reasonCode to be sent in
+ * Re/Assoc response to STA
+ * @session_entry: pointer to PE session
+ *
+ * This function is called whenever Re/Association Request need
+ * to be rejected due to failure in assigning an AID or failure
+ * in adding STA context at Polaris or reject by applications.
+ * Resources allocated if any are freedup and (Re) Association
+ * Response frame is sent to requesting STA. Pre-Auth context
+ * will be added for this STA if it does not exist already
+ *
+ * Return: none
+ */
+
+void
+lim_reject_association(tpAniSirGlobal mac_ctx, tSirMacAddr peer_addr,
+ uint8_t sub_type, uint8_t add_pre_auth_context,
+ tAniAuthType auth_type, uint16_t sta_id,
+ uint8_t delete_sta, tSirResultCodes result_code,
+ tpPESession session_entry)
+{
+ tpDphHashNode sta_ds;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Sessionid: %d auth_type: %d sub_type: %d add_pre_auth_context: %d sta_id: %d delete_sta: %d result_code : %d peer_addr: " MAC_ADDRESS_STR),
+ session_entry->peSessionId, auth_type, sub_type,
+ add_pre_auth_context, sta_id, delete_sta, result_code,
+ MAC_ADDR_ARRAY(peer_addr));
+
+ if (add_pre_auth_context) {
+ /* Create entry for this STA in pre-auth list */
+ struct tLimPreAuthNode *auth_node;
+
+ auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
+ &mac_ctx->lim.gLimPreAuthTimerTable);
+
+ if (auth_node) {
+ cdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
+ peer_addr, sizeof(tSirMacAddr));
+ auth_node->fTimerStarted = 0;
+ auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+ auth_node->authType = (tAniAuthType) auth_type;
+ auth_node->timestamp = cdf_mc_timer_get_system_ticks();
+ lim_add_pre_auth_node(mac_ctx, auth_node);
+ }
+ }
+
+ if (delete_sta == false) {
+ lim_send_assoc_rsp_mgmt_frame(mac_ctx,
+ eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
+ 1, peer_addr, sub_type, 0, session_entry);
+ /* Log error */
+ lim_log(mac_ctx, LOGW,
+ FL("received Re/Assoc req when max associated STAs reached from "));
+ lim_print_mac_addr(mac_ctx, peer_addr, LOGW);
+ lim_send_sme_max_assoc_exceeded_ntf(mac_ctx, peer_addr,
+ session_entry->smeSessionId);
+ return;
+ }
+
+ sta_ds = dph_get_hash_entry(mac_ctx, sta_id,
+ &session_entry->dph.dphHashTable);
+
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGW,
+ FL("No STA context, yet rejecting Association"));
+ return;
+ }
+
+ /*
+ * Polaris has state for this STA.
+ * Trigger cleanup.
+ */
+ sta_ds->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;
+
+ /* Receive path cleanup */
+ lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
+
+ /*
+ * Send Re/Association Response with
+ * status code to requesting STA.
+ */
+ lim_send_assoc_rsp_mgmt_frame(mac_ctx, result_code, 0, peer_addr,
+ sub_type, 0, session_entry);
+
+ if (session_entry->parsedAssocReq[sta_ds->assocId] != NULL) {
+ uint8_t *assoc_req_frame;
+
+ assoc_req_frame = (uint8_t *)((tpSirAssocReq) (session_entry->
+ parsedAssocReq[sta_ds->assocId]))->assocReqFrame;
+ /*
+ *Assoction confirmation is complete,
+ *free the copy of association request frame.
+ */
+ if (assoc_req_frame) {
+ cdf_mem_free(assoc_req_frame);
+ assoc_req_frame = NULL;
+ }
+
+ cdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
+ session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
+ }
+}
+
+/**
+ * lim_decide_ap_protection_on_ht20_delete() - function to update protection
+ * parameters.
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * protection related function while HT20 station is getting deleted.
+ *
+ * Return: none
+ */
+static void
+lim_decide_ap_protection_on_ht20_delete(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds,
+ tpUpdateBeaconParams beacon_params,
+ tpPESession session_entry)
+{
+ uint32_t i = 0;
+
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A HT 20 STA is disassociated. Addr is %pM"),
+ session_entry->gLimHt20Params.numSta, sta_ds->staAddr);
+
+ if (session_entry->gLimHt20Params.numSta > 0) {
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (!session_entry->protStaCache[i].active)
+ continue;
+
+ if (cdf_mem_compare(session_entry->protStaCache[i].addr,
+ sta_ds->staAddr, sizeof(tSirMacAddr))) {
+ session_entry->gLimHt20Params.numSta--;
+ session_entry->protStaCache[i].active =
+ false;
+ break;
+ }
+ }
+ }
+
+ if (session_entry->gLimHt20Params.numSta == 0) {
+ /* disable protection */
+ lim_log(mac_ctx, LOG1, FL("No 11B STA exists, PESessionID %d"),
+ session_entry->peSessionId);
+ lim_enable_ht20_protection(mac_ctx, false, false, beacon_params,
+ session_entry);
+ }
+}
+
+/**
+ * lim_decide_ap_protection_on_delete() - update SAP protection on station
+ * deletion.
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * Decides about protection related settings when a station is getting deleted.
+ *
+ * Return: none
+ */
+void
+lim_decide_ap_protection_on_delete(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds,
+ tpUpdateBeaconParams beacon_params,
+ tpPESession session_entry)
+{
+ uint32_t phy_mode;
+ tHalBitVal erp_enabled = eHAL_CLEAR;
+ tSirRFBand rf_band = SIR_BAND_UNKNOWN;
+ uint32_t i;
+
+ if (NULL == sta_ds)
+ return;
+
+ lim_get_rf_band_new(mac_ctx, &rf_band, session_entry);
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+ erp_enabled = sta_ds->erpEnabled;
+
+ if ((SIR_BAND_5_GHZ == rf_band) &&
+ (true == session_entry->htCapability) &&
+ (session_entry->beaconParams.llaCoexist) &&
+ (false == sta_ds->mlmStaContext.htCapability)) {
+ /*
+ * we are HT. if we are 11A, then protection is not required or
+ * we are HT and 11A station is leaving.
+ * protection consideration required.
+ * HT station leaving ==> this case is commonly handled
+ * between both the bands below.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A 11A STA is disassociated. Addr is %pM"),
+ session_entry->gLim11aParams.numSta, sta_ds->staAddr);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->protStaCache[i].active &&
+ cdf_mem_compare(
+ session_entry->protStaCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ session_entry->protStaCache[i].active = false;
+ break;
+ }
+ }
+
+ if (session_entry->gLim11aParams.numSta == 0) {
+ /* disable protection */
+ lim_update_11a_protection(mac_ctx, false, false,
+ beacon_params, session_entry);
+ }
+ }
+
+ /* we are HT or 11G and 11B station is getting deleted */
+ if ((SIR_BAND_2_4_GHZ == rf_band) &&
+ (phy_mode == WNI_CFG_PHY_MODE_11G ||
+ session_entry->htCapability) &&
+ (erp_enabled == eHAL_CLEAR)) {
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A legacy STA is disassociated. Addr is %pM"),
+ session_entry->gLim11bParams.numSta, sta_ds->staAddr);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->protStaCache[i].active &&
+ cdf_mem_compare(
+ session_entry->protStaCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ session_entry->gLim11bParams.numSta--;
+ session_entry->protStaCache[i].active =
+ false;
+ break;
+ }
+ }
+
+ if (session_entry->gLim11bParams.numSta == 0) {
+ /* disable protection */
+ lim_enable11g_protection(mac_ctx, false, false,
+ beacon_params, session_entry);
+ }
+ }
+
+ /*
+ * we are HT AP and non-11B station is leaving.
+ * 11g station is leaving
+ */
+ if ((SIR_BAND_2_4_GHZ == rf_band) &&
+ session_entry->htCapability &&
+ !sta_ds->mlmStaContext.htCapability) {
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A 11g STA is disassociated. Addr is %pM"),
+ session_entry->gLim11bParams.numSta, sta_ds->staAddr);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->protStaCache[i].active &&
+ cdf_mem_compare(
+ session_entry->protStaCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ session_entry->gLim11gParams.numSta--;
+ session_entry->protStaCache[i].active = false;
+ break;
+ }
+ }
+
+ if (session_entry->gLim11gParams.numSta == 0) {
+ /* disable protection */
+ lim_enable_ht_protection_from11g(mac_ctx, false, false,
+ beacon_params,
+ session_entry);
+ }
+ }
+
+ if (!((true == session_entry->htCapability) &&
+ (true == sta_ds->mlmStaContext.htCapability)))
+ return;
+
+ /*
+ * Applies to 2.4 as well as 5 GHZ.
+ * HT non-GF leaving
+ */
+ if (!sta_ds->htGreenfield) {
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A non-GF STA is disassociated. Addr is %pM"),
+ session_entry->gLimNonGfParams.numSta, sta_ds->staAddr);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->protStaCache[i].active &&
+ cdf_mem_compare(
+ session_entry->protStaCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ session_entry->protStaCache[i].active = false;
+ break;
+ }
+ }
+
+ if (session_entry->gLimNonGfParams.numSta == 0) {
+ /* disable protection */
+ lim_enable_ht_non_gf_protection(mac_ctx, false, false,
+ beacon_params, session_entry);
+ }
+ }
+
+ /*
+ * Applies to 2.4 as well as 5 GHZ.
+ * HT 20Mhz station leaving
+ */
+ if (session_entry->beaconParams.ht20Coexist &&
+ (eHT_CHANNEL_WIDTH_20MHZ ==
+ sta_ds->htSupportedChannelWidthSet)) {
+ lim_decide_ap_protection_on_ht20_delete(mac_ctx, sta_ds,
+ beacon_params, session_entry);
+ }
+
+ /*
+ * Applies to 2.4 as well as 5 GHZ.
+ * LSIG TXOP not supporting staiton leaving
+ */
+ if ((false == session_entry->beaconParams.
+ fLsigTXOPProtectionFullSupport) &&
+ (false == sta_ds->htLsigTXOPProtection)) {
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is %pM"),
+ session_entry->gLimLsigTxopParams.numSta,
+ sta_ds->staAddr);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->protStaCache[i].active &&
+ cdf_mem_compare(
+ session_entry->protStaCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ session_entry->protStaCache[i].active = false;
+ break;
+ }
+ }
+
+ if (session_entry->gLimLsigTxopParams.numSta == 0) {
+ /* disable protection */
+ lim_enable_ht_lsig_txop_protection(mac_ctx, true,
+ false, beacon_params, session_entry);
+ }
+ }
+}
+
+/**
+ * lim_decide_short_preamble() - update short preamble parameters
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * Decides about any short preamble related change because of new station
+ * joining.
+ *
+ * Return: None
+ */
+void lim_decide_short_preamble(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds,
+ tpUpdateBeaconParams beacon_params,
+ tpPESession session_entry)
+{
+ uint32_t i;
+
+ if (sta_ds->shortPreambleEnabled == eHAL_CLEAR) {
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A non-short preamble STA is disassociated. Addr is %pM"),
+ session_entry->gLimNoShortParams.numNonShortPreambleSta,
+ sta_ds->staAddr);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->gLimNoShortParams.
+ staNoShortCache[i].active &&
+ cdf_mem_compare(session_entry->
+ gLimNoShortParams.
+ staNoShortCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ session_entry->gLimNoShortParams.
+ numNonShortPreambleSta--;
+ session_entry->gLimNoShortParams.
+ staNoShortCache[i].active = false;
+ break;
+ }
+ }
+
+ if (session_entry->gLimNoShortParams.numNonShortPreambleSta)
+ return;
+
+ /*
+ * enable short preamble
+ * reset the cache
+ */
+ cdf_mem_set((uint8_t *) &session_entry->gLimNoShortParams,
+ sizeof(tLimNoShortParams), 0);
+ if (lim_enable_short_preamble(mac_ctx, true,
+ beacon_params, session_entry) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("Cannot enable short preamble"));
+ }
+ }
+}
+
+/**
+ * lim_decide_short_slot() - update short slot time related parameters
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @beacon_params: ap beacon parameters
+ * @session_entry: pe session entry
+ *
+ * Decides about any short slot time related change because of station leaving
+ * the BSS.
+ * Return: None
+ */
+void
+lim_decide_short_slot(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+ tpUpdateBeaconParams beacon_params,
+ tpPESession session_entry)
+{
+ uint32_t i, val, non_short_slot_sta_count;
+
+ if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR)
+ return;
+
+ lim_log(mac_ctx, LOG1,
+ FL("(%d) A non-short slottime STA is disassociated. Addr is %pM"),
+ mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta,
+ sta_ds->staAddr);
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
+ &val);
+
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ non_short_slot_sta_count =
+ session_entry->gLimNoShortSlotParams.numNonShortSlotSta;
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active &&
+ cdf_mem_compare(session_entry->
+ gLimNoShortSlotParams.
+ staNoShortSlotCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ non_short_slot_sta_count--;
+ session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active = false;
+ break;
+ }
+ }
+
+ if (non_short_slot_sta_count == 0 && val) {
+ /*
+ * enable short slot time
+ * reset the cache
+ */
+ cdf_mem_set((uint8_t *) &session_entry->
+ gLimNoShortSlotParams,
+ sizeof(tLimNoShortSlotParams), 0);
+ beacon_params->fShortSlotTime = true;
+ beacon_params->paramChangeBitmap |=
+ PARAM_SHORT_SLOT_TIME_CHANGED;
+ session_entry->shortSlotTimeSupported = true;
+ }
+ session_entry->gLimNoShortSlotParams.numNonShortSlotSta =
+ non_short_slot_sta_count;
+ } else {
+ non_short_slot_sta_count =
+ mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta;
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active &&
+ cdf_mem_compare(
+ mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].addr,
+ sta_ds->staAddr,
+ sizeof(tSirMacAddr))) {
+ non_short_slot_sta_count--;
+ mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active = false;
+ break;
+ }
+ }
+
+ if (val && !non_short_slot_sta_count) {
+ /*
+ * enable short slot time
+ * reset the cache
+ */
+ cdf_mem_set(
+ (uint8_t *) &mac_ctx->lim.gLimNoShortSlotParams,
+ sizeof(tLimNoShortSlotParams), 0);
+ /*in case of AP set SHORT_SLOT_TIME to enable*/
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ beacon_params->fShortSlotTime = true;
+ beacon_params->paramChangeBitmap |=
+ PARAM_SHORT_SLOT_TIME_CHANGED;
+ session_entry->shortSlotTimeSupported = true;
+ }
+ }
+ mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta =
+ non_short_slot_sta_count;
+ }
+}
+
+void
+lim_post_reassoc_failure(tpAniSirGlobal pMac,
+ tSirResultCodes resultCode,
+ uint16_t protStatusCode, tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+
+ psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+ /* 'Change' timer for future activations */
+ lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+ mlmReassocCnf.resultCode = resultCode;
+ mlmReassocCnf.protStatusCode = protStatusCode;
+ /* Update PE session Id */
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+ lim_post_sme_message(pMac,
+ LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
+} /*** end lim_post_reassoc_failure() ***/
+
+/**
+ * lim_restore_pre_reassoc_state()
+ *
+ ***FUNCTION:
+ * This function is called on STA role whenever Reasociation
+ * Response with a reject code is received from AP.
+ *
+ ***LOGIC:
+ * Reassociation failure timer is stopped, Old (or current) AP's
+ * context is restored both at Polaris & software
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param resultCode - Result code that specifies why Reassociation
+ * attemp failed
+ *
+ * @return None
+ */
+
+void
+lim_restore_pre_reassoc_state(tpAniSirGlobal pMac,
+ tSirResultCodes resultCode,
+ uint16_t protStatusCode, tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+
+ lim_log(pMac, LOG1,
+ FL("sessionid: %d protStatusCode: %d resultCode: %d"),
+ psessionEntry->smeSessionId, protStatusCode, resultCode);
+
+ psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ eLIM_MLM_LINK_ESTABLISHED_STATE));
+
+ /* 'Change' timer for future activations */
+ lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);
+
+ lim_set_channel(pMac, psessionEntry->currentOperChannel,
+ psessionEntry->ch_center_freq_seg0,
+ psessionEntry->ch_center_freq_seg1,
+ psessionEntry->ch_width,
+ psessionEntry->maxTxPower,
+ psessionEntry->peSessionId);
+
+ /** @ToDo : Need to Integrate the STOP the DataTransfer to the AP from 11H code */
+
+ mlmReassocCnf.resultCode = resultCode;
+ mlmReassocCnf.protStatusCode = protStatusCode;
+ /* Update PE session Id */
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+ lim_post_sme_message(pMac,
+ LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
+} /*** end lim_restore_pre_reassoc_state() ***/
+
+/**
+ * lim_is_reassoc_in_progress()
+ *
+ ***FUNCTION:
+ * This function is called to see if STA is in wt-reassoc-rsp state.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return true When STA is waiting for Reassoc response from AP \n
+ * else false
+ */
+
+bool lim_is_reassoc_in_progress(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ if (psessionEntry == NULL) {
+ return false;
+ }
+ if ((LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
+ ((psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) ||
+ (psessionEntry->limSmeState ==
+ eLIM_SME_WT_REASSOC_LINK_FAIL_STATE)))
+ return true;
+
+ return false;
+} /*** end lim_is_reassoc_in_progress() ***/
+
+#ifdef WLAN_FEATURE_11AC
+/**
+ * lim_populate_vht_mcs_set - function to populate vht mcs rate set
+ * @mac_ctx: pointer to global mac structure
+ * @rates: pointer to supported rate set
+ * @peer_vht_caps: pointer to peer vht capabilities
+ * @session_entry: pe session entry
+ *
+ * Populates vht mcs rate set based on peer and self capabilities
+ *
+ * Return: eSIR_SUCCESS on success else eSIR_FAILURE
+ */
+tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal mac_ctx,
+ tpSirSupportedRates rates,
+ tDot11fIEVHTCaps *peer_vht_caps,
+ tpPESession session_entry)
+{
+ uint32_t val;
+ uint32_t self_sta_dot11mode = 0;
+ uint16_t mcs_map_mask = MCSMAPMASK1x1;
+ uint16_t mcs_map_mask2x2 = 0;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
+
+ if (!IS_DOT11_MODE_VHT(self_sta_dot11mode))
+ return eSIR_SUCCESS;
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_VHT_RX_MCS_MAP, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE, FL("could not retrieve VHT RX MCS MAP"));
+ goto error;
+ }
+ rates->vhtRxMCSMap = (uint16_t) val;
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_VHT_TX_MCS_MAP, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE, FL("could not retrieve VHT TX MCS MAP"));
+ goto error;
+ }
+ rates->vhtTxMCSMap = (uint16_t) val;
+
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
+ &val) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("couldn't retrieve VHT RX Supported data rate MAP"));
+ goto error;
+ }
+ rates->vhtRxHighestDataRate = (uint16_t) val;
+
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
+ &val) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("couldn't retrieve VHT RX Supported data rate MAP"));
+ goto error;
+ }
+ rates->vhtTxHighestDataRate = (uint16_t) val;
+
+ if (peer_vht_caps == NULL)
+ return eSIR_SUCCESS;
+
+ rates->vhtTxHighestDataRate =
+ CDF_MIN(rates->vhtTxHighestDataRate,
+ peer_vht_caps->txSupDataRate);
+ rates->vhtRxHighestDataRate =
+ CDF_MIN(rates->vhtRxHighestDataRate,
+ peer_vht_caps->rxHighSupDataRate);
+
+ if (mac_ctx->roam.configParam.enable2x2) {
+ if (session_entry && mac_ctx->lteCoexAntShare &&
+ IS_24G_CH(session_entry->currentOperChannel)) {
+ if (IS_2X2_CHAIN(session_entry->chainMask))
+ mcs_map_mask2x2 = MCSMAPMASK2x2;
+ else
+ lim_log(mac_ctx, LOGE, FL("2x2 not enabled %d"),
+ session_entry->chainMask);
+ } else {
+ mcs_map_mask2x2 = MCSMAPMASK2x2;
+ }
+ }
+
+ if ((peer_vht_caps->txMCSMap & mcs_map_mask) <
+ (rates->vhtRxMCSMap & mcs_map_mask)) {
+ rates->vhtRxMCSMap &= ~(mcs_map_mask);
+ rates->vhtRxMCSMap |=
+ (peer_vht_caps->txMCSMap & mcs_map_mask);
+ }
+ if ((peer_vht_caps->rxMCSMap & mcs_map_mask) <
+ (rates->vhtTxMCSMap & mcs_map_mask)) {
+ rates->vhtTxMCSMap &= ~(mcs_map_mask);
+ rates->vhtTxMCSMap |=
+ (peer_vht_caps->rxMCSMap & mcs_map_mask);
+ }
+
+ if (mcs_map_mask2x2) {
+
+ uint16_t peer_mcs_map, self_mcs_map;
+
+ peer_mcs_map =
+ peer_vht_caps->txMCSMap & mcs_map_mask2x2;
+ self_mcs_map =
+ rates->vhtRxMCSMap & mcs_map_mask2x2;
+
+ if ((self_mcs_map != mcs_map_mask2x2) &&
+ ((peer_mcs_map == mcs_map_mask2x2) ||
+ (peer_mcs_map < self_mcs_map))) {
+ rates->vhtRxMCSMap &= ~mcs_map_mask2x2;
+ rates->vhtRxMCSMap |= peer_mcs_map;
+ }
+
+ peer_mcs_map =
+ (peer_vht_caps->rxMCSMap & mcs_map_mask2x2);
+ self_mcs_map =
+ (rates->vhtTxMCSMap & mcs_map_mask2x2);
+
+ if ((self_mcs_map != mcs_map_mask2x2) &&
+ ((peer_mcs_map == mcs_map_mask2x2) ||
+ (peer_mcs_map < self_mcs_map))) {
+ rates->vhtTxMCSMap &= ~mcs_map_mask2x2;
+ rates->vhtTxMCSMap |= peer_mcs_map;
+ }
+ }
+
+ lim_log(mac_ctx, LOG1,
+ FL("enable2x2 - %d vhtRxMCSMap - %x vhtTxMCSMap - %x\n"),
+ mac_ctx->roam.configParam.enable2x2,
+ rates->vhtRxMCSMap, rates->vhtTxMCSMap);
+
+ return eSIR_SUCCESS;
+error:
+
+ return eSIR_FAILURE;
+}
+#endif
+
+/**
+ * lim_populate_own_rate_set() - comprises the basic and extended rates read
+ * from CFG
+ * @mac_ctx: pointer to global mac structure
+ * @rates: pointer to supported rates
+ * @supported_mcs_set: pointer to supported mcs rates
+ * @basic_only: update only basic rates if set true
+ * @session_entry: pe session entry
+ * @vht_caps: pointer to vht capability
+ *
+ * This function is called by limProcessAssocRsp() or
+ * lim_add_staInIBSS()
+ * - It creates a combined rate set of 12 rates max which
+ * comprises the basic and extended rates read from CFG
+ * - It sorts the combined rate Set and copy it in the
+ * rate array of the pSTA descriptor
+ * - It sets the erpEnabled bit of the STA descriptor
+ * ERP bit is set iff the dph PHY mode is 11G and there is at least
+ * an A rate in the supported or extended rate sets
+ *
+ * Return: eSIR_SUCCESS or eSIR_FAILURE.
+ */
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus
+lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
+ tpSirSupportedRates rates, uint8_t *supported_mcs_set,
+ uint8_t basic_only, tpPESession session_entry,
+ tDot11fIEVHTCaps *vht_caps)
+#else
+tSirRetStatus
+lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
+ tpSirSupportedRates rates,
+ uint8_t *supported_mcs_set,
+ uint8_t basic_only, tpPESession session_entry)
+#endif
+{
+ tSirMacRateSet temp_rate_set;
+ tSirMacRateSet temp_rate_set2;
+ uint32_t i, j, val, min, is_arate;
+ uint32_t phy_mode = 0;
+ uint32_t self_sta_dot11mode = 0;
+ uint8_t a_rate_index = 0;
+ uint8_t b_rate_index = 0;
+
+
+ is_arate = 0;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+ /*
+ * Include 11b rates only when the device configured in
+ * auto, 11a/b/g or 11b_only
+ */
+ if ((self_sta_dot11mode == WNI_CFG_DOT11_MODE_ALL) ||
+ (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11A) ||
+ (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
+ (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11N) ||
+ (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+ (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11B)) {
+ val = WNI_CFG_SUPPORTED_RATES_11B_LEN;
+ wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_RATES_11B,
+ (uint8_t *) &temp_rate_set.rate, &val);
+ temp_rate_set.numRates = (uint8_t) val;
+ } else {
+ temp_rate_set.numRates = 0;
+ }
+
+ /* Include 11a rates when the device configured in non-11b mode */
+ if (!IS_DOT11_MODE_11B(self_sta_dot11mode)) {
+ val = WNI_CFG_SUPPORTED_RATES_11A_LEN;
+ wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_RATES_11A,
+ (uint8_t *) &temp_rate_set2.rate, &val);
+ temp_rate_set2.numRates = (uint8_t) val;
+ } else {
+ temp_rate_set2.numRates = 0;
+ }
+
+ if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
+ /* we are in big trouble */
+ lim_log(mac_ctx, LOGP, FL("more than 12 rates in CFG"));
+ /* panic */
+ goto error;
+ }
+ /* copy all rates in temp_rate_set, there are 12 rates max */
+ for (i = 0; i < temp_rate_set2.numRates; i++)
+ temp_rate_set.rate[i + temp_rate_set.numRates] =
+ temp_rate_set2.rate[i];
+
+ temp_rate_set.numRates += temp_rate_set2.numRates;
+
+ /**
+ * Sort rates in temp_rate_set (they are likely to be already sorted)
+ * put the result in pSupportedRates
+ */
+
+ cdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
+ for (i = 0; i < temp_rate_set.numRates; i++) {
+ min = 0;
+ val = 0xff;
+ is_arate = 0;
+
+ for (j = 0; (j < temp_rate_set.numRates) &&
+ (j < SIR_MAC_RATESET_EID_MAX); j++) {
+ if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) <
+ val) {
+ val = temp_rate_set.rate[j] & 0x7f;
+ min = j;
+ }
+ }
+
+ if (sirIsArate(temp_rate_set.rate[min] & 0x7f))
+ is_arate = 1;
+
+ /*
+ * HAL needs to know whether the rate is basic rate or
+ * not, as it needs to update the response rate table
+ * accordingly. e.g. if one of the 11a rates is
+ * basic rate, then that rate can be used for sending
+ * control frames.
+ * HAL updates the response rate table whenever basic
+ * rate set is changed.
+ */
+ if (basic_only && temp_rate_set.rate[min] & 0x80) {
+ if (is_arate)
+ rates->llaRates[a_rate_index++] =
+ temp_rate_set.rate[min];
+ else
+ rates->llbRates[b_rate_index++] =
+ temp_rate_set.rate[min];
+ } else {
+ if (is_arate)
+ rates->llaRates[a_rate_index++] =
+ temp_rate_set.rate[min];
+ else
+ rates->llbRates[b_rate_index++] =
+ temp_rate_set.rate[min];
+ }
+ temp_rate_set.rate[min] = 0xff;
+ }
+
+ if (IS_DOT11_MODE_HT(self_sta_dot11mode)) {
+ val = SIZE_OF_SUPPORTED_MCS_SET;
+ if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
+ rates->supportedMCSSet,
+ &val) != eSIR_SUCCESS) {
+ /* Could not get rateset from CFG. Log error. */
+ lim_log(mac_ctx, LOGE,
+ FL("could not retrieve supportedMCSSet"));
+ goto error;
+ }
+
+ /*
+ * if supported MCS Set of the peer is passed in,
+ * then do the intersection
+ * else use the MCS set from local CFG.
+ */
+
+ if (supported_mcs_set != NULL) {
+ for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ rates->supportedMCSSet[i] &=
+ supported_mcs_set[i];
+ }
+
+ lim_log(mac_ctx, LOG2, FL("MCS Rate Set Bitmap: "));
+ for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ PELOG2(lim_log(mac_ctx, LOG2, FL("%x "),
+ rates->supportedMCSSet[i]);)
+ }
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, session_entry);
+#endif
+
+ return eSIR_SUCCESS;
+error:
+ return eSIR_FAILURE;
+}
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus
+lim_populate_peer_rate_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ uint8_t *pSupportedMCSSet,
+ uint8_t basicOnly,
+ tpPESession psessionEntry, tDot11fIEVHTCaps *pVHTCaps)
+#else
+tSirRetStatus
+lim_populate_peer_rate_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ uint8_t *pSupportedMCSSet,
+ uint8_t basicOnly, tpPESession psessionEntry)
+#endif
+{
+ tSirMacRateSet tempRateSet;
+ tSirMacRateSet tempRateSet2;
+ uint32_t i, j, val, min, isArate;
+ isArate = 0;
+
+ /* copy operational rate set from psessionEntry */
+ if (psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX) {
+ cdf_mem_copy((uint8_t *) tempRateSet.rate,
+ (uint8_t *) (psessionEntry->rateSet.rate),
+ psessionEntry->rateSet.numRates);
+ tempRateSet.numRates = psessionEntry->rateSet.numRates;
+ } else {
+ lim_log(pMac, LOGE,
+ FL("more than SIR_MAC_RATESET_EID_MAX rates\n"));
+ goto error;
+ }
+ if ((psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11A) ||
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N)) {
+ if (psessionEntry->extRateSet.numRates <=
+ SIR_MAC_RATESET_EID_MAX) {
+ cdf_mem_copy((uint8_t *) tempRateSet2.rate,
+ (uint8_t *) (psessionEntry->extRateSet.
+ rate),
+ psessionEntry->extRateSet.numRates);
+ tempRateSet2.numRates =
+ psessionEntry->extRateSet.numRates;
+ } else {
+ lim_log(pMac, LOGE,
+ FL
+ ("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates\n"));
+ goto error;
+ }
+ } else
+ tempRateSet2.numRates = 0;
+ if ((tempRateSet.numRates + tempRateSet2.numRates) >
+ SIR_MAC_RATESET_EID_MAX) {
+ /* we are in big trouble */
+ lim_log(pMac, LOGP, FL("more than 12 rates in CFG"));
+ goto error;
+ }
+
+ /* copy all rates in tempRateSet, there are 12 rates max */
+ for (i = 0; i < tempRateSet2.numRates; i++)
+ tempRateSet.rate[i + tempRateSet.numRates] =
+ tempRateSet2.rate[i];
+ tempRateSet.numRates += tempRateSet2.numRates;
+ /**
+ * Sort rates in tempRateSet (they are likely to be already sorted)
+ * put the result in pSupportedRates
+ */
+ {
+ uint8_t aRateIndex = 0;
+ uint8_t bRateIndex = 0;
+ cdf_mem_set((uint8_t *) pRates, sizeof(tSirSupportedRates), 0);
+ for (i = 0; i < tempRateSet.numRates; i++) {
+ min = 0;
+ val = 0xff;
+ isArate = 0;
+ for (j = 0;
+ (j < tempRateSet.numRates)
+ && (j < SIR_MAC_RATESET_EID_MAX); j++) {
+ if ((uint32_t) (tempRateSet.rate[j] & 0x7f) <
+ val) {
+ val = tempRateSet.rate[j] & 0x7f;
+ min = j;
+ }
+ }
+ if (sirIsArate(tempRateSet.rate[min] & 0x7f))
+ isArate = 1;
+ /*
+ * HAL needs to know whether the rate is basic rate or not, as it needs to
+ * update the response rate table accordingly. e.g. if one of the 11a rates is
+ * basic rate, then that rate can be used for sending control frames.
+ * HAL updates the response rate table whenever basic rate set is changed.
+ */
+ if (basicOnly) {
+ if (tempRateSet.rate[min] & 0x80) {
+ if (isArate)
+ pRates->llaRates[aRateIndex++] =
+ tempRateSet.rate[min];
+ else
+ pRates->llbRates[bRateIndex++] =
+ tempRateSet.rate[min];
+ }
+ } else {
+ if (isArate)
+ pRates->llaRates[aRateIndex++] =
+ tempRateSet.rate[min];
+ else
+ pRates->llbRates[bRateIndex++] =
+ tempRateSet.rate[min];
+ }
+ tempRateSet.rate[min] = 0xff;
+ }
+ }
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
+ val = SIZE_OF_SUPPORTED_MCS_SET;
+ if (wlan_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
+ pRates->supportedMCSSet,
+ &val) != eSIR_SUCCESS) {
+ /* / Could not get rateset from CFG. Log error. */
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve supportedMCSSet"));
+ )
+ goto error;
+ }
+ /* if supported MCS Set of the peer is passed in, then do the intersection */
+ /* else use the MCS set from local CFG. */
+ if (pSupportedMCSSet != NULL) {
+ for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ pRates->supportedMCSSet[i] &=
+ pSupportedMCSSet[i];
+ }
+ PELOG2(lim_log(pMac, LOG2, FL("MCS Rate Set Bitmap: "));)
+ for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
+ PELOG2(lim_log
+ (pMac, LOG2, FL("%x "),
+ pRates->supportedMCSSet[i]);
+ )
+ }
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_vht_mcs_set(pMac, pRates, pVHTCaps, psessionEntry);
+#endif
+ return eSIR_SUCCESS;
+error:
+ return eSIR_FAILURE;
+} /*** lim_populate_peer_rate_set() ***/
+
+/**
+ * lim_populate_matching_rate_set() -process the CFG rate sets and
+ * the rate sets received in the Assoc request on AP.
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @oper_rate_set: pointer to operating rate set
+ * @ext_rate_set: pointer to extended rate set
+ * @supported_mcs_set: pointer to supported rate set
+ * @session_entry: pointer to pe session entry
+ * @vht_caps: pointer to vht capabilities
+ *
+ * This is called at the time of Association Request
+ * processing on AP and while adding peer's context
+ * in IBSS role to process the CFG rate sets and
+ * the rate sets received in the Assoc request on AP
+ * or Beacon/Probe Response from peer in IBSS.
+ *
+ * 1. It makes the intersection between our own rate Sat
+ * and extemcded rate set and the ones received in the
+ * association request.
+ * 2. It creates a combined rate set of 12 rates max which
+ * comprised the basic and extended rates
+ * 3. It sorts the combined rate Set and copy it in the
+ * rate array of the pSTA descriptor
+ *
+ * The parser has already ensured unicity of the rates in the
+ * association request structure
+ *
+ * Return: eSIR_SUCCESS on success else eSIR_FAILURE
+ */
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus
+lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+ tSirMacRateSet *oper_rate_set, tSirMacRateSet *ext_rate_set,
+ uint8_t *supported_mcs_set, tpPESession session_entry,
+ tDot11fIEVHTCaps * vht_caps)
+#else
+tSirRetStatus
+lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+ tSirMacRateSet *oper_rate_set, tSirMacRateSet *ext_rate_set,
+ uint8_t *supported_mcs_set, tpPESession session_entry)
+#endif
+{
+ tSirMacRateSet temp_rate_set;
+ tSirMacRateSet temp_rate_set2;
+ uint32_t i, j, val, min, is_arate;
+ uint32_t phy_mode;
+ uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
+ tpSirSupportedRates rates;
+ uint8_t a_rate_index = 0;
+ uint8_t b_rate_index = 0;
+
+ is_arate = 0;
+
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+ /* copy operational rate set from session_entry */
+ cdf_mem_copy((temp_rate_set.rate), (session_entry->rateSet.rate),
+ session_entry->rateSet.numRates);
+ temp_rate_set.numRates = (uint8_t) session_entry->rateSet.numRates;
+
+ if (phy_mode == WNI_CFG_PHY_MODE_11G) {
+ cdf_mem_copy((temp_rate_set2.rate),
+ (session_entry->extRateSet.rate),
+ session_entry->extRateSet.numRates);
+ temp_rate_set2.numRates =
+ (uint8_t) session_entry->extRateSet.numRates;
+ } else {
+ temp_rate_set2.numRates = 0;
+ }
+
+ if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
+ lim_log(mac_ctx, LOGE, FL("more than 12 rates in CFG"));
+ goto error;
+ }
+
+ /*
+ * Handling of the rate set IEs is the following:
+ * - keep only rates that we support and that the station supports
+ * - sort and the rates into the pSta->rate array
+ */
+
+ /* Copy all rates in temp_rate_set, there are 12 rates max */
+ for (i = 0; i < temp_rate_set2.numRates; i++)
+ temp_rate_set.rate[i + temp_rate_set.numRates] =
+ temp_rate_set2.rate[i];
+
+ temp_rate_set.numRates += temp_rate_set2.numRates;
+
+ /*
+ * Sort rates in temp_rate_set (they are likely to be already sorted)
+ * put the result in temp_rate_set2
+ */
+ temp_rate_set2.numRates = 0;
+
+ for (i = 0; i < temp_rate_set.numRates; i++) {
+ min = 0;
+ val = 0xff;
+
+ for (j = 0; j < temp_rate_set.numRates; j++)
+ if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
+ val = temp_rate_set.rate[j] & 0x7f;
+ min = j;
+ }
+
+ temp_rate_set2.rate[temp_rate_set2.numRates++] =
+ temp_rate_set.rate[min];
+ temp_rate_set.rate[min] = 0xff;
+ }
+
+ /*
+ * Copy received rates in temp_rate_set, the parser has ensured
+ * unicity of the rates so there cannot be more than 12
+ */
+ for (i = 0; (i < oper_rate_set->numRates &&
+ i < SIR_MAC_RATESET_EID_MAX); i++)
+ temp_rate_set.rate[i] = oper_rate_set->rate[i];
+
+ temp_rate_set.numRates = oper_rate_set->numRates;
+
+ lim_log(mac_ctx, LOG2,
+ "Sum of SUPPORTED and EXTENDED Rate Set (%1d)",
+ temp_rate_set.numRates + ext_rate_set->numRates);
+
+ if (ext_rate_set->numRates &&
+ ((temp_rate_set.numRates + ext_rate_set->numRates) > 12) &&
+ temp_rate_set.numRates < 12) {
+ int found = 0;
+ int tail = temp_rate_set.numRates;
+
+ for (i = 0; (i < ext_rate_set->numRates &&
+ i < SIR_MAC_RATESET_EID_MAX); i++) {
+ found = 0;
+ for (j = 0; j < (uint32_t) tail; j++) {
+ if ((temp_rate_set.rate[j] & 0x7F) ==
+ (ext_rate_set->rate[i] & 0x7F)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ temp_rate_set.rate[temp_rate_set.numRates++] =
+ ext_rate_set->rate[i];
+ if (temp_rate_set.numRates >= 12)
+ break;
+ }
+ }
+ } else if (ext_rate_set->numRates &&
+ ((temp_rate_set.numRates + ext_rate_set->numRates) <= 12)) {
+ for (j = 0; ((j < ext_rate_set->numRates) &&
+ (j < SIR_MAC_RATESET_EID_MAX) &&
+ ((i + j) < SIR_MAC_RATESET_EID_MAX)); j++)
+ temp_rate_set.rate[i + j] = ext_rate_set->rate[j];
+
+ temp_rate_set.numRates += ext_rate_set->numRates;
+ } else if (ext_rate_set->numRates) {
+ lim_log(mac_ctx, LOG2,
+ "Relying only on the SUPPORTED Rate Set IE...");
+ }
+
+
+ rates = &sta_ds->supportedRates;
+ cdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
+ for (i = 0; (i < temp_rate_set2.numRates &&
+ i < SIR_MAC_RATESET_EID_MAX); i++) {
+ for (j = 0; (j < temp_rate_set.numRates &&
+ j < SIR_MAC_RATESET_EID_MAX); j++) {
+ if ((temp_rate_set2.rate[i] & 0x7F) !=
+ (temp_rate_set.rate[j] & 0x7F))
+ continue;
+
+ if (sirIsArate(temp_rate_set2.rate[i] & 0x7f) &&
+ a_rate_index < SIR_NUM_11A_RATES) {
+ is_arate = 1;
+ rates->llaRates[a_rate_index++] =
+ temp_rate_set2.rate[i];
+ } else if ((b_rate_index < SIR_NUM_11B_RATES) &&
+ !(sirIsArate(temp_rate_set2.rate[i] & 0x7f))) {
+ rates->llbRates[b_rate_index++] =
+ temp_rate_set2.rate[i];
+ }
+ break;
+ }
+ }
+
+ /*
+ * Now add the Polaris rates only when Proprietary rates are enabled.
+ * compute the matching MCS rate set, if peer is 11n capable and self
+ * mode is 11n
+ */
+#ifdef FEATURE_WLAN_TDLS
+ if (sta_ds->mlmStaContext.htCapability)
+#else
+ if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
+ (sta_ds->mlmStaContext.htCapability))
+#endif
+ {
+ val = SIZE_OF_SUPPORTED_MCS_SET;
+ if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
+ mcs_set, &val) != eSIR_SUCCESS) {
+ /* Could not get rateset from CFG. Log error. */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve supportedMCSet"));
+ goto error;
+ }
+
+ for (i = 0; i < val; i++)
+ sta_ds->supportedRates.supportedMCSSet[i] =
+ mcs_set[i] & supported_mcs_set[i];
+
+ lim_log(mac_ctx, LOG2,
+ FL("lim_populate_matching_rate_set: MCS Rate Set Bitmap"
+ " from CFG and DPH : "));
+ for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
+ lim_log(mac_ctx, LOG2, FL("%x %x "), mcs_set[i],
+ sta_ds->supportedRates.supportedMCSSet[i]);
+ }
+ }
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps,
+ session_entry);
+#endif
+ /*
+ * Set the erpEnabled bit if the phy is in G mode and at least
+ * one A rate is supported
+ */
+ if ((phy_mode == WNI_CFG_PHY_MODE_11G) && is_arate)
+ sta_ds->erpEnabled = eHAL_SET;
+
+ return eSIR_SUCCESS;
+
+error:
+
+ return eSIR_FAILURE;
+}
+
+/**
+ * lim_populate_vht_caps() - populates vht capabilities based on input
+ * capabilities
+ * @input_caps: input capabilities based on which we format the vht
+ * capabilities
+ *
+ * function to populate the supported vht capabilities.
+ *
+ * Return: vht capabilities derived based on input parameters.
+ */
+static uint32_t lim_populate_vht_caps(tDot11fIEVHTCaps input_caps)
+{
+ uint32_t vht_caps;
+
+ vht_caps = ((input_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
+ (input_caps.supportedChannelWidthSet <<
+ SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
+ (input_caps.ldpcCodingCap <<
+ SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
+ (input_caps.shortGI80MHz <<
+ SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
+ (input_caps.shortGI160and80plus80MHz <<
+ SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
+ (input_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
+ (input_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
+ (input_caps.suBeamFormerCap <<
+ SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
+ (input_caps.suBeamformeeCap <<
+ SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
+ (input_caps.csnofBeamformerAntSup <<
+ SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
+ (input_caps.numSoundingDim <<
+ SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
+ (input_caps.muBeamformerCap <<
+ SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
+ (input_caps.muBeamformeeCap <<
+ SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
+ (input_caps.vhtTXOPPS <<
+ SIR_MAC_VHT_CAP_TXOPPS) |
+ (input_caps.htcVHTCap <<
+ SIR_MAC_VHT_CAP_HTC_CAP) |
+ (input_caps.maxAMPDULenExp <<
+ SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
+ (input_caps.vhtLinkAdaptCap <<
+ SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
+ (input_caps.rxAntPattern <<
+ SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
+ (input_caps.txAntPattern <<
+ SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
+ (input_caps.reserved1 <<
+ SIR_MAC_VHT_CAP_RESERVED2));
+
+ return vht_caps;
+}
+/**
+ * lim_add_sta()- called to add an STA context at hardware
+ * @mac_ctx: pointer to global mac structure
+ * @sta_ds: station node
+ * @update_entry: set to true for updating the entry
+ * @session_entry: pe session entry
+ *
+ * This function is called to add an STA context at hardware
+ * whenever a STA is (Re) Associated.
+ *
+ * Return: eSIR_SUCCESS on success else eSirRetStatus failure codes
+ */
+
+tSirRetStatus
+lim_add_sta(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds, uint8_t update_entry, tpPESession session_entry)
+{
+ tpAddStaParams add_sta_params = NULL;
+ tSirMsgQ msg_q;
+ tSirRetStatus ret_code = eSIR_SUCCESS;
+ tSirMacAddr sta_mac, *sta_Addr;
+ uint8_t i, nw_type_11b = 0;
+ tpSirAssocReq assoc_req;
+ tLimIbssPeerNode *peer_node; /* for IBSS mode */
+ uint8_t *p2p_ie = NULL;
+
+ sir_copy_mac_addr(sta_mac, session_entry->selfMacAddr);
+
+ lim_log(mac_ctx, LOG1,
+ FL("sessionid: %d update_entry = %d limsystemrole = %d "),
+ session_entry->smeSessionId, update_entry,
+ GET_LIM_SYSTEM_ROLE(session_entry));
+
+ add_sta_params = cdf_mem_malloc(sizeof(tAddStaParams));
+ if (NULL == add_sta_params) {
+ lim_log(mac_ctx, LOGP,
+ FL("Unable to allocate memory during ADD_STA"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set((uint8_t *) add_sta_params, sizeof(tAddStaParams), 0);
+
+ if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry))
+ sta_Addr = &sta_ds->staAddr;
+#ifdef FEATURE_WLAN_TDLS
+ /* SystemRole shouldn't be matter if staType is TDLS peer */
+ else if (STA_ENTRY_TDLS_PEER == sta_ds->staType)
+ sta_Addr = &sta_ds->staAddr;
+#endif
+ else
+ sta_Addr = &sta_mac;
+
+ lim_log(mac_ctx, LOG1,
+ FL(MAC_ADDRESS_STR ": Subtype(Assoc/Reassoc): %d"),
+ MAC_ADDR_ARRAY(*sta_Addr), sta_ds->mlmStaContext.subType);
+
+ cdf_mem_copy((uint8_t *) add_sta_params->staMac,
+ (uint8_t *) *sta_Addr, sizeof(tSirMacAddr));
+ cdf_mem_copy((uint8_t *) add_sta_params->bssId,
+ session_entry->bssId, sizeof(tSirMacAddr));
+ cdf_mem_copy(&add_sta_params->capab_info,
+ &sta_ds->mlmStaContext.capabilityInfo,
+ sizeof(add_sta_params->capab_info));
+
+ lim_fill_supported_rates_info(mac_ctx, sta_ds, &sta_ds->supportedRates,
+ session_entry);
+
+ /* Copy legacy rates */
+ cdf_mem_copy((uint8_t *) &add_sta_params->supportedRates,
+ (uint8_t *) &sta_ds->supportedRates,
+ sizeof(tSirSupportedRates));
+
+ add_sta_params->assocId = sta_ds->assocId;
+
+ add_sta_params->wmmEnabled = sta_ds->qosMode;
+ add_sta_params->listenInterval = sta_ds->mlmStaContext.listenInterval;
+ add_sta_params->shortPreambleSupported = sta_ds->shortPreambleEnabled;
+ if (LIM_IS_AP_ROLE(session_entry) &&
+ (sta_ds->mlmStaContext.subType == LIM_REASSOC)) {
+ /*
+ * TBD - need to remove this REASSOC check
+ * after fixinf rmmod issue
+ */
+ add_sta_params->updateSta = sta_ds->mlmStaContext.updateContext;
+ }
+ sta_ds->valid = 0;
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+
+ lim_log(mac_ctx, LOG2,
+ FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d"
+ " shortPreambleSupported: %d "), add_sta_params->assocId,
+ add_sta_params->wmmEnabled, add_sta_params->listenInterval,
+ add_sta_params->shortPreambleSupported);
+ /* This will indicate HAL to "allocate" a new STA index */
+#ifdef FEATURE_WLAN_TDLS
+ /*
+ * As there is corner case in-between add_sta and change_sta,if del_sta
+ * for other staIdx happened, firmware return wrong staIdx
+ * (recently removed staIdx). Until we get a confirmation from the
+ * firmware team it is now return correct staIdx for same sta_mac_addr
+ * for update case, we want to get around it by passing valid staIdx
+ * given by add_sta time.
+ */
+ if ((STA_ENTRY_TDLS_PEER == sta_ds->staType) && (true == update_entry))
+ add_sta_params->staIdx = sta_ds->staIndex;
+ else
+#endif
+ add_sta_params->staIdx = STA_INVALID_IDX;
+ add_sta_params->staType = sta_ds->staType;
+
+ add_sta_params->updateSta = update_entry;
+
+ add_sta_params->status = CDF_STATUS_SUCCESS;
+ add_sta_params->respReqd = 1;
+ /* Update HT Capability */
+
+ if (LIM_IS_AP_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry) ||
+ LIM_IS_IBSS_ROLE(session_entry)) {
+ add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
+#ifdef WLAN_FEATURE_11AC
+ add_sta_params->vhtCapable =
+ sta_ds->mlmStaContext.vhtCapability;
+#endif
+ }
+#ifdef FEATURE_WLAN_TDLS
+ /* SystemRole shouldn't be matter if staType is TDLS peer */
+ else if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
+ add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
+#ifdef WLAN_FEATURE_11AC
+ add_sta_params->vhtCapable =
+ sta_ds->mlmStaContext.vhtCapability;
+#endif
+ }
+#endif
+ else {
+ add_sta_params->htCapable = session_entry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ add_sta_params->vhtCapable = session_entry->vhtCapability;
+#endif
+
+ }
+#ifdef WLAN_FEATURE_11AC
+ lim_log(mac_ctx, LOG2, FL("vhtCapable: %d "),
+ add_sta_params->vhtCapable);
+#endif
+ lim_log(mac_ctx, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
+ add_sta_params->staIdx, add_sta_params->updateSta,
+ add_sta_params->htCapable);
+
+ add_sta_params->greenFieldCapable = sta_ds->htGreenfield;
+ add_sta_params->maxAmpduDensity = sta_ds->htAMpduDensity;
+ add_sta_params->maxAmpduSize = sta_ds->htMaxRxAMpduFactor;
+ add_sta_params->fDsssCckMode40Mhz = sta_ds->htDsssCckRate40MHzSupport;
+ add_sta_params->fShortGI20Mhz = sta_ds->htShortGI20Mhz;
+ add_sta_params->fShortGI40Mhz = sta_ds->htShortGI40Mhz;
+ add_sta_params->lsigTxopProtection = sta_ds->htLsigTXOPProtection;
+ add_sta_params->maxAmsduSize = sta_ds->htMaxAmsduLength;
+ add_sta_params->ch_width = sta_ds->htSupportedChannelWidthSet;
+ add_sta_params->mimoPS = sta_ds->htMIMOPSState;
+
+ lim_log(mac_ctx, LOG2,
+ FL("greenFieldCapable: %d maxAmpduDensity = %d maxAmpduDensity = %d"),
+ add_sta_params->greenFieldCapable,
+ add_sta_params->maxAmpduDensity, add_sta_params->maxAmpduSize);
+
+ lim_log(mac_ctx, LOG2,
+ FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d fShortGI40Mhz: %d"),
+ add_sta_params->fDsssCckMode40Mhz,
+ add_sta_params->fShortGI20Mhz, add_sta_params->fShortGI40Mhz);
+
+ lim_log(mac_ctx, LOG2,
+ FL("lsigTxopProtection: %d maxAmsduSize: %d txChannelWidth: %d mimoPS: %d "),
+ add_sta_params->lsigTxopProtection,
+ add_sta_params->maxAmsduSize, add_sta_params->ch_width,
+ add_sta_params->mimoPS);
+
+ if (add_sta_params->vhtCapable) {
+ if (sta_ds->vhtSupportedChannelWidthSet)
+ add_sta_params->ch_width =
+ sta_ds->vhtSupportedChannelWidthSet + 1;
+
+ add_sta_params->vhtSupportedRxNss = sta_ds->vhtSupportedRxNss;
+ add_sta_params->vhtTxBFCapable =
+#ifdef FEATURE_WLAN_TDLS
+ ((STA_ENTRY_PEER == sta_ds->staType)
+ || (STA_ENTRY_TDLS_PEER == sta_ds->staType)) ?
+ sta_ds->vhtBeamFormerCapable :
+ session_entry->txBFIniFeatureEnabled;
+#else
+ (STA_ENTRY_PEER == sta_ds->staType) ?
+ sta_ds->vhtBeamFormerCapable :
+ session_entry->txBFIniFeatureEnabled;
+#endif
+ add_sta_params->enable_su_tx_bformer =
+ sta_ds->vht_su_bfee_capable;
+ }
+
+ lim_log(mac_ctx, LOGE, FL("TxChWidth %d vhtTxBFCap %d, su_bfer %d"),
+ add_sta_params->ch_width, add_sta_params->vhtTxBFCapable,
+ add_sta_params->enable_su_tx_bformer);
+#ifdef FEATURE_WLAN_TDLS
+ if ((STA_ENTRY_PEER == sta_ds->staType) ||
+ (STA_ENTRY_TDLS_PEER == sta_ds->staType))
+#else
+ if (STA_ENTRY_PEER == sta_ds->staType)
+#endif
+ {
+ /*
+ * peer STA get the LDPC capability from sta_ds,
+ * which populated from
+ * HT/VHT capability
+ */
+ if (add_sta_params->vhtTxBFCapable
+ && mac_ctx->lim.disableLDPCWithTxbfAP) {
+ add_sta_params->htLdpcCapable = 0;
+ add_sta_params->vhtLdpcCapable = 0;
+ } else {
+ add_sta_params->htLdpcCapable = sta_ds->htLdpcCapable;
+ add_sta_params->vhtLdpcCapable = sta_ds->vhtLdpcCapable;
+ }
+ } else if (STA_ENTRY_SELF == sta_ds->staType) {
+ /* For Self STA get the LDPC capability from config.ini */
+ add_sta_params->htLdpcCapable =
+ (session_entry->txLdpcIniFeatureEnabled & 0x01);
+ add_sta_params->vhtLdpcCapable =
+ ((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
+ }
+
+ /* Update PE session ID */
+ add_sta_params->sessionId = session_entry->peSessionId;
+
+ /* Update SME session ID */
+ add_sta_params->smesessionId = session_entry->smeSessionId;
+
+ add_sta_params->maxTxPower = session_entry->maxTxPower;
+
+ if (session_entry->parsedAssocReq != NULL) {
+ uint16_t aid = sta_ds->assocId;
+ /* Get a copy of the already parsed Assoc Request */
+ assoc_req =
+ (tpSirAssocReq) session_entry->parsedAssocReq[aid];
+ if (assoc_req && assoc_req->addIEPresent
+ && assoc_req->addIE.length) {
+ p2p_ie = limGetP2pIEPtr(mac_ctx,
+ assoc_req->addIE.addIEdata,
+ assoc_req->addIE.length);
+ }
+
+ add_sta_params->p2pCapableSta = (p2p_ie != NULL);
+ if (assoc_req && add_sta_params->htCapable) {
+ cdf_mem_copy(&add_sta_params->ht_caps,
+ ((uint8_t *) &assoc_req->HTCaps) + 1,
+ sizeof(add_sta_params->ht_caps));
+ }
+
+ if (assoc_req && add_sta_params->vhtCapable)
+ add_sta_params->vht_caps =
+ lim_populate_vht_caps(assoc_req->VHTCaps);
+ } else if (LIM_IS_IBSS_ROLE(session_entry)) {
+
+ /*
+ * in IBSS mode, use peer node as the source of ht_caps
+ * and vht_caps
+ */
+ peer_node = lim_ibss_peer_find(mac_ctx, *sta_Addr);
+ if (!peer_node) {
+ lim_log(mac_ctx, LOGP,
+ FL("Can't find IBSS peer node for ADD_STA"));
+ return eSIR_HAL_STA_DOES_NOT_EXIST;
+ }
+
+ if (peer_node->atimIePresent) {
+ add_sta_params->atimIePresent =
+ peer_node->atimIePresent;
+ add_sta_params->peerAtimWindowLength =
+ peer_node->peerAtimWindowLength;
+ }
+
+ add_sta_params->ht_caps =
+ (peer_node->htSupportedChannelWidthSet <<
+ SIR_MAC_HT_CAP_CHWIDTH40_S) |
+ (peer_node->htGreenfield <<
+ SIR_MAC_HT_CAP_GREENFIELD_S) |
+ (peer_node->htShortGI20Mhz <<
+ SIR_MAC_HT_CAP_SHORTGI20MHZ_S) |
+ (peer_node->htShortGI40Mhz <<
+ SIR_MAC_HT_CAP_SHORTGI40MHZ_S) |
+ (SIR_MAC_TXSTBC <<
+ SIR_MAC_HT_CAP_TXSTBC_S) |
+ (SIR_MAC_RXSTBC <<
+ SIR_MAC_HT_CAP_RXSTBC_S) |
+ (peer_node->htMaxAmsduLength <<
+ SIR_MAC_HT_CAP_MAXAMSDUSIZE_S) |
+ (peer_node->htDsssCckRate40MHzSupport <<
+ SIR_MAC_HT_CAP_DSSSCCK40_S);
+
+ add_sta_params->vht_caps =
+ lim_populate_vht_caps(peer_node->VHTCaps);
+ }
+#ifdef FEATURE_WLAN_TDLS
+ if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
+ add_sta_params->ht_caps = sta_ds->ht_caps;
+ add_sta_params->vht_caps = sta_ds->vht_caps;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x"),
+ add_sta_params->ht_caps,
+ add_sta_params->vht_caps);
+ }
+#endif
+
+#ifdef FEATURE_WLAN_TDLS
+ if (sta_ds->wmeEnabled &&
+ (LIM_IS_AP_ROLE(session_entry) ||
+ (STA_ENTRY_TDLS_PEER == sta_ds->staType)))
+#else
+ if (sta_ds->wmeEnabled && LIM_IS_AP_ROLE(session_entry))
+#endif
+ {
+ add_sta_params->uAPSD = 0;
+ /*
+ * update UAPSD and send it to LIM to add STA
+ * bitmap MSB <- LSB MSB 4 bits are for
+ * trigger enabled AC setting and LSB 4 bits
+ * are for delivery enabled AC setting
+ * 7 6 5 4 3 2 1 0
+ * BE BK VI VO BE BK VI VO
+ */
+ add_sta_params->uAPSD |=
+ sta_ds->qos.capability.qosInfo.acvo_uapsd;
+ add_sta_params->uAPSD |=
+ (sta_ds->qos.capability.qosInfo.acvi_uapsd << 1);
+ add_sta_params->uAPSD |=
+ (sta_ds->qos.capability.qosInfo.acbk_uapsd << 2);
+ add_sta_params->uAPSD |=
+ (sta_ds->qos.capability.qosInfo.acbe_uapsd << 3);
+ /*
+ * making delivery enabled and
+ * trigger enabled setting the same.
+ */
+ add_sta_params->uAPSD |= add_sta_params->uAPSD << 4;
+
+ add_sta_params->maxSPLen =
+ sta_ds->qos.capability.qosInfo.maxSpLen;
+ lim_log(mac_ctx, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"),
+ add_sta_params->uAPSD, add_sta_params->maxSPLen);
+ }
+#ifdef WLAN_FEATURE_11W
+ add_sta_params->rmfEnabled = sta_ds->rmfEnabled;
+ lim_log(mac_ctx, LOG1, FL("PMF enabled %d"),
+ add_sta_params->rmfEnabled);
+#endif
+
+ lim_log(mac_ctx, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
+ "p2pCapableSta: %d"),
+ add_sta_params->htLdpcCapable, add_sta_params->vhtLdpcCapable,
+ add_sta_params->p2pCapableSta);
+
+ /*
+ * we need to defer the message until we get the
+ * response back from HAL.
+ */
+ if (add_sta_params->respReqd)
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false);
+
+ for (i = 0; i < SIR_NUM_11A_RATES; i++) {
+ if (sirIsArate(sta_ds->supportedRates.llaRates[i] & 0x7F)) {
+ nw_type_11b = 0;
+ break;
+ } else {
+ nw_type_11b = 1;
+ }
+ }
+ if (nw_type_11b)
+ add_sta_params->nwType = eSIR_11B_NW_TYPE;
+ else
+ add_sta_params->nwType = session_entry->nwType;
+
+ msg_q.type = WMA_ADD_STA_REQ;
+
+ msg_q.reserved = 0;
+ msg_q.bodyptr = add_sta_params;
+ msg_q.bodyval = 0;
+
+ lim_log(mac_ctx, LOG1, FL("Sending WMA_ADD_STA_REQ for assocId %d"),
+ sta_ds->assocId);
+ MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
+ msg_q.type));
+
+ ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
+ if (eSIR_SUCCESS != ret_code) {
+ if (add_sta_params->respReqd)
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+ lim_log(mac_ctx, LOGE,
+ FL("ADD_STA_REQ for aId %d failed (reason %X)"),
+ sta_ds->assocId, ret_code);
+ cdf_mem_free(add_sta_params);
+ }
+
+ return ret_code;
+}
+
+/**
+ * lim_del_sta()
+ *
+ ***FUNCTION:
+ * This function is called to delete an STA context at hardware
+ * whenever a STA is disassociated
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @param fRespReqd - flag to indicate whether the delete is synchronous (true)
+ * or not (false)
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+lim_del_sta(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, bool fRespReqd, tpPESession psessionEntry)
+{
+ tpDeleteStaParams pDelStaParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ pDelStaParams = cdf_mem_malloc(sizeof(tDeleteStaParams));
+ if (NULL == pDelStaParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during ADD_STA"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set((uint8_t *) pDelStaParams, sizeof(tDeleteStaParams), 0);
+
+ /* */
+ /* DPH contains the STA index only for "peer" STA entries. */
+ /* LIM global contains "self" STA index */
+ /* Thus, */
+ /* if( STA role ) */
+ /* get STA index from LIM global */
+ /* else */
+ /* get STA index from DPH */
+ /* */
+
+#ifdef FEATURE_WLAN_TDLS
+ if ((LIM_IS_STA_ROLE(psessionEntry) &&
+ (pStaDs->staType != STA_ENTRY_TDLS_PEER)) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
+#else
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
+#endif
+ pDelStaParams->staIdx = psessionEntry->staId;
+
+ else
+ pDelStaParams->staIdx = pStaDs->staIndex;
+
+ pDelStaParams->assocId = pStaDs->assocId;
+ pStaDs->valid = 0;
+
+ if (!fRespReqd)
+ pDelStaParams->respReqd = 0;
+ else {
+ /* when lim_del_sta is called from processSmeAssocCnf then mlmState is already set properly. */
+ if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
+ GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs)) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ eLIM_MLM_WT_DEL_STA_RSP_STATE));
+ SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs,
+ eLIM_MLM_WT_DEL_STA_RSP_STATE);
+ }
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ eLIM_MLM_WT_DEL_STA_RSP_STATE));
+
+ psessionEntry->limMlmState =
+ eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ }
+ pDelStaParams->respReqd = 1;
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ }
+
+ /* Update PE session ID */
+ pDelStaParams->sessionId = psessionEntry->peSessionId;
+ pDelStaParams->smesessionId = psessionEntry->smeSessionId;
+
+ pDelStaParams->staType = pStaDs->staType;
+ cdf_mem_copy((uint8_t *) pDelStaParams->staMac,
+ (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr));
+
+ pDelStaParams->status = CDF_STATUS_SUCCESS;
+ msgQ.type = WMA_DELETE_STA_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pDelStaParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG1, FL("Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ "
+ "for STAID: %X and AssocID: %d MAC : "
+ MAC_ADDRESS_STR), pDelStaParams->sessionId,
+ pDelStaParams->staIdx, pDelStaParams->assocId,
+ MAC_ADDR_ARRAY(pStaDs->staAddr));
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ if (fRespReqd)
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ lim_log(pMac, LOGE,
+ FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"),
+ retCode);
+ cdf_mem_free(pDelStaParams);
+ }
+
+ return retCode;
+}
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+/**
+ * lim_add_ft_sta_self()- function to add STA once we have connected with a
+ * new AP
+ * @mac_ctx: pointer to global mac structure
+ * @assoc_id: association id for the station connection
+ * @session_entry: pe session entr
+ *
+ * This function is called to add a STA once we have connected with a new
+ * AP, that we have performed an FT to.
+ *
+ * The Add STA Response is created and now after the ADD Bss Is Successful
+ * we add the self sta. We update with the association id from the reassoc
+ * response from the AP.
+ *
+ * Return: eSIR_SUCCESS on success else eSirRetStatus failure codes
+ */
+tSirRetStatus lim_add_ft_sta_self(tpAniSirGlobal mac_ctx, uint16_t assoc_id,
+ tpPESession session_entry)
+{
+ tpAddStaParams add_sta_params = NULL;
+ tSirRetStatus ret_code = eSIR_SUCCESS;
+ tSirMsgQ msg_q;
+
+ add_sta_params = session_entry->ftPEContext.pAddStaReq;
+ add_sta_params->assocId = assoc_id;
+ add_sta_params->smesessionId = session_entry->smeSessionId;
+
+ msg_q.type = WMA_ADD_STA_REQ;
+ msg_q.reserved = 0;
+ msg_q.bodyptr = add_sta_params;
+ msg_q.bodyval = 0;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "Sending WMA_ADD_STA_REQ (aid %d)",
+ add_sta_params->assocId);
+#endif
+ MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
+ msg_q.type));
+
+ session_entry->limPrevMlmState = session_entry->limMlmState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
+ session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+ ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
+ if (eSIR_SUCCESS != ret_code) {
+ lim_log(mac_ctx, LOGE,
+ FL("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X"),
+ ret_code);
+ cdf_mem_free(add_sta_params);
+ }
+
+ session_entry->ftPEContext.pAddStaReq = NULL;
+ return ret_code;
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+/**
+ * lim_add_sta_self()
+ *
+ ***FUNCTION:
+ * This function is called to add an STA context at hardware
+ * whenever a STA is (Re) Associated.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+lim_add_sta_self(tpAniSirGlobal pMac, uint16_t staIdx, uint8_t updateSta,
+ tpPESession psessionEntry)
+{
+ tpAddStaParams pAddStaParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMacAddr staMac;
+ uint32_t listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+ uint32_t shortGi20MhzSupport;
+ uint32_t shortGi40MhzSupport;
+ uint32_t ampduLenExponent = 0;
+ /*This self Sta dot 11 mode comes from the cfg and the expectation here is
+ * that cfg carries the systemwide capability that device under
+ * consideration can support. This capability gets plumbed into the cfg
+ * cache at system initialization time via the .dat and .ini file override
+ * mechanisms and will not change. If it does change, it is the
+ * responsibility of SME to evict the selfSta and reissue a new AddStaSelf
+ * command.*/
+ uint32_t selfStaDot11Mode = 0, selfTxWidth = 0;
+ uint32_t val;
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
+ lim_log(pMac, LOG1, FL("cfgDot11Mode %d"), (int)selfStaDot11Mode);
+ wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,
+ &selfTxWidth);
+ lim_log(pMac, LOG1, FL("SGI 20 %d"), (int)selfTxWidth);
+ lim_log(pMac, LOG1, FL("Roam Channel Bonding Mode %d"),
+ (int)pMac->roam.configParam.uCfgDot11Mode);
+
+ sir_copy_mac_addr(staMac, psessionEntry->selfMacAddr);
+ lim_log(pMac, LOG1, FL(MAC_ADDRESS_STR ": "), MAC_ADDR_ARRAY(staMac));
+ pAddStaParams = cdf_mem_malloc(sizeof(tAddStaParams));
+ if (NULL == pAddStaParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during ADD_STA"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set((uint8_t *) pAddStaParams, sizeof(tAddStaParams), 0);
+
+ /* / Add STA context at MAC HW (BMU, RHP & TFP) */
+ cdf_mem_copy((uint8_t *) pAddStaParams->staMac,
+ (uint8_t *) staMac, sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) pAddStaParams->bssId,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ pAddStaParams->assocId = psessionEntry->limAID;
+ pAddStaParams->staType = STA_ENTRY_SELF;
+ pAddStaParams->status = CDF_STATUS_SUCCESS;
+ pAddStaParams->respReqd = 1;
+
+ /* Update PE session ID */
+ pAddStaParams->sessionId = psessionEntry->peSessionId;
+
+ /* Update SME session ID */
+ pAddStaParams->smesessionId = psessionEntry->smeSessionId;
+
+ pAddStaParams->maxTxPower = psessionEntry->maxTxPower;
+
+ /* This will indicate HAL to "allocate" a new STA index */
+ pAddStaParams->staIdx = staIdx;
+ pAddStaParams->updateSta = updateSta;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, FL(
+ "Couldn't get SHORT_PREAMBLE, set default"));
+ pAddStaParams->shortPreambleSupported = 1;
+ } else {
+ pAddStaParams->shortPreambleSupported = val;
+ }
+
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
+ psessionEntry, NULL);
+#else
+ lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
+ psessionEntry);
+#endif
+ if (IS_DOT11_MODE_HT(selfStaDot11Mode)) {
+ pAddStaParams->htCapable = true;
+#ifdef DISABLE_GF_FOR_INTEROP
+ if ((psessionEntry->pLimJoinReq != NULL)
+ && (!psessionEntry->pLimJoinReq->bssDescription.
+ aniIndicator)) {
+ lim_log(pMac, LOGE,
+ FL
+ (" Turning off Greenfield, when adding self entry"));
+ pAddStaParams->greenFieldCapable =
+ WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
+ } else
+#endif
+ {
+ pAddStaParams->greenFieldCapable =
+ lim_get_ht_capability(pMac, eHT_GREENFIELD,
+ psessionEntry);
+ pAddStaParams->ch_width =
+ pMac->roam.configParam.channelBondingMode5GHz;
+ pAddStaParams->mimoPS =
+ lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
+ psessionEntry);
+ pAddStaParams->rifsMode =
+ lim_get_ht_capability(pMac, eHT_RIFS_MODE,
+ psessionEntry);
+ pAddStaParams->lsigTxopProtection =
+ lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
+ psessionEntry);
+ pAddStaParams->maxAmpduDensity =
+ lim_get_ht_capability(pMac, eHT_MPDU_DENSITY,
+ psessionEntry);
+ pAddStaParams->maxAmpduSize =
+ lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
+ psessionEntry);
+ pAddStaParams->maxAmsduSize =
+ lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
+ psessionEntry);
+ pAddStaParams->fDsssCckMode40Mhz =
+ lim_get_ht_capability(pMac, eHT_DSSS_CCK_MODE_40MHZ,
+ psessionEntry);
+ /*
+ * We will read the gShortGI20Mhz from ini file, and if it is set
+ * to 1 then we will tell Peer that we support 40Mhz short GI
+ */
+ if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
+ (pMac, WNI_CFG_SHORT_GI_20MHZ,
+ &shortGi20MhzSupport))) {
+ if (true == shortGi20MhzSupport) {
+ pAddStaParams->fShortGI20Mhz =
+ WNI_CFG_SHORT_GI_20MHZ_STAMAX;
+ } else {
+ pAddStaParams->fShortGI20Mhz = false;
+ }
+ } else {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve shortGI 20Mhz"
+ "CFG,setting value to default"));
+ )
+ pAddStaParams->fShortGI20Mhz =
+ WNI_CFG_SHORT_GI_20MHZ_STADEF;
+ }
+
+ /*
+ * We will read the gShortGI40Mhz from ini file, and if it is set
+ * to 1 then we will tell Peer that we support 40Mhz short GI
+ */
+ if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
+ (pMac, WNI_CFG_SHORT_GI_40MHZ,
+ &shortGi40MhzSupport))) {
+ if (true == shortGi40MhzSupport) {
+ pAddStaParams->fShortGI40Mhz =
+ WNI_CFG_SHORT_GI_40MHZ_STAMAX;
+ } else {
+ pAddStaParams->fShortGI40Mhz = false;
+ }
+ } else {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve shortGI 40Mhz"
+ "CFG,setting value to default"));
+ )
+ pAddStaParams->fShortGI40Mhz =
+ WNI_CFG_SHORT_GI_40MHZ_STADEF;
+ }
+ lim_log(pMac, LOG2,
+ FL(" greenFieldCapable: %d maxAmpduDensity = %d "
+ "maxAmpduSize = %d"),
+ pAddStaParams->greenFieldCapable,
+ pAddStaParams->maxAmpduDensity,
+ pAddStaParams->maxAmpduSize);
+
+ lim_log(pMac, LOG2,
+ FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d "
+ "fShortGI40Mhz: %d lsigTxopProtection: %d"),
+ pAddStaParams->fDsssCckMode40Mhz,
+ pAddStaParams->fShortGI20Mhz,
+ pAddStaParams->fShortGI40Mhz,
+ pAddStaParams->lsigTxopProtection);
+
+ lim_log(pMac, LOG2,
+ FL("maxAmsduSize: %d txChannelWidth: %d mimoPS: %d rifsMode %d"),
+ pAddStaParams->maxAmsduSize,
+ pAddStaParams->ch_width,
+ pAddStaParams->mimoPS, pAddStaParams->rifsMode);
+ }
+ }
+#ifdef WLAN_FEATURE_11AC
+ pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode);
+ if (pAddStaParams->vhtCapable) {
+ pAddStaParams->ch_width =
+ psessionEntry->ch_width;
+ lim_log(pMac, LOG1, FL("VHT WIDTH SET %d"),
+ pAddStaParams->ch_width);
+ }
+ pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled;
+ pAddStaParams->enable_su_tx_bformer =
+ psessionEntry->enable_su_tx_bformer;
+ lim_log(pMac, LOG2, FL("vhtCapable: %d vhtTxBFCapable %d, su_bfer %d"),
+ pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable,
+ pAddStaParams->enable_su_tx_bformer);
+
+ /* In 11ac mode, the hardware is capable of supporting 128K AMPDU size */
+ if (IS_DOT11_MODE_VHT(selfStaDot11Mode)) {
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &duLenExponent)
+ != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT"));
+ }
+ pAddStaParams->maxAmpduSize = (uint8_t) ampduLenExponent;
+ }
+ pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee;
+ pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid;
+#endif
+ pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs;
+ pAddStaParams->enableHtSmps = psessionEntry->enableHtSmps;
+ pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue;
+
+ /* For Self STA get the LDPC capability from session i.e config.ini */
+ pAddStaParams->htLdpcCapable =
+ (psessionEntry->txLdpcIniFeatureEnabled & 0x01);
+ pAddStaParams->vhtLdpcCapable =
+ ((psessionEntry->txLdpcIniFeatureEnabled >> 1) & 0x01);
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
+ pAddStaParams->listenInterval = (uint16_t) listenInterval;
+
+ if (CDF_P2P_CLIENT_MODE == psessionEntry->pePersona) {
+ pAddStaParams->p2pCapableSta = 1;
+ }
+
+ pAddStaParams->supportedRates.opRateMode =
+ lim_get_sta_rate_mode((uint8_t) selfStaDot11Mode);
+
+ lim_log(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
+ pAddStaParams->staIdx, pAddStaParams->updateSta,
+ pAddStaParams->htCapable);
+
+ lim_log(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
+ "p2pCapableSta: %d"),
+ pAddStaParams->htLdpcCapable, pAddStaParams->vhtLdpcCapable,
+ pAddStaParams->p2pCapableSta);
+
+ if (psessionEntry->isNonRoamReassoc) {
+ pAddStaParams->nonRoamReassoc = 1;
+ psessionEntry->isNonRoamReassoc = 0;
+ }
+ lim_log(pMac, LOG2, FL("sessionid: %d Assoc ID: %d listenInterval = %d "
+ "shortPreambleSupported: %d"),
+ psessionEntry->smeSessionId, pAddStaParams->assocId,
+ pAddStaParams->listenInterval,
+ pAddStaParams->shortPreambleSupported);
+
+ msgQ.type = WMA_ADD_STA_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddStaParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG1, FL(MAC_ADDRESS_STR ":Sessionid %d : "
+ "Sending WMA_ADD_STA_REQ. (aid %d)"),
+ MAC_ADDR_ARRAY(pAddStaParams->staMac),
+ pAddStaParams->sessionId, pAddStaParams->assocId);
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ lim_log(pMac, LOGE,
+ FL("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X"),
+ retCode);
+ cdf_mem_free(pAddStaParams);
+ }
+ return retCode;
+}
+
+/**
+ * limTeardownInfraBSS()
+ *
+ ***FUNCTION:
+ * This function is called by various LIM functions to teardown
+ * an established Infrastructure BSS
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_teardown_infra_bss(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ /**
+ * Send Broadcast Disassociate frame with
+ * 'leaving BSS' reason.
+ */
+ lim_send_disassoc_mgmt_frame(pMac,
+ eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
+ bcAddr, psessionEntry, false);
+} /*** end lim_teardown_infra_bss() ***/
+
+/**
+ * lim_handle_cnf_wait_timeout()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue to handle
+ * various confirmation failure cases.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to a sta descriptor
+ * @return None
+ */
+
+void lim_handle_cnf_wait_timeout(tpAniSirGlobal pMac, uint16_t staId)
+{
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry = NULL;
+
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+ pStaDs = dph_get_hash_entry(pMac, staId, &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT."));
+ )
+ return;
+ }
+
+ switch (pStaDs->mlmStaContext.mlmState) {
+ case eLIM_MLM_WT_ASSOC_CNF_STATE:
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL
+ ("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d"),
+ pStaDs->assocId);
+ )
+ lim_print_mac_addr(pMac, pStaDs->staAddr, LOGW);
+
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ lim_reject_association(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true,
+ pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ }
+ break;
+
+ default:
+ lim_log(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d"),
+ pStaDs->mlmStaContext.mlmState);
+ }
+}
+
+/**
+ * lim_delete_dph_hash_entry()- function to delete dph hash entry
+ * @mac_ctx: pointer to global mac structure
+ * @sta_addr: peer station address
+ * @sta_id: id assigned to peer station
+ * @session_entry: pe session entry
+ *
+ * This function is called whenever we need to delete
+ * the dph hash entry
+ *
+ * Return: none
+ */
+
+void
+lim_delete_dph_hash_entry(tpAniSirGlobal mac_ctx, tSirMacAddr sta_addr,
+ uint16_t sta_id, tpPESession session_entry)
+{
+ uint16_t aid;
+ tpDphHashNode sta_ds;
+ tUpdateBeaconParams beacon_params;
+
+ cdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+ beacon_params.paramChangeBitmap = 0;
+ lim_deactivate_and_change_per_sta_id_timer(mac_ctx, eLIM_CNF_WAIT_TIMER,
+ sta_id);
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGE, FL("NULL session_entry"));
+ return;
+ }
+
+ beacon_params.bssIdx = session_entry->bssIdx;
+ sta_ds = dph_lookup_hash_entry(mac_ctx, sta_addr, &aid,
+ &session_entry->dph.dphHashTable);
+
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGE, FL("sta_ds is NULL"));
+ return;
+ }
+
+ lim_log(mac_ctx, LOGW, FL("Deleting DPH Hash entry for STAID: %X"),
+ sta_id);
+ /*
+ * update the station count and perform associated actions
+ * do this before deleting the dph hash entry
+ */
+ lim_util_count_sta_del(mac_ctx, sta_ds, session_entry);
+
+ if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry)) {
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ if (session_entry->gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_ap_protection_on_delete(mac_ctx,
+ sta_ds, &beacon_params, session_entry);
+ }
+
+ if (LIM_IS_IBSS_ROLE(session_entry))
+ lim_ibss_decide_protection_on_delete(mac_ctx, sta_ds,
+ &beacon_params, session_entry);
+
+ lim_decide_short_preamble(mac_ctx, sta_ds, &beacon_params,
+ session_entry);
+ lim_decide_short_slot(mac_ctx, sta_ds, &beacon_params,
+ session_entry);
+
+ /* Send message to HAL about beacon parameter change. */
+ lim_log(mac_ctx, LOGW, FL("param bitmap = %d "),
+ beacon_params.paramChangeBitmap);
+ if (beacon_params.paramChangeBitmap &&
+ (false ==
+ mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+ sch_set_fixed_beacon_fields(mac_ctx, session_entry);
+ lim_send_beacon_params(mac_ctx, &beacon_params,
+ session_entry);
+ }
+#ifdef WLAN_FEATURE_11W
+ tx_timer_delete(&sta_ds->pmfSaQueryTimer);
+#endif
+ }
+
+ if (dph_delete_hash_entry(mac_ctx, sta_addr, sta_id,
+ &session_entry->dph.dphHashTable) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP, FL("error deleting hash entry"));
+}
+
+/**
+ * lim_check_and_announce_join_success()- function to check if the received
+ * Beacon/Probe Response is from the BSS that we're attempting to join.
+ * @mac: pointer to global mac structure
+ * @beacon_probe_rsp: pointer to reveived beacon/probe response frame
+ * @header: pointer to received management frame header
+ * @session_entry: pe session entry
+ *
+ * This function is called upon receiving Beacon/Probe Response
+ * frame in WT_JOIN_BEACON_STATE to check if the received
+ * Beacon/Probe Response is from the BSS that we're attempting
+ * to join.
+ * If the Beacon/Probe Response is indeed from the BSS we're
+ * attempting to join, join success is sent to SME.
+ *
+ * Return: none
+ */
+
+void
+lim_check_and_announce_join_success(tpAniSirGlobal mac_ctx,
+ tSirProbeRespBeacon *beacon_probe_rsp, tpSirMacMgmtHdr header,
+ tpPESession session_entry)
+{
+ tSirMacSSid current_ssid;
+ tLimMlmJoinCnf mlm_join_cnf;
+ uint32_t val = 0;
+ uint32_t *noa_duration_from_beacon = NULL;
+ uint32_t *noa2_duration_from_beacon = NULL;
+ uint32_t noa;
+ uint32_t total_num_noa_desc = 0;
+
+ cdf_mem_copy(current_ssid.ssId,
+ session_entry->ssId.ssId, session_entry->ssId.length);
+
+ current_ssid.length = (uint8_t) session_entry->ssId.length;
+
+ /*
+ * Check for SSID only in probe response. Beacons may not carry
+ * SSID information in hidden SSID case
+ */
+ if (((SIR_MAC_MGMT_FRAME == header->fc.type) &&
+ (SIR_MAC_MGMT_PROBE_RSP == header->fc.subType)) &&
+ current_ssid.length &&
+ (!cdf_mem_compare((uint8_t *) &beacon_probe_rsp->ssId,
+ (uint8_t *) ¤t_ssid,
+ (uint8_t) (1 + current_ssid.length)))) {
+ /*
+ * Received SSID does not match with the one we've.
+ * Ignore received Beacon frame
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("SSID received in Beacon does not match"));
+#ifdef WLAN_DEBUG
+ mac_ctx->lim.gLimBcnSSIDMismatchCnt++;
+#endif
+ return;
+ }
+
+ if (!(LIM_IS_BT_AMP_STA_ROLE(session_entry) ||
+ LIM_IS_STA_ROLE(session_entry)))
+ return;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Received Beacon/PR with matching BSSID:%pM PESessionID %d"),
+ session_entry->bssId, session_entry->peSessionId);
+
+ /* Deactivate Join Failure timer */
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
+ /* Deactivate Periodic Join timer */
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+
+ if (CDF_P2P_CLIENT_MODE == session_entry->pePersona &&
+ beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.present) {
+
+ noa_duration_from_beacon = (uint32_t *)
+ (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc + 1);
+
+ if (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.num_NoADesc)
+ total_num_noa_desc =
+ beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.
+ num_NoADesc / SIZE_OF_NOA_DESCRIPTOR;
+
+ noa = *noa_duration_from_beacon;
+
+ if (total_num_noa_desc > 1) {
+ noa2_duration_from_beacon = (uint32_t *)
+ (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc +
+ SIZE_OF_NOA_DESCRIPTOR + 1);
+ noa += *noa2_duration_from_beacon;
+ }
+
+ /*
+ * If MAX Noa exceeds 3 secs we will consider only 3 secs to
+ * avoid arbitary values in noa duration field
+ */
+ noa = noa > MAX_NOA_PERIOD_IN_MICROSECS ?
+ MAX_NOA_PERIOD_IN_MICROSECS : noa;
+ noa = noa / 1000; /* Convert to ms */
+
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, &val) ==
+ eSIR_SUCCESS) {
+ session_entry->defaultAuthFailureTimeout = val;
+ cfg_set_int(mac_ctx,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ val + noa);
+ }
+ } else {
+ session_entry->defaultAuthFailureTimeout = 0;
+ }
+
+ /* Update Beacon Interval at CFG database */
+
+ if (beacon_probe_rsp->HTCaps.present)
+ lim_update_sta_run_time_ht_capability(mac_ctx,
+ &beacon_probe_rsp->HTCaps);
+ if (beacon_probe_rsp->HTInfo.present)
+ lim_update_sta_run_time_ht_info(mac_ctx,
+ &beacon_probe_rsp->HTInfo, session_entry);
+ session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
+
+ /*
+ * update the capability info based on recently received beacon/probe
+ * response frame
+ */
+ session_entry->limCurrentBssCaps =
+ lim_get_u16((uint8_t *)&beacon_probe_rsp->capabilityInfo);
+
+ /*
+ * Announce join success by sending
+ * Join confirm to SME.
+ */
+ mlm_join_cnf.resultCode = eSIR_SME_SUCCESS;
+ mlm_join_cnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS;
+ /* Update PE sessionId */
+ mlm_join_cnf.sessionId = session_entry->peSessionId;
+ lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+ (uint32_t *) &mlm_join_cnf);
+
+ if (beacon_probe_rsp->vendor2_ie.VHTCaps.present) {
+ session_entry->is_vendor_specific_vhtcaps = true;
+ session_entry->vendor_specific_vht_ie_type =
+ beacon_probe_rsp->vendor2_ie.type;
+ session_entry->vendor_specific_vht_ie_sub_type =
+ beacon_probe_rsp->vendor2_ie.sub_type;
+ lim_log(mac_ctx, LOG1, FL(
+ "VHT caps are present in vendor specific IE"));
+ }
+}
+
+/**
+ * lim_extract_ap_capabilities()
+ *
+ ***FUNCTION:
+ * This function is called to extract all of the AP's capabilities
+ * from the IEs received from it in Beacon/Probe Response frames
+ *
+ ***LOGIC:
+ * This routine mimics the lim_extract_ap_capability() API. The difference here
+ * is that this API returns the entire tSirProbeRespBeacon info as is. It is
+ * left to the caller of this API to use this info as required
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pIE Pointer to starting IE in Beacon/Probe Response
+ * @param ieLen Length of all IEs combined
+ * @param beaconStruct A pointer to tSirProbeRespBeacon that needs to be
+ * populated
+ * @return status A status reporting eSIR_SUCCESS or eSIR_FAILURE
+ */
+tSirRetStatus lim_extract_ap_capabilities(tpAniSirGlobal pMac,
+ uint8_t *pIE,
+ uint16_t ieLen,
+ tpSirProbeRespBeacon beaconStruct)
+{
+ cdf_mem_set((uint8_t *) beaconStruct, sizeof(tSirProbeRespBeacon), 0);
+
+ PELOG3(lim_log(pMac, LOG3,
+ FL
+ ("In lim_extract_ap_capabilities: The IE's being received are:"));
+ sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen);
+ )
+ /* Parse the Beacon IE's, Don't try to parse if we dont have anything in IE */
+ if (ieLen > 0) {
+ if (eSIR_SUCCESS !=
+ sir_parse_beacon_ie(pMac, beaconStruct, pIE,
+ (uint32_t) ieLen)) {
+ lim_log(pMac, LOGE,
+ FL("APCapExtract: Beacon parsing error!"));
+ return eSIR_FAILURE;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_del_bss()
+ *
+ ***FUNCTION:
+ * This function is called to delete BSS context at hardware
+ * whenever a STA is disassociated
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the STA datastructure created by
+ * LIM and maintained by DPH
+ * @return retCode - Indicates success or failure return code
+ */
+
+tSirRetStatus
+lim_del_bss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, uint16_t bssIdx,
+ tpPESession psessionEntry)
+{
+ tpDeleteBssParams pDelBssParams = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ pDelBssParams = cdf_mem_malloc(sizeof(tDeleteBssParams));
+ if (NULL == pDelBssParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during ADD_BSS"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set((uint8_t *) pDelBssParams, sizeof(tDeleteBssParams), 0);
+
+ pDelBssParams->sessionId = psessionEntry->peSessionId; /* update PE session Id */
+
+ /* DPH was storing the AssocID in staID field, */
+ /* staID is actually assigned by HAL when AddSTA message is sent. */
+ if (pStaDs != NULL) {
+ pDelBssParams->bssIdx = pStaDs->bssId;
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ } else
+ pDelBssParams->bssIdx = bssIdx;
+ psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ eLIM_MLM_WT_DEL_BSS_RSP_STATE));
+
+ if ((psessionEntry->peSessionId ==
+ pMac->lim.limTimers.gLimJoinFailureTimer.sessionId)
+ && (true ==
+ tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) {
+ lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
+ }
+
+ pDelBssParams->status = CDF_STATUS_SUCCESS;
+ pDelBssParams->respReqd = 1;
+ cdf_mem_copy(pDelBssParams->bssid, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ pDelBssParams->smesessionId = psessionEntry->smeSessionId;
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Sessionid %d : Sending HAL_DELETE_BSS_REQ "
+ "for bss idx: %X BSSID:" MAC_ADDRESS_STR),
+ pDelBssParams->sessionId, pDelBssParams->bssIdx,
+ MAC_ADDR_ARRAY(psessionEntry->bssId));
+ )
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WMA_DELETE_BSS_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pDelBssParams;
+ msgQ.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ lim_log(pMac, LOGE,
+ FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"),
+ retCode);
+ cdf_mem_free(pDelBssParams);
+ }
+
+ return retCode;
+}
+
+/**
+ * lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response.
+ * @mac_ctx Pointer to Global MAC structure
+ * @pAddBssParams: parameters required for add bss params.
+ * @vht_caps: VHT capabilities.
+ * @psessionEntry : session entry.
+ *
+ * Return : void
+ */
+void lim_update_vhtcaps_assoc_resp(tpAniSirGlobal mac_ctx,
+ tpAddBssParams pAddBssParams,
+ tDot11fIEVHTCaps *vht_caps, tpPESession psessionEntry)
+{
+ pAddBssParams->staContext.vht_caps =
+ ((vht_caps->maxMPDULen <<
+ SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
+ (vht_caps->supportedChannelWidthSet <<
+ SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
+ (vht_caps->ldpcCodingCap <<
+ SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
+ (vht_caps->shortGI80MHz <<
+ SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
+ (vht_caps->shortGI160and80plus80MHz <<
+ SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
+ (vht_caps->txSTBC <<
+ SIR_MAC_VHT_CAP_TXSTBC) |
+ (vht_caps->rxSTBC <<
+ SIR_MAC_VHT_CAP_RXSTBC) |
+ (vht_caps->suBeamFormerCap <<
+ SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
+ (vht_caps->suBeamformeeCap <<
+ SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
+ (vht_caps->csnofBeamformerAntSup <<
+ SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
+ (vht_caps->numSoundingDim <<
+ SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
+ (vht_caps->muBeamformerCap <<
+ SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
+ (vht_caps->muBeamformeeCap <<
+ SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
+ (vht_caps->vhtTXOPPS <<
+ SIR_MAC_VHT_CAP_TXOPPS) |
+ (vht_caps->htcVHTCap <<
+ SIR_MAC_VHT_CAP_HTC_CAP) |
+ (vht_caps->maxAMPDULenExp <<
+ SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
+ (vht_caps->vhtLinkAdaptCap <<
+ SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
+ (vht_caps->rxAntPattern <<
+ SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
+ (vht_caps->txAntPattern <<
+ SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
+ (vht_caps->reserved1 <<
+ SIR_MAC_VHT_CAP_RESERVED2));
+
+ pAddBssParams->staContext.maxAmpduSize =
+ SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
+ pAddBssParams->staContext.vht_caps);
+
+ lim_log(mac_ctx, LOG1,
+ FL("Updating VHT caps in assoc Response"));
+}
+
+/**
+ * lim_update_vht_oper_assoc_resp : Update VHT Operations in assoc response.
+ * @mac_ctx Pointer to Global MAC structure
+ * @pAddBssParams: parameters required for add bss params.
+ * @vht_oper: VHT Operations to update.
+ * @psessionEntry : session entry.
+ *
+ * Return : void
+ */
+void lim_update_vht_oper_assoc_resp(tpAniSirGlobal mac_ctx,
+ tpAddBssParams pAddBssParams,
+ tDot11fIEVHTOperation *vht_oper, tpPESession psessionEntry)
+{
+ if (vht_oper->chanWidth &&
+ psessionEntry->ch_width) {
+ pAddBssParams->ch_width = vht_oper->chanWidth + 1;
+
+ pAddBssParams->ch_center_freq_seg0 =
+ vht_oper->chanCenterFreqSeg1;
+
+ pAddBssParams->ch_center_freq_seg1 =
+ vht_oper->chanCenterFreqSeg2;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("Updating VHT Operation in assoc Response"));
+}
+
+
+/**
+ * limSendAddBss()
+ *
+ ***FUNCTION:
+ *
+ ***LOGIC:
+ * 1) LIM receives eWNI_SME_JOIN_REQ
+ * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends
+ * SIR_HAL_ADD_BSS_REQ to HAL
+ *
+ ***ASSUMPTIONS:
+ * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq
+ * ADD BSS parameters can be obtained from two sources:
+ * 1) pMac->lim.gLimMlmJoinReq
+ * 2) beaconStruct, passed as paramter
+ * So, if a reqd parameter is found in bssDescriptions
+ * then it is given preference over beaconStruct
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * pAssocRsp contains the structured assoc/reassoc Response got from AP
+ * beaconstruct Has the ProbeRsp/Beacon structured details
+ * bssDescription bssDescription passed to PE from the SME
+ * @return None
+ */
+
+tSirRetStatus lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpSchBeaconStruct pBeaconStruct,
+ tpSirBssDescription bssDescription,
+ uint8_t updateEntry, tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpAddBssParams pAddBssParams = NULL;
+ uint32_t retCode;
+ tpDphHashNode pStaDs = NULL;
+ uint8_t chanWidthSupp = 0;
+ uint32_t shortGi20MhzSupport;
+ uint32_t shortGi40MhzSupport;
+ uint32_t enableTxBF20MHz;
+ tDot11fIEVHTCaps *vht_caps = NULL;
+ tDot11fIEVHTOperation *vht_oper = NULL;
+ tAddStaParams *sta_context;
+
+ /* Package SIR_HAL_ADD_BSS_REQ message parameters */
+ pAddBssParams = cdf_mem_malloc(sizeof(tAddBssParams));
+ if (NULL == pAddBssParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during ADD_BSS"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ } else
+ cdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams),
+ 0);
+
+ cdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
+ sizeof(tSirMacAddr));
+ /* Fill in tAddBssParams selfMacAddr */
+ cdf_mem_copy(pAddBssParams->selfMacAddr,
+ psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+
+ lim_log(pMac, LOG1,
+ FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
+ psessionEntry->smeSessionId, updateEntry,
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+ lim_log(pMac, LOG1, FL("BSSID: " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pAddBssParams->bssId));
+
+ if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
+ pAddBssParams->bssType = eSIR_BTAMP_AP_MODE;
+ } else {
+ pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE;
+ }
+
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+ /* Update PE session ID */
+ pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+ pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+ pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod =
+ pBeaconStruct->cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration =
+ pBeaconStruct->cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining =
+ pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+ pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates;
+ cdf_mem_copy(pAddBssParams->rateSet.rate,
+ pAssocRsp->supportedRates.rate,
+ pAssocRsp->supportedRates.numRates);
+
+ if (IS_DOT11_MODE_11B(psessionEntry->dot11mode) &&
+ bssDescription->nwType != eSIR_11B_NW_TYPE) {
+ pAddBssParams->nwType = eSIR_11B_NW_TYPE;
+ } else {
+ pAddBssParams->nwType = bssDescription->nwType;
+ }
+
+ pAddBssParams->shortSlotTimeSupported =
+ (uint8_t) pAssocRsp->capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist =
+ (uint8_t) psessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist =
+ (uint8_t) psessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist =
+ (uint8_t) psessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist =
+ (uint8_t) psessionEntry->beaconParams.ht20Coexist;
+
+ lim_log(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
+ "cfpCount: %d"), pAddBssParams->bssType,
+ pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
+ pAddBssParams->cfParamSet.cfpCount);
+
+ lim_log(pMac, LOG2,
+ FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
+ " %d numRates: %d "), pAddBssParams->cfParamSet.cfpPeriod,
+ pAddBssParams->cfParamSet.cfpMaxDuration,
+ pAddBssParams->cfParamSet.cfpDurRemaining,
+ pAddBssParams->rateSet.numRates);
+
+ lim_log(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d"
+ "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"),
+ pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
+ pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
+ pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
+
+ pAddBssParams->dot11_mode = psessionEntry->dot11mode;
+ lim_log(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode);
+
+ /* Use the advertised capabilities from the received beacon/PR */
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+ && (pAssocRsp->HTCaps.present)) {
+ pAddBssParams->htCapable = pAssocRsp->HTCaps.present;
+ lim_log(pMac, LOG2, FL("htCapable: %d"),
+ pAddBssParams->htCapable);
+ if (pBeaconStruct->HTInfo.present) {
+ pAddBssParams->htOperMode =
+ (tSirMacHTOperatingMode) pAssocRsp->HTInfo.opMode;
+ pAddBssParams->dualCTSProtection =
+ (uint8_t) pAssocRsp->HTInfo.dualCTSProtection;
+ chanWidthSupp =
+ lim_get_ht_capability(pMac,
+ eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+ psessionEntry);
+ if ((pAssocRsp->HTCaps.supportedChannelWidthSet)
+ && (chanWidthSupp)) {
+ pAddBssParams->ch_width = (uint8_t)
+ pAssocRsp->HTInfo.recommendedTxWidthSet;
+ if (pAssocRsp->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ pAddBssParams->ch_center_freq_seg0 =
+ bssDescription->channelId + 2;
+ else if (pAssocRsp->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+ pAddBssParams->ch_center_freq_seg0 =
+ bssDescription->channelId - 2;
+ } else {
+ pAddBssParams->ch_width = CH_WIDTH_20MHZ;
+ pAddBssParams->ch_center_freq_seg0 = 0;
+ }
+ pAddBssParams->llnNonGFCoexist =
+ (uint8_t) pAssocRsp->HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport =
+ (uint8_t) pAssocRsp->HTInfo.
+ lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;
+
+ lim_log(pMac, LOGE,
+ FL("htOperMode: %d dualCTSProtection: %d txChannelWidth: %d center_freq_0: %d "),
+ pAddBssParams->htOperMode,
+ pAddBssParams->dualCTSProtection,
+ pAddBssParams->ch_width,
+ pAddBssParams->ch_center_freq_seg0);
+
+ lim_log(pMac, LOG2, FL("llnNonGFCoexist: %d "
+ "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
+ pAddBssParams->llnNonGFCoexist,
+ pAddBssParams->fLsigTXOPProtectionFullSupport,
+ pAddBssParams->fRIFSMode);
+ }
+ }
+
+ pAddBssParams->currentOperChannel = bssDescription->channelId;
+ lim_log(pMac, LOGE, FL("currentOperChannel %d"),
+ pAddBssParams->currentOperChannel);
+ if (psessionEntry->vhtCapability && (pAssocRsp->VHTCaps.present)) {
+ pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present;
+ vht_caps = &pAssocRsp->VHTCaps;
+ vht_oper = &pAssocRsp->VHTOperation;
+ } else if (psessionEntry->vhtCapability &&
+ pAssocRsp->vendor2_ie.VHTCaps.present){
+ pAddBssParams->vhtCapable =
+ pAssocRsp->vendor2_ie.VHTCaps.present;
+ lim_log(pMac, LOG1,
+ FL("VHT Caps and Operation are present in vendor Specfic IE"));
+ vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
+ vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
+ } else {
+ pAddBssParams->vhtCapable = 0;
+ }
+ if (pAddBssParams->vhtCapable) {
+ if (vht_oper != NULL)
+ lim_update_vht_oper_assoc_resp(pMac, pAddBssParams,
+ vht_oper, psessionEntry);
+ if (vht_caps != NULL)
+ lim_update_vhtcaps_assoc_resp(pMac, pAddBssParams,
+ vht_caps, psessionEntry);
+ }
+
+ lim_log(pMac, LOGE, FL("vhtCapable %d TxChannelWidth %d center_freq_0 %d center_freq_1 %d"),
+ pAddBssParams->vhtCapable, pAddBssParams->ch_width,
+ pAddBssParams->ch_center_freq_seg0,
+ pAddBssParams->ch_center_freq_seg1);
+
+ /*
+ * Populate the STA-related parameters here
+ * Note that the STA here refers to the AP
+ * staType = PEER
+ */
+ sta_context = &pAddBssParams->staContext;
+ /* Identifying AP as an STA */
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
+
+ cdf_mem_copy(pAddBssParams->staContext.bssId,
+ bssDescription->bssId, sizeof(tSirMacAddr));
+ pAddBssParams->staContext.listenInterval =
+ bssDescription->beaconInterval;
+
+ /* Fill Assoc id from the dph table */
+ pStaDs = dph_lookup_hash_entry(pMac, pAddBssParams->staContext.bssId,
+ &pAddBssParams->staContext.assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ lim_log(pMac, LOGE, FL(
+ "Couldn't get assoc id for " "MAC ADDR: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(
+ pAddBssParams->staContext.staMac));
+ return eSIR_FAILURE;
+ }
+
+ pAddBssParams->staContext.uAPSD =
+ psessionEntry->gUapsdPerAcBitmask;
+
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported =
+ (uint8_t) pAssocRsp->capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+
+ lim_log(pMac, LOG2, FL("StaContext: " MAC_ADDRESS_STR
+ " shortPreambleSupported: %d"),
+ MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
+ pAddBssParams->staContext.shortPreambleSupported);
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+ && pBeaconStruct->HTCaps.present) {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable =
+ (uint8_t) pAssocRsp->HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection =
+ (uint8_t) pAssocRsp->HTCaps.lsigTXOPProtection;
+ lim_log(pMac, LOG2, FL(
+ "StaCtx: htCap %d GFcap %d lsigTxopProtn %d"),
+ pAddBssParams->staContext.htCapable,
+ pAddBssParams->staContext.greenFieldCapable,
+ pAddBssParams->staContext.lsigTxopProtection);
+ if (psessionEntry->vhtCapability &&
+ (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
+ IS_BSS_VHT_CAPABLE(
+ pBeaconStruct->vendor2_ie.VHTCaps))) {
+ pAddBssParams->staContext.vhtCapable = 1;
+ pAddBssParams->staContext.vhtSupportedRxNss =
+ pStaDs->vhtSupportedRxNss;
+ if (pAssocRsp->VHTCaps.present)
+ vht_caps = &pAssocRsp->VHTCaps;
+ else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
+ vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
+ lim_log(pMac, LOG1, FL(
+ "VHT Caps are in vendor Specfic IE"));
+ }
+
+ if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
+ vht_caps->muBeamformerCap) &&
+ psessionEntry->txBFIniFeatureEnabled)
+ sta_context->vhtTxBFCapable = 1;
+
+ if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
+ psessionEntry->txMuBformee)
+ sta_context->vhtTxMUBformeeCapable = 1;
+ if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
+ psessionEntry->enable_su_tx_bformer)
+ sta_context->enable_su_tx_bformer = 1;
+ }
+
+ if ((pAssocRsp->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp)) {
+ pAddBssParams->staContext.ch_width = (uint8_t)
+ pAssocRsp->HTInfo.recommendedTxWidthSet;
+ if (pAssocRsp->VHTCaps.present)
+ vht_oper = &pAssocRsp->VHTOperation;
+ else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
+ vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
+ lim_log(pMac, LOG1, FL(
+ "VHT Op IE is in vendor Specfic IE"));
+ }
+ if ((vht_oper != NULL) &&
+ pAddBssParams->staContext.vhtCapable &&
+ vht_oper->chanWidth)
+ pAddBssParams->staContext.ch_width =
+ vht_oper->chanWidth + 1;
+
+ lim_log(pMac, LOGE, FL(
+ "StaCtx: vhtCap %d ChBW %d TxBF %d"),
+ pAddBssParams->staContext.vhtCapable,
+ pAddBssParams->staContext.ch_width,
+ sta_context->vhtTxBFCapable);
+ lim_log(pMac, LOGE, FL("StaContext su_tx_bfer %d"),
+ sta_context->enable_su_tx_bformer);
+ } else {
+ sta_context->ch_width = CH_WIDTH_20MHZ;
+ if ((IS_SIR_STATUS_SUCCESS(
+ wlan_cfg_get_int(pMac,
+ WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
+ &enableTxBF20MHz))) &&
+ (false == enableTxBF20MHz))
+ sta_context->vhtTxBFCapable = 0;
+ }
+ pAddBssParams->staContext.mimoPS =
+ (tSirMacHTMIMOPowerSaveState)
+ pAssocRsp->HTCaps.mimoPowerSave;
+ pAddBssParams->staContext.maxAmsduSize =
+ (uint8_t) pAssocRsp->HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity =
+ pAssocRsp->HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz =
+ (uint8_t) pAssocRsp->HTCaps.dsssCckMode40MHz;
+ /*
+ * We will check gShortGI20Mhz and gShortGI40Mhz from
+ * ini file. if they are set then we will use what ever
+ * Assoc response coming from AP supports. If these
+ * values are set as 0 in ini file then we will
+ * hardcode this values to 0.
+ */
+ if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
+ (pMac, WNI_CFG_SHORT_GI_20MHZ,
+ &shortGi20MhzSupport))) {
+ if (true == shortGi20MhzSupport) {
+ pAddBssParams->staContext.
+ fShortGI20Mhz =
+ (uint8_t) pAssocRsp->HTCaps.
+ shortGI20MHz;
+ } else {
+ pAddBssParams->staContext.
+ fShortGI20Mhz = false;
+ }
+ } else {
+ lim_log(pMac, LOGE, FL(
+ "failed to get shortGI 20Mhz, set default"));
+ pAddBssParams->staContext.fShortGI20Mhz =
+ WNI_CFG_SHORT_GI_20MHZ_STADEF;
+ }
+
+ if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
+ (pMac, WNI_CFG_SHORT_GI_40MHZ,
+ &shortGi40MhzSupport))) {
+ if (true == shortGi40MhzSupport) {
+ pAddBssParams->staContext.
+ fShortGI40Mhz =
+ (uint8_t) pAssocRsp->HTCaps.
+ shortGI40MHz;
+ } else {
+ pAddBssParams->staContext.
+ fShortGI40Mhz = false;
+ }
+ } else {
+ lim_log(pMac, LOGE, FL(
+ "failed to get shortGI 40Mhz, set default"));
+ pAddBssParams->staContext.fShortGI40Mhz =
+ WNI_CFG_SHORT_GI_40MHZ_STADEF;
+ }
+
+ if (!pAddBssParams->staContext.vhtCapable)
+ /* Use max ampd factor advertised in
+ * HTCAP for non-vht connection */
+ {
+ pAddBssParams->staContext.maxAmpduSize =
+ pAssocRsp->HTCaps.maxRxAMPDUFactor;
+ } else if (pAddBssParams->staContext.maxAmpduSize <
+ pAssocRsp->HTCaps.maxRxAMPDUFactor) {
+ pAddBssParams->staContext.maxAmpduSize =
+ pAssocRsp->HTCaps.maxRxAMPDUFactor;
+ }
+ if (pAddBssParams->staContext.vhtTxBFCapable
+ && pMac->lim.disableLDPCWithTxbfAP) {
+ pAddBssParams->staContext.htLdpcCapable = 0;
+ pAddBssParams->staContext.vhtLdpcCapable = 0;
+ } else {
+ pAddBssParams->staContext.htLdpcCapable =
+ (uint8_t) pAssocRsp->HTCaps.advCodingCap;
+ if (pAssocRsp->VHTCaps.present)
+ vht_caps = &pAssocRsp->VHTCaps;
+ else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
+ vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
+ lim_log(pMac, LOG1, FL(
+ "VHT Caps is in vendor Specfic IE"));
+ }
+ if (vht_caps != NULL)
+ pAddBssParams->staContext.vhtLdpcCapable =
+ (uint8_t) vht_caps->ldpcCodingCap;
+ }
+
+ if (pBeaconStruct->HTInfo.present)
+ pAddBssParams->staContext.rifsMode =
+ pAssocRsp->HTInfo.rifsMode;
+
+ lim_log(pMac, LOGE, FL(
+ "StaCtx: ChBW %d mimoPS %d maxAmsduSize %d"),
+ pAddBssParams->staContext.ch_width,
+ pAddBssParams->staContext.mimoPS,
+ pAddBssParams->staContext.maxAmsduSize);
+
+ lim_log(pMac, LOG2, FL(
+ "maxAmpduDens %d CckMode40Mhz %d SGI20Mhz %d"),
+ pAddBssParams->staContext.maxAmpduDensity,
+ pAddBssParams->staContext.fDsssCckMode40Mhz,
+ pAddBssParams->staContext.fShortGI20Mhz);
+
+ lim_log(pMac, LOG2, FL(
+ "SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %d"),
+ pAddBssParams->staContext.fShortGI40Mhz,
+ pAddBssParams->staContext.maxAmpduSize,
+ pAddBssParams->staContext.htLdpcCapable,
+ pAddBssParams->staContext.vhtLdpcCapable);
+ }
+ pAddBssParams->staContext.smesessionId =
+ psessionEntry->smeSessionId;
+ pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
+ pAddBssParams->staContext.wpa_rsn |=
+ (pBeaconStruct->wpaPresent << 1);
+ /* For OSEN Connection AP does not advertise RSN or WPA IE
+ * so from the IEs we get from supplicant we get this info
+ * so for FW to transmit EAPOL message 4 we shall set
+ * wpa_rsn
+ */
+ if ((!pAddBssParams->staContext.wpa_rsn)
+ && (psessionEntry->isOSENConnection))
+ pAddBssParams->staContext.wpa_rsn = 1;
+ cdf_mem_copy(&pAddBssParams->staContext.capab_info,
+ &pAssocRsp->capabilityInfo,
+ sizeof(pAddBssParams->staContext.capab_info));
+ cdf_mem_copy(&pAddBssParams->staContext.ht_caps,
+ (uint8_t *) &pAssocRsp->HTCaps + sizeof(uint8_t),
+ sizeof(pAddBssParams->staContext.ht_caps));
+
+ /* If WMM IE or 802.11E IE is present then enable WMM */
+ if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) ||
+ (psessionEntry->limQosEnabled && pAssocRsp->edcaPresent))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ /* Update the rates */
+ pStaDs = dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL) {
+ lim_fill_supported_rates_info(pMac, pStaDs,
+ &pStaDs->supportedRates,
+ psessionEntry);
+ cdf_mem_copy((uint8_t *) &pAddBssParams->staContext.
+ supportedRates,
+ (uint8_t *) &pStaDs->supportedRates,
+ sizeof(tSirSupportedRates));
+ } else
+ lim_log(pMac, LOGE, FL(
+ "could not Update the supported rates"));
+ pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+ lim_log(pMac, LOG2, FL("maxTxPower: %d"), pAddBssParams->maxTxPower);
+#endif
+ /* FIXME_GEN4 - Any other value that can be used for initialization? */
+ pAddBssParams->status = CDF_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+ /* update persona */
+ pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona;
+
+ if (CDF_P2P_CLIENT_MODE == psessionEntry->pePersona)
+ pAddBssParams->staContext.p2pCapableSta = 1;
+
+ pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ pAddBssParams->extSetStaKeyParamValid = 0;
+ lim_log(pMac, LOG2, FL("extSetStaKeyParamValid: %d"),
+ pAddBssParams->extSetStaKeyParamValid);
+#endif
+
+#ifdef WLAN_FEATURE_11W
+ if (psessionEntry->limRmfEnabled) {
+ pAddBssParams->rmfEnabled = 1;
+ pAddBssParams->staContext.rmfEnabled = 1;
+ }
+#endif
+
+ /* Set a new state for MLME */
+ if (eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState)
+ psessionEntry->limMlmState =
+ eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE;
+ else
+ psessionEntry->limMlmState =
+ eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+
+ lim_log(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
+ "p2pCapableSta: %d"),
+ pAddBssParams->staContext.wmmEnabled,
+ pAddBssParams->staContext.encryptType,
+ pAddBssParams->staContext.p2pCapableSta);
+
+ lim_log(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
+ "LimMlm state to %d"),
+ pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
+ psessionEntry->limMlmState);
+ if (psessionEntry->isNonRoamReassoc)
+ pAddBssParams->nonRoamReassoc = 1;
+ pAddBssParams->nss = psessionEntry->nss;
+ lim_log(pMac, LOG2, FL("nss value: %d"), pAddBssParams->nss);
+
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WMA_ADD_BSS_REQ;
+ /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBssParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG1, FL("SessionId:%d Sending WMA_ADD_BSS_REQ"),
+ psessionEntry->peSessionId);
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ cdf_mem_free(pAddBssParams);
+ lim_log(pMac, LOGE,
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
+ retCode);
+ goto returnFailure;
+
+ } else
+ return retCode;
+
+returnFailure:
+ /* Clean-up will be done by the caller... */
+ return retCode;
+}
+
+tSirRetStatus lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t updateEntry,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpAddBssParams pAddBssParams = NULL;
+ uint32_t retCode;
+ tSchBeaconStruct *pBeaconStruct;
+ uint8_t chanWidthSupp = 0;
+ uint32_t shortGi20MhzSupport;
+ uint32_t shortGi40MhzSupport;
+ tDot11fIEVHTOperation *vht_oper = NULL;
+ tDot11fIEVHTCaps *vht_caps = NULL;
+
+ tpSirBssDescription bssDescription =
+ &psessionEntry->pLimJoinReq->bssDescription;
+
+ pBeaconStruct = cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == pBeaconStruct) {
+ lim_log(pMac, LOGE,
+ FL("Unable to allocate memory during ADD_BSS"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* Package SIR_HAL_ADD_BSS_REQ message parameters */
+ pAddBssParams = cdf_mem_malloc(sizeof(tAddBssParams));
+ if (NULL == pAddBssParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during ADD_BSS"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+
+ cdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams), 0);
+
+ lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields,
+ lim_get_ielen_from_bss_description(bssDescription),
+ pBeaconStruct);
+
+ if (pMac->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct,
+ psessionEntry);
+ cdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
+ sizeof(tSirMacAddr));
+
+ /* Fill in tAddBssParams selfMacAddr */
+ cdf_mem_copy(pAddBssParams->selfMacAddr,
+ psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+ lim_log(pMac, LOG1,
+ FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
+ psessionEntry->smeSessionId, updateEntry,
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+ lim_log(pMac, LOG1, FL("BSSID: " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pAddBssParams->bssId));
+ /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on
+ * top of an already established Infra link. This lead to issues in
+ * concurrent data transfer.
+ */
+
+ pAddBssParams->bssType = psessionEntry->bssType; /* eSIR_INFRASTRUCTURE_MODE; */
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+ pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+ pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod =
+ pBeaconStruct->cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration =
+ pBeaconStruct->cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining =
+ pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+ pAddBssParams->rateSet.numRates =
+ pBeaconStruct->supportedRates.numRates;
+ cdf_mem_copy(pAddBssParams->rateSet.rate,
+ pBeaconStruct->supportedRates.rate,
+ pBeaconStruct->supportedRates.numRates);
+
+ pAddBssParams->nwType = bssDescription->nwType;
+
+ pAddBssParams->shortSlotTimeSupported =
+ (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist =
+ (uint8_t) psessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist =
+ (uint8_t) psessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist =
+ (uint8_t) psessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist =
+ (uint8_t) psessionEntry->beaconParams.ht20Coexist;
+
+ lim_log(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
+ "cfpCount: %d"), pAddBssParams->bssType,
+ pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
+ pAddBssParams->cfParamSet.cfpCount);
+
+ lim_log(pMac, LOG2,
+ FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
+ " %d numRates: %d "), pAddBssParams->cfParamSet.cfpPeriod,
+ pAddBssParams->cfParamSet.cfpMaxDuration,
+ pAddBssParams->cfParamSet.cfpDurRemaining,
+ pAddBssParams->rateSet.numRates);
+
+ lim_log(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d"
+ "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"),
+ pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
+ pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
+ pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
+ /* Use the advertised capabilities from the received beacon/PR */
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+ && (pBeaconStruct->HTCaps.present)) {
+ pAddBssParams->htCapable = pBeaconStruct->HTCaps.present;
+ lim_log(pMac, LOG2, FL("htCapable: %d"),
+ pAddBssParams->htCapable);
+ if (pBeaconStruct->HTInfo.present) {
+ pAddBssParams->htOperMode =
+ (tSirMacHTOperatingMode) pBeaconStruct->HTInfo.
+ opMode;
+ pAddBssParams->dualCTSProtection =
+ (uint8_t) pBeaconStruct->HTInfo.dualCTSProtection;
+
+ chanWidthSupp =
+ lim_get_ht_capability(pMac,
+ eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+ psessionEntry);
+ if ((pBeaconStruct->HTCaps.supportedChannelWidthSet)
+ && (chanWidthSupp)) {
+ pAddBssParams->ch_width =
+ (uint8_t) pBeaconStruct->HTInfo.
+ recommendedTxWidthSet;
+ if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ pAddBssParams->ch_center_freq_seg0 =
+ bssDescription->channelId + 2;
+
+ if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+ pAddBssParams->ch_center_freq_seg0 =
+ bssDescription->channelId - 2;
+ } else {
+ pAddBssParams->ch_width = CH_WIDTH_20MHZ;
+ pAddBssParams->ch_center_freq_seg0 = 0;
+ }
+ pAddBssParams->llnNonGFCoexist =
+ (uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport =
+ (uint8_t) pBeaconStruct->HTInfo.
+ lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode =
+ pBeaconStruct->HTInfo.rifsMode;
+
+ lim_log(pMac, LOG2,
+ FL("htOperMode: %d dualCTSProtection: %d txChannelWidthSet: %d center_freq_seg0: %d "),
+ pAddBssParams->htOperMode,
+ pAddBssParams->dualCTSProtection,
+ pAddBssParams->txChannelWidthSet,
+ pAddBssParams->ch_center_freq_seg0);
+
+ lim_log(pMac, LOG2, FL("llnNonGFCoexist: %d "
+ "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
+ pAddBssParams->llnNonGFCoexist,
+ pAddBssParams->fLsigTXOPProtectionFullSupport,
+ pAddBssParams->fRIFSMode);
+ }
+ }
+
+ pAddBssParams->currentOperChannel = bssDescription->channelId;
+ lim_log(pMac, LOG2, FL("currentOperChannel %d"),
+ pAddBssParams->currentOperChannel);
+#ifdef WLAN_FEATURE_11AC
+ if (psessionEntry->vhtCapability &&
+ (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
+ IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor2_ie.VHTCaps))) {
+
+ pAddBssParams->vhtCapable = 1;
+ if (pBeaconStruct->VHTOperation.present)
+ vht_oper = &pBeaconStruct->VHTOperation;
+ else if (pBeaconStruct->vendor2_ie.VHTOperation.present) {
+ vht_oper = &pBeaconStruct->vendor2_ie.VHTOperation;
+ lim_log(pMac, LOG1,
+ FL("VHT Operation is present in vendor Specfic IE"));
+ }
+
+
+ if ((vht_oper != NULL) &&
+ vht_oper->chanWidth &&
+ chanWidthSupp) {
+ pAddBssParams->ch_width =
+ vht_oper->chanWidth + 1;
+ pAddBssParams->ch_center_freq_seg0 =
+ vht_oper->chanCenterFreqSeg1;
+ pAddBssParams->ch_center_freq_seg1 =
+ vht_oper->chanCenterFreqSeg2;
+ }
+ pAddBssParams->staContext.maxAmpduSize =
+ SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
+ pAddBssParams->staContext.vht_caps);
+ } else {
+ pAddBssParams->vhtCapable = 0;
+ }
+ lim_log(pMac, LOGE, FL("vhtCapable %d vhtTxChannelWidthSet %d center_freq_seg0 - %d, center_freq_seg1 - %d"),
+ pAddBssParams->vhtCapable, pAddBssParams->ch_width,
+ pAddBssParams->ch_center_freq_seg0,
+ pAddBssParams->ch_center_freq_seg1);
+#endif
+
+ /*
+ * Populate the STA-related parameters here
+ * Note that the STA here refers to the AP
+ */
+ /* Identifying AP as an STA */
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
+
+ cdf_mem_copy(pAddBssParams->staContext.bssId,
+ bssDescription->bssId, sizeof(tSirMacAddr));
+ pAddBssParams->staContext.listenInterval =
+ bssDescription->beaconInterval;
+
+ pAddBssParams->staContext.assocId = 0;
+ pAddBssParams->staContext.uAPSD = 0;
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported =
+ (uint8_t) pBeaconStruct->capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+
+ lim_log(pMac, LOG2, FL(
+ "StaCtx: " MAC_ADDRESS_STR " shortPreamble: %d"),
+ MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
+ pAddBssParams->staContext.shortPreambleSupported);
+
+ pAddBssParams->dot11_mode = psessionEntry->dot11mode;
+ lim_log(pMac, LOG2, FL("dot11_mode:%d"),
+ pAddBssParams->dot11_mode);
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
+ && (pBeaconStruct->HTCaps.present)) {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable =
+ (uint8_t) pBeaconStruct->HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection =
+ (uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection;
+ lim_log(pMac, LOG2, FL(
+ "StaCtx: htCap %d GFCap %d lsigTxopProtn %d"),
+ pAddBssParams->staContext.htCapable,
+ pAddBssParams->staContext.greenFieldCapable,
+ pAddBssParams->staContext.lsigTxopProtection);
+ if (psessionEntry->vhtCapability &&
+ (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
+ IS_BSS_VHT_CAPABLE(
+ pBeaconStruct->vendor2_ie.VHTCaps))) {
+ pAddBssParams->staContext.vhtCapable = 1;
+ if (pBeaconStruct->VHTCaps.present)
+ vht_caps = &pBeaconStruct->VHTCaps;
+ else if (pBeaconStruct->vendor2_ie.VHTCaps.present)
+ vht_caps = &pBeaconStruct->vendor2_ie.VHTCaps;
+
+ if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
+ vht_caps->muBeamformerCap) &&
+ psessionEntry->txBFIniFeatureEnabled)
+ pAddBssParams->staContext.vhtTxBFCapable = 1;
+
+ if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
+ psessionEntry->txMuBformee)
+ pAddBssParams->staContext.vhtTxMUBformeeCapable
+ = 1;
+ if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
+ psessionEntry->enable_su_tx_bformer)
+ pAddBssParams->staContext.enable_su_tx_bformer
+ = 1;
+ lim_log(pMac, LOG2, FL("StaContext: su_tx_bfer %d"),
+ pAddBssParams->staContext.enable_su_tx_bformer);
+ }
+ if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp)) {
+ pAddBssParams->staContext.ch_width =
+ (uint8_t) pBeaconStruct->HTInfo.
+ recommendedTxWidthSet;
+ if ((vht_oper != NULL) &&
+ pAddBssParams->staContext.vhtCapable &&
+ vht_oper->chanWidth)
+ pAddBssParams->staContext.ch_width =
+ vht_oper->chanWidth + 1;
+ lim_log(pMac, LOG2, FL(
+ "StaCtx: vhtCap %d ch_bw %d TxBF %d"),
+ pAddBssParams->staContext.vhtCapable,
+ pAddBssParams->staContext.ch_width,
+ pAddBssParams->staContext.
+ vhtTxBFCapable);
+ } else {
+ pAddBssParams->staContext.ch_width =
+ CH_WIDTH_20MHZ;
+ }
+ pAddBssParams->staContext.mimoPS =
+ (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
+ mimoPowerSave;
+ pAddBssParams->staContext.maxAmsduSize =
+ (uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity =
+ pBeaconStruct->HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz =
+ (uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz;
+ /*
+ * We will check gShortGI20Mhz and gShortGI40Mhz from ini file.
+ * if they are set then we will use what ever Beacon coming
+ * from AP supports. If these values are set as 0 in ini file
+ * then we will hardcode this values to 0.
+ */
+ if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
+ (pMac, WNI_CFG_SHORT_GI_20MHZ,
+ &shortGi20MhzSupport))) {
+ if (true == shortGi20MhzSupport)
+ pAddBssParams->staContext.fShortGI20Mhz =
+ (uint8_t)pBeaconStruct->HTCaps.shortGI20MHz;
+ else
+ pAddBssParams->staContext.fShortGI20Mhz =
+ false;
+ } else {
+ lim_log(pMac, LOGE, FL(
+ "get shortGI 20Mhz failed, set default"));
+ pAddBssParams->staContext.fShortGI20Mhz =
+ WNI_CFG_SHORT_GI_20MHZ_STADEF;
+ }
+
+ if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
+ (pMac, WNI_CFG_SHORT_GI_40MHZ,
+ &shortGi40MhzSupport))) {
+ if (true == shortGi40MhzSupport) {
+ pAddBssParams->staContext.
+ fShortGI40Mhz =
+ (uint8_t) pBeaconStruct->HTCaps.
+ shortGI40MHz;
+ } else {
+ pAddBssParams->staContext.
+ fShortGI40Mhz = false;
+ }
+ } else {
+ lim_log(pMac, LOGE, FL(
+ "get shortGI 40Mhz failed, set default"));
+ pAddBssParams->staContext.fShortGI40Mhz =
+ WNI_CFG_SHORT_GI_40MHZ_STADEF;
+ }
+
+ pAddBssParams->staContext.maxAmpduSize =
+ pBeaconStruct->HTCaps.maxRxAMPDUFactor;
+ if (pAddBssParams->staContext.vhtTxBFCapable
+ && pMac->lim.disableLDPCWithTxbfAP) {
+ pAddBssParams->staContext.htLdpcCapable = 0;
+ pAddBssParams->staContext.vhtLdpcCapable = 0;
+ } else {
+ pAddBssParams->staContext.htLdpcCapable =
+ (uint8_t) pBeaconStruct->HTCaps.
+ advCodingCap;
+ if (pBeaconStruct->VHTCaps.present)
+ vht_caps = &pBeaconStruct->VHTCaps;
+ else if (pBeaconStruct->vendor2_ie.VHTCaps.present) {
+ vht_caps =
+ &pBeaconStruct->vendor2_ie.VHTCaps;
+ lim_log(pMac, LOG1, FL(
+ "VHT Caps are in vendor Specfic IE"));
+ }
+ if (vht_caps != NULL)
+ pAddBssParams->staContext.vhtLdpcCapable =
+ (uint8_t) vht_caps->ldpcCodingCap;
+ }
+
+ if (pBeaconStruct->HTInfo.present)
+ pAddBssParams->staContext.rifsMode =
+ pBeaconStruct->HTInfo.rifsMode;
+ lim_log(pMac, LOG2,
+ FL("StaContext ChannelWidth: %d mimoPS: %d maxAmsduSize: %d"),
+ pAddBssParams->staContext.ch_width,
+ pAddBssParams->staContext.mimoPS,
+ pAddBssParams->staContext.maxAmsduSize);
+
+ lim_log(pMac, LOG2, FL(
+ "maxAmpduDensity %d Cck40Mhz %d SGI20Mhz %d"),
+ pAddBssParams->staContext.maxAmpduDensity,
+ pAddBssParams->staContext.fDsssCckMode40Mhz,
+ pAddBssParams->staContext.fShortGI20Mhz);
+
+ lim_log(pMac, LOG2, FL(
+ "SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %d"),
+ pAddBssParams->staContext.fShortGI40Mhz,
+ pAddBssParams->staContext.maxAmpduSize,
+ pAddBssParams->staContext.htLdpcCapable,
+ pAddBssParams->staContext.vhtLdpcCapable);
+ }
+ /*
+ * If WMM IE or 802.11E IE is not present
+ * and AP is HT AP then enable WMM
+ */
+ if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent ||
+ pAddBssParams->staContext.htCapable)) ||
+ (psessionEntry->limQosEnabled &&
+ (pBeaconStruct->edcaPresent ||
+ pAddBssParams->staContext.htCapable)))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ /* Update the rates */
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_peer_rate_set(pMac,
+ &pAddBssParams->staContext.
+ supportedRates,
+ pBeaconStruct->HTCaps.supportedMCSSet,
+ false, psessionEntry,
+ &pBeaconStruct->VHTCaps);
+#else
+ lim_populate_peer_rate_set(pMac,
+ &pAddBssParams->staContext.
+ supportedRates,
+ pBeaconStruct->HTCaps.supportedMCSSet,
+ false, psessionEntry);
+#endif
+ lim_fill_supported_rates_info(pMac, NULL,
+ &pAddBssParams->staContext.
+ supportedRates, psessionEntry);
+
+
+ pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
+ lim_log(pMac, LOG2, FL("maxTxPower: %d"), pAddBssParams->maxTxPower);
+#endif
+
+ pAddBssParams->status = CDF_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+
+ pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId;
+ pAddBssParams->staContext.sessionId = psessionEntry->peSessionId;
+ pAddBssParams->sessionId = psessionEntry->peSessionId;
+
+ pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona; /* update persona */
+
+ pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ pAddBssParams->extSetStaKeyParamValid = 0;
+ lim_log(pMac, LOG2, FL("extSetStaKeyParamValid: %d"),
+ pAddBssParams->extSetStaKeyParamValid);
+#endif
+
+#ifdef WLAN_FEATURE_11W
+ if (psessionEntry->limRmfEnabled) {
+ pAddBssParams->rmfEnabled = 1;
+ pAddBssParams->staContext.rmfEnabled = 1;
+ }
+#endif
+
+ pAddBssParams->nss = psessionEntry->nss;
+ lim_log(pMac, LOG2, FL("nss value: %d"), pAddBssParams->nss);
+
+ /* Set a new state for MLME */
+ psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+
+ lim_log(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
+ "p2pCapableSta: %d"),
+ pAddBssParams->staContext.wmmEnabled,
+ pAddBssParams->staContext.encryptType,
+ pAddBssParams->staContext.p2pCapableSta);
+
+ lim_log(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
+ "LimMlm state to %d"),
+ pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
+ psessionEntry->limMlmState);
+
+ /* we need to defer the message until we get the response back from HAL. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = WMA_ADD_BSS_REQ;
+ /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pAddBssParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG1, FL("SessionId:%d Sending WMA_ADD_BSS_REQ"),
+ psessionEntry->peSessionId);
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ cdf_mem_free(pAddBssParams);
+ lim_log(pMac, LOGE,
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
+ retCode);
+ goto returnFailure;
+
+ } else {
+ cdf_mem_free(pBeaconStruct);
+ return retCode;
+ }
+
+returnFailure:
+ /* Clean-up will be done by the caller... */
+ cdf_mem_free(pBeaconStruct);
+ return retCode;
+}
+
+/**
+ * lim_prepare_and_send_del_sta_cnf() - prepares and send del sta cnf
+ *
+ * @pMac: mac global context
+ * @pStaDs: sta dph node
+ * @statusCode: status code
+ * @psessionEntry: session context
+ *
+ * deletes DPH entry, changes the MLM mode for station, calls
+ * lim_send_del_sta_cnf
+ *
+ * Return: void
+ */
+void
+lim_prepare_and_send_del_sta_cnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tSirResultCodes statusCode,
+ tpPESession psessionEntry)
+{
+ uint16_t staDsAssocId = 0;
+ tSirMacAddr staDsAddr;
+ tLimMlmStaContext mlmStaContext;
+
+ if (pStaDs == NULL) {
+ PELOGW(lim_log(pMac, LOGW, FL("pStaDs is NULL"));)
+ return;
+ }
+ staDsAssocId = pStaDs->assocId;
+ cdf_mem_copy((uint8_t *) staDsAddr,
+ pStaDs->staAddr, sizeof(tSirMacAddr));
+
+ mlmStaContext = pStaDs->mlmStaContext;
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
+ }
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
+ psessionEntry);
+
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+ }
+ lim_send_del_sta_cnf(pMac, staDsAddr, staDsAssocId, mlmStaContext,
+ statusCode, psessionEntry);
+}
+
+/** -------------------------------------------------------------
+ \fn lim_get_sta_rate_mode
+ \brief Gets the Station Rate Mode.
+ \param uint8_t dot11Mode
+ \return none
+ -------------------------------------------------------------*/
+tStaRateMode lim_get_sta_rate_mode(uint8_t dot11Mode)
+{
+ switch (dot11Mode) {
+ case WNI_CFG_DOT11_MODE_11A:
+ return eSTA_11a;
+ case WNI_CFG_DOT11_MODE_11B:
+ return eSTA_11b;
+ case WNI_CFG_DOT11_MODE_11G:
+ return eSTA_11bg;
+ case WNI_CFG_DOT11_MODE_11N:
+ return eSTA_11n;
+#ifdef WLAN_FEATURE_11AC
+ case WNI_CFG_DOT11_MODE_11AC:
+ return eSTA_11ac;
+#endif
+ case WNI_CFG_DOT11_MODE_ALL:
+ default:
+ return eSTA_11n;
+
+ }
+}
+
+/** -------------------------------------------------------------
+ \fn lim_init_pre_auth_timer_table
+ \brief Initialize the Pre Auth Tanle and creates the timer for
+ each node for the timeout value got from cfg.
+ \param tpAniSirGlobal pMac
+ \param tpLimPreAuthTable pPreAuthTimerTable
+ \return none
+ -------------------------------------------------------------*/
+void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
+ tpLimPreAuthTable pPreAuthTimerTable)
+{
+ uint32_t cfgValue;
+ uint32_t authNodeIdx;
+ tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable;
+
+ /* Get AUTH_RSP Timers value */
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS) {
+ /*
+ ** Could not get AUTH_RSP timeout value
+ ** from CFG. Log error.
+ **/
+ lim_log(pMac, LOGP,
+ FL("could not retrieve AUTH_RSP timeout value"));
+ return;
+ }
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ for (authNodeIdx = 0; authNodeIdx < pPreAuthTimerTable->numEntry;
+ authNodeIdx++, pAuthNode++) {
+ if (tx_timer_create
+ (&pAuthNode->timer, "AUTH RESPONSE TIMEOUT",
+ lim_auth_response_timer_handler, authNodeIdx, cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS) {
+ /* Cannot create timer. Log error. */
+ lim_log(pMac, LOGP,
+ FL("Cannot create Auth Rsp timer of Index :%d."),
+ authNodeIdx);
+ return;
+ }
+ pAuthNode->authNodeIdx = (uint8_t) authNodeIdx;
+ pAuthNode->fFree = 1;
+ }
+
+}
+
+/** -------------------------------------------------------------
+ \fn lim_acquire_free_pre_auth_node
+ \brief Retrives a free Pre Auth node from Pre Auth Table.
+ \param tpAniSirGlobal pMac
+ \param tpLimPreAuthTable pPreAuthTimerTable
+ \return none
+ -------------------------------------------------------------*/
+tLimPreAuthNode *lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
+ tpLimPreAuthTable pPreAuthTimerTable)
+{
+ uint32_t i;
+ tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable;
+ for (i = 0; i < pPreAuthTimerTable->numEntry; i++, pTempNode++) {
+ if (pTempNode->fFree == 1) {
+ pTempNode->fFree = 0;
+ return pTempNode;
+ }
+ }
+
+ return NULL;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_get_pre_auth_node_from_index
+ \brief Depending on the Index this retrives the pre auth node.
+ \param tpAniSirGlobal pMac
+ \param tpLimPreAuthTable pAuthTable
+ \param uint32_t authNodeIdx
+ \return none
+ -------------------------------------------------------------*/
+tLimPreAuthNode *lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
+ tpLimPreAuthTable pAuthTable,
+ uint32_t authNodeIdx)
+{
+ if ((authNodeIdx >= pAuthTable->numEntry)
+ || (pAuthTable->pTable == NULL)) {
+ lim_log(pMac, LOGE,
+ FL("Invalid Auth Timer Index : %d NumEntry : %d"),
+ authNodeIdx, pAuthTable->numEntry);
+ return NULL;
+ }
+
+ return pAuthTable->pTable + authNodeIdx;
+}
+
+/* Util API to check if the channels supported by STA is within range */
+tSirRetStatus lim_is_dot11h_supported_channels_valid(tpAniSirGlobal pMac,
+ tSirAssocReq *assoc)
+{
+ /*
+ * Allow all the stations to join with us.
+ * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs
+ * as an input into an algorithm used to select a new channel for the BSS.
+ * The specification of the algorithm is beyond the scope of this amendment.
+ */
+
+ return eSIR_SUCCESS;
+}
+
+/* Util API to check if the txpower supported by STA is within range */
+tSirRetStatus lim_is_dot11h_power_capabilities_in_range(tpAniSirGlobal pMac,
+ tSirAssocReq *assoc,
+ tpPESession psessionEntry)
+{
+ tPowerdBm localMaxTxPower;
+ uint32_t localPwrConstraint;
+
+ localMaxTxPower =
+ cfg_get_regulatory_max_transmit_power(pMac,
+ psessionEntry->currentOperChannel);
+
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ &localPwrConstraint) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to get Local Power Constraint from cfg"));
+ return eSIR_FAILURE;
+ }
+ localMaxTxPower -= (tPowerdBm) localPwrConstraint;
+
+ /**
+ * The min Tx Power of the associating station should not be greater than (regulatory
+ * max tx power - local power constraint configured on AP).
+ */
+ if (assoc->powerCapability.minTxPower > localMaxTxPower) {
+ lim_log(pMac, LOGW,
+ FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d"),
+ assoc->powerCapability.minTxPower, localMaxTxPower);
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_fill_rx_highest_supported_rate
+ \brief Fills in the Rx Highest Supported Data Rate field from
+ \ the 'supported MCS set' field in HT capability element.
+ \param tpAniSirGlobal pMac
+ \param tpSirSupportedRates pRates
+ \param uint8_t* pSupportedMCSSet
+ \return none
+ -------------------------------------------------------------*/
+void lim_fill_rx_highest_supported_rate(tpAniSirGlobal pMac,
+ uint16_t *rxHighestRate,
+ uint8_t *pSupportedMCSSet)
+{
+ tSirMacRxHighestSupportRate *pRxHighestRate;
+ uint8_t *pBuf;
+ uint16_t rate = 0;
+
+ pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET;
+ rate = lim_get_u16(pBuf);
+
+ pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate;
+ *rxHighestRate = pRxHighestRate->rate;
+
+ return;
+}
+
+#ifdef WLAN_FEATURE_11W
+/** -------------------------------------------------------------
+ \fn lim_send_sme_unprotected_mgmt_frame_ind
+ \brief Forwards the unprotected management frame to SME.
+ \param tpAniSirGlobal pMac
+ \param frameType - 802.11 frame type
+ \param frame - frame buffer
+ \param sessionId - id for the current session
+ \param psessionEntry - PE session context
+ \return none
+ -------------------------------------------------------------*/
+void lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
+ uint8_t *frame, uint32_t frameLen,
+ uint16_t sessionId,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeUnprotMgmtFrameInd *pSirSmeMgmtFrame = NULL;
+ uint16_t length;
+
+ length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen;
+
+ pSirSmeMgmtFrame = cdf_mem_malloc(length);
+ if (NULL == pSirSmeMgmtFrame) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd"));
+ return;
+ }
+ cdf_mem_set((void *)pSirSmeMgmtFrame, length, 0);
+
+ pSirSmeMgmtFrame->sessionId = sessionId;
+ pSirSmeMgmtFrame->frameType = frameType;
+
+ cdf_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
+ pSirSmeMgmtFrame->frameLen = frameLen;
+
+ mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND;
+ mmhMsg.bodyptr = pSirSmeMgmtFrame;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+#endif
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/** -------------------------------------------------------------
+ \fn lim_send_sme_tsm_ie_ind
+ \brief Forwards the TSM IE information to SME.
+ \param tpAniSirGlobal pMac
+ \param psessionEntry - PE session context
+ \param tid - traffic id
+ \param state - tsm state (enabled/disabled)
+ \param measurementInterval - measurement interval
+ \return none
+ -------------------------------------------------------------*/
+void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint8_t tid, uint8_t state, uint16_t measInterval)
+{
+ tSirMsgQ mmhMsg;
+ tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL;
+
+ if (!pMac || !psessionEntry)
+ return;
+
+ pSirSmeTsmIeInd = cdf_mem_malloc(sizeof(tSirSmeTsmIEInd));
+ if (NULL == pSirSmeTsmIeInd) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for tSirSmeTsmIEInd"));
+ return;
+ }
+ cdf_mem_set((void *)pSirSmeTsmIeInd, sizeof(tSirSmeTsmIEInd), 0);
+
+ pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeTsmIeInd->tsmIe.tsid = tid;
+ pSirSmeTsmIeInd->tsmIe.state = state;
+ pSirSmeTsmIeInd->tsmIe.msmt_interval = measInterval;
+
+ mmhMsg.type = eWNI_SME_TSM_IE_IND;
+ mmhMsg.bodyptr = pSirSmeTsmIeInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
diff --git a/core/mac/src/pe/lim/lim_assoc_utils.h b/core/mac/src/pe/lim/lim_assoc_utils.h
new file mode 100644
index 0000000..b9efbff
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_assoc_utils.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_assoc_utils.h contains the utility definitions
+ * LIM uses while processing Re/Association messages.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+#ifndef __LIM_ASSOC_UTILS_H
+#define __LIM_ASSOC_UTILS_H
+
+#include "sir_api.h"
+#include "sir_debug.h"
+#include "cfg_api.h"
+
+#include "lim_types.h"
+
+uint8_t lim_cmp_s_sid(tpAniSirGlobal, tSirMacSSid *, tpPESession);
+uint8_t lim_compare_capabilities(tpAniSirGlobal,
+ tSirAssocReq *,
+ tSirMacCapabilityInfo *, tpPESession);
+uint8_t lim_check_rx_basic_rates(tpAniSirGlobal, tSirMacRateSet, tpPESession);
+uint8_t lim_check_rx_rsn_ie_match(tpAniSirGlobal, tDot11fIERSN, tpPESession, uint8_t,
+ bool *);
+uint8_t lim_check_rx_wpa_ie_match(tpAniSirGlobal, tDot11fIEWPA, tpPESession,
+ uint8_t);
+uint8_t lim_check_mcs_set(tpAniSirGlobal pMac, uint8_t *supportedMCSSet);
+void limPostDummyToTmRing(tpAniSirGlobal, tpDphHashNode);
+void limPostPacketToTdRing(tpAniSirGlobal, tpDphHashNode, uint8_t);
+tSirRetStatus lim_cleanup_rx_path(tpAniSirGlobal, tpDphHashNode, tpPESession);
+void lim_reject_association(tpAniSirGlobal, tSirMacAddr, uint8_t,
+ uint8_t, tAniAuthType,
+ uint16_t, uint8_t, tSirResultCodes, tpPESession);
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus lim_populate_peer_rate_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ uint8_t *pSupportedMCSSet,
+ uint8_t basicOnly,
+ tpPESession psessionEntry,
+ tDot11fIEVHTCaps *pVHTCaps);
+#else
+tSirRetStatus lim_populate_peer_rate_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ uint8_t *pSupportedMCSSet,
+ uint8_t basicOnly,
+ tpPESession psessionEntry);
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus lim_populate_own_rate_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ uint8_t *pSupportedMCSSet,
+ uint8_t basicOnly,
+ tpPESession psessionEntry,
+ tDot11fIEVHTCaps *pVHTCaps);
+
+#else
+tSirRetStatus lim_populate_own_rate_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ uint8_t *pSupportedMCSSet,
+ uint8_t basicOnly,
+ tpPESession psessionEntry);
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus
+lim_populate_matching_rate_set(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tSirMacRateSet *pOperRateSet,
+ tSirMacRateSet *pExtRateSet,
+ uint8_t *pSupportedMCSSet,
+ tpPESession psessionEntry,
+ tDot11fIEVHTCaps *pVHTCaps);
+#else
+tSirRetStatus lim_populate_matching_rate_set(tpAniSirGlobal,
+ tpDphHashNode,
+ tSirMacRateSet *,
+ tSirMacRateSet *,
+ uint8_t *pSupportedMCSSet,
+ tpPESession);
+
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+#define MCSMAPMASK1x1 0x3
+#define MCSMAPMASK2x2 0xC
+#endif
+
+tSirRetStatus lim_add_sta(tpAniSirGlobal, tpDphHashNode, uint8_t, tpPESession);
+tSirRetStatus lim_del_bss(tpAniSirGlobal, tpDphHashNode, uint16_t, tpPESession);
+tSirRetStatus lim_del_sta(tpAniSirGlobal, tpDphHashNode, bool, tpPESession);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+tSirRetStatus lim_add_ft_sta_self(tpAniSirGlobal pMac, uint16_t assocId,
+ tpPESession psessionEntry);
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+tSirRetStatus lim_add_sta_self(tpAniSirGlobal, uint16_t, uint8_t, tpPESession);
+tStaRateMode lim_get_sta_rate_mode(uint8_t dot11Mode);
+
+void lim_teardown_infra_bss(tpAniSirGlobal, tpPESession);
+void lim_restore_pre_reassoc_state(tpAniSirGlobal,
+ tSirResultCodes, uint16_t, tpPESession);
+void lim_post_reassoc_failure(tpAniSirGlobal,
+ tSirResultCodes, uint16_t, tpPESession);
+bool lim_is_reassoc_in_progress(tpAniSirGlobal, tpPESession);
+void
+lim_send_del_sta_cnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr,
+ uint16_t staDsAssocId, tLimMlmStaContext mlmStaContext,
+ tSirResultCodes statusCode, tpPESession psessionEntry);
+
+void lim_handle_cnf_wait_timeout(tpAniSirGlobal pMac, uint16_t staId);
+void lim_delete_dph_hash_entry(tpAniSirGlobal, tSirMacAddr, uint16_t, tpPESession);
+void lim_check_and_announce_join_success(tpAniSirGlobal,
+ tSirProbeRespBeacon *,
+ tpSirMacMgmtHdr, tpPESession);
+void lim_update_re_assoc_globals(tpAniSirGlobal pMac,
+ tpSirAssocRsp pAssocRsp,
+ tpPESession psessionEntry);
+
+void lim_update_assoc_sta_datas(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpSirAssocRsp pAssocRsp,
+ tpPESession psessionEntry);
+void lim_fill_supported_rates_info(tpAniSirGlobal pMac, tpDphHashNode pSta,
+ tpSirSupportedRates pRates,
+ tpPESession psessionEntry);
+
+tSirRetStatus lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpSchBeaconStruct pBeaconStruct,
+ tpSirBssDescription bssDescription,
+ uint8_t updateEntry, tpPESession psessionEntry);
+tSirRetStatus lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t updateEntry,
+ tpPESession psessionEntry);
+
+void lim_prepare_and_send_del_sta_cnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tSirResultCodes statusCode, tpPESession);
+tSirRetStatus lim_extract_ap_capabilities(tpAniSirGlobal pMac, uint8_t *pIE,
+ uint16_t ieLen,
+ tpSirProbeRespBeacon beaconStruct);
+void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
+ tpLimPreAuthTable pPreAuthTimerTable);
+tpLimPreAuthNode lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
+ tpLimPreAuthTable
+ pPreAuthTimerTable);
+tpLimPreAuthNode lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
+ tpLimPreAuthTable pAuthTable,
+ uint32_t authNodeIdx);
+
+/* Util API to check if the channels supported by STA is within range */
+tSirRetStatus lim_is_dot11h_supported_channels_valid(tpAniSirGlobal pMac,
+ tSirAssocReq *assoc);
+
+/* Util API to check if the txpower supported by STA is within range */
+tSirRetStatus lim_is_dot11h_power_capabilities_in_range(tpAniSirGlobal pMac,
+ tSirAssocReq *assoc,
+ tpPESession);
+
+/* API to re-add the same BSS during re-association */
+void lim_handle_add_bss_in_re_assoc_context(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry);
+
+/* API to fill in RX Highest Supported data Rate */
+void lim_fill_rx_highest_supported_rate(tpAniSirGlobal pMac,
+ uint16_t *rxHighestRate,
+ uint8_t *pSupportedMCSSet);
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,
+ tpPESession psessionEntry);
+#endif
+#ifdef WLAN_FEATURE_11W
+void lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
+ uint8_t *frame, uint32_t frameLen,
+ uint16_t sessionId,
+ tpPESession psessionEntry);
+#endif
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint8_t tid, uint8_t state, uint16_t measInterval);
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+#endif /* __LIM_ASSOC_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_debug.c b/core/mac/src/pe/lim/lim_debug.c
new file mode 100644
index 0000000..51620d7
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_debug.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file lim_debug.c
+
+ \brief implementation for log Debug related APIs
+
+ \author Sunit Bhatia
+
+ ========================================================================*/
+
+#include "lim_debug.h"
+
+void lim_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...)
+{
+#ifdef WLAN_DEBUG
+ /* Verify against current log level */
+ if (loglevel >
+ pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_LIM_MODULE_ID)])
+ return;
+ else {
+ va_list marker;
+
+ va_start(marker, pString); /* Initialize variable arguments. */
+
+ log_debug(pMac, SIR_LIM_MODULE_ID, loglevel, pString, marker);
+
+ va_end(marker); /* Reset variable arguments. */
+ }
+#endif
+}
diff --git a/core/mac/src/pe/lim/lim_debug.h b/core/mac/src/pe/lim/lim_debug.h
new file mode 100644
index 0000000..e0ab7f6
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_debug.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_debug.h contains log function called by LIM module.
+ *
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_DEBUG_H__
+#define __LIM_DEBUG_H__
+
+#include "utils_api.h"
+#include "sir_debug.h"
+
+#if !defined(__printf)
+#define __printf(a, b)
+#endif
+
+void __printf(3, 4) lim_log(tpAniSirGlobal pMac, uint32_t loglevel,
+ const char *pString, ...);
+
+/* define this to show more message in the LIM during TDLS development */
+#define LIM_DEBUG_TDLS
+
+#ifdef LIM_DEBUG_TDLS
+#define LIM_LOG_TDLS(x0) x0
+#else
+#define LIM_LOG_TDLS(x0)
+#endif
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_ft.c b/core/mac/src/pe/lim/lim_ft.c
new file mode 100644
index 0000000..c96327c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ft.c
@@ -0,0 +1,2027 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/**=========================================================================
+
+ \brief implementation for PE 11r VoWiFi FT Protocol
+
+ ========================================================================*/
+
+/* $Header$ */
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include <lim_send_messages.h>
+#include <lim_types.h>
+#include <lim_ft.h>
+#include <lim_ft_defs.h>
+#include <lim_utils.h>
+#include <lim_prop_exts_utils.h>
+#include <lim_assoc_utils.h>
+#include <lim_session.h>
+#include <lim_admit_control.h>
+#include "wmm_apsd.h"
+
+extern void lim_send_set_sta_key_req(tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ uint16_t staIdx,
+ uint8_t defWEPIdx,
+ tpPESession sessionEntry, bool sendRsp);
+
+/*--------------------------------------------------------------------------
+ Initialize the FT variables.
+ ------------------------------------------------------------------------*/
+void lim_ft_open(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ if (psessionEntry)
+ cdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext),
+ 0);
+}
+
+/*--------------------------------------------------------------------------
+ Cleanup FT variables.
+ ------------------------------------------------------------------------*/
+void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tpPESession pReAssocSessionEntry = NULL;
+ uint8_t sessionId = 0;
+
+ if (!psessionEntry) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, "%s: psessionEntry is NULL", __func__);
+ )
+#endif
+ return;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+
+ if (psessionEntry->ftPEContext.pFTPreAuthReq) {
+ pReAssocSessionEntry =
+ pe_find_session_by_bssid(pMac,
+ psessionEntry->ftPEContext.
+ pFTPreAuthReq->preAuthbssId,
+ &sessionId);
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(lim_log(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+ psessionEntry->ftPEContext.pFTPreAuthReq);
+ )
+#endif
+ if (psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription) {
+ cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription);
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription = NULL;
+ }
+ cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq);
+ psessionEntry->ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ if (psessionEntry->ftPEContext.pAddBssReq) {
+ cdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+ psessionEntry->ftPEContext.pAddBssReq = NULL;
+ }
+
+ if (psessionEntry->ftPEContext.pAddStaReq) {
+ cdf_mem_free(psessionEntry->ftPEContext.pAddStaReq);
+ psessionEntry->ftPEContext.pAddStaReq = NULL;
+ }
+
+ /* The session is being deleted, cleanup the contents */
+ cdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
+
+ /* Delete the session created while handling pre-auth response */
+ if (pReAssocSessionEntry) {
+ /* If we have successful pre-auth response, then we would have
+ * created a session on which reassoc request will be sent
+ */
+ if (pReAssocSessionEntry->valid &&
+ pReAssocSessionEntry->limSmeState ==
+ eLIM_SME_WT_REASSOC_STATE) {
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_DEBUG,
+ FL("Deleting Preauth session(%d)"),
+ pReAssocSessionEntry->peSessionId);
+ pe_delete_session(pMac, pReAssocSessionEntry);
+ }
+ }
+}
+
+void lim_ft_cleanup_all_ft_sessions(tpAniSirGlobal pMac)
+{
+ /* Wrapper function to cleanup all FT sessions */
+ int i;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if (true == pMac->lim.gpSession[i].valid) {
+ /* The session is valid, may have FT data */
+ lim_ft_cleanup(pMac, &pMac->lim.gpSession[i]);
+ }
+ }
+}
+
+void lim_ft_cleanup(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ if (NULL == psessionEntry) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL"));)
+#endif
+ return;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+
+ if (NULL != psessionEntry->ftPEContext.pFTPreAuthReq) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(lim_log(pMac, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+ psessionEntry->ftPEContext.pFTPreAuthReq);
+ )
+#endif
+ if (NULL !=
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription) {
+ cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription);
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription = NULL;
+ }
+ cdf_mem_free(psessionEntry->ftPEContext.pFTPreAuthReq);
+ psessionEntry->ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ if (psessionEntry->ftPEContext.pAddBssReq) {
+ cdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+ psessionEntry->ftPEContext.pAddBssReq = NULL;
+ }
+
+ if (psessionEntry->ftPEContext.pAddStaReq) {
+ cdf_mem_free(psessionEntry->ftPEContext.pAddStaReq);
+ psessionEntry->ftPEContext.pAddStaReq = NULL;
+ }
+
+ /* The session is being deleted, cleanup the contents */
+ cdf_mem_set(&psessionEntry->ftPEContext, sizeof(tftPEContext), 0);
+}
+
+/*------------------------------------------------------------------
+ *
+ * This is the handler after suspending the link.
+ * We suspend the link and then now proceed to switch channel.
+ *
+ *------------------------------------------------------------------*/
+void static
+lim_ft_pre_auth_suspend_link_handler(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data)
+{
+ tpPESession psessionEntry = (tpPESession) data;
+
+ /* The link is suspended of not */
+ if (NULL == psessionEntry ||
+ NULL == psessionEntry->ftPEContext.pFTPreAuthReq ||
+ status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("preAuth error, status = %d"), status);
+ )
+ lim_post_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0,
+ psessionEntry);
+ return;
+ }
+
+ /* Suspended, now move to a different channel.
+ * Perform some sanity check before proceeding
+ */
+ if (psessionEntry->ftPEContext.pFTPreAuthReq) {
+ lim_change_channel_with_callback(pMac,
+ psessionEntry->ftPEContext.
+ pFTPreAuthReq->preAuthchannelNum,
+ lim_perform_ft_pre_auth, NULL,
+ psessionEntry);
+ return;
+ }
+}
+
+/*
+ * lim_process_ft_pre_auth_req() - process ft pre auth req
+ *
+ * @mac_ctx: global mac ctx
+ * @msg: pointer to message
+ *
+ * In this function, we process the FT Pre Auth Req:
+ * We receive Pre-Auth, suspend link, register a call back. In the call back,
+ * we will need to accept frames from the new bssid. Send out the auth req to
+ * new AP. Start timer and when the timer is done or if we receive the Auth
+ * response. We change channel. Resume link
+ *
+ * Return: value to indicate if buffer was consumed
+ */
+int lim_process_ft_pre_auth_req(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+ int buf_consumed = false;
+ tpPESession session;
+ uint8_t session_id;
+ tpSirFTPreAuthReq ft_pre_auth_req = (tSirFTPreAuthReq *) msg->bodyptr;
+
+ if (NULL == ft_pre_auth_req) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log(mac_ctx, LOGE, FL("tSirFTPreAuthReq is NULL"));)
+#endif
+ return buf_consumed;
+ }
+
+ /* Get the current session entry */
+ session = pe_find_session_by_bssid(mac_ctx,
+ ft_pre_auth_req->currbssId,
+ &session_id);
+ if (session == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to find session for the bssid"
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(ft_pre_auth_req->currbssId));
+ /* Post the FT Pre Auth Response to SME */
+ lim_post_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0,
+ session);
+ /*
+ * return FALSE, since the Pre-Auth Req will be freed in
+ * limPostFTPreAuthRsp on failure
+ */
+ return buf_consumed;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOGE, FL("session is not in STA mode"));
+#endif
+ buf_consumed = true;
+ return buf_consumed;
+ }
+
+ /* Can set it only after sending auth */
+ session->ftPEContext.ftPreAuthStatus = eSIR_FAILURE;
+ session->ftPEContext.ftPreAuthSession = true;
+
+ /* Indicate that this is the session on which preauth is being done */
+ if (session->ftPEContext.pFTPreAuthReq) {
+ if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ cdf_mem_free(
+ session->ftPEContext.pFTPreAuthReq->pbssDescription);
+ session->ftPEContext.pFTPreAuthReq->pbssDescription =
+ NULL;
+ }
+ cdf_mem_free(session->ftPEContext.pFTPreAuthReq);
+ session->ftPEContext.pFTPreAuthReq = NULL;
+ }
+
+ /* We need information from the Pre-Auth Req. Lets save that */
+ session->ftPEContext.pFTPreAuthReq = ft_pre_auth_req;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("PRE Auth ft_ies_length=%02x%02x%02x"),
+ session->ftPEContext.pFTPreAuthReq->ft_ies[0],
+ session->ftPEContext.pFTPreAuthReq->ft_ies[1],
+ session->ftPEContext.pFTPreAuthReq->ft_ies[2]);
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+ session, 0, 0);
+#endif
+
+ /* Dont need to suspend if APs are in same channel */
+ if (session->currentOperChannel !=
+ session->ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ /* Need to suspend link only if the channels are different */
+ lim_log(mac_ctx, LOG2,
+ FL("Performing pre-auth on diff channel(session %p)"),
+ session);
+ lim_ft_pre_auth_suspend_link_handler(mac_ctx, CDF_STATUS_SUCCESS,
+ (uint32_t *)session);
+ } else {
+ lim_log(mac_ctx, LOG2,
+ FL("Performing pre-auth on same channel (session %p)"),
+ session);
+ /* We are in the same channel. Perform pre-auth */
+ lim_perform_ft_pre_auth(mac_ctx, CDF_STATUS_SUCCESS, NULL,
+ session);
+ }
+
+ return buf_consumed;
+}
+
+/*------------------------------------------------------------------
+ * Send the Auth1
+ * Receive back Auth2
+ *------------------------------------------------------------------*/
+void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry)
+{
+ tSirMacAuthFrameBody authFrame;
+
+ if (NULL == psessionEntry) {
+ PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL"));)
+ return;
+ }
+
+ if (psessionEntry->is11Rconnection &&
+ psessionEntry->ftPEContext.pFTPreAuthReq) {
+ /* Only 11r assoc has FT IEs */
+ if (psessionEntry->ftPEContext.pFTPreAuthReq->ft_ies == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ "%s: FTIEs for Auth Req Seq 1 is absent",
+ __func__);
+ )
+ goto preauth_fail;
+ }
+ }
+
+ if (status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE,
+ "%s: Change channel not successful for FT pre-auth",
+ __func__);
+ )
+ goto preauth_fail;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG2(lim_log(pMac, LOG2, "Entered wait auth2 state for FT"
+ " (old session %p)", psessionEntry);
+ )
+#endif
+ if (psessionEntry->is11Rconnection) {
+ /* Now we are on the right channel and need to send out Auth1 and
+ * receive Auth2
+ */
+ authFrame.authAlgoNumber = eSIR_FT_AUTH;
+ }
+#if defined FEATURE_WLAN_ESE || defined FEATURE_WLAN_LFR
+ else {
+ /* Will need to make isESEconnection a enum may be for further
+ * improvements to this to match this algorithm number
+ */
+ authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM;
+ }
+#endif
+ authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ authFrame.authStatusCode = 0;
+
+ /* Start timer here to come back to operating channel */
+ pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId =
+ psessionEntry->peSessionId;
+ if (TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log(pMac, LOGE, FL("FT Auth Rsp Timer Start Failed"));)
+#endif
+ }
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
+ eLIM_FT_PREAUTH_RSP_TIMER));
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOG1(lim_log(pMac, LOG1, FL("FT Auth Rsp Timer Started"));)
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT,
+ pMac->lim.pSessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ preAuthbssId, LIM_NO_WEP_IN_FC, psessionEntry);
+
+ return;
+
+preauth_fail:
+ lim_handle_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry);
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Create the new Add Bss Req to the new AP.
+ * This will be used when we are ready to FT to the new AP.
+ * The newly created ft Session entry is passed to this function
+ *
+ *------------------------------------------------------------------*/
+tSirRetStatus lim_ft_prepare_add_bss_req(tpAniSirGlobal pMac,
+ uint8_t updateEntry,
+ tpPESession pftSessionEntry,
+ tpSirBssDescription bssDescription)
+{
+ tpAddBssParams pAddBssParams = NULL;
+ tAddStaParams *sta_ctx;
+ uint8_t chanWidthSupp = 0;
+ tSchBeaconStruct *pBeaconStruct;
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(pftSessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return eSIR_FAILURE;
+ }
+
+ pBeaconStruct = cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == pBeaconStruct) {
+ lim_log(pMac, LOGE,
+ FL("Unable to allocate memory for creating ADD_BSS"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ /* Package SIR_HAL_ADD_BSS_REQ message parameters */
+ pAddBssParams = cdf_mem_malloc(sizeof(tAddBssParams));
+ if (NULL == pAddBssParams) {
+ cdf_mem_free(pBeaconStruct);
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory for creating ADD_BSS"));
+ return (eSIR_MEM_ALLOC_FAILED);
+ }
+
+ cdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams), 0);
+
+ lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields,
+ lim_get_ielen_from_bss_description(bssDescription),
+ pBeaconStruct);
+
+ if (pMac->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct,
+ pftSessionEntry);
+
+ cdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
+ sizeof(tSirMacAddr));
+
+ /* Fill in tAddBssParams selfMacAddr */
+ cdf_mem_copy(pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ pAddBssParams->bssType = pftSessionEntry->bssType;
+ pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
+
+ pAddBssParams->beaconInterval = bssDescription->beaconInterval;
+
+ pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
+ pAddBssParams->updateBss = updateEntry;
+
+ pAddBssParams->reassocReq = true;
+
+ pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
+ pAddBssParams->cfParamSet.cfpPeriod =
+ pBeaconStruct->cfParamSet.cfpPeriod;
+ pAddBssParams->cfParamSet.cfpMaxDuration =
+ pBeaconStruct->cfParamSet.cfpMaxDuration;
+ pAddBssParams->cfParamSet.cfpDurRemaining =
+ pBeaconStruct->cfParamSet.cfpDurRemaining;
+
+ pAddBssParams->rateSet.numRates =
+ pBeaconStruct->supportedRates.numRates;
+ cdf_mem_copy(pAddBssParams->rateSet.rate,
+ pBeaconStruct->supportedRates.rate,
+ pBeaconStruct->supportedRates.numRates);
+
+ pAddBssParams->nwType = bssDescription->nwType;
+
+ pAddBssParams->shortSlotTimeSupported =
+ (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
+ pAddBssParams->llaCoexist =
+ (uint8_t) pftSessionEntry->beaconParams.llaCoexist;
+ pAddBssParams->llbCoexist =
+ (uint8_t) pftSessionEntry->beaconParams.llbCoexist;
+ pAddBssParams->llgCoexist =
+ (uint8_t) pftSessionEntry->beaconParams.llgCoexist;
+ pAddBssParams->ht20Coexist =
+ (uint8_t) pftSessionEntry->beaconParams.ht20Coexist;
+#ifdef WLAN_FEATURE_11W
+ pAddBssParams->rmfEnabled = pftSessionEntry->limRmfEnabled;
+#endif
+
+ /* Use the advertised capabilities from the received beacon/PR */
+ if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) &&
+ (pBeaconStruct->HTCaps.present)) {
+ pAddBssParams->htCapable = pBeaconStruct->HTCaps.present;
+ cdf_mem_copy(&pAddBssParams->staContext.capab_info,
+ &pBeaconStruct->capabilityInfo,
+ sizeof(pAddBssParams->staContext.capab_info));
+ cdf_mem_copy(&pAddBssParams->staContext.ht_caps,
+ (uint8_t *) &pBeaconStruct->HTCaps +
+ sizeof(uint8_t),
+ sizeof(pAddBssParams->staContext.ht_caps));
+
+ if (pBeaconStruct->HTInfo.present) {
+ pAddBssParams->htOperMode =
+ (tSirMacHTOperatingMode) pBeaconStruct->HTInfo.
+ opMode;
+ pAddBssParams->dualCTSProtection =
+ (uint8_t) pBeaconStruct->HTInfo.dualCTSProtection;
+
+ chanWidthSupp = lim_get_ht_capability(pMac,
+ eHT_SUPPORTED_CHANNEL_WIDTH_SET,
+ pftSessionEntry);
+ if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp)) {
+ pAddBssParams->ch_width = (uint8_t)
+ pBeaconStruct->HTInfo.recommendedTxWidthSet;
+ if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ pAddBssParams->ch_center_freq_seg0 =
+ bssDescription->channelId + 2;
+ else if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+ pAddBssParams->ch_center_freq_seg0 =
+ bssDescription->channelId - 2;
+ } else {
+ pAddBssParams->ch_width = CH_WIDTH_20MHZ;
+ pAddBssParams->ch_center_freq_seg0 = 0;
+ }
+ pAddBssParams->llnNonGFCoexist =
+ (uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent;
+ pAddBssParams->fLsigTXOPProtectionFullSupport =
+ (uint8_t) pBeaconStruct->HTInfo.
+ lsigTXOPProtectionFullSupport;
+ pAddBssParams->fRIFSMode =
+ pBeaconStruct->HTInfo.rifsMode;
+ }
+ }
+
+ pAddBssParams->currentOperChannel = bssDescription->channelId;
+ pftSessionEntry->htSecondaryChannelOffset =
+ pBeaconStruct->HTInfo.secondaryChannelOffset;
+ sta_ctx = &pAddBssParams->staContext;
+
+#ifdef WLAN_FEATURE_11AC
+ if (pftSessionEntry->vhtCapability &&
+ pftSessionEntry->vhtCapabilityPresentInBeacon) {
+ pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present;
+ if (pBeaconStruct->VHTOperation.chanWidth && chanWidthSupp) {
+ pAddBssParams->ch_width =
+ pBeaconStruct->VHTOperation.chanWidth + 1;
+ pAddBssParams->ch_center_freq_seg0 =
+ pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
+ pAddBssParams->ch_center_freq_seg1 =
+ pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
+ }
+ pAddBssParams->staContext.vht_caps =
+ ((pBeaconStruct->VHTCaps.maxMPDULen <<
+ SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
+ (pBeaconStruct->VHTCaps.supportedChannelWidthSet <<
+ SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
+ (pBeaconStruct->VHTCaps.ldpcCodingCap <<
+ SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
+ (pBeaconStruct->VHTCaps.shortGI80MHz <<
+ SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
+ (pBeaconStruct->VHTCaps.shortGI160and80plus80MHz <<
+ SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
+ (pBeaconStruct->VHTCaps.txSTBC <<
+ SIR_MAC_VHT_CAP_TXSTBC) |
+ (pBeaconStruct->VHTCaps.rxSTBC <<
+ SIR_MAC_VHT_CAP_RXSTBC) |
+ (pBeaconStruct->VHTCaps.suBeamFormerCap <<
+ SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
+ (pBeaconStruct->VHTCaps.suBeamformeeCap <<
+ SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
+ (pBeaconStruct->VHTCaps.csnofBeamformerAntSup <<
+ SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
+ (pBeaconStruct->VHTCaps.numSoundingDim <<
+ SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
+ (pBeaconStruct->VHTCaps.muBeamformerCap <<
+ SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
+ (pBeaconStruct->VHTCaps.muBeamformeeCap <<
+ SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
+ (pBeaconStruct->VHTCaps.vhtTXOPPS <<
+ SIR_MAC_VHT_CAP_TXOPPS) |
+ (pBeaconStruct->VHTCaps.htcVHTCap <<
+ SIR_MAC_VHT_CAP_HTC_CAP) |
+ (pBeaconStruct->VHTCaps.maxAMPDULenExp <<
+ SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
+ (pBeaconStruct->VHTCaps.vhtLinkAdaptCap <<
+ SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
+ (pBeaconStruct->VHTCaps.rxAntPattern <<
+ SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
+ (pBeaconStruct->VHTCaps.txAntPattern <<
+ SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
+ (pBeaconStruct->VHTCaps.reserved1 <<
+ SIR_MAC_VHT_CAP_RESERVED2));
+ } else {
+ pAddBssParams->vhtCapable = 0;
+ }
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1, FL("SIR_HAL_ADD_BSS_REQ with channel = %d..."),
+ pAddBssParams->currentOperChannel);
+#endif
+
+ /* Populate the STA-related parameters here */
+ /* Note that the STA here refers to the AP */
+ {
+ pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
+
+ cdf_mem_copy(pAddBssParams->staContext.bssId,
+ bssDescription->bssId, sizeof(tSirMacAddr));
+ pAddBssParams->staContext.listenInterval =
+ bssDescription->beaconInterval;
+
+ pAddBssParams->staContext.assocId = 0;
+ pAddBssParams->staContext.uAPSD = 0;
+ pAddBssParams->staContext.maxSPLen = 0;
+ pAddBssParams->staContext.shortPreambleSupported =
+ (uint8_t) pBeaconStruct->capabilityInfo.shortPreamble;
+ pAddBssParams->staContext.updateSta = updateEntry;
+ pAddBssParams->staContext.encryptType =
+ pftSessionEntry->encryptType;
+#ifdef WLAN_FEATURE_11W
+ pAddBssParams->staContext.rmfEnabled =
+ pftSessionEntry->limRmfEnabled;
+#endif
+
+ if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) &&
+ (pBeaconStruct->HTCaps.present)) {
+ pAddBssParams->staContext.us32MaxAmpduDuration = 0;
+ pAddBssParams->staContext.htCapable = 1;
+ pAddBssParams->staContext.greenFieldCapable =
+ (uint8_t) pBeaconStruct->HTCaps.greenField;
+ pAddBssParams->staContext.lsigTxopProtection =
+ (uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection;
+ if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp)) {
+ pAddBssParams->staContext.ch_width = (uint8_t)
+ pBeaconStruct->HTInfo.recommendedTxWidthSet;
+ } else {
+ pAddBssParams->staContext.ch_width =
+ CH_WIDTH_20MHZ;
+ }
+ if (pftSessionEntry->vhtCapability &&
+ IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) {
+ pAddBssParams->staContext.vhtCapable = 1;
+ if ((pBeaconStruct->VHTCaps.suBeamFormerCap ||
+ pBeaconStruct->VHTCaps.muBeamformerCap) &&
+ pftSessionEntry->txBFIniFeatureEnabled)
+ sta_ctx->vhtTxBFCapable
+ = 1;
+ if (pBeaconStruct->VHTCaps.suBeamformeeCap &&
+ pftSessionEntry->enable_su_tx_bformer)
+ sta_ctx->enable_su_tx_bformer = 1;
+ }
+ if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
+ (chanWidthSupp)) {
+ sta_ctx->ch_width = (uint8_t)
+ pBeaconStruct->HTInfo.recommendedTxWidthSet;
+ if (pAddBssParams->staContext.vhtCapable &&
+ pBeaconStruct->VHTOperation.chanWidth)
+ sta_ctx->ch_width =
+ pBeaconStruct->VHTOperation.chanWidth
+ + 1;
+ } else {
+ pAddBssParams->staContext.ch_width =
+ CH_WIDTH_20MHZ;
+ }
+ pAddBssParams->staContext.mimoPS =
+ (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
+ mimoPowerSave;
+ pAddBssParams->staContext.maxAmsduSize =
+ (uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize;
+ pAddBssParams->staContext.maxAmpduDensity =
+ pBeaconStruct->HTCaps.mpduDensity;
+ pAddBssParams->staContext.fDsssCckMode40Mhz =
+ (uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz;
+ pAddBssParams->staContext.fShortGI20Mhz =
+ (uint8_t) pBeaconStruct->HTCaps.shortGI20MHz;
+ pAddBssParams->staContext.fShortGI40Mhz =
+ (uint8_t) pBeaconStruct->HTCaps.shortGI40MHz;
+ pAddBssParams->staContext.maxAmpduSize =
+ pBeaconStruct->HTCaps.maxRxAMPDUFactor;
+
+ if (pBeaconStruct->HTInfo.present)
+ pAddBssParams->staContext.rifsMode =
+ pBeaconStruct->HTInfo.rifsMode;
+ }
+
+ if ((pftSessionEntry->limWmeEnabled
+ && pBeaconStruct->wmeEdcaPresent)
+ || (pftSessionEntry->limQosEnabled
+ && pBeaconStruct->edcaPresent))
+ pAddBssParams->staContext.wmmEnabled = 1;
+ else
+ pAddBssParams->staContext.wmmEnabled = 0;
+
+ pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
+ /* For OSEN Connection AP does not advertise RSN or WPA IE
+ * so from the IEs we get from supplicant we get this info
+ * so for FW to transmit EAPOL message 4 we shall set
+ * wpa_rsn
+ */
+ pAddBssParams->staContext.wpa_rsn |=
+ (pBeaconStruct->wpaPresent << 1);
+ if ((!pAddBssParams->staContext.wpa_rsn)
+ && (pftSessionEntry->isOSENConnection))
+ pAddBssParams->staContext.wpa_rsn = 1;
+ /* Update the rates */
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_peer_rate_set(pMac,
+ &pAddBssParams->staContext.
+ supportedRates,
+ pBeaconStruct->HTCaps.supportedMCSSet,
+ false, pftSessionEntry,
+ &pBeaconStruct->VHTCaps);
+#else
+ lim_populate_peer_rate_set(pMac,
+ &pAddBssParams->staContext.
+ supportedRates,
+ beaconStruct.HTCaps.supportedMCSSet,
+ false, pftSessionEntry);
+#endif
+ if (pftSessionEntry->htCapability) {
+ pAddBssParams->staContext.supportedRates.opRateMode =
+ eSTA_11n;
+ if (pftSessionEntry->vhtCapability)
+ pAddBssParams->staContext.supportedRates.
+ opRateMode = eSTA_11ac;
+ } else {
+ if (pftSessionEntry->limRFBand == SIR_BAND_5_GHZ) {
+ pAddBssParams->staContext.supportedRates.
+ opRateMode = eSTA_11a;
+ } else {
+ pAddBssParams->staContext.supportedRates.
+ opRateMode = eSTA_11bg;
+ }
+ }
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower;
+#endif
+
+#ifdef WLAN_FEATURE_11W
+ if (pftSessionEntry->limRmfEnabled) {
+ pAddBssParams->rmfEnabled = 1;
+ pAddBssParams->staContext.rmfEnabled = 1;
+ }
+#endif
+
+ pAddBssParams->status = CDF_STATUS_SUCCESS;
+ pAddBssParams->respReqd = true;
+
+ pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId;
+ pAddBssParams->staContext.smesessionId = pftSessionEntry->smeSessionId;
+ pAddBssParams->sessionId = pftSessionEntry->peSessionId;
+
+ /* Set a new state for MLME */
+
+ pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, pftSessionEntry->peSessionId,
+ eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE));
+ pAddBssParams->halPersona = (uint8_t) pftSessionEntry->pePersona;
+
+ pftSessionEntry->ftPEContext.pAddBssReq = pAddBssParams;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1, FL("Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap..."));
+#endif
+
+ cdf_mem_free(pBeaconStruct);
+ return 0;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Setup the new session for the pre-auth AP.
+ * Return the newly created session entry.
+ *
+ *------------------------------------------------------------------*/
+void lim_fill_ft_session(tpAniSirGlobal pMac,
+ tpSirBssDescription pbssDescription,
+ tpPESession pftSessionEntry, tpPESession psessionEntry)
+{
+ uint8_t currentBssUapsd;
+ tPowerdBm localPowerConstraint;
+ tPowerdBm regMax;
+ tSchBeaconStruct *pBeaconStruct;
+ uint32_t selfDot11Mode;
+ ePhyChanBondState cbEnabledMode;
+
+ pBeaconStruct = cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == pBeaconStruct) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to allocate memory for creating lim_fill_ft_session"));
+#endif
+ return;
+ }
+
+ /* Retrieve the session that has already been created and update the entry */
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ lim_print_mac_addr(pMac, pbssDescription->bssId, LOG1);
+#endif
+ pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled;
+ pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled;
+ pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled;
+ pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable;
+ pftSessionEntry->isOSENConnection = psessionEntry->isOSENConnection;
+
+ /* Fields to be filled later */
+ pftSessionEntry->pLimJoinReq = NULL;
+ pftSessionEntry->smeSessionId = psessionEntry->smeSessionId;
+ pftSessionEntry->transactionId = 0;
+
+ lim_extract_ap_capabilities(pMac, (uint8_t *) pbssDescription->ieFields,
+ lim_get_ielen_from_bss_description(pbssDescription),
+ pBeaconStruct);
+
+ pftSessionEntry->rateSet.numRates =
+ pBeaconStruct->supportedRates.numRates;
+ cdf_mem_copy(pftSessionEntry->rateSet.rate,
+ pBeaconStruct->supportedRates.rate,
+ pBeaconStruct->supportedRates.numRates);
+
+ pftSessionEntry->extRateSet.numRates =
+ pBeaconStruct->extendedRates.numRates;
+ cdf_mem_copy(pftSessionEntry->extRateSet.rate,
+ pBeaconStruct->extendedRates.rate,
+ pftSessionEntry->extRateSet.numRates);
+
+ pftSessionEntry->ssId.length = pBeaconStruct->ssId.length;
+ cdf_mem_copy(pftSessionEntry->ssId.ssId, pBeaconStruct->ssId.ssId,
+ pftSessionEntry->ssId.length);
+
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+ lim_log(pMac, LOG1, FL("selfDot11Mode %d"), selfDot11Mode);
+ pftSessionEntry->dot11mode = selfDot11Mode;
+ pftSessionEntry->vhtCapability =
+ (IS_DOT11_MODE_VHT(pftSessionEntry->dot11mode)
+ && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps));
+ pftSessionEntry->htCapability =
+ (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode)
+ && pBeaconStruct->HTCaps.present);
+
+ /* Copy The channel Id to the session Table */
+ pftSessionEntry->limReassocChannelId = pbssDescription->channelId;
+ pftSessionEntry->currentOperChannel = pbssDescription->channelId;
+
+ pftSessionEntry->limRFBand = lim_get_rf_band(
+ pftSessionEntry->currentOperChannel);
+
+ if (pftSessionEntry->limRFBand == SIR_BAND_2_4_GHZ) {
+ cbEnabledMode = pMac->roam.configParam.channelBondingMode24GHz;
+ } else {
+ cbEnabledMode = pMac->roam.configParam.channelBondingMode5GHz;
+ }
+ pftSessionEntry->htSupportedChannelWidthSet =
+ (pBeaconStruct->HTInfo.present) ?
+ (cbEnabledMode && pBeaconStruct->HTInfo.recommendedTxWidthSet) : 0;
+ pftSessionEntry->htRecommendedTxWidthSet =
+ pftSessionEntry->htSupportedChannelWidthSet;
+
+
+#ifdef WLAN_FEATURE_11AC
+ if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) &&
+ pBeaconStruct->VHTOperation.present &&
+ pftSessionEntry->vhtCapability) {
+ pftSessionEntry->vhtCapabilityPresentInBeacon = 1;
+ } else {
+ pftSessionEntry->vhtCapabilityPresentInBeacon = 0;
+ }
+#endif
+ if (pftSessionEntry->htRecommendedTxWidthSet) {
+ pftSessionEntry->ch_width = CH_WIDTH_40MHZ;
+ if (pftSessionEntry->vhtCapabilityPresentInBeacon &&
+ pBeaconStruct->VHTOperation.chanWidth) {
+ pftSessionEntry->ch_width =
+ pBeaconStruct->VHTOperation.chanWidth + 1;
+ pftSessionEntry->ch_center_freq_seg0 =
+ pBeaconStruct->VHTOperation.chanCenterFreqSeg1;
+ pftSessionEntry->ch_center_freq_seg1 =
+ pBeaconStruct->VHTOperation.chanCenterFreqSeg2;
+ } else {
+ if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ pftSessionEntry->ch_center_freq_seg0 =
+ pbssDescription->channelId + 2;
+ else if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
+ pftSessionEntry->ch_center_freq_seg0 =
+ pbssDescription->channelId - 2;
+ else
+ lim_log(pMac, LOGE, FL("Invalid sec ch offset"));
+ }
+ } else {
+ pftSessionEntry->ch_width = CH_WIDTH_20MHZ;
+ pftSessionEntry->ch_center_freq_seg0 = 0;
+ pftSessionEntry->ch_center_freq_seg1 = 0;
+ }
+
+ sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
+ psessionEntry->selfMacAddr);
+ sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
+ pbssDescription->bssId);
+ sir_copy_mac_addr(pftSessionEntry->prev_ap_bssid, psessionEntry->bssId);
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ lim_print_mac_addr(pMac, pftSessionEntry->limReAssocbssId, LOG1);
+#endif
+
+ /* Store beaconInterval */
+ pftSessionEntry->beaconParams.beaconInterval =
+ pbssDescription->beaconInterval;
+ pftSessionEntry->bssType = psessionEntry->bssType;
+
+ pftSessionEntry->statypeForBss = STA_ENTRY_PEER;
+ pftSessionEntry->nwType = pbssDescription->nwType;
+
+
+ if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) {
+ pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
+ } else if (pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
+ pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ } else {
+ /* Throw an error and return and make sure to delete the session. */
+ lim_log(pMac, LOGE, FL("Invalid bss type"));
+ }
+
+ pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo;
+ pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo;
+ if (pMac->roam.configParam.shortSlotTime &&
+ SIR_MAC_GET_SHORT_SLOT_TIME(pftSessionEntry->limReassocBssCaps)) {
+ pftSessionEntry->shortSlotTimeSupported = true;
+ }
+
+ regMax = cfg_get_regulatory_max_transmit_power(pMac,
+ pftSessionEntry->
+ currentOperChannel);
+ localPowerConstraint = regMax;
+ lim_extract_ap_capability(pMac, (uint8_t *) pbssDescription->ieFields,
+ lim_get_ielen_from_bss_description(pbssDescription),
+ &pftSessionEntry->limCurrentBssQosCaps,
+ &pftSessionEntry->limCurrentBssPropCap, ¤tBssUapsd,
+ &localPowerConstraint, pftSessionEntry);
+
+ pftSessionEntry->limReassocBssQosCaps =
+ pftSessionEntry->limCurrentBssQosCaps;
+ pftSessionEntry->limReassocBssPropCap =
+ pftSessionEntry->limCurrentBssPropCap;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ pftSessionEntry->isESEconnection = psessionEntry->isESEconnection;
+ pftSessionEntry->is_ese_version_ie_present =
+ pBeaconStruct->is_ese_ver_ie_present;
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ pftSessionEntry->isFastTransitionEnabled =
+ psessionEntry->isFastTransitionEnabled;
+#endif
+
+#ifdef FEATURE_WLAN_LFR
+ pftSessionEntry->isFastRoamIniFeatureEnabled =
+ psessionEntry->isFastRoamIniFeatureEnabled;
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ pftSessionEntry->maxTxPower =
+ lim_get_max_tx_power(regMax, localPowerConstraint,
+ pMac->roam.configParam.nTxPowerCap);
+#else
+ pftSessionEntry->maxTxPower = CDF_MIN(regMax, (localPowerConstraint));
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1,
+ FL
+ ("Reg max = %d, local power = %d, ini tx power = %d, max tx = %d"),
+ regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap,
+ pftSessionEntry->maxTxPower);
+#endif
+
+ pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+ pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, pftSessionEntry->peSessionId,
+ pftSessionEntry->limSmeState));
+
+ pftSessionEntry->encryptType = psessionEntry->encryptType;
+#ifdef WLAN_FEATURE_11W
+ pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled;
+#endif
+
+ cdf_mem_free(pBeaconStruct);
+}
+
+/*------------------------------------------------------------------
+ *
+ * Setup the session and the add bss req for the pre-auth AP.
+ *
+ *------------------------------------------------------------------*/
+tSirRetStatus lim_ft_setup_auth_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ tpPESession pftSessionEntry = NULL;
+ uint8_t sessionId = 0;
+
+ pftSessionEntry =
+ pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId,
+ &sessionId);
+ if (pftSessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("Unable to find session for the following bssid"));
+ )
+ lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOGE);
+ return eSIR_FAILURE;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return eSIR_FAILURE;
+ }
+
+ if (psessionEntry->ftPEContext.pFTPreAuthReq &&
+ psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ lim_fill_ft_session(pMac,
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription, pftSessionEntry,
+ psessionEntry);
+
+ lim_ft_prepare_add_bss_req(pMac, false, pftSessionEntry,
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ pbssDescription);
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/*------------------------------------------------------------------
+ * Resume Link Call Back
+ *------------------------------------------------------------------*/
+void lim_ft_process_pre_auth_result(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data)
+{
+ tpPESession psessionEntry = (tpPESession) data;
+
+ if (NULL == psessionEntry ||
+ NULL == psessionEntry->ftPEContext.pFTPreAuthReq)
+ return;
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+
+ if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+ psessionEntry->ftPEContext.ftPreAuthStatus =
+ lim_ft_setup_auth_session(pMac, psessionEntry);
+ }
+ /* Post the FT Pre Auth Response to SME */
+ lim_post_ft_pre_auth_rsp(pMac, psessionEntry->ftPEContext.ftPreAuthStatus,
+ psessionEntry->ftPEContext.saved_auth_rsp,
+ psessionEntry->ftPEContext.saved_auth_rsp_length,
+ psessionEntry);
+}
+
+/*------------------------------------------------------------------
+ * Resume Link Call Back
+ *------------------------------------------------------------------*/
+void lim_perform_post_ft_pre_auth_and_channel_change(tpAniSirGlobal pMac,
+ CDF_STATUS status,
+ uint32_t *data,
+ tpPESession psessionEntry)
+{
+ /* Set the resume channel to Any valid channel (invalid)
+ * This will instruct HAL to set it to any previous valid channel.
+ */
+ pe_set_resume_channel(pMac, 0, 0);
+ lim_ft_process_pre_auth_result(pMac, CDF_STATUS_SUCCESS,
+ (uint32_t *) psessionEntry);
+}
+
+/*
+ * lim_post_ft_pre_auth_rsp() - post ft pre auth response to SME.
+ *
+ * @mac_ctx: global mac ctx
+ * @status: status code to post in auth rsp
+ * @auth_rsp: pointer to auth rsp FT ie
+ * @auth_rsp_length: len of the IE field
+ * @session: pe session
+ *
+ * post pre auth response to SME.
+ *
+ * Return: void
+ */
+void lim_post_ft_pre_auth_rsp(tpAniSirGlobal mac_ctx,
+ tSirRetStatus status,
+ uint8_t *auth_rsp,
+ uint16_t auth_rsp_length,
+ tpPESession session)
+{
+ tpSirFTPreAuthRsp ft_pre_auth_rsp;
+ tSirMsgQ mmh_msg;
+ uint16_t rsp_len = sizeof(tSirFTPreAuthRsp);
+
+ ft_pre_auth_rsp = (tpSirFTPreAuthRsp) cdf_mem_malloc(rsp_len);
+ if (NULL == ft_pre_auth_rsp) {
+ lim_log(mac_ctx, LOGE, "Failed to allocate memory");
+ CDF_ASSERT(ft_pre_auth_rsp != NULL);
+ return;
+ }
+ cdf_mem_zero(ft_pre_auth_rsp, rsp_len);
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("Auth Rsp = %p"), ft_pre_auth_rsp);
+#endif
+ if (session) {
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOGE,
+ FL("session is not in STA mode"));
+#endif
+ cdf_mem_free(ft_pre_auth_rsp);
+ return;
+ }
+ ft_pre_auth_rsp->smeSessionId = session->smeSessionId;
+ /* The bssid of the AP we are sending Auth1 to. */
+ if (session->ftPEContext.pFTPreAuthReq)
+ sir_copy_mac_addr(ft_pre_auth_rsp->preAuthbssId,
+ session->ftPEContext.pFTPreAuthReq->preAuthbssId);
+ }
+
+ ft_pre_auth_rsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP;
+ ft_pre_auth_rsp->length = (uint16_t) rsp_len;
+ ft_pre_auth_rsp->status = status;
+
+ /* Attach the auth response now back to SME */
+ ft_pre_auth_rsp->ft_ies_length = 0;
+ if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
+ /* Only 11r assoc has FT IEs */
+ cdf_mem_copy(ft_pre_auth_rsp->ft_ies,
+ auth_rsp, auth_rsp_length);
+ ft_pre_auth_rsp->ft_ies_length = auth_rsp_length;
+ }
+
+ if (status != eSIR_SUCCESS) {
+ /*
+ * Ensure that on Pre-Auth failure the cached Pre-Auth Req and
+ * other allocated memory is freed up before returning.
+ */
+ lim_log(mac_ctx, LOG1, "Pre-Auth Failed, Cleanup!");
+ lim_ft_cleanup(mac_ctx, session);
+ }
+
+ mmh_msg.type = ft_pre_auth_rsp->messageType;
+ mmh_msg.bodyptr = ft_pre_auth_rsp;
+ mmh_msg.bodyval = 0;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("Posted Auth Rsp to SME with status of 0x%x"),
+ status);
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ if (status == eSIR_SUCCESS)
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_PREAUTH_DONE,
+ session, status, 0);
+#endif
+ lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+}
+
+/*------------------------------------------------------------------
+ *
+ * Send the FT Pre Auth Response to SME whenever we have a status
+ * ready to be sent to SME
+ *
+ * SME will be the one to send it up to the supplicant to receive
+ * FTIEs which will be required for Reassoc Req.
+ *
+ *------------------------------------------------------------------*/
+void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac, tSirRetStatus status,
+ uint8_t *auth_rsp, uint16_t auth_rsp_length,
+ tpPESession psessionEntry)
+{
+ tpPESession pftSessionEntry = NULL;
+ uint8_t sessionId = 0;
+ tpSirBssDescription pbssDescription = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT,
+ psessionEntry, (uint16_t) status, 0);
+#endif
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+
+ /* Save the status of pre-auth */
+ psessionEntry->ftPEContext.ftPreAuthStatus = status;
+
+ /* Save the auth rsp, so we can send it to
+ * SME once we resume link
+ */
+ psessionEntry->ftPEContext.saved_auth_rsp_length = 0;
+ if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) {
+ cdf_mem_copy(psessionEntry->ftPEContext.saved_auth_rsp,
+ auth_rsp, auth_rsp_length);
+ psessionEntry->ftPEContext.saved_auth_rsp_length =
+ auth_rsp_length;
+ }
+
+ if (!psessionEntry->ftPEContext.pFTPreAuthReq ||
+ !psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ lim_log(pMac, LOGE,
+ FL("pFTPreAuthReq or pbssDescription is NULL"));
+ return;
+ }
+
+ /* Create FT session for the re-association at this point */
+ if (psessionEntry->ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) {
+ pbssDescription =
+ psessionEntry->ftPEContext.pFTPreAuthReq->pbssDescription;
+ lim_print_mac_addr(pMac, pbssDescription->bssId, LOG1);
+ if ((pftSessionEntry =
+ pe_create_session(pMac, pbssDescription->bssId,
+ &sessionId, pMac->lim.maxStation,
+ psessionEntry->bssType)) == NULL) {
+ lim_log(pMac, LOGE, FL(
+ "Session not created for pre-auth 11R AP"));
+ status = eSIR_FAILURE;
+ psessionEntry->ftPEContext.ftPreAuthStatus = status;
+ goto send_rsp;
+ }
+ pftSessionEntry->peSessionId = sessionId;
+ pftSessionEntry->smeSessionId = psessionEntry->smeSessionId;
+ sir_copy_mac_addr(pftSessionEntry->selfMacAddr,
+ psessionEntry->selfMacAddr);
+ sir_copy_mac_addr(pftSessionEntry->limReAssocbssId,
+ pbssDescription->bssId);
+ pftSessionEntry->bssType = psessionEntry->bssType;
+
+ if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) {
+ pftSessionEntry->limSystemRole = eLIM_STA_ROLE;
+ } else if (pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
+ pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ } else {
+ lim_log(pMac, LOGE, FL("Invalid bss type"));
+ }
+ pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState;
+ cdf_mem_copy(&(pftSessionEntry->htConfig),
+ &(psessionEntry->htConfig),
+ sizeof(psessionEntry->htConfig));
+ pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+ PELOGE(lim_log
+ (pMac, LOG1, "%s:created session (%p) with id = %d",
+ __func__, pftSessionEntry,
+ pftSessionEntry->peSessionId);
+ )
+
+ /* Update the ReAssoc BSSID of the current session */
+ sir_copy_mac_addr(psessionEntry->limReAssocbssId,
+ pbssDescription->bssId);
+ lim_print_mac_addr(pMac, psessionEntry->limReAssocbssId, LOG1);
+ }
+send_rsp:
+ if (psessionEntry->currentOperChannel !=
+ psessionEntry->ftPEContext.pFTPreAuthReq->preAuthchannelNum) {
+ /* Need to move to the original AP channel */
+ lim_change_channel_with_callback(pMac,
+ psessionEntry->currentOperChannel,
+ lim_perform_post_ft_pre_auth_and_channel_change,
+ NULL, psessionEntry);
+ } else {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log(pMac, LOG1,
+ "Pre auth on same channel as connected AP channel %d",
+ psessionEntry->ftPEContext.pFTPreAuthReq->
+ preAuthchannelNum);
+ )
+#endif
+ lim_ft_process_pre_auth_result(pMac, status,
+ (uint32_t *) psessionEntry);
+ }
+}
+
+/*------------------------------------------------------------------
+ *
+ * This function handles the 11R Reassoc Req from SME
+ *
+ *------------------------------------------------------------------*/
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
+ tpPESession psessionEntry)
+{
+ uint8_t smeSessionId = 0;
+ uint16_t transactionId = 0;
+ uint8_t chanNum = 0;
+ tLimMlmReassocReq *pMlmReassocReq;
+ uint16_t caps;
+ uint32_t val;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode;
+ uint32_t teleBcnEn = 0;
+
+ chanNum = psessionEntry->currentOperChannel;
+ lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smeSessionId,
+ &transactionId);
+ psessionEntry->smeSessionId = smeSessionId;
+ psessionEntry->transactionId = transactionId;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOCIATING, psessionEntry, 0,
+ 0);
+#endif
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+
+ if (NULL == psessionEntry->ftPEContext.pAddBssReq) {
+ lim_log(pMac, LOGE, FL("pAddBssReq is NULL"));
+ return;
+ }
+ pMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
+ if (NULL == pMlmReassocReq) {
+ lim_log(pMac, LOGE,
+ FL("call to AllocateMemory failed for mlmReassocReq"));
+ return;
+ }
+
+ cdf_mem_copy(pMlmReassocReq->peerMacAddr,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ (uint32_t *) &pMlmReassocReq->reassocFailureTimeout)
+ != eSIR_SUCCESS) {
+ /**
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve ReassocFailureTimeout value"));
+ cdf_mem_free(pMlmReassocReq);
+ return;
+ }
+
+ if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
+ /**
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE, FL("could not retrieve Capabilities value"));
+ cdf_mem_free(pMlmReassocReq);
+ return;
+ }
+ pMlmReassocReq->capabilityInfo = caps;
+
+ /* Update PE sessionId */
+ pMlmReassocReq->sessionId = psessionEntry->peSessionId;
+
+ /* If telescopic beaconing is enabled, set listen interval
+ to WNI_CFG_TELE_BCN_MAX_LI
+ */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));
+ cdf_mem_free(pMlmReassocReq);
+ return;
+ }
+
+ if (teleBcnEn) {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
+ eSIR_SUCCESS) {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve ListenInterval"));
+ cdf_mem_free(pMlmReassocReq);
+ return;
+ }
+ } else {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &val) !=
+ eSIR_SUCCESS) {
+ /**
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve ListenInterval"));
+ cdf_mem_free(pMlmReassocReq);
+ return;
+ }
+ }
+ if (lim_set_link_state
+ (pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) {
+ cdf_mem_free(pMlmReassocReq);
+ return;
+ }
+
+ pMlmReassocReq->listenInterval = (uint16_t) val;
+ psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
+
+ /* we need to defer the message until we get the response back from HAL */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+
+ msgQ.type = SIR_HAL_ADD_BSS_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = psessionEntry->ftPEContext.pAddBssReq;
+ msgQ.bodyval = 0;
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ..."));
+#endif
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+ lim_log(pMac, LOGE,
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
+ retCode);
+ }
+
+ psessionEntry->ftPEContext.pAddBssReq = NULL;
+ return;
+}
+
+/*
+ * lim_process_ft_preauth_rsp_timeout() - process ft preauth rsp timeout
+ *
+ * @mac_ctx: global mac ctx
+ *
+ * This function is called if preauth response is not received from the AP
+ * within this timeout while FT in progress
+ *
+ * Return: void
+ */
+void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal mac_ctx)
+{
+ tpPESession session;
+
+ /*
+ * We have failed pre auth. We need to resume link and get back on
+ * home channel
+ */
+ lim_log(mac_ctx, LOGE, FL("FT Pre-Auth Time Out!!!!"));
+ session = pe_find_session_by_session_id(mac_ctx,
+ mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(session)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOGE, FL("session is not in STA mode"));
+#endif
+ return;
+ }
+
+ /* Reset the flag to indicate preauth request session */
+ session->ftPEContext.ftPreAuthSession = false;
+
+ if (NULL == session->ftPEContext.pFTPreAuthReq) {
+ lim_log(mac_ctx, LOGE,
+ FL("pFTPreAuthReq is NULL. Auth Rsp might already be posted to SME and ftcleanup done! sessionId:%d"),
+ mac_ctx->lim.limTimers.gLimFTPreAuthRspTimer.sessionId);
+ return;
+ }
+
+ /*
+ * To handle the race condition where we recieve preauth rsp after
+ * timer has expired.
+ */
+ if (true ==
+ session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+ lim_log(mac_ctx, LOGE,
+ FL("Auth rsp already posted to SME (session %p)"),
+ session);
+ return;
+ } else {
+ /*
+ * Here we are sending preauth rsp with failure state
+ * and which is forwarded to SME. Now, if we receive an preauth
+ * resp from AP with success it would create a FT pesession, but
+ * will be dropped in SME leaving behind the pesession. Mark
+ * Preauth rsp processed so that any rsp from AP is dropped in
+ * lim_process_auth_frame_no_session.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("Auth rsp not yet posted to SME (session %p)"),
+ session);
+ session->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = true;
+ }
+
+ /*
+ * Attempted at Pre-Auth and failed. If we are off channel. We need
+ * to get back to home channel
+ */
+ lim_handle_ft_pre_auth_rsp(mac_ctx, eSIR_FAILURE, NULL, 0, session);
+}
+
+/*------------------------------------------------------------------
+ *
+ * This function is called to process the update key request from SME
+ *
+ *------------------------------------------------------------------*/
+bool lim_process_ft_update_key(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tAddBssParams *pAddBssParams;
+ tSirFTUpdateKeyInfo *pKeyInfo;
+ uint32_t val = 0;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+
+ /* Sanity Check */
+ if (pMac == NULL || pMsgBuf == NULL) {
+ return false;
+ }
+
+ pKeyInfo = (tSirFTUpdateKeyInfo *) pMsgBuf;
+
+ psessionEntry = pe_find_session_by_bssid(pMac, pKeyInfo->bssId, &sessionId);
+ if (NULL == psessionEntry) {
+ PELOGE(lim_log(pMac, LOGE,
+ "%s: Unable to find session for the following bssid",
+ __func__);
+ )
+ lim_print_mac_addr(pMac, pKeyInfo->bssId, LOGE);
+ return false;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return false;
+ }
+
+ if (NULL == psessionEntry->ftPEContext.pAddBssReq) {
+ /* AddBss Req is NULL, save the keys to configure them later. */
+ tpLimMlmSetKeysReq pMlmSetKeysReq =
+ &psessionEntry->ftPEContext.PreAuthKeyInfo.
+ extSetStaKeyParam;
+
+ cdf_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq));
+ cdf_mem_copy(pMlmSetKeysReq->peerMacAddr, pKeyInfo->bssId,
+ sizeof(tSirMacAddr));
+ pMlmSetKeysReq->sessionId = psessionEntry->peSessionId;
+ pMlmSetKeysReq->smesessionId = psessionEntry->smeSessionId;
+ pMlmSetKeysReq->edType = pKeyInfo->keyMaterial.edType;
+ pMlmSetKeysReq->numKeys = pKeyInfo->keyMaterial.numKeys;
+ cdf_mem_copy((uint8_t *) &pMlmSetKeysReq->key,
+ (uint8_t *) &pKeyInfo->keyMaterial.key,
+ sizeof(tSirKeys));
+
+ psessionEntry->ftPEContext.PreAuthKeyInfo.
+ extSetStaKeyParamValid = true;
+
+ lim_log(pMac, LOGE, FL("pAddBssReq is NULL"));
+
+ if (psessionEntry->ftPEContext.pAddStaReq == NULL) {
+ lim_log(pMac, LOGE, FL("pAddStaReq is NULL"));
+ lim_send_set_sta_key_req(pMac, pMlmSetKeysReq, 0, 0,
+ psessionEntry, false);
+ psessionEntry->ftPEContext.PreAuthKeyInfo.
+ extSetStaKeyParamValid = false;
+ }
+ } else {
+ pAddBssParams = psessionEntry->ftPEContext.pAddBssReq;
+
+ /* Store the key information in the ADD BSS parameters */
+ pAddBssParams->extSetStaKeyParamValid = 1;
+ pAddBssParams->extSetStaKeyParam.encType =
+ pKeyInfo->keyMaterial.edType;
+ cdf_mem_copy((uint8_t *) &pAddBssParams->extSetStaKeyParam.key,
+ (uint8_t *) &pKeyInfo->keyMaterial.key,
+ sizeof(tSirKeys));
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac, WNI_CFG_SINGLE_TID_RC, &val)) {
+ lim_log(pMac, LOGP,
+ FL("Unable to read WNI_CFG_SINGLE_TID_RC"));
+ }
+
+ pAddBssParams->extSetStaKeyParam.singleTidRc = val;
+ PELOG1(lim_log(pMac, LOG1, FL("Key valid %d"),
+ pAddBssParams->extSetStaKeyParamValid,
+ pAddBssParams->extSetStaKeyParam.key[0].
+ keyLength);
+ )
+
+ pAddBssParams->extSetStaKeyParam.staIdx = 0;
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL("BSSID = " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pKeyInfo->bssId));
+ )
+
+ sir_copy_mac_addr(pAddBssParams->extSetStaKeyParam.peerMacAddr,
+ pKeyInfo->bssId);
+
+ pAddBssParams->extSetStaKeyParam.sendRsp = false;
+
+ if (pAddBssParams->extSetStaKeyParam.key[0].keyLength == 16) {
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("BSS key = %02X-%02X-%02X-%02X-%02X-%02X-%02X- "
+ "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X"),
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[0],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[1],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[2],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[3],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[4],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[5],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[6],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[7],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[8],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[9],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[10],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[11],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[12],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[13],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[14],
+ pAddBssParams->extSetStaKeyParam.key[0].
+ key[15]);
+ )
+ }
+ }
+ return true;
+}
+
+void
+lim_ft_send_aggr_qos_rsp(tpAniSirGlobal pMac, uint8_t rspReqd,
+ tpAggrAddTsParams aggrQosRsp, uint8_t smesessionId)
+{
+ tpSirAggrQosRsp rsp;
+ int i = 0;
+ if (!rspReqd) {
+ return;
+ }
+ rsp = cdf_mem_malloc(sizeof(tSirAggrQosRsp));
+ if (NULL == rsp) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for tSirAggrQosRsp"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+ rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP;
+ rsp->sessionId = smesessionId;
+ rsp->length = sizeof(*rsp);
+ rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx;
+ for (i = 0; i < SIR_QOS_NUM_AC_MAX; i++) {
+ if ((1 << i) & aggrQosRsp->tspecIdx) {
+ rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i];
+ rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i];
+ }
+ }
+ lim_send_sme_aggr_qos_rsp(pMac, rsp, smesessionId);
+ return;
+}
+void lim_process_ft_aggr_qo_s_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpAggrAddTsParams pAggrQosRspMsg = NULL;
+ tAddTsParams addTsParam = { 0 };
+ tpDphHashNode pSta = NULL;
+ uint16_t assocId = 0;
+ tSirMacAddr peerMacAddr;
+ uint8_t rspReqd = 1;
+ tpPESession psessionEntry = NULL;
+ int i = 0;
+ PELOG1(lim_log(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL"));)
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr);
+ if (NULL == pAggrQosRspMsg) {
+ PELOGE(lim_log(pMac, LOGE, FL("NULL pAggrQosRspMsg"));)
+ return;
+ }
+ psessionEntry =
+ pe_find_session_by_session_id(pMac, pAggrQosRspMsg->sessionId);
+ if (NULL == psessionEntry) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("Cant find session entry for %s"), __func__);
+ )
+ if (pAggrQosRspMsg != NULL) {
+ cdf_mem_free(pAggrQosRspMsg);
+ }
+ return;
+ }
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ return;
+ }
+ for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) {
+ if ((((1 << i) & pAggrQosRspMsg->tspecIdx)) &&
+ (pAggrQosRspMsg->status[i] != CDF_STATUS_SUCCESS)) {
+ sir_copy_mac_addr(peerMacAddr, psessionEntry->bssId);
+ addTsParam.staIdx = pAggrQosRspMsg->staIdx;
+ addTsParam.sessionId = pAggrQosRspMsg->sessionId;
+ addTsParam.tspec = pAggrQosRspMsg->tspec[i];
+ addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx;
+ lim_send_delts_req_action_frame(pMac, peerMacAddr, rspReqd,
+ &addTsParam.tspec.tsinfo,
+ &addTsParam.tspec,
+ psessionEntry);
+ pSta =
+ dph_lookup_assoc_id(pMac, addTsParam.staIdx, &assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta != NULL) {
+ lim_admit_control_delete_ts(pMac, assocId,
+ &addTsParam.tspec.
+ tsinfo, NULL,
+ (uint8_t *) &
+ addTsParam.tspecIdx);
+ }
+ }
+ }
+ lim_ft_send_aggr_qos_rsp(pMac, rspReqd, pAggrQosRspMsg,
+ psessionEntry->smeSessionId);
+ if (pAggrQosRspMsg != NULL) {
+ cdf_mem_free(pAggrQosRspMsg);
+ }
+ return;
+}
+tSirRetStatus lim_process_ft_aggr_qos_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirMsgQ msg;
+ tSirAggrQosReq *aggrQosReq = (tSirAggrQosReq *) pMsgBuf;
+ tpAggrAddTsParams pAggrAddTsParam;
+ tpPESession psessionEntry = NULL;
+ tpLimTspecInfo tspecInfo;
+ uint8_t ac;
+ tpDphHashNode pSta;
+ uint16_t aid;
+ uint8_t sessionId;
+ int i;
+
+ pAggrAddTsParam = cdf_mem_malloc(sizeof(tAggrAddTsParams));
+ if (NULL == pAggrAddTsParam) {
+ PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory() failed"));)
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ psessionEntry =
+ pe_find_session_by_bssid(pMac, aggrQosReq->bssId, &sessionId);
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("psession Entry Null for sessionId = %d"),
+ aggrQosReq->sessionId);
+ )
+ cdf_mem_free(pAggrAddTsParam);
+ return eSIR_FAILURE;
+ }
+
+ /* Nothing to be done if the session is not in STA mode */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, FL("psessionEntry is not in STA mode"));
+ )
+#endif
+ cdf_mem_free(pAggrAddTsParam);
+ return eSIR_FAILURE;
+ }
+
+ pSta = dph_lookup_hash_entry(pMac, aggrQosReq->bssId, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("Station context not found - ignoring AddTsRsp"));
+ )
+ cdf_mem_free(pAggrAddTsParam);
+ return eSIR_FAILURE;
+ }
+
+ cdf_mem_set((uint8_t *) pAggrAddTsParam, sizeof(tAggrAddTsParams), 0);
+ pAggrAddTsParam->staIdx = psessionEntry->staId;
+ /* Fill in the sessionId specific to PE */
+ pAggrAddTsParam->sessionId = sessionId;
+ pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx;
+
+ for (i = 0; i < HAL_QOS_NUM_AC_MAX; i++) {
+ if (aggrQosReq->aggrInfo.tspecIdx & (1 << i)) {
+ tSirMacTspecIE *pTspec =
+ &aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
+ /* Since AddTS response was successful, check for the PSB flag
+ * and directional flag inside the TS Info field.
+ * An AC is trigger enabled AC if the PSB subfield is set to 1
+ * in the uplink direction.
+ * An AC is delivery enabled AC if the PSB subfield is set to 1
+ * in the downlink direction.
+ * An AC is trigger and delivery enabled AC if the PSB subfield
+ * is set to 1 in the bi-direction field.
+ */
+ if (pTspec->tsinfo.traffic.psb == 1) {
+ lim_set_tspec_uapsd_mask_per_session(pMac,
+ psessionEntry,
+ &pTspec->
+ tsinfo,
+ SET_UAPSD_MASK);
+ } else {
+ lim_set_tspec_uapsd_mask_per_session(pMac,
+ psessionEntry,
+ &pTspec->
+ tsinfo,
+ CLEAR_UAPSD_MASK);
+ }
+ /*
+ * ADDTS success, so AC is now admitted.
+ * We shall now use the default
+ * EDCA parameters as advertised by AP and
+ * send the updated EDCA params
+ * to HAL.
+ */
+ ac = upToAc(pTspec->tsinfo.traffic.userPrio);
+ if (pTspec->tsinfo.traffic.direction ==
+ SIR_MAC_DIRECTION_UPLINK) {
+ psessionEntry->
+ gAcAdmitMask
+ [SIR_MAC_DIRECTION_UPLINK] |=
+ (1 << ac);
+ } else if (pTspec->tsinfo.traffic.direction ==
+ SIR_MAC_DIRECTION_DNLINK) {
+ psessionEntry->
+ gAcAdmitMask
+ [SIR_MAC_DIRECTION_DNLINK] |=
+ (1 << ac);
+ } else if (pTspec->tsinfo.traffic.direction ==
+ SIR_MAC_DIRECTION_BIDIR) {
+ psessionEntry->
+ gAcAdmitMask
+ [SIR_MAC_DIRECTION_UPLINK] |=
+ (1 << ac);
+ psessionEntry->
+ gAcAdmitMask
+ [SIR_MAC_DIRECTION_DNLINK] |=
+ (1 << ac);
+ }
+ lim_set_active_edca_params(pMac,
+ psessionEntry->gLimEdcaParams,
+ psessionEntry);
+
+ lim_send_edca_params(pMac,
+ psessionEntry->gLimEdcaParamsActive,
+ pSta->bssId);
+
+ if (eSIR_SUCCESS !=
+ lim_tspec_add(pMac, pSta->staAddr, pSta->assocId,
+ pTspec, 0, &tspecInfo)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("Adding entry in lim Tspec Table failed "));
+ )
+ pMac->lim.gLimAddtsSent = false;
+ cdf_mem_free(pAggrAddTsParam);
+ return eSIR_FAILURE;
+ }
+
+ pAggrAddTsParam->tspec[i] =
+ aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec;
+ }
+ }
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (!pMac->roam.configParam.isRoamOffloadEnabled ||
+ (pMac->roam.configParam.isRoamOffloadEnabled &&
+ !psessionEntry->is11Rconnection))
+#endif
+ {
+ msg.type = WMA_AGGR_QOS_REQ;
+ msg.bodyptr = pAggrAddTsParam;
+ msg.bodyval = 0;
+
+ /* We need to defer any incoming messages until we get a
+ * WMA_AGGR_QOS_RSP from HAL.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msg.type));
+
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("wma_post_ctrl_msg() failed"));
+ )
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ cdf_mem_free(pAggrAddTsParam);
+ return eSIR_FAILURE;
+ }
+ }
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ else {
+ /* Implies it is a LFR3.0 based 11r connection
+ * so donot send add ts request to fimware since it
+ * already has the RIC IEs */
+
+ /* Send the Aggr QoS response to SME */
+ lim_ft_send_aggr_qos_rsp(pMac, true, pAggrAddTsParam,
+ psessionEntry->smeSessionId);
+ if (pAggrAddTsParam != NULL) {
+ cdf_mem_free(pAggrAddTsParam);
+ }
+ }
+#endif
+
+ return eSIR_SUCCESS;
+}
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
diff --git a/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c
new file mode 100644
index 0000000..c2c3dba
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.c
@@ -0,0 +1,1833 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "cds_api.h"
+#include "ani_global.h"
+#include "sir_common.h"
+#include "wni_cfg.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h" /* sch_set_fixed_beacon_fields for IBSS coalesce */
+#include "lim_security_utils.h"
+#include "lim_send_messages.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_types.h"
+
+/**
+ * ibss_peer_find
+ *
+ ***FUNCTION:
+ * This function is called while adding a context at
+ * DPH & Polaris for a peer in IBSS.
+ * If peer is found in the list, capabilities from the
+ * returned BSS description are used at DPH node & Polaris.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param macAddr - MAC address of the peer
+ *
+ * @return Pointer to peer node if found, else NULL
+ */
+
+static tLimIbssPeerNode *ibss_peer_find(tpAniSirGlobal pMac,
+ tSirMacAddr macAddr)
+{
+ tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList;
+
+ while (pTempNode != NULL) {
+ if (cdf_mem_compare((uint8_t *) macAddr,
+ (uint8_t *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)))
+ break;
+ pTempNode = pTempNode->next;
+ }
+ return pTempNode;
+} /*** end ibss_peer_find() ***/
+
+/**
+ * ibss_peer_add
+ *
+ ***FUNCTION:
+ * This is called on a STA in IBSS upon receiving Beacon/
+ * Probe Response from a peer.
+ *
+ ***LOGIC:
+ * Node is always added to the front of the list
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pPeerNode - Pointer to peer node to be added to the list.
+ *
+ * @return None
+ */
+
+static tSirRetStatus
+ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode)
+{
+#ifdef ANI_SIR_IBSS_PEER_CACHING
+ uint32_t numIbssPeers = (2 * pMac->lim.maxStation);
+
+ if (pMac->lim.gLimNumIbssPeers >= numIbssPeers) {
+ /**
+ * Reached max number of peers to be maintained.
+ * Delete last entry & add new entry at the beginning.
+ */
+ tLimIbssPeerNode *pTemp, *pPrev;
+ pTemp = pPrev = pMac->lim.gLimIbssPeerList;
+ while (pTemp->next != NULL) {
+ pPrev = pTemp;
+ pTemp = pTemp->next;
+ }
+ if (pTemp->beacon) {
+ cdf_mem_free(pTemp->beacon);
+ }
+
+ cdf_mem_free(pTemp);
+ pPrev->next = NULL;
+ } else
+#endif
+ pMac->lim.gLimNumIbssPeers++;
+
+ pPeerNode->next = pMac->lim.gLimIbssPeerList;
+ pMac->lim.gLimIbssPeerList = pPeerNode;
+
+ return eSIR_SUCCESS;
+
+} /*** end limAddIbssPeerToList() ***/
+
+/**
+ * ibss_peer_collect
+ *
+ ***FUNCTION:
+ * This is called to collect IBSS peer information
+ * from received Beacon/Probe Response frame from it.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pBD - Pointer to received BD
+ * @param pPeer - Pointer to IBSS peer node
+ *
+ * @return None
+ */
+
+static void
+ibss_peer_collect(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeacon,
+ tpSirMacMgmtHdr pHdr,
+ tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
+{
+ cdf_mem_copy(pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr));
+
+ pPeer->capabilityInfo = pBeacon->capabilityInfo;
+ pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent;
+ pPeer->edcaPresent = pBeacon->edcaPresent;
+ pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent;
+ pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent;
+
+ if (pBeacon->IBSSParams.present) {
+ pPeer->atimIePresent = pBeacon->IBSSParams.present;
+ pPeer->peerAtimWindowLength = pBeacon->IBSSParams.atim;
+ }
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+ (pBeacon->HTCaps.present)) {
+ pPeer->htCapable = pBeacon->HTCaps.present;
+ cdf_mem_copy((uint8_t *) pPeer->supportedMCSSet,
+ (uint8_t *) pBeacon->HTCaps.supportedMCSSet,
+ sizeof(pPeer->supportedMCSSet));
+ pPeer->htGreenfield = (uint8_t) pBeacon->HTCaps.greenField;
+ pPeer->htSupportedChannelWidthSet =
+ (uint8_t) pBeacon->HTCaps.supportedChannelWidthSet;
+ pPeer->htMIMOPSState =
+ (tSirMacHTMIMOPowerSaveState) pBeacon->HTCaps.mimoPowerSave;
+ pPeer->htMaxAmsduLength =
+ (uint8_t) pBeacon->HTCaps.maximalAMSDUsize;
+ pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity;
+ pPeer->htDsssCckRate40MHzSupport =
+ (uint8_t) pBeacon->HTCaps.dsssCckMode40MHz;
+ pPeer->htShortGI20Mhz = (uint8_t) pBeacon->HTCaps.shortGI20MHz;
+ pPeer->htShortGI40Mhz = (uint8_t) pBeacon->HTCaps.shortGI40MHz;
+ pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor;
+ pPeer->htSecondaryChannelOffset =
+ pBeacon->HTInfo.secondaryChannelOffset;
+ pPeer->htLdpcCapable = (uint8_t) pBeacon->HTCaps.advCodingCap;
+ }
+
+ /* Collect peer VHT capabilities based on the received beacon from the peer */
+#ifdef WLAN_FEATURE_11AC
+ if (pBeacon->VHTCaps.present) {
+ pPeer->vhtSupportedChannelWidthSet =
+ pBeacon->VHTOperation.chanWidth;
+ pPeer->vhtCapable = pBeacon->VHTCaps.present;
+
+ /* Collect VHT capabilities from beacon */
+ cdf_mem_copy((uint8_t *) &pPeer->VHTCaps,
+ (uint8_t *) &pBeacon->VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+#endif
+ pPeer->erpIePresent = pBeacon->erpPresent;
+
+ cdf_mem_copy((uint8_t *) &pPeer->supportedRates,
+ (uint8_t *) &pBeacon->supportedRates,
+ pBeacon->supportedRates.numRates + 1);
+ if (pPeer->extendedRatesPresent)
+ cdf_mem_copy((uint8_t *) &pPeer->extendedRates,
+ (uint8_t *) &pBeacon->extendedRates,
+ pBeacon->extendedRates.numRates + 1);
+ else
+ pPeer->extendedRates.numRates = 0;
+
+ pPeer->next = NULL;
+} /*** end ibss_peer_collect() ***/
+
+/* handle change in peer qos/wme capabilities */
+static void
+ibss_sta_caps_update(tpAniSirGlobal pMac,
+ tLimIbssPeerNode *pPeerNode, tpPESession psessionEntry)
+{
+ uint16_t peerIdx;
+ tpDphHashNode pStaDs;
+
+ pPeerNode->beaconHBCount++; /* Update beacon count. */
+
+ /* if the peer node exists, update its qos capabilities */
+ pStaDs = dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL)
+ return;
+
+ /* Update HT Capabilities */
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
+ pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable;
+ if (pPeerNode->htCapable) {
+ pStaDs->htGreenfield = pPeerNode->htGreenfield;
+ pStaDs->htSupportedChannelWidthSet =
+ pPeerNode->htSupportedChannelWidthSet;
+ pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState;
+ pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength;
+ pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity;
+ pStaDs->htDsssCckRate40MHzSupport =
+ pPeerNode->htDsssCckRate40MHzSupport;
+ pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz;
+ pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz;
+ pStaDs->htMaxRxAMpduFactor =
+ pPeerNode->htMaxRxAMpduFactor;
+ /* In the future, may need to check for "delayedBA" */
+ /* For now, it is IMMEDIATE BA only on ALL TID's */
+ pStaDs->baPolicyFlag = 0xFF;
+ pStaDs->htLdpcCapable = pPeerNode->htLdpcCapable;
+ }
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) {
+ pStaDs->mlmStaContext.vhtCapability = pPeerNode->vhtCapable;
+ if (pPeerNode->vhtCapable) {
+ pStaDs->vhtSupportedChannelWidthSet =
+ pPeerNode->vhtSupportedChannelWidthSet;
+
+ /* If in 11AC mode and if session requires 11AC mode, consider peer's */
+ /* max AMPDU length factor */
+ pStaDs->htMaxRxAMpduFactor =
+ pPeerNode->VHTCaps.maxAMPDULenExp;
+ pStaDs->vhtLdpcCapable =
+ (uint8_t) pPeerNode->VHTCaps.ldpcCodingCap;
+ }
+ }
+#endif
+ /* peer is 11e capable but is not 11e enabled yet */
+ /* some STA's when joining Airgo IBSS, assert qos capability even when */
+ /* they don't suport qos. however, they do not include the edca parameter */
+ /* set. so let's check for edcaParam in addition to the qos capability */
+ if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled)
+ && pPeerNode->edcaPresent) {
+ pStaDs->qosMode = 1;
+ pStaDs->wmeEnabled = 0;
+ if (!pStaDs->lleEnabled) {
+ pStaDs->lleEnabled = 1;
+ /* dphSetACM(pMac, pStaDs); */
+ }
+ return;
+ }
+ /* peer is not 11e capable now but was 11e enabled earlier */
+ else if (pStaDs->lleEnabled) {
+ pStaDs->qosMode = 0;
+ pStaDs->lleEnabled = 0;
+ }
+ /* peer is wme capable but is not wme enabled yet */
+ if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled) {
+ pStaDs->qosMode = 1;
+ pStaDs->lleEnabled = 0;
+ if (!pStaDs->wmeEnabled) {
+ pStaDs->wmeEnabled = 1;
+ }
+ return;
+ }
+ /* When the peer device supports EDCA parameters, then we were not
+ considering. Added this code when we saw that one of the Peer Device
+ was advertising WMM param where we were not honouring that. CR# 210756
+ */
+ if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) {
+ pStaDs->qosMode = 1;
+ pStaDs->lleEnabled = 0;
+ if (!pStaDs->wmeEnabled) {
+ pStaDs->wmeEnabled = 1;
+ }
+ return;
+ }
+ /* peer is not wme capable now but was wme enabled earlier */
+ else if (pStaDs->wmeEnabled) {
+ pStaDs->qosMode = 0;
+ pStaDs->wmeEnabled = 0;
+ }
+
+}
+
+static void
+ibss_sta_rates_update(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
+{
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_matching_rate_set(pMac, pStaDs, &pPeer->supportedRates,
+ &pPeer->extendedRates,
+ pPeer->supportedMCSSet, psessionEntry,
+ &pPeer->VHTCaps);
+#else
+ /* Populate supported rateset */
+ lim_populate_matching_rate_set(pMac, pStaDs, &pPeer->supportedRates,
+ &pPeer->extendedRates,
+ pPeer->supportedMCSSet, psessionEntry);
+#endif
+
+ pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo;
+} /*** end ibss_sta_info_update() ***/
+
+/**
+ * ibss_sta_info_update
+ *
+ ***FUNCTION:
+ * This is called to program both SW & Polaris context
+ * for peer in IBSS.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to DPH node
+ * @param pPeer - Pointer to IBSS peer node
+ *
+ * @return None
+ */
+
+static void
+ibss_sta_info_update(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
+{
+ pStaDs->staType = STA_ENTRY_PEER;
+ ibss_sta_caps_update(pMac, pPeer, psessionEntry);
+ ibss_sta_rates_update(pMac, pStaDs, pPeer, psessionEntry);
+} /*** end ibss_sta_info_update() ***/
+
+static void ibss_coalesce_free(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.ibssInfo.pHdr != NULL)
+ cdf_mem_free(pMac->lim.ibssInfo.pHdr);
+ if (pMac->lim.ibssInfo.pBeacon != NULL)
+ cdf_mem_free(pMac->lim.ibssInfo.pBeacon);
+
+ pMac->lim.ibssInfo.pHdr = NULL;
+ pMac->lim.ibssInfo.pBeacon = NULL;
+}
+
+/*
+ * save the beacon params for use when adding the bss
+ */
+static void
+ibss_coalesce_save(tpAniSirGlobal pMac,
+ tpSirMacMgmtHdr pHdr, tpSchBeaconStruct pBeacon)
+{
+ /* get rid of any saved info */
+ ibss_coalesce_free(pMac);
+
+ pMac->lim.ibssInfo.pHdr = cdf_mem_malloc(sizeof(*pHdr));
+ if (NULL == pMac->lim.ibssInfo.pHdr) {
+ PELOGE(lim_log(pMac, LOGE, FL("ibbs-save: Failed malloc pHdr"));)
+ return;
+ }
+ pMac->lim.ibssInfo.pBeacon = cdf_mem_malloc(sizeof(*pBeacon));
+ if (NULL == pMac->lim.ibssInfo.pBeacon) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("ibbs-save: Failed malloc pBeacon"));
+ )
+ ibss_coalesce_free(pMac);
+ return;
+ }
+
+ cdf_mem_copy(pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr));
+ cdf_mem_copy(pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon));
+}
+
+/*
+ * tries to add a new entry to dph hash node
+ * if necessary, an existing entry is eliminated
+ */
+static tSirRetStatus
+ibss_dph_entry_add(tpAniSirGlobal pMac,
+ tSirMacAddr peerAddr,
+ tpDphHashNode *ppSta, tpPESession psessionEntry)
+{
+ uint16_t peerIdx;
+ tpDphHashNode pStaDs;
+
+ *ppSta = NULL;
+
+ pStaDs =
+ dph_lookup_hash_entry(pMac, peerAddr, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL) {
+ /* Trying to add context for already existing STA in IBSS */
+ PELOGE(lim_log(pMac, LOGE, FL("STA exists already "));)
+ lim_print_mac_addr(pMac, peerAddr, LOGE);
+ return eSIR_FAILURE;
+ }
+
+ /**
+ * Assign an AID, delete context existing with that
+ * AID and then add an entry to hash table maintained
+ * by DPH module.
+ */
+ peerIdx = lim_assign_peer_idx(pMac, psessionEntry);
+
+ pStaDs =
+ dph_get_hash_entry(pMac, peerIdx, &psessionEntry->dph.dphHashTable);
+ if (pStaDs) {
+ (void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
+ psessionEntry);
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, peerIdx,
+ psessionEntry);
+ }
+
+ pStaDs =
+ dph_add_hash_entry(pMac, peerAddr, peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ /* Could not add hash table entry */
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("could not add hash entry at DPH for peerIdx/aid=%d MACaddr:"),
+ peerIdx);
+ )
+ lim_print_mac_addr(pMac, peerAddr, LOGE);
+ return eSIR_FAILURE;
+ }
+
+ *ppSta = pStaDs;
+ return eSIR_SUCCESS;
+}
+
+/* send a status change notification */
+static void
+ibss_status_chg_notify(tpAniSirGlobal pMac,
+ tSirMacAddr peerAddr,
+ uint16_t staIndex,
+ uint8_t ucastSig,
+ uint8_t bcastSig, uint16_t status, uint8_t sessionId)
+{
+
+ tLimIbssPeerNode *peerNode;
+ uint8_t *beacon = NULL;
+ uint16_t bcnLen = 0;
+
+ peerNode = ibss_peer_find(pMac, peerAddr);
+ if (peerNode != NULL) {
+ if (peerNode->beacon == NULL)
+ peerNode->beaconLen = 0;
+ beacon = peerNode->beacon;
+ bcnLen = peerNode->beaconLen;
+ peerNode->beacon = NULL;
+ peerNode->beaconLen = 0;
+ }
+
+ lim_send_sme_ibss_peer_ind(pMac, peerAddr, staIndex, ucastSig, bcastSig,
+ beacon, bcnLen, status, sessionId);
+
+ if (beacon != NULL) {
+ cdf_mem_free(beacon);
+ }
+}
+
+static void ibss_bss_add(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tLimMlmStartReq mlmStartReq;
+ uint32_t cfg;
+ tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
+ tpSchBeaconStruct pBeacon =
+ (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
+ uint8_t numExtRates = 0;
+
+ if ((pHdr == NULL) || (pBeacon == NULL)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Unable to add BSS (no cached BSS info)"));
+ )
+ return;
+ }
+
+ cdf_mem_copy(psessionEntry->bssId, pHdr->bssId, sizeof(tSirMacAddr));
+
+ sir_copy_mac_addr(pHdr->bssId, psessionEntry->bssId);
+
+ /* Copy beacon interval from sessionTable */
+ cfg = psessionEntry->beaconParams.beaconInterval;
+ if (cfg != pBeacon->beaconInterval)
+ psessionEntry->beaconParams.beaconInterval =
+ pBeacon->beaconInterval;
+
+ /* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to
+ * adapt to peer's capability with respect to short slot time. Changes have been made to lim_apply_configuration()
+ * so that the IBSS doesnt blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt
+ * to peer's short slot using code below.
+ */
+ /* If cfg is already set to current peer's capability then no need to set it again */
+ if (psessionEntry->shortSlotTimeSupported !=
+ pBeacon->capabilityInfo.shortSlotTime) {
+ psessionEntry->shortSlotTimeSupported =
+ pBeacon->capabilityInfo.shortSlotTime;
+ }
+ cdf_mem_copy((uint8_t *) &psessionEntry->pLimStartBssReq->
+ operationalRateSet, (uint8_t *) &pBeacon->supportedRates,
+ pBeacon->supportedRates.numRates);
+
+ /**
+ * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when
+ * there is no extended rate IE present in beacon. This is especially important when
+ * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce.
+ * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to
+ * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile.
+ * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued.
+ * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12.
+ */
+
+ if (pBeacon->extendedRatesPresent)
+ numExtRates = pBeacon->extendedRates.numRates;
+ if (cfg_set_str(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ (uint8_t *) &pBeacon->extendedRates.rate,
+ numExtRates) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not update ExtendedOperRateset at CFG"));
+ return;
+ }
+
+ /*
+ * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities
+ * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities
+ * leaves the IBSS. e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode
+ * even though all the nodes are capable of doing CB.
+ * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop.
+ */
+ cdf_mem_set((void *)&mlmStartReq, sizeof(mlmStartReq), 0);
+
+ cdf_mem_copy(mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr));
+ mlmStartReq.rateSet.numRates =
+ psessionEntry->pLimStartBssReq->operationalRateSet.numRates;
+ cdf_mem_copy(&mlmStartReq.rateSet.rate[0],
+ &psessionEntry->pLimStartBssReq->operationalRateSet.
+ rate[0], mlmStartReq.rateSet.numRates);
+ mlmStartReq.bssType = eSIR_IBSS_MODE;
+ mlmStartReq.beaconPeriod = pBeacon->beaconInterval;
+ mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType; /* psessionEntry->nwType is also OK???? */
+ mlmStartReq.htCapable = psessionEntry->htCapability;
+ mlmStartReq.htOperMode = pMac->lim.gHTOperMode;
+ mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection;
+ mlmStartReq.txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet;
+
+ /* reading the channel num from session Table */
+ mlmStartReq.channelNumber = psessionEntry->currentOperChannel;
+
+ mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode;
+
+ /* Copy the SSID for RxP filtering based on SSID. */
+ cdf_mem_copy((uint8_t *) &mlmStartReq.ssId,
+ (uint8_t *) &psessionEntry->pLimStartBssReq->ssId,
+ psessionEntry->pLimStartBssReq->ssId.length + 1);
+
+ PELOG1(lim_log
+ (pMac, LOG1, FL("invoking ADD_BSS as part of coalescing!"));
+ )
+ if (lim_mlm_add_bss(pMac, &mlmStartReq, psessionEntry) !=
+ eSIR_SME_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("AddBss failure"));)
+ return;
+ }
+ /* Update fields in Beacon */
+ if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("*** Unable to set fixed Beacon fields ***"));
+ )
+ return;
+ }
+
+}
+
+/* delete the current BSS */
+static void ibss_bss_delete(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirRetStatus status;
+ PELOGW(lim_log(pMac, LOGW, FL("Initiating IBSS Delete BSS"));)
+ if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
+ lim_log(pMac, LOGW,
+ FL("Incorrect LIM MLM state for delBss (%d)"),
+ psessionEntry->limMlmState);
+ return;
+ }
+ status = lim_del_bss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
+ if (status != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE, FL("delBss failed for bss %d"),
+ psessionEntry->bssIdx);
+ )
+}
+
+/**
+ * lim_ibss_init
+ *
+ ***FUNCTION:
+ * This function is called while starting an IBSS
+ * to initialize list used to maintain IBSS peers.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_ibss_init(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimIbssCoalescingHappened = 0;
+ pMac->lim.gLimIbssPeerList = NULL;
+ pMac->lim.gLimNumIbssPeers = 0;
+
+ /* ibss info - params for which ibss to join while coalescing */
+ cdf_mem_set(&pMac->lim.ibssInfo, sizeof(tAniSirLimIbss), 0);
+} /*** end lim_ibss_init() ***/
+
+/**
+ * lim_ibss_delete_all_peers
+ *
+ ***FUNCTION:
+ * This function is called to delete all peers.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_ibss_delete_all_peers(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tLimIbssPeerNode *pCurrNode, *pTempNode;
+ tpDphHashNode pStaDs;
+ uint16_t peerIdx;
+
+ pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList;
+
+ while (pCurrNode != NULL) {
+ if (!pMac->lim.gLimNumIbssPeers) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Number of peers in the list is zero and node present"));
+ return;
+ }
+ /* Delete the dph entry for the station
+ * Since it is called to remove all peers, just delete from dph,
+ * no need to do any beacon related params i.e., dont call lim_delete_dph_hash_entry
+ */
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pCurrNode->peerMacAddr, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs) {
+
+ ibss_status_chg_notify(pMac, pCurrNode->peerMacAddr,
+ pStaDs->staIndex,
+ pStaDs->ucUcastSig,
+ pStaDs->ucBcastSig,
+ eWNI_SME_IBSS_PEER_DEPARTED_IND,
+ psessionEntry->smeSessionId);
+ lim_release_peer_idx(pMac, peerIdx, psessionEntry);
+ dph_delete_hash_entry(pMac, pStaDs->staAddr, peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ }
+
+ pTempNode = pCurrNode->next;
+
+ /* TODO :Sessionize this code */
+ /* Fix CR 227642: PeerList should point to the next node since the current node is being
+ * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this
+ * peer list to find the next peer. So this list needs to be updated with the no of peers left
+ * after each iteration in this while loop since one by one peers are deleted (freed) in this
+ * loop causing the lim.gLimIbssPeerList to point to some freed memory.
+ */
+ pMac->lim.gLimIbssPeerList = pTempNode;
+
+ if (pCurrNode->beacon) {
+ cdf_mem_free(pCurrNode->beacon);
+ }
+ cdf_mem_free(pCurrNode);
+ if (pMac->lim.gLimNumIbssPeers > 0) /* be paranoid */
+ pMac->lim.gLimNumIbssPeers--;
+ pCurrNode = pTempNode;
+ }
+
+ if (pMac->lim.gLimNumIbssPeers)
+ lim_log(pMac, LOGP,
+ FL("Number of peers[%d] in the list is non-zero"),
+ pMac->lim.gLimNumIbssPeers);
+
+ pMac->lim.gLimNumIbssPeers = 0;
+ pMac->lim.gLimIbssPeerList = NULL;
+
+}
+
+/**
+ * lim_ibss_delete() - This function is called while tearing down an IBSS
+ *
+ * @pMac: Pointer to Global MAC structure
+ * @psessionEntry: Pointer to session entry
+ *
+ * Return: none
+ */
+
+void lim_ibss_delete(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ lim_ibss_delete_all_peers(pMac, psessionEntry);
+ ibss_coalesce_free(pMac);
+}
+
+/** -------------------------------------------------------------
+ \fn lim_ibss_set_protection
+ \brief Decides all the protection related information.
+ \
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr peerMacAddr
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+static void
+lim_ibss_set_protection(tpAniSirGlobal pMac, uint8_t enable,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+
+ if (!pMac->lim.cfgProtection.fromllb) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("protection from 11b is disabled"));
+ )
+ return;
+ }
+
+ if (enable) {
+ psessionEntry->gLim11bParams.protectionEnabled = true;
+ if (false ==
+ psessionEntry->beaconParams.
+ llbCoexist /*pMac->lim.llbCoexist */) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("=> IBSS: Enable Protection "));
+ )
+ pBeaconParams->llbCoexist =
+ psessionEntry->beaconParams.llbCoexist = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_llBCOEXIST_CHANGED;
+ }
+ } else if (true ==
+ psessionEntry->beaconParams.
+ llbCoexist /*pMac->lim.llbCoexist */) {
+ psessionEntry->gLim11bParams.protectionEnabled = false;
+ PELOGE(lim_log(pMac, LOGE, FL("===> IBSS: Disable protection "));)
+ pBeaconParams->llbCoexist =
+ psessionEntry->beaconParams.llbCoexist = false;
+ pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
+ }
+ return;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_ibss_update_protection_params
+ \brief Decides all the protection related information.
+ \
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr peerMacAddr
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+static void
+lim_ibss_update_protection_params(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tLimProtStaCacheType protStaCacheType,
+ tpPESession psessionEntry)
+{
+ uint32_t i;
+
+ PELOG1(lim_log(pMac, LOG1, FL("A STA is associated:"));
+ lim_log(pMac, LOG1, FL("Addr : "));
+ lim_print_mac_addr(pMac, peerMacAddr, LOG1);
+ )
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (pMac->lim.protStaCache[i].active) {
+ PELOG1(lim_log(pMac, LOG1, FL("Addr: "));)
+ PELOG1(lim_print_mac_addr
+ (pMac, pMac->lim.protStaCache[i].addr, LOG1);
+ )
+
+ if (cdf_mem_compare(pMac->lim.protStaCache[i].addr,
+ peerMacAddr,
+ sizeof(tSirMacAddr))) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("matching cache entry at %d already active."),
+ i);
+ )
+ return;
+ }
+ }
+ }
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (!pMac->lim.protStaCache[i].active)
+ break;
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE) {
+ PELOGE(lim_log(pMac, LOGE, FL("No space in ProtStaCache"));)
+ return;
+ }
+
+ cdf_mem_copy(pMac->lim.protStaCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr));
+
+ pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType;
+ pMac->lim.protStaCache[i].active = true;
+ if (eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) {
+ psessionEntry->gLim11bParams.numSta++;
+ } else if (eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) {
+ psessionEntry->gLim11gParams.numSta++;
+ }
+}
+
+/** -------------------------------------------------------------
+ \fn lim_ibss_decide_protection
+ \brief Decides all the protection related information.
+ \
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr peerMacAddr
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+static void
+lim_ibss_decide_protection(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ uint32_t phyMode;
+ tLimProtStaCacheType protStaCacheType =
+ eLIM_PROT_STA_CACHE_TYPE_INVALID;
+
+ pBeaconParams->paramChangeBitmap = 0;
+
+ if (NULL == pStaDs) {
+ PELOGE(lim_log(pMac, LOGE, FL("pStaDs is NULL"));)
+ return;
+ }
+
+ lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+ if (SIR_BAND_2_4_GHZ == rfBand) {
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ /* We are 11G or 11n. Check if we need protection from 11b Stations. */
+ if ((phyMode == WNI_CFG_PHY_MODE_11G)
+ || (psessionEntry->htCapability)) {
+ /* As we found in the past, it is possible that a 11n STA sends
+ * Beacon with HT IE but not ERP IE. So the absense of ERP IE
+ * in the Beacon is not enough to conclude that STA is 11b.
+ */
+ if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
+ (!pStaDs->mlmStaContext.htCapability)) {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Enable protection from 11B"));
+ )
+ lim_ibss_set_protection(pMac, true,
+ pBeaconParams,
+ psessionEntry);
+ }
+ }
+ }
+ lim_ibss_update_protection_params(pMac, pStaDs->staAddr, protStaCacheType,
+ psessionEntry);
+ return;
+}
+
+/**
+ * lim_ibss_peer_find()
+ *
+ ***FUNCTION:
+ * This function is called while adding a context at
+ * DPH & Polaris for a peer in IBSS.
+ * If peer is found in the list, capabilities from the
+ * returned BSS description are used at DPH node & Polaris.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param macAddr - MAC address of the peer
+ *
+ * @return Pointer to peer node if found, else NULL
+ */
+tLimIbssPeerNode *lim_ibss_peer_find(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+ return ibss_peer_find(pMac, macAddr);
+}
+
+/**
+ * lim_ibss_sta_add()
+ *
+ ***FUNCTION:
+ * This function is called to add an STA context in IBSS role
+ * whenever a data frame is received from/for a STA that failed
+ * hash lookup at DPH.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param peerAdddr MAC address of the peer being added
+ * @return retCode Indicates success or failure return code
+ * @return
+ */
+
+tSirRetStatus
+lim_ibss_sta_add(tpAniSirGlobal pMac, void *pBody, tpPESession psessionEntry)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tpDphHashNode pStaDs;
+ tLimIbssPeerNode *pPeerNode;
+ tLimMlmStates prevState;
+ tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody;
+ tUpdateBeaconParams beaconParams;
+
+ cdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
+
+ if (pBody == 0) {
+ PELOGE(lim_log(pMac, LOGE, FL("Invalid IBSS AddSta"));)
+ return eSIR_FAILURE;
+ }
+
+ PELOGE(lim_log(pMac, LOGE, FL("Rx Add-Ibss-Sta for MAC:"));)
+ lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
+
+ pPeerNode = ibss_peer_find(pMac, *pPeerAddr);
+ if (NULL != pPeerNode) {
+ retCode =
+ ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs,
+ psessionEntry);
+ if (eSIR_SUCCESS == retCode) {
+ prevState = pStaDs->mlmStaContext.mlmState;
+ pStaDs->erpEnabled = pPeerNode->erpIePresent;
+
+ ibss_sta_info_update(pMac, pStaDs, pPeerNode,
+ psessionEntry);
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("initiating ADD STA for the IBSS peer."));
+ )
+ retCode =
+ lim_add_sta(pMac, pStaDs, false, psessionEntry);
+ if (retCode != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("ibss-sta-add failed (reason %x)"),
+ retCode);
+ )
+ lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
+ pStaDs->mlmStaContext.mlmState = prevState;
+ dph_delete_hash_entry(pMac, pStaDs->staAddr,
+ pStaDs->assocId,
+ &psessionEntry->dph.
+ dphHashTable);
+ } else {
+ if (pMac->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_ibss_decide_protection(pMac, pStaDs,
+ &beaconParams,
+ psessionEntry);
+
+ if (beaconParams.paramChangeBitmap) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("---> Update Beacon Params "));
+ )
+ sch_set_fixed_beacon_fields(pMac,
+ psessionEntry);
+ beaconParams.bssIdx =
+ psessionEntry->bssIdx;
+ lim_send_beacon_params(pMac, &beaconParams,
+ psessionEntry);
+ }
+ }
+ } else {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("hashTblAdd failed (reason %x)"),
+ retCode);
+ )
+ lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
+ }
+ } else {
+ retCode = eSIR_FAILURE;
+ }
+
+ return retCode;
+}
+
+/* handle the response from HAL for an ADD STA request */
+tSirRetStatus
+lim_ibss_add_sta_rsp(tpAniSirGlobal pMac, void *msg, tpPESession psessionEntry)
+{
+ tpDphHashNode pStaDs;
+ uint16_t peerIdx;
+ tpAddStaParams pAddStaParams = (tpAddStaParams) msg;
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if (pAddStaParams == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("IBSS: ADD_STA_RSP with no body!"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("IBSS: ADD_STA_RSP for unknown MAC addr "));
+ )
+ lim_print_mac_addr(pMac, pAddStaParams->staMac, LOGE);
+ cdf_mem_free(pAddStaParams);
+ return eSIR_FAILURE;
+ }
+
+ if (pAddStaParams->status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("IBSS: ADD_STA_RSP error (%x) "),
+ pAddStaParams->status);
+ )
+ lim_print_mac_addr(pMac, pAddStaParams->staMac, LOGE);
+ cdf_mem_free(pAddStaParams);
+ return eSIR_FAILURE;
+ }
+
+ pStaDs->bssId = pAddStaParams->bssIdx;
+ pStaDs->staIndex = pAddStaParams->staIdx;
+ pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
+ pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
+ pStaDs->valid = 1;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+
+ PELOGW(lim_log
+ (pMac, LOGW, FL("IBSS: sending IBSS_NEW_PEER msg to SME!"));
+ )
+
+ ibss_status_chg_notify(pMac, pAddStaParams->staMac,
+ pStaDs->staIndex, pStaDs->ucUcastSig,
+ pStaDs->ucBcastSig,
+ eWNI_SME_IBSS_NEW_PEER_IND,
+ psessionEntry->smeSessionId);
+
+ cdf_mem_free(pAddStaParams);
+
+ return eSIR_SUCCESS;
+}
+
+void lim_ibss_del_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
+ tpPESession psessionEntry)
+{
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
+
+ PELOGW(lim_log
+ (pMac, LOGW, FL("IBSS: DEL_BSS_RSP Rcvd during coalescing!"));
+ )
+
+ if (pDelBss == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("IBSS: DEL_BSS_RSP(coalesce) with no body!"));
+ )
+ goto end;
+ }
+
+ if (pDelBss->status != CDF_STATUS_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("IBSS: DEL_BSS_RSP(coalesce) error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);
+ goto end;
+ }
+ /* Delete peer entries. */
+ lim_ibss_delete_all_peers(pMac, psessionEntry);
+
+ /* add the new bss */
+ ibss_bss_add(pMac, psessionEntry);
+
+end:
+ if (pDelBss != NULL)
+ cdf_mem_free(pDelBss);
+}
+
+void lim_ibss_add_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
+ tpPESession pSessionEntry)
+{
+ uint8_t infoLen;
+ tSirSmeNewBssInfo newBssInfo;
+
+ tpAddBssParams pAddBss = (tpAddBssParams) msg;
+
+ tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
+ tpSchBeaconStruct pBeacon =
+ (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
+
+ if ((pHdr == NULL) || (pBeacon == NULL)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)"));
+ )
+ goto end;
+ }
+ /* Inform Host of IBSS coalescing */
+ infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) +
+ sizeof(uint8_t) + pBeacon->ssId.length + 1;
+
+ cdf_mem_set((void *)&newBssInfo, sizeof(newBssInfo), 0);
+ cdf_mem_copy(newBssInfo.bssId, pHdr->bssId, sizeof(tSirMacAddr));
+ newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel;
+ cdf_mem_copy((uint8_t *) &newBssInfo.ssId,
+ (uint8_t *) &pBeacon->ssId, pBeacon->ssId.length + 1);
+
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Sending JOINED_NEW_BSS notification to SME."));
+ )
+
+ lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_JOINED_NEW_BSS,
+ (uint32_t *) &newBssInfo,
+ infoLen, pSessionEntry->smeSessionId);
+ {
+ /* Configure beacon and send beacons to HAL */
+ lim_send_beacon_ind(pMac, pSessionEntry);
+ }
+
+end:
+ ibss_coalesce_free(pMac);
+}
+
+void lim_ibss_del_bss_rsp(tpAniSirGlobal pMac, void *msg, tpPESession psessionEntry)
+{
+ tSirResultCodes rc = eSIR_SME_SUCCESS;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
+ tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if (pDelBss == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("IBSS: DEL_BSS_RSP with no body!"));
+ )
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ psessionEntry = pe_find_session_by_session_id(pMac, pDelBss->sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ goto end;
+ }
+
+ /*
+ * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true.
+ * BSS has to be added again in this scenario, so this case needs to be handled separately.
+ * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to
+ * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME.
+ */
+ if (true == pMac->lim.gLimIbssCoalescingHappened) {
+
+ lim_ibss_del_bss_rsp_when_coalescing(pMac, msg, psessionEntry);
+ return;
+ }
+
+ if (pDelBss->status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("IBSS: DEL_BSS_RSP error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);
+ )
+ rc = eSIR_SME_STOP_BSS_FAILURE;
+ goto end;
+ }
+
+ if (lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ psessionEntry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("IBSS: DEL_BSS_RSP setLinkState failed"));
+ )
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ lim_ibss_delete(pMac, psessionEntry);
+
+ dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
+ lim_delete_pre_auth_list(pMac);
+
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+
+ psessionEntry->limSystemRole = eLIM_STA_ROLE;
+
+ /* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra
+ * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from lim_apply_configuration
+ */
+ psessionEntry->shortSlotTimeSupported = WNI_CFG_SHORT_SLOT_TIME_STADEF;
+
+end:
+ if (pDelBss != NULL)
+ cdf_mem_free(pDelBss);
+ /* Delete PE session once BSS is deleted */
+ if (NULL != psessionEntry) {
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+ pe_delete_session(pMac, psessionEntry);
+ psessionEntry = NULL;
+ }
+}
+
+static void
+__lim_ibss_search_and_delete_peer(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, tSirMacAddr macAddr)
+{
+ tLimIbssPeerNode *pTempNode, *pPrevNode;
+ tLimIbssPeerNode *pTempNextNode = NULL;
+ tpDphHashNode pStaDs = NULL;
+ uint16_t peerIdx = 0;
+ uint16_t staIndex = 0;
+ uint8_t ucUcastSig;
+ uint8_t ucBcastSig;
+
+ pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList;
+
+ lim_log(pMac, LOG1, FL(" PEER ADDR :" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(macAddr));
+
+ /** Compare Peer */
+ while (NULL != pTempNode) {
+ pTempNextNode = pTempNode->next;
+
+ /* Delete the STA with MAC address */
+ if (cdf_mem_compare((uint8_t *) macAddr,
+ (uint8_t *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr))) {
+ pStaDs = dph_lookup_hash_entry(pMac, macAddr,
+ &peerIdx,
+ &psessionEntry->dph.
+ dphHashTable);
+ if (pStaDs) {
+ staIndex = pStaDs->staIndex;
+ ucUcastSig = pStaDs->ucUcastSig;
+ ucBcastSig = pStaDs->ucBcastSig;
+
+ (void)lim_del_sta(pMac, pStaDs,
+ false /*asynchronous */,
+ psessionEntry);
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
+ peerIdx, psessionEntry);
+ lim_release_peer_idx(pMac, peerIdx, psessionEntry);
+
+ /* Send indication to upper layers */
+ ibss_status_chg_notify(pMac, macAddr, staIndex,
+ ucUcastSig, ucBcastSig,
+ eWNI_SME_IBSS_PEER_DEPARTED_IND,
+ psessionEntry->
+ smeSessionId);
+ if (pTempNode == pMac->lim.gLimIbssPeerList) {
+ pMac->lim.gLimIbssPeerList =
+ pTempNode->next;
+ pPrevNode = pMac->lim.gLimIbssPeerList;
+ } else
+ pPrevNode->next = pTempNode->next;
+
+ cdf_mem_free(pTempNode);
+ pMac->lim.gLimNumIbssPeers--;
+
+ pTempNode = pTempNextNode;
+ break;
+ }
+ }
+ pPrevNode = pTempNode;
+ pTempNode = pTempNextNode;
+ }
+ /*
+ * if it is the last peer walking out, we better
+ * we set IBSS state to inactive.
+ */
+ if (0 == pMac->lim.gLimNumIbssPeers) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ "Last STA from IBSS walked out");
+ psessionEntry->limIbssActive = false;
+ }
+}
+
+/**
+ * lim_ibss_coalesce()
+ *
+ ***FUNCTION:
+ * This function is called upon receiving Beacon/Probe Response
+ * while operating in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBeacon - Parsed Beacon Frame structure
+ * @param pBD - Pointer to received BD
+ *
+ * @return Status whether to process or ignore received Beacon Frame
+ */
+
+tSirRetStatus
+lim_ibss_coalesce(tpAniSirGlobal pMac,
+ tpSirMacMgmtHdr pHdr,
+ tpSchBeaconStruct pBeacon,
+ uint8_t *pIEs,
+ uint32_t ieLen, uint16_t fTsfLater, tpPESession psessionEntry)
+{
+ uint16_t peerIdx;
+ tSirMacAddr currentBssId;
+ tLimIbssPeerNode *pPeerNode;
+ tpDphHashNode pStaDs;
+ tUpdateBeaconParams beaconParams;
+
+ cdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
+
+ sir_copy_mac_addr(currentBssId, psessionEntry->bssId);
+
+ lim_log(pMac, LOG1,
+ FL("Current BSSID :" MAC_ADDRESS_STR " Received BSSID :"
+ MAC_ADDRESS_STR), MAC_ADDR_ARRAY(currentBssId),
+ MAC_ADDR_ARRAY(pHdr->bssId));
+
+ /* Check for IBSS Coalescing only if Beacon is from different BSS */
+ if (!cdf_mem_compare(currentBssId, pHdr->bssId, sizeof(tSirMacAddr))
+ && psessionEntry->isCoalesingInIBSSAllowed) {
+ /*
+ * If STA entry is already available in the LIM hash table, then it is
+ * possible that the peer may have left and rejoined within the heartbeat
+ * timeout. In the offloaded case with 32 peers, the HB timeout is whopping
+ * 128 seconds. In that case, the FW will not let any frames come in until
+ * atleast the last sequence number is received before the peer is left
+ * Hence, if the coalescing peer is already there in the peer list and if
+ * the BSSID matches then, invoke delSta() to cleanup the entries. We will
+ * let the peer coalesce when we receive next beacon from the peer
+ */
+ pPeerNode = ibss_peer_find(pMac, pHdr->sa);
+ if (NULL != pPeerNode) {
+ __lim_ibss_search_and_delete_peer(pMac, psessionEntry,
+ pHdr->sa);
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL
+ ("** Peer attempting to reconnect before HB timeout, deleted **"));
+ )
+ return eSIR_LIM_IGNORE_BEACON;
+ }
+
+ if (!fTsfLater) { /* No Coalescing happened. */
+ PELOGW(lim_log(pMac, LOGW, FL("No Coalescing happened"));)
+ return eSIR_LIM_IGNORE_BEACON;
+ }
+ /*
+ * IBSS Coalescing happened.
+ * save the received beacon, and delete the current BSS. The rest of the
+ * processing will be done in the delBss response processing
+ */
+ pMac->lim.gLimIbssCoalescingHappened = true;
+ PELOGW(lim_log(pMac, LOGW, FL("IBSS Coalescing happened"));)
+ ibss_coalesce_save(pMac, pHdr, pBeacon);
+ lim_log(pMac, LOGW, FL("Delete BSSID :" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(currentBssId));
+ ibss_bss_delete(pMac, psessionEntry);
+ return eSIR_SUCCESS;
+ } else {
+ if (!cdf_mem_compare
+ (currentBssId, pHdr->bssId, sizeof(tSirMacAddr)))
+ return eSIR_LIM_IGNORE_BEACON;
+ }
+
+ /* STA in IBSS mode and SSID matches with ours */
+ pPeerNode = ibss_peer_find(pMac, pHdr->sa);
+ if (pPeerNode == NULL) {
+ /* Peer not in the list - Collect BSS description & add to the list */
+ uint32_t frameLen;
+ tSirRetStatus retCode;
+
+ /*
+ * Limit the Max number of IBSS Peers allowed as the max
+ * number of STA's allowed
+ * pMac->lim.gLimNumIbssPeers will be increamented after exiting
+ * this function. so we will add additional 1 to compare against
+ * pMac->lim.gLimIbssStaLimit
+ */
+ if ((pMac->lim.gLimNumIbssPeers + 1) >=
+ pMac->lim.gLimIbssStaLimit) {
+ /*Print every 100th time */
+ if (pMac->lim.ibss_retry_cnt % 100 == 0) {
+ PELOGE(lim_log(pMac, LOG1,
+ FL("**** MAX STA LIMIT HAS REACHED ****"));)
+ }
+ pMac->lim.ibss_retry_cnt++;
+ return eSIR_LIM_MAX_STA_REACHED_ERROR;
+ }
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("IBSS Peer node does not exist, adding it***"));
+ )
+ frameLen =
+ sizeof(tLimIbssPeerNode) + ieLen - sizeof(uint32_t);
+
+ pPeerNode = cdf_mem_malloc((uint16_t) frameLen);
+ if (NULL == pPeerNode) {
+ lim_log(pMac, LOGP,
+ FL
+ ("alloc fail (%d bytes) storing IBSS peer info"),
+ frameLen);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ pPeerNode->beacon = NULL;
+ pPeerNode->beaconLen = 0;
+
+ ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,
+ psessionEntry);
+ pPeerNode->beacon = cdf_mem_malloc(ieLen);
+ if (NULL == pPeerNode->beacon) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("Unable to allocate memory to store beacon"));
+ )
+ } else {
+ cdf_mem_copy(pPeerNode->beacon, pIEs, ieLen);
+ pPeerNode->beaconLen = (uint16_t) ieLen;
+ }
+ ibss_peer_add(pMac, pPeerNode);
+
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL) {
+ /* / DPH node already exists for the peer */
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("DPH Node present for just learned peer"));
+ )
+ PELOG1(lim_print_mac_addr
+ (pMac, pPeerNode->peerMacAddr, LOG1);
+ )
+ ibss_sta_info_update(pMac, pStaDs, pPeerNode,
+ psessionEntry);
+ return eSIR_SUCCESS;
+ }
+ retCode =
+ lim_ibss_sta_add(pMac, pPeerNode->peerMacAddr, psessionEntry);
+ if (retCode != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("lim-ibss-sta-add failed (reason %x)"),
+ retCode);
+ )
+ lim_print_mac_addr(pMac, pPeerNode->peerMacAddr, LOGE);
+ return retCode;
+ }
+ /* Decide protection mode */
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pMac->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_ibss_decide_protection(pMac, pStaDs, &beaconParams,
+ psessionEntry);
+
+ if (beaconParams.paramChangeBitmap) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params "));
+ )
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ beaconParams.bssIdx = psessionEntry->bssIdx;
+ lim_send_beacon_params(pMac, &beaconParams, psessionEntry);
+ }
+ } else
+ ibss_sta_caps_update(pMac, pPeerNode, psessionEntry);
+
+ if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE)
+ return eSIR_SUCCESS;
+
+ /* Received Beacon from same IBSS we're */
+ /* currently part of. Inform Roaming algorithm */
+ /* if not already that IBSS is active. */
+ if (psessionEntry->limIbssActive == false) {
+ limResetHBPktCount(psessionEntry);
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL
+ ("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME"));
+ )
+ psessionEntry->limIbssActive = true;
+ lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0,
+ psessionEntry->smeSessionId);
+ }
+
+ return eSIR_SUCCESS;
+} /*** end lim_handle_ibs_scoalescing() ***/
+
+/**
+ * lim_ibss_heart_beat_handle() - handle IBSS hearbeat failure
+ *
+ * @mac_ctx: global mac context
+ * @session: PE session entry
+ *
+ * Hanlde IBSS hearbeat failure.
+ *
+ * Return: None.
+ */
+void lim_ibss_heart_beat_handle(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+ tLimIbssPeerNode *tempnode, *prevnode;
+ tLimIbssPeerNode *temp_next = NULL;
+ uint16_t peer_idx = 0;
+ tpDphHashNode stads = 0;
+ uint32_t threshold = 0;
+ uint16_t sta_idx = 0;
+ uint8_t ucast_sig = 0;
+ uint8_t bcast_sig = 0;
+
+ /*
+ * MLM BSS is started and if PE in scanmode then MLM state will be
+ * waiting for probe resp. If Heart beat timeout triggers during this
+ * corner case then we need to reactivate HeartBeat timer.
+ */
+ if (session->limMlmState != eLIM_MLM_BSS_STARTED_STATE)
+ return;
+
+ /* If LinkMonitor is Disabled */
+ if (!mac_ctx->sys.gSysEnableLinkMonitorMode)
+ return;
+
+ prevnode = tempnode = mac_ctx->lim.gLimIbssPeerList;
+ threshold = (mac_ctx->lim.gLimNumIbssPeers / 4) + 1;
+
+ /* Monitor the HeartBeat with the Individual PEERS in the IBSS */
+ while (tempnode != NULL) {
+ temp_next = tempnode->next;
+ if (tempnode->beaconHBCount) {
+ /* There was a beacon for this peer during heart beat */
+ tempnode->beaconHBCount = 0;
+ tempnode->heartbeatFailure = 0;
+ prevnode = tempnode;
+ tempnode = temp_next;
+ continue;
+ }
+
+ /* There wasnt any beacon received during heartbeat timer. */
+ tempnode->heartbeatFailure++;
+ lim_log(mac_ctx, LOGE, FL("Heartbeat fail = %d thres = %d"),
+ tempnode->heartbeatFailure, mac_ctx->lim.gLimNumIbssPeers);
+ if (tempnode->heartbeatFailure >= threshold) {
+ /* Remove this entry from the list. */
+ stads = dph_lookup_hash_entry(mac_ctx,
+ tempnode->peerMacAddr, &peer_idx,
+ &session->dph.dphHashTable);
+ if (stads) {
+ sta_idx = stads->staIndex;
+ ucast_sig = stads->ucUcastSig;
+ bcast_sig = stads->ucBcastSig;
+
+ (void)lim_del_sta(mac_ctx, stads, false,
+ session);
+ lim_delete_dph_hash_entry(mac_ctx,
+ stads->staAddr, peer_idx, session);
+ lim_release_peer_idx(mac_ctx, peer_idx,
+ session);
+ /* Send indication. */
+ ibss_status_chg_notify(mac_ctx,
+ tempnode->peerMacAddr, sta_idx,
+ ucast_sig, bcast_sig,
+ eWNI_SME_IBSS_PEER_DEPARTED_IND,
+ session->smeSessionId);
+ }
+ if (tempnode == mac_ctx->lim.gLimIbssPeerList) {
+ mac_ctx->lim.gLimIbssPeerList = tempnode->next;
+ prevnode = mac_ctx->lim.gLimIbssPeerList;
+ } else {
+ prevnode->next = tempnode->next;
+ }
+
+ cdf_mem_free(tempnode);
+ mac_ctx->lim.gLimNumIbssPeers--;
+
+ /* we deleted current node, so prevNode remains same. */
+ tempnode = temp_next;
+ continue;
+ }
+ prevnode = tempnode;
+ tempnode = temp_next;
+ }
+
+ /*
+ * General IBSS Activity Monitor,
+ * check if in IBSS Mode we are received any Beacons
+ */
+ if (mac_ctx->lim.gLimNumIbssPeers) {
+ if (session->LimRxedBeaconCntDuringHB <
+ MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
+ mac_ctx->lim.gLimHeartBeatBeaconStats[
+ session->LimRxedBeaconCntDuringHB]++;
+ else
+ mac_ctx->lim.gLimHeartBeatBeaconStats[0]++;
+
+ /* Reset number of beacons received */
+ limResetHBPktCount(session);
+ return;
+ } else {
+ lim_log(mac_ctx, LOGW, FL("Heartbeat Failure"));
+ mac_ctx->lim.gLimHBfailureCntInLinkEstState++;
+
+ if (session->limIbssActive == true) {
+ /*
+ * We don't receive Beacon frames from any
+ * other STA in IBSS. Announce IBSS inactive
+ * to Roaming algorithm
+ */
+ lim_log(mac_ctx, LOGW, FL("Alone in IBSS"));
+ session->limIbssActive = false;
+
+ lim_send_sme_wm_status_change_ntf(mac_ctx,
+ eSIR_SME_IBSS_INACTIVE, NULL, 0,
+ session->smeSessionId);
+ }
+ }
+}
+
+/**
+ * lim_ibss_decide_protection_on_delete() - decides protection related info.
+ *
+ * @mac_ctx: global mac context
+ * @stads: station hash node
+ * @bcn_param: beacon parameters
+ * @session: PE session entry
+ *
+ * Decides all the protection related information.
+ *
+ * Return: None
+ */
+void lim_ibss_decide_protection_on_delete(tpAniSirGlobal mac_ctx,
+ tpDphHashNode stads,
+ tpUpdateBeaconParams bcn_param,
+ tpPESession session)
+{
+ uint32_t phymode;
+ tHalBitVal erpenabled = eHAL_CLEAR;
+ tSirRFBand rfband = SIR_BAND_UNKNOWN;
+ uint32_t i;
+
+ if (NULL == stads)
+ return;
+
+ lim_get_rf_band_new(mac_ctx, &rfband, session);
+ if (SIR_BAND_2_4_GHZ != rfband)
+ return;
+
+ lim_get_phy_mode(mac_ctx, &phymode, session);
+ erpenabled = stads->erpEnabled;
+ /* we are HT or 11G and 11B station is getting deleted. */
+ if (((phymode == WNI_CFG_PHY_MODE_11G) ||
+ session->htCapability) && (erpenabled == eHAL_CLEAR)) {
+ lim_log(mac_ctx, LOGE,
+ FL("(%d) A legacy STA is disassociated. Addr is "),
+ session->gLim11bParams.numSta);
+ lim_print_mac_addr(mac_ctx, stads->staAddr, LOGE);
+ if (session->gLim11bParams.numSta == 0) {
+ lim_log(mac_ctx, LOGE,
+ FL("No 11B STA exists. Disable protection."));
+ lim_ibss_set_protection(mac_ctx, false,
+ bcn_param, session);
+ }
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (!mac_ctx->lim.protStaCache[i].active)
+ continue;
+ if (cdf_mem_compare(mac_ctx->lim.protStaCache[i].addr,
+ stads->staAddr, sizeof(tSirMacAddr))) {
+ session->gLim11bParams.numSta--;
+ mac_ctx->lim.protStaCache[i].active = false;
+ break;
+ }
+ }
+
+ }
+}
+
+/** -----------------------------------------------------------------
+ \fn __lim_ibss_peer_inactivity_handler
+ \brief Internal function. Deletes FW indicated peer which is inactive
+ \
+ \param tpAniSirGlobal pMac
+ \param tpPESession psessionEntry
+ \param tpSirIbssPeerInactivityInd peerInactivityInd
+ \return None
+ -----------------------------------------------------------------*/
+static void
+__lim_ibss_peer_inactivity_handler(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tpSirIbssPeerInactivityInd peerInactivityInd)
+{
+ if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
+ return;
+ }
+
+ /* delete the peer for which heartbeat is observed */
+ __lim_ibss_search_and_delete_peer(pMac, psessionEntry,
+ peerInactivityInd->peerAddr);
+
+}
+
+/** -------------------------------------------------------------
+ \fn lim_process_ibss_peer_inactivity
+ \brief Peer inactivity message handler
+ \
+ \param tpAniSirGlobal pMac
+ \param void* buf
+ \return None
+ -------------------------------------------------------------*/
+void lim_process_ibss_peer_inactivity(tpAniSirGlobal pMac, void *buf)
+{
+ /*
+ * --------------- HEARTBEAT OFFLOAD CASE ------------------
+ * This message handler is executed when the firmware identifies
+ * inactivity from one or more peer devices. We will come here
+ * for every inactive peer device
+ */
+ uint8_t i;
+
+ tSirIbssPeerInactivityInd *peerInactivityInd =
+ (tSirIbssPeerInactivityInd *) buf;
+
+ /*
+ * If IBSS is not started or heartbeat offload is not enabled
+ * we should not handle this request
+ */
+ if (eLIM_STA_IN_IBSS_ROLE != pMac->lim.gLimSystemRole &&
+ !IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) {
+ return;
+ }
+
+ /** If LinkMonitor is Disabled */
+ if (!pMac->sys.gSysEnableLinkMonitorMode) {
+ return;
+ }
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if (true == pMac->lim.gpSession[i].valid &&
+ eSIR_IBSS_MODE == pMac->lim.gpSession[i].bssType) {
+ __lim_ibss_peer_inactivity_handler(pMac,
+ &pMac->lim.gpSession[i],
+ peerInactivityInd);
+ break;
+ }
+ }
+}
diff --git a/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h
new file mode 100644
index 0000000..0c97919
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ibss_peer_mgmt.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_ibss_peer_mgmt.h contains prototypes for
+ * the utility functions LIM uses to maintain peers in IBSS.
+ * Author: Chandra Modumudi
+ * Date: 03/12/04
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "sir_common.h"
+#include "lim_utils.h"
+
+#define IBSS_STATIONS_USED_DURING_INIT 4 /* (broadcast + self + p2p + softap) */
+
+void lim_ibss_init(tpAniSirGlobal);
+void lim_ibss_delete(tpAniSirGlobal, tpPESession psessionEntry);
+tSirRetStatus lim_ibss_coalesce(tpAniSirGlobal, tpSirMacMgmtHdr,
+ tpSchBeaconStruct, uint8_t *, uint32_t, uint16_t,
+ tpPESession);
+tSirRetStatus lim_ibss_sta_add(tpAniSirGlobal, void *, tpPESession);
+tSirRetStatus lim_ibss_add_sta_rsp(tpAniSirGlobal, void *, tpPESession);
+tLimIbssPeerNode *lim_ibss_peer_find(tpAniSirGlobal pMac, tSirMacAddr macAddr);
+void lim_ibss_del_bss_rsp(tpAniSirGlobal, void *, tpPESession);
+void lim_ibss_del_bss_rsp_when_coalescing(tpAniSirGlobal, void *, tpPESession);
+void lim_ibss_add_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
+ tpPESession pSessionEntry);
+void lim_ibss_decide_protection_on_delete(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession pSessionEntry);
+void lim_ibss_heart_beat_handle(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_process_ibss_peer_inactivity(tpAniSirGlobal pMac, void *buf);
diff --git a/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
new file mode 100644
index 0000000..2ce55b0
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_link_monitoring_algo.cc contains the code for
+ * Link monitoring algorithm on AP and heart beat failure
+ * handling on STA.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_assoc_utils.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_prop_exts_utils.h"
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "lim_ser_des_utils.h"
+
+/**
+ * lim_delete_sta_util - utility function for deleting station context
+ *
+ * @mac_ctx: global MAC context
+ * @msg: pointer to delte station context
+ * @session_entry: PE session entry
+ *
+ * utility function called to clear up station context.
+ *
+ * Return: None.
+ */
+static void lim_delete_sta_util(tpAniSirGlobal mac_ctx, tpDeleteStaContext msg,
+ tpPESession session_entry)
+{
+ tpDphHashNode stads;
+
+ lim_log(mac_ctx, LOGE,
+ FL("Deleting station: staId = %d, reasonCode = %d"),
+ msg->staId, msg->reasonCode);
+
+ if (LIM_IS_IBSS_ROLE(session_entry)) {
+ cdf_mem_free(msg);
+ return;
+ }
+
+ stads = dph_lookup_assoc_id(mac_ctx, msg->staId, &msg->assocId,
+ &session_entry->dph.dphHashTable);
+
+ if (!stads) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid STA limSystemRole=%d"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ cdf_mem_free(msg);
+ return;
+ }
+
+ /* check and see if same staId. This is to avoid the scenario
+ * where we're trying to delete a staId we just added.
+ */
+ if (stads->staIndex != msg->staId) {
+ lim_log(mac_ctx, LOGE, FL("staid mismatch: %d vs %d "),
+ stads->staIndex, msg->staId);
+ cdf_mem_free(msg);
+ return;
+ }
+
+ if (LIM_IS_BT_AMP_AP_ROLE(session_entry) ||
+ LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOG1,
+ FL("Delete Station staId: %d, assocId: %d"),
+ msg->staId, msg->assocId);
+ /*
+ * Check if Deauth/Disassoc is triggered from Host.
+ * If mlmState is in some transient state then
+ * don't trigger STA deletion to avoid the race
+ * condition.
+ */
+ if ((stads &&
+ ((stads->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (stads->mlmStaContext.mlmState !=
+ eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+ (stads->mlmStaContext.mlmState !=
+ eLIM_MLM_ASSOCIATED_STATE)))) {
+ lim_log(mac_ctx, LOGE,
+ FL("Inv Del STA staId:%d, assocId:%d"),
+ msg->staId, msg->assocId);
+ cdf_mem_free(msg);
+ return;
+ } else {
+ lim_trigger_sta_deletion(mac_ctx, stads, session_entry);
+ }
+ } else {
+#ifdef FEATURE_WLAN_TDLS
+ if (LIM_IS_STA_ROLE(session_entry) &&
+ STA_ENTRY_TDLS_PEER == stads->staType) {
+ /*
+ * TeardownLink with PEER reason code
+ * HAL_DEL_STA_REASON_CODE_KEEP_ALIVE means
+ * eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE
+ */
+ lim_send_sme_tdls_del_sta_ind(mac_ctx, stads,
+ session_entry,
+ eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE);
+ } else {
+#endif
+ /* TearDownLink with AP */
+ tLimMlmDeauthInd mlm_deauth_ind;
+ lim_log(mac_ctx, LOGW,
+ FL("Delete Station (staId: %d, assocId: %d) "),
+ msg->staId, msg->assocId);
+
+ if ((stads &&
+ ((stads->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (stads->mlmStaContext.mlmState !=
+ eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+ (stads->mlmStaContext.mlmState !=
+ eLIM_MLM_ASSOCIATED_STATE)))) {
+
+ /*
+ * Received SIR_LIM_DELETE_STA_CONTEXT_IND for STA that
+ * does not have context or in some transit state.
+ * Log error
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("Received SIR_LIM_DELETE_STA_CONTEXT_IND for "
+ "STA that either has no context or "
+ "in some transit state, Addr = "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(msg->bssId));
+ cdf_mem_free(msg);
+ return;
+ }
+
+ stads->mlmStaContext.disassocReason =
+ eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+ stads->mlmStaContext.cleanupTrigger =
+ eLIM_LINK_MONITORING_DEAUTH;
+
+ /* Issue Deauth Indication to SME. */
+ cdf_mem_copy((uint8_t *) &mlm_deauth_ind.peerMacAddr,
+ stads->staAddr, sizeof(tSirMacAddr));
+ mlm_deauth_ind.reasonCode =
+ (uint8_t) stads->mlmStaContext.disassocReason;
+ mlm_deauth_ind.deauthTrigger =
+ stads->mlmStaContext.cleanupTrigger;
+
+#ifdef FEATURE_WLAN_TDLS
+ /* Delete all TDLS peers connected before leaving BSS */
+ lim_delete_tdls_peers(mac_ctx, session_entry);
+#endif
+ lim_post_sme_message(mac_ctx, LIM_MLM_DEAUTH_IND,
+ (uint32_t *) &mlm_deauth_ind);
+
+ lim_send_sme_deauth_ind(mac_ctx, stads, session_entry);
+#ifdef FEATURE_WLAN_TDLS
+ }
+#endif
+ }
+}
+
+/**
+ * lim_delete_sta_context() - delete sta context.
+ *
+ * @mac_ctx: global mac_ctx context
+ * @lim_msg: lim message.
+ *
+ * This function handles the message from HAL: WMA_DELETE_STA_CONTEXT_IND.
+ * This function validates that the given station id exist, and if so,
+ * deletes the station by calling lim_trigger_sta_deletion.
+ *
+ * Return: none
+ */
+void lim_delete_sta_context(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg)
+{
+ tpDeleteStaContext msg = (tpDeleteStaContext) lim_msg->bodyptr;
+ tpPESession session_entry;
+ uint8_t session_id;
+
+ if (NULL == msg) {
+ lim_log(mac_ctx, LOGE, FL("Invalid body pointer in message"));
+ return;
+ }
+ session_entry = pe_find_session_by_bssid(mac_ctx, msg->bssId,
+ &session_id);
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGE, FL("session does not exist"));
+ cdf_mem_free(msg);
+ return;
+ }
+
+ switch (msg->reasonCode) {
+ case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE:
+ case HAL_DEL_STA_REASON_CODE_TIM_BASED:
+ lim_delete_sta_util(mac_ctx, msg, session_entry);
+ break;
+
+ case HAL_DEL_STA_REASON_CODE_UNKNOWN_A2:
+ lim_log(mac_ctx, LOGE, FL("Deleting Unknown station "));
+ lim_print_mac_addr(mac_ctx, msg->addr2, LOGE);
+ lim_send_deauth_mgmt_frame(mac_ctx,
+ eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON,
+ msg->addr2, session_entry, false);
+ break;
+
+ default:
+ lim_log(mac_ctx, LOGE, FL(" Unknown reason code "));
+ break;
+ }
+ cdf_mem_free(msg);
+ return;
+}
+
+/**
+ * lim_trigger_sta_deletion()
+ *
+ ***FUNCTION:
+ * This function is called to trigger STA context deletion
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param pStaDs - Pointer to internal STA Datastructure
+ * @return None
+ */
+void
+lim_trigger_sta_deletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tSirSmeDeauthReq *pSmeDeauthReq;
+ uint8_t *pBuf;
+ uint8_t *pLen;
+ uint16_t msgLength = 0;
+
+ if (!pStaDs) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Skip STA deletion (invalid STA)"));
+ )
+ return;
+ }
+ /**
+ * MAC based Authentication was used. Trigger
+ * Deauthentication frame to peer since it will
+ * take care of disassociation as well.
+ */
+
+ pSmeDeauthReq = cdf_mem_malloc(sizeof(tSirSmeDeauthReq));
+ if (NULL == pSmeDeauthReq) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_DEAUTH_REQ "));
+ return;
+ }
+
+ pBuf = (uint8_t *) &pSmeDeauthReq->messageType;
+
+ /* messageType */
+ lim_copy_u16((uint8_t *) pBuf, eWNI_SME_DISASSOC_REQ);
+ pBuf += sizeof(uint16_t);
+ msgLength += sizeof(uint16_t);
+
+ /* length */
+ pLen = pBuf;
+ pBuf += sizeof(uint16_t);
+ msgLength += sizeof(uint16_t);
+
+ /* sessionId */
+ *pBuf = psessionEntry->smeSessionId;
+ pBuf++;
+ msgLength++;
+
+ /* transactionId */
+ lim_copy_u16((uint8_t *) pBuf, psessionEntry->transactionId);
+ pBuf += sizeof(uint16_t);
+ msgLength += sizeof(uint16_t);
+
+ /* bssId */
+ cdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ msgLength += sizeof(tSirMacAddr);
+
+ /* peerMacAddr */
+ cdf_mem_copy(pBuf, pStaDs->staAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+ msgLength += sizeof(tSirMacAddr);
+
+ /* reasonCode */
+ lim_copy_u16((uint8_t *) pBuf, (uint16_t) eLIM_LINK_MONITORING_DISASSOC);
+ pBuf += sizeof(uint16_t);
+ msgLength += sizeof(uint16_t);
+
+ /* Do not send disassoc OTA */
+ /* pBuf[0] = 1 means do not send the disassoc frame over the air */
+ /* pBuf[0] = 0 means send the disassoc frame over the air */
+ pBuf[0] = 0;
+ pBuf += sizeof(uint8_t);
+ msgLength += sizeof(uint8_t);
+
+ /* Fill in length */
+ lim_copy_u16((uint8_t *) pLen, msgLength);
+
+ lim_post_sme_message(pMac, eWNI_SME_DISASSOC_REQ,
+ (uint32_t *) pSmeDeauthReq);
+ cdf_mem_free(pSmeDeauthReq);
+
+} /*** end lim_trigger_st_adeletion() ***/
+
+/**
+ * lim_tear_down_link_with_ap()
+ *
+ ***FUNCTION:
+ * This function is called when heartbeat (beacon reception)
+ * fails on STA
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+lim_tear_down_link_with_ap(tpAniSirGlobal pMac, uint8_t sessionId,
+ tSirMacReasonCodes reasonCode)
+{
+ tpDphHashNode pStaDs = NULL;
+
+ /* tear down the following sessionEntry */
+ tpPESession psessionEntry;
+
+ if ((psessionEntry = pe_find_session_by_session_id(pMac, sessionId)) == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+ /**
+ * Heart beat failed for upto threshold value
+ * and AP did not respond for Probe request.
+ * Trigger link tear down.
+ */
+ psessionEntry->pmmOffloadInfo.bcnmiss = false;
+
+ lim_log(pMac, LOGW,
+ FL("No ProbeRsp from AP after HB failure. Tearing down link"));
+
+ /* Announce loss of link to Roaming algorithm */
+ /* and cleanup by sending SME_DISASSOC_REQ to SME */
+
+ pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs != NULL) {
+ tLimMlmDeauthInd mlmDeauthInd;
+
+#ifdef FEATURE_WLAN_TDLS
+ /* Delete all TDLS peers connected before leaving BSS */
+ lim_delete_tdls_peers(pMac, psessionEntry);
+#endif
+
+ pStaDs->mlmStaContext.disassocReason = reasonCode;
+ pStaDs->mlmStaContext.cleanupTrigger =
+ eLIM_LINK_MONITORING_DEAUTH;
+
+ /*
+ * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+ * This is to address the issue of race condition between
+ * disconnect request from the HDD and deauth from
+ * Tx inactivity timer by FWR. This will make sure that we
+ * will not process disassoc if deauth is in progress for
+ * the station and thus mlmStaContext.cleanupTrigger will
+ * not be overwritten.
+ */
+
+ pStaDs->mlmStaContext.mlmState =
+ eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ /* / Issue Deauth Indication to SME. */
+ cdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr,
+ pStaDs->staAddr, sizeof(tSirMacAddr));
+
+ /*
+ * if sendDeauthBeforeCon is enabled and reasoncode is
+ * Beacon Missed Store the MAC of AP in the flip flop
+ * buffer. This MAC will be used to send Deauth before
+ * connection, if we connect to same AP after HB failure.
+ */
+ if (pMac->roam.configParam.sendDeauthBeforeCon &&
+ eSIR_BEACON_MISSED == reasonCode) {
+ int apCount = pMac->lim.gLimHeartBeatApMacIndex;
+
+ if (pMac->lim.gLimHeartBeatApMacIndex)
+ pMac->lim.gLimHeartBeatApMacIndex = 0;
+ else
+ pMac->lim.gLimHeartBeatApMacIndex = 1;
+
+ lim_log(pMac, LOGE, FL("HB Failure on MAC "
+ MAC_ADDRESS_STR" Store it on Index %d"),
+ MAC_ADDR_ARRAY(pStaDs->staAddr),apCount);
+
+ sir_copy_mac_addr(pMac->lim.gLimHeartBeatApMac[apCount],
+ pStaDs->staAddr);
+ }
+
+ mlmDeauthInd.reasonCode =
+ (uint8_t) pStaDs->mlmStaContext.disassocReason;
+ mlmDeauthInd.deauthTrigger =
+ pStaDs->mlmStaContext.cleanupTrigger;
+
+ lim_post_sme_message(pMac, LIM_MLM_DEAUTH_IND,
+ (uint32_t *) &mlmDeauthInd);
+
+ lim_send_sme_deauth_ind(pMac, pStaDs, psessionEntry);
+ }
+} /*** lim_tear_down_link_with_ap() ***/
+
+/**
+ * lim_handle_heart_beat_failure() - handle hear beat failure in STA
+ *
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called when heartbeat (beacon reception)
+ * fails on STA
+ *
+ * Return: None
+ */
+
+void lim_handle_heart_beat_failure(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ uint8_t curr_chan;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ host_log_beacon_update_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_beacon_update_pkt_type,
+ LOG_WLAN_BEACON_UPDATE_C);
+ if (log_ptr)
+ log_ptr->bcn_rx_cnt = session->LimRxedBeaconCntDuringHB;
+ WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ /* Ensure HB Status for the session has been reseted */
+ session->LimHBFailureStatus = false;
+
+ if ((LIM_IS_STA_ROLE(session) ||
+ LIM_IS_BT_AMP_STA_ROLE(session)) &&
+ (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (session->limSmeState != eLIM_SME_WT_DISASSOC_STATE) &&
+ (session->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
+ if (!mac_ctx->sys.gSysEnableLinkMonitorMode)
+ return;
+
+ /* Beacon frame not received within heartbeat timeout. */
+ lim_log(mac_ctx, LOGW, FL("Heartbeat Failure"));
+ mac_ctx->lim.gLimHBfailureCntInLinkEstState++;
+
+ /*
+ * Check if connected on the DFS channel, if not connected on
+ * DFS channel then only send the probe request otherwise tear
+ * down the link
+ */
+ curr_chan = session->currentOperChannel;
+ if (!lim_isconnected_on_dfs_channel(curr_chan)) {
+ /* Detected continuous Beacon Misses */
+ session->LimHBFailureStatus = true;
+
+ /*Reset the HB packet count before sending probe*/
+ limResetHBPktCount(session);
+ /**
+ * Send Probe Request frame to AP to see if
+ * it is still around. Wait until certain
+ * timeout for Probe Response from AP.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("HB missed from AP. Sending Probe Req"));
+ /* for searching AP, we don't include any more IE */
+ lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId,
+ session->bssId, curr_chan, session->selfMacAddr,
+ session->dot11mode, 0, NULL);
+ } else {
+ lim_log(mac_ctx, LOGW,
+ FL("HB missed from AP on DFS chanel moving to passive"));
+ if (curr_chan < SIR_MAX_24G_5G_CHANNEL_RANGE) {
+ lim_covert_channel_scan_type(mac_ctx, curr_chan,
+ false);
+ mac_ctx->lim.dfschannelList.timeStamp[curr_chan]
+ = 0;
+ }
+ /*
+ * Connected on DFS channel so should not send the
+ * probe request tear down the link directly
+ */
+ lim_tear_down_link_with_ap(mac_ctx,
+ session->peSessionId,
+ eSIR_BEACON_MISSED);
+ }
+ } else {
+ /**
+ * Heartbeat timer may have timed out
+ * while we're doing background scanning/learning
+ * or in states other than link-established state.
+ * Log error.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("received heartbeat timeout in state %X"),
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOG1, session->limMlmState);
+ mac_ctx->lim.gLimHBfailureCntInOtherStates++;
+ }
+}
diff --git a/core/mac/src/pe/lim/lim_p2p.c b/core/mac/src/pe/lim/lim_p2p.c
new file mode 100644
index 0000000..7f29157
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_p2p.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+ L I M _ P 2 P . C
+
+ OVERVIEW:
+
+ This software unit holds the implementation of the WLAN Protocol Engine for
+ P2P.
+ ===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+ $Header$$DateTime$$Author$
+
+ when who what, where, why
+ ---------- --- --------------------------------------------------------
+ 2011-05-02 djindal Corrected file indentation and changed remain on channel
+ handling for concurrency.
+ ===========================================================================*/
+
+#include "lim_utils.h"
+#include "lim_session_utils.h"
+#include "wma_types.h"
+#include "lim_types.h"
+
+#define PROBE_RSP_IE_OFFSET 36
+#define BSSID_OFFSET 16
+#define ADDR2_OFFSET 10
+#define ACTION_OFFSET 24
+
+/* A DFS channel can be ACTIVE for max 9000 msec, from the last
+ received Beacon/Prpbe Resp. */
+#define MAX_TIME_TO_BE_ACTIVE_CHANNEL 9000
+
+void lim_exit_remain_on_channel(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry);
+extern tSirRetStatus lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
+ tSirMacAddr bssId, tSirMacAddr selfMacAddr,
+ tpSetLinkStateCallback callback,
+ void *callbackArg);
+
+CDF_STATUS lim_p2p_action_cnf(tpAniSirGlobal pMac, uint32_t txCompleteSuccess);
+
+/*------------------------------------------------------------------
+ *
+ * Below function is called if hdd requests a remain on channel.
+ *
+ *------------------------------------------------------------------*/
+static CDF_STATUS lim_send_hal_req_remain_on_chan_offload(tpAniSirGlobal pMac,
+ tSirRemainOnChnReq *
+ pRemOnChnReq)
+{
+ tSirScanOffloadReq *pScanOffloadReq;
+ tSirMsgQ msg;
+ tSirRetStatus rc = eSIR_SUCCESS;
+ uint8_t bssid[CDF_MAC_ADDR_SIZE] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ pScanOffloadReq = cdf_mem_malloc(sizeof(tSirScanOffloadReq));
+ if (NULL == pScanOffloadReq) {
+ lim_log(pMac, LOGE,
+ FL("Memory allocation failed for pScanOffloadReq"));
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ cdf_mem_zero(pScanOffloadReq, sizeof(tSirScanOffloadReq));
+
+ msg.type = WMA_START_SCAN_OFFLOAD_REQ;
+ msg.bodyptr = pScanOffloadReq;
+ msg.bodyval = 0;
+
+ cdf_mem_copy((uint8_t *) pScanOffloadReq->selfMacAddr,
+ (uint8_t *) pRemOnChnReq->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) pScanOffloadReq->bssId,
+ (uint8_t *) bssid, sizeof(tSirMacAddr));
+ pScanOffloadReq->scanType = eSIR_PASSIVE_SCAN;
+ pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_LISTEN;
+ pScanOffloadReq->minChannelTime = pRemOnChnReq->duration;
+ pScanOffloadReq->maxChannelTime = pRemOnChnReq->duration;
+ pScanOffloadReq->sessionId = pRemOnChnReq->sessionId;
+ pScanOffloadReq->channelList.numChannels = 1;
+ pScanOffloadReq->channelList.channelNumber[0] = pRemOnChnReq->chnNum;
+ pScanOffloadReq->scan_id = pRemOnChnReq->scan_id;
+
+ lim_log(pMac, LOG1,
+ FL("Req-rem-on-channel: duration %u, session %hu, chan %hu"),
+ pRemOnChnReq->duration, pRemOnChnReq->sessionId,
+ pRemOnChnReq->chnNum);
+
+ rc = wma_post_ctrl_msg(pMac, &msg);
+ if (rc != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure %u"),
+ rc);
+ cdf_mem_free(pScanOffloadReq);
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ return CDF_STATUS_SUCCESS;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Remain on channel req handler. Initiate the INIT_SCAN, CHN_CHANGE
+ * and SET_LINK Request from SME, chnNum and duration to remain on channel.
+ *
+ *------------------------------------------------------------------*/
+int lim_process_remain_on_chnl_req(tpAniSirGlobal pMac, uint32_t *pMsg)
+{
+ tSirRemainOnChnReq *msgbuff = (tSirRemainOnChnReq *) pMsg;
+ CDF_STATUS status;
+
+ pMac->lim.gpLimRemainOnChanReq = msgbuff;
+ status = lim_send_hal_req_remain_on_chan_offload(pMac, msgbuff);
+ if (status != CDF_STATUS_SUCCESS) {
+ /* Post the meessage to Sme */
+ lim_send_sme_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
+ status, msgbuff->sessionId, msgbuff->scan_id);
+ cdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
+ pMac->lim.gpLimRemainOnChanReq = NULL;
+ }
+ return false;
+}
+
+/*------------------------------------------------------------------
+ *
+ * lim Insert NOA timer timeout callback - when timer fires, deactivate it and send
+ * scan rsp to csr/hdd
+ *
+ *------------------------------------------------------------------*/
+void lim_process_insert_single_shot_noa_timeout(tpAniSirGlobal pMac)
+{
+ /* timeout means start NOA did not arrive; we need to deactivate and change the timer for
+ * future activations
+ */
+ lim_deactivate_and_change_timer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER);
+
+ /* Even if insert NOA timedout, go ahead and process/send stored SME request */
+ lim_process_regd_defd_sme_req_after_noa_start(pMac);
+
+ return;
+}
+
+/*-----------------------------------------------------------------
+ * lim Insert Timer callback function to check active DFS channels
+ * and convert them to passive channels if there was no
+ * beacon/proberesp for MAX_TIME_TO_BE_ACTIVE_CHANNEL time
+ *------------------------------------------------------------------*/
+void lim_convert_active_channel_to_passive_channel(tpAniSirGlobal pMac)
+{
+ uint32_t currentTime;
+ uint32_t lastTime = 0;
+ uint32_t timeDiff;
+ uint8_t i;
+ currentTime = cdf_mc_timer_get_system_time();
+ for (i = 1; i < SIR_MAX_24G_5G_CHANNEL_RANGE; i++) {
+ if ((pMac->lim.dfschannelList.timeStamp[i]) != 0) {
+ lastTime = pMac->lim.dfschannelList.timeStamp[i];
+ if (currentTime >= lastTime) {
+ timeDiff = (currentTime - lastTime);
+ } else {
+ timeDiff =
+ (0xFFFFFFFF - lastTime) + currentTime;
+ }
+
+ if (timeDiff >= MAX_TIME_TO_BE_ACTIVE_CHANNEL) {
+ lim_covert_channel_scan_type(pMac, i, false);
+ pMac->lim.dfschannelList.timeStamp[i] = 0;
+ }
+ }
+ }
+ /* lastTime is zero if there is no DFS active channels in the list.
+ * If this is non zero then we have active DFS channels so restart the timer.
+ */
+ if (lastTime != 0) {
+ if (tx_timer_activate
+ (&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer)
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Could not activate Active to Passive Channel timer"));
+ }
+ }
+
+ return;
+
+}
+
+/**
+ * lim_process_remain_on_chn_timeout() - ROC timeout handler
+ *
+ * @mac_ctx: MAC context
+ *
+ * limchannelchange callback, on success channel change, set the
+ * link_state to LISTEN
+ *
+ * Return: NULL
+ */
+void lim_process_remain_on_chn_timeout(tpAniSirGlobal mac_ctx)
+{
+ tpPESession session;
+ tSirMacAddr null_bssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ TX_TIMER *roc_timer;
+
+ roc_timer = &mac_ctx->lim.limTimers.gLimRemainOnChannelTimer;
+ /*
+ * Timer might get extended while Sending Action Frame
+ * In that case don't process Channel Timeout
+ */
+ if (tx_timer_running(roc_timer)) {
+ lim_log(mac_ctx, LOGE,
+ FL("already timer is running and not processing "));
+ return;
+ }
+
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_REMAIN_CHN_TIMER);
+ if (NULL == mac_ctx->lim.gpLimRemainOnChanReq) {
+ lim_log(mac_ctx, LOGE, FL("No Remain on channel pending"));
+ return;
+ }
+
+ /* get the previous valid LINK state */
+ if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE, null_bssid,
+ mac_ctx->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS)
+ {
+ lim_log(mac_ctx, LOGE, FL("Unable to change link state"));
+ return;
+ }
+
+ if (mac_ctx->lim.gLimMlmState != eLIM_MLM_P2P_LISTEN_STATE) {
+ lim_remain_on_chn_rsp(mac_ctx, CDF_STATUS_SUCCESS, NULL);
+ } else {
+ session = pe_find_session_by_session_id(mac_ctx,
+ roc_timer->sessionId);
+ /* get the session */
+ if (session == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session Does not exist sessionID %d"),
+ roc_timer->sessionId);
+ goto error;
+ }
+
+ lim_exit_remain_on_channel(mac_ctx, CDF_STATUS_SUCCESS, NULL,
+ session);
+ return;
+error:
+ lim_remain_on_chn_rsp(mac_ctx, CDF_STATUS_E_FAILURE, NULL);
+ }
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * limchannelchange callback, on success channel change, set the link_state
+ * to LISTEN
+ *
+ *------------------------------------------------------------------*/
+
+void lim_exit_remain_on_channel(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry)
+{
+
+ if (status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, "Remain on Channel Failed");)
+ goto error;
+ }
+ /* Set the resume channel to Any valid channel (invalid). */
+ /* This will instruct HAL to set it to any previous valid channel. */
+ pe_set_resume_channel(pMac, 0, 0);
+ lim_remain_on_chn_rsp(pMac, CDF_STATUS_SUCCESS, NULL);
+ return;
+error:
+ lim_remain_on_chn_rsp(pMac, CDF_STATUS_E_FAILURE, NULL);
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Send remain on channel respone: Success/ Failure
+ *
+ *------------------------------------------------------------------*/
+void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, CDF_STATUS status, uint32_t *data)
+{
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+ tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq;
+ tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ if (NULL == MsgRemainonChannel) {
+ PELOGE(lim_log(pMac, LOGP,
+ "%s: No Pointer for Remain on Channel Req",
+ __func__);
+ )
+ return;
+ }
+ /* Incase of the Remain on Channel Failure Case */
+ /* Cleanup Everything */
+ if (CDF_STATUS_E_FAILURE == status) {
+ /* Deactivate Remain on Channel Timer */
+ lim_deactivate_and_change_timer(pMac, eLIM_REMAIN_CHN_TIMER);
+
+ /* Set the Link State to Idle */
+ /* get the previous valid LINK state */
+ if (lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ pMac->lim.gSelfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, "Unable to change link state");
+ }
+
+ pMac->lim.gLimSystemInScanLearnMode = 0;
+ pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ }
+
+ /* delete the session */
+ if ((psessionEntry = pe_find_session_by_bssid(pMac,
+ MsgRemainonChannel->
+ selfMacAddr,
+ &sessionId)) != NULL) {
+ if (LIM_IS_P2P_DEVICE_ROLE(psessionEntry)) {
+ pe_delete_session(pMac, psessionEntry);
+ }
+ }
+
+ /* Post the meessage to Sme */
+ lim_send_sme_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
+ status,
+ MsgRemainonChannel->sessionId, 0);
+
+ cdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
+ pMac->lim.gpLimRemainOnChanReq = NULL;
+
+ pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState;
+
+ /* If remain on channel timer expired and action frame is pending then
+ * indicaiton confirmation with status failure */
+ if (pMac->lim.mgmtFrameSessionId != 0xff) {
+ lim_p2p_action_cnf(pMac, 0);
+ }
+
+ return;
+}
+
+/*------------------------------------------------------------------
+ *
+ * Indicate the Mgmt Frame received to SME to HDD callback
+ * handle Probe_req/Action frame currently
+ *
+ *------------------------------------------------------------------*/
+void lim_send_sme_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
+ uint8_t *frame, uint32_t frameLen,
+ uint16_t sessionId, uint32_t rxChannel,
+ tpPESession psessionEntry, int8_t rxRssi)
+{
+ tSirMsgQ mmhMsg;
+ tpSirSmeMgmtFrameInd pSirSmeMgmtFrame = NULL;
+ uint16_t length;
+
+ length = sizeof(tSirSmeMgmtFrameInd) + frameLen;
+
+ pSirSmeMgmtFrame = cdf_mem_malloc(length);
+ if (NULL == pSirSmeMgmtFrame) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_LISTEN_RSP"));
+ return;
+ }
+ cdf_mem_set((void *)pSirSmeMgmtFrame, length, 0);
+
+ pSirSmeMgmtFrame->mesgType = eWNI_SME_MGMT_FRM_IND;
+ pSirSmeMgmtFrame->mesgLen = length;
+ pSirSmeMgmtFrame->sessionId = sessionId;
+ pSirSmeMgmtFrame->frameType = frameType;
+ pSirSmeMgmtFrame->rxRssi = rxRssi;
+ pSirSmeMgmtFrame->rxChan = rxChannel;
+
+ cdf_mem_zero(pSirSmeMgmtFrame->frameBuf, frameLen);
+ cdf_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
+
+ mmhMsg.type = eWNI_SME_MGMT_FRM_IND;
+ mmhMsg.bodyptr = pSirSmeMgmtFrame;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+CDF_STATUS lim_p2p_action_cnf(tpAniSirGlobal pMac, uint32_t txCompleteSuccess)
+{
+ if (pMac->lim.mgmtFrameSessionId != 0xff) {
+ /* The session entry might be invalid(0xff) action confirmation received after
+ * remain on channel timer expired */
+ lim_send_sme_rsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ (txCompleteSuccess ? eSIR_SME_SUCCESS :
+ eSIR_SME_SEND_ACTION_FAIL),
+ pMac->lim.mgmtFrameSessionId, 0);
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ }
+
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_tx_action_frame() - Handles action frame transmission request
+ * @mac_ctx: Pointer to mac context
+ * @mb_msg: message sent from SME
+ * @msg_len: Message length
+ * @packet: network buffer for TX
+ * @frame: frame buffer
+ *
+ * This function processes the action frame transmission request and
+ * posts message to WMA.
+ *
+ * Return: NULL
+ */
+static void lim_tx_action_frame(tpAniSirGlobal mac_ctx,
+ tSirMbMsgP2p *mb_msg, uint32_t msg_len, void *packet, uint8_t *frame)
+{
+ uint8_t tx_flag = 0;
+ tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+ CDF_STATUS cdf_status;
+ uint8_t sme_session_id = 0;
+ uint16_t channel_freq;
+
+ sme_session_id = mb_msg->sessionId;
+ channel_freq = mb_msg->channel_freq;
+ /*
+ * Use BD rate 2 for all P2P related frames. As these frames
+ * need to go at OFDM rates. And BD rate2 we configured at 6Mbps.
+ */
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+ if ((SIR_MAC_MGMT_PROBE_RSP == fc->subType) ||
+ (mb_msg->noack)) {
+ cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) msg_len,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS, 7, lim_tx_complete,
+ frame, tx_flag, sme_session_id,
+ channel_freq);
+
+ if (!mb_msg->noack)
+ lim_send_sme_rsp(mac_ctx,
+ eWNI_SME_ACTION_FRAME_SEND_CNF,
+ cdf_status, mb_msg->sessionId, 0);
+ mac_ctx->lim.mgmtFrameSessionId = 0xff;
+ } else {
+ mac_ctx->lim.mgmtFrameSessionId = mb_msg->sessionId;
+ cdf_status =
+ wma_tx_frameWithTxComplete(mac_ctx, packet,
+ (uint16_t) msg_len,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS, 7, lim_tx_complete,
+ frame, lim_p2p_action_cnf, tx_flag,
+ sme_session_id, false,
+ channel_freq);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("couldn't send action frame"));
+ lim_send_sme_rsp(mac_ctx,
+ eWNI_SME_ACTION_FRAME_SEND_CNF,
+ cdf_status, mb_msg->sessionId, 0);
+ mac_ctx->lim.mgmtFrameSessionId = 0xff;
+ } else {
+ mac_ctx->lim.mgmtFrameSessionId = mb_msg->sessionId;
+ lim_log(mac_ctx, LOG2,
+ FL("lim.actionFrameSessionId = %u"),
+ mac_ctx->lim.mgmtFrameSessionId);
+ }
+ }
+
+ return;
+}
+
+/**
+ * lim_send_p2p_action_frame() - Process action frame request
+ * @mac_ctx: Pointer to mac context
+ * @msg: message sent from SME
+ *
+ * This function processes the action frame request sent from the
+ * SME and generates the ACTION frame.
+ *
+ * Return: NULL
+ */
+void lim_send_p2p_action_frame(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg)
+{
+ tSirMbMsgP2p *mb_msg = (tSirMbMsgP2p *) msg->bodyptr;
+ uint32_t msg_len;
+ uint8_t *frame;
+ void *packet;
+ CDF_STATUS cdf_status;
+ tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
+ uint8_t noa_len = 0;
+ uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + (2 * SIR_P2P_IE_HEADER_LEN)];
+ uint8_t orig_len = 0;
+ uint8_t session_id = 0;
+ uint8_t *p2p_ie = NULL;
+ tpPESession session_entry = NULL;
+ uint8_t *presence_noa_attr = NULL;
+ uint8_t *tmp_p2p_ie = NULL;
+ uint16_t remain_len = 0;
+ uint8_t sme_session_id = 0;
+#ifdef WLAN_FEATURE_11W
+ tpSirMacMgmtHdr mac_hdr;
+ tpSirMacActionFrameHdr action_hdr;
+#endif
+
+ msg_len = mb_msg->msgLen - sizeof(tSirMbMsgP2p);
+ lim_log(mac_ctx, LOG1, FL("sending fc->type=%d fc->subType=%d"),
+ fc->type, fc->subType);
+
+ if ((!mac_ctx->lim.gpLimRemainOnChanReq) && (0 != mb_msg->wait)) {
+ lim_log(mac_ctx, LOGE,
+ FL("RemainOnChannel is not running\n"));
+ lim_send_sme_rsp(mac_ctx, eWNI_SME_ACTION_FRAME_SEND_CNF,
+ CDF_STATUS_E_FAILURE, mb_msg->sessionId, 0);
+ return;
+ }
+ sme_session_id = mb_msg->sessionId;
+
+ if ((SIR_MAC_MGMT_FRAME == fc->type) &&
+ (SIR_MAC_MGMT_PROBE_RSP == fc->subType)) {
+ /* get proper offset for Probe RSP */
+ p2p_ie = limGetP2pIEPtr(mac_ctx,
+ (uint8_t *) mb_msg->data +
+ PROBE_RSP_IE_OFFSET,
+ msg_len - PROBE_RSP_IE_OFFSET);
+ while ((NULL != p2p_ie)
+ && (SIR_MAC_MAX_IE_LENGTH == p2p_ie[1])) {
+ remain_len =
+ msg_len - (p2p_ie -
+ (uint8_t *) mb_msg->data);
+ if (remain_len > 2) {
+ tmp_p2p_ie = limGetP2pIEPtr(mac_ctx,
+ p2p_ie + SIR_MAC_MAX_IE_LENGTH + 2,
+ remain_len);
+ }
+ if (tmp_p2p_ie) {
+ p2p_ie = tmp_p2p_ie;
+ tmp_p2p_ie = NULL;
+ } else {
+ break;
+ }
+ } /* end of while */
+ } else if ((SIR_MAC_MGMT_FRAME == fc->type) &&
+ (SIR_MAC_MGMT_ACTION == fc->subType) &&
+ (SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY ==
+ *((uint8_t *) mb_msg->data + ACTION_OFFSET))) {
+ tpSirMacP2PActionFrameHdr action_hdr =
+ (tpSirMacP2PActionFrameHdr) ((uint8_t *)
+ mb_msg->data + ACTION_OFFSET);
+ if (cdf_mem_compare(action_hdr->Oui, SIR_MAC_P2P_OUI,
+ SIR_MAC_P2P_OUI_SIZE) &&
+ (SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP ==
+ action_hdr->OuiSubType)) {
+
+ /* In case of Presence RSP response */
+ p2p_ie = limGetP2pIEPtr(mac_ctx,
+ (uint8_t *)mb_msg->data +
+ ACTION_OFFSET +
+ sizeof(tSirMacP2PActionFrameHdr),
+ (msg_len - ACTION_OFFSET
+ - sizeof(tSirMacP2PActionFrameHdr)));
+ if (NULL != p2p_ie) {
+ /* extract the presence of NoA attribute inside
+ * P2P IE */
+ presence_noa_attr = lim_get_ie_ptr_new(mac_ctx,
+ p2p_ie + SIR_P2P_IE_HEADER_LEN,
+ p2p_ie[1], SIR_P2P_NOA_ATTR, TWO_BYTE);
+ }
+ }
+ }
+
+ if ((SIR_MAC_MGMT_FRAME == fc->type) &&
+ (SIR_MAC_MGMT_PROBE_RSP == fc->subType ||
+ SIR_MAC_MGMT_ACTION == fc->subType) && p2p_ie != NULL) {
+ /* get NoA attribute stream P2P IE */
+ noa_len =
+ lim_get_noa_attr_stream(mac_ctx, noa_stream,
+ session_entry);
+ /* need to append NoA attribute in P2P IE */
+ if (noa_len > 0) {
+ orig_len = p2p_ie[1];
+ /* if Presence Rsp has NoAttr */
+ if (presence_noa_attr) {
+ uint16_t noa_len =
+ presence_noa_attr[1] |
+ (presence_noa_attr[2] << 8);
+ /*One byte for attribute, 2bytes for length */
+ orig_len -= (noa_len + 1 + 2);
+ /* remove those bytes to copy */
+ msg_len -= (noa_len + 1 + 2);
+ /* remove NoA from original Len */
+ p2p_ie[1] = orig_len;
+ }
+ if ((p2p_ie[1] + (uint16_t) noa_len) >
+ SIR_MAC_MAX_IE_LENGTH) {
+ /*
+ * Form the new NoA Byte array in multiple
+ * P2P IEs
+ */
+ noa_len =
+ lim_get_noa_attr_stream_in_mult_p2p_ies
+ (mac_ctx, noa_stream, noa_len,
+ ((p2p_ie[1] + (uint16_t)noa_len)
+ - SIR_MAC_MAX_IE_LENGTH));
+ p2p_ie[1] = SIR_MAC_MAX_IE_LENGTH;
+ } else {
+ /* increment the length of P2P IE */
+ p2p_ie[1] += noa_len;
+ }
+ msg_len += noa_len;
+ lim_log(mac_ctx, LOGE,
+ FL("noa_len=%d orig_len=%d p2p_ie=%p"
+ " msg_len=%d nBytesToCopy=%zu "),
+ noa_len, orig_len, p2p_ie, msg_len,
+ ((p2p_ie + orig_len + 2) -
+ (uint8_t *) mb_msg->data));
+ }
+ }
+
+ if ((SIR_MAC_MGMT_PROBE_RSP == fc->subType ||
+ SIR_MAC_MGMT_ACTION == fc->subType))
+ lim_set_ht_caps(mac_ctx, session_entry,
+ (uint8_t *) mb_msg->data + PROBE_RSP_IE_OFFSET,
+ msg_len - PROBE_RSP_IE_OFFSET);
+
+ /* Ok-- try to allocate some memory: */
+ cdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame,
+ (void **)&packet);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to allocate %d bytes for a Probe Request."),
+ msg_len);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(frame, msg_len, 0);
+
+ /*
+ * Add sequence number to action frames
+ * Frames are handed over in .11 format by supplicant already
+ */
+ lim_populate_p2p_mac_header(mac_ctx, (uint8_t *) mb_msg->data);
+
+ if ((noa_len > 0)
+ && (noa_len < (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN))) {
+ /* Add 2 bytes for length and Arribute field */
+ uint32_t nBytesToCopy = ((p2p_ie + orig_len + 2) -
+ (uint8_t *) mb_msg->data);
+ cdf_mem_copy(frame, mb_msg->data, nBytesToCopy);
+ cdf_mem_copy((frame + nBytesToCopy), noa_stream, noa_len);
+ cdf_mem_copy((frame + nBytesToCopy + noa_len),
+ mb_msg->data + nBytesToCopy,
+ msg_len - nBytesToCopy - noa_len);
+
+ } else {
+ cdf_mem_copy(frame, mb_msg->data, msg_len);
+ }
+
+#ifdef WLAN_FEATURE_11W
+ action_hdr = (tpSirMacActionFrameHdr) (frame + sizeof(tSirMacMgmtHdr));
+
+ /*
+ * Setting Protected bit for SA_QUERY Action Frame
+ * This has to be based on the current Connection with the
+ * station lim_set_protected_bit API will set the protected bit
+ * if PMF
+ */
+ if ((SIR_MAC_MGMT_ACTION == fc->subType) &&
+ (SIR_MAC_ACTION_SA_QUERY == action_hdr->category)) {
+ mac_hdr = (tpSirMacMgmtHdr) frame;
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ (uint8_t *) mb_msg->data + BSSID_OFFSET,
+ &session_id);
+
+ /*
+ * Check for session corresponding to ADDR2 ss supplicant
+ * is filling ADDR2 with BSSID
+ */
+ if (NULL == session_entry) {
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ (uint8_t *) mb_msg->data + ADDR2_OFFSET,
+ &session_id);
+ }
+
+ if (NULL != session_entry) {
+ lim_set_protected_bit(mac_ctx, session_entry,
+ mac_hdr->da, mac_hdr);
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("Dropping SA Query - PE Session not found"));
+ lim_send_sme_rsp(mac_ctx,
+ eWNI_SME_ACTION_FRAME_SEND_CNF,
+ CDF_STATUS_E_FAILURE, mb_msg->sessionId, 0);
+ cds_packet_free((void *)packet);
+ return;
+ }
+
+ /*
+ * If wep bit is not set in MAC header then we are trying to
+ * send SA Query via non PMF connection. Drop the packet.
+ */
+ if (0 == mac_hdr->fc.wep) {
+ lim_log(mac_ctx, LOGE,
+ FL("Dropping SA Query due to non PMF conne."));
+ lim_send_sme_rsp(mac_ctx,
+ eWNI_SME_ACTION_FRAME_SEND_CNF,
+ CDF_STATUS_E_FAILURE, mb_msg->sessionId, 0);
+ cds_packet_free((void *)packet);
+ return;
+ }
+ }
+#endif
+ lim_tx_action_frame(mac_ctx, mb_msg, msg_len, packet, frame);
+ return;
+}
+
+void lim_abort_remain_on_chan(tpAniSirGlobal pMac, uint8_t sessionId,
+ uint32_t scan_id)
+{
+ lim_process_abort_scan_ind(pMac, sessionId, scan_id);
+}
+
+/* Power Save Related Functions */
+tSirRetStatus __lim_process_sme_no_a_update(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpP2pPsConfig pNoA;
+ tpP2pPsParams pMsgNoA;
+ tSirMsgQ msg;
+
+ pNoA = (tpP2pPsConfig) pMsgBuf;
+
+ pMsgNoA = cdf_mem_malloc(sizeof(tP2pPsConfig));
+ if (NULL == pMsgNoA) {
+ lim_log(pMac, LOGE,
+ FL("Unable to allocate memory during NoA Update"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set((uint8_t *) pMsgNoA, sizeof(tP2pPsConfig), 0);
+ pMsgNoA->opp_ps = pNoA->opp_ps;
+ pMsgNoA->ctWindow = pNoA->ctWindow;
+ pMsgNoA->duration = pNoA->duration;
+ pMsgNoA->interval = pNoA->interval;
+ pMsgNoA->count = pNoA->count;
+ pMsgNoA->single_noa_duration = pNoA->single_noa_duration;
+ pMsgNoA->psSelection = pNoA->psSelection;
+ pMsgNoA->sessionId = pNoA->sessionid;
+
+ msg.type = WMA_SET_P2P_GO_NOA_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = pMsgNoA;
+ msg.bodyval = 0;
+
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+ lim_log(pMac, LOGE, FL("halPostMsgApi failed"));
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+} /*** end __limProcessSmeGoNegReq() ***/
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
new file mode 100644
index 0000000..c77ae53
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -0,0 +1,2093 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_process_action_frame.cc contains the code
+ * for processing Action Frame.
+ * Author: Michael Lui
+ * Date: 05/23/03
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "parser_api.h"
+#include "lim_admit_control.h"
+#include "wmm_apsd.h"
+#include "lim_send_messages.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+#include "lim_session_utils.h"
+
+#include "wma_types.h"
+
+
+#define BA_DEFAULT_TX_BUFFER_SIZE 64
+
+/* Note: The test passes if the STAUT stops sending any frames, and no further
+ frames are transmitted on this channel by the station when the AP has sent
+ the last 6 beacons, with the channel switch information elements as seen
+ with the sniffer.*/
+#define SIR_CHANSW_TX_STOP_MAX_COUNT 6
+/**-----------------------------------------------------------------
+ \fn lim_stop_tx_and_switch_channel
+ \brief Stops the transmission if channel switch mode is silent and
+ starts the channel switch timer.
+
+ \param pMac
+ \return NONE
+ -----------------------------------------------------------------*/
+void lim_stop_tx_and_switch_channel(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+ tpPESession psessionEntry;
+
+ psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE, FL("Session %d not active"), sessionId);
+ return;
+ }
+
+ PELOG1(lim_log(pMac, LOG1, FL("Channel switch Mode == %d"),
+ psessionEntry->gLimChannelSwitch.switchMode);
+ )
+
+ if (psessionEntry->gLimChannelSwitch.switchMode ==
+ eSIR_CHANSW_MODE_SILENT
+ || psessionEntry->gLimChannelSwitch.switchCount <=
+ SIR_CHANSW_TX_STOP_MAX_COUNT) {
+ /* Freeze the transmission */
+ lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_STOP_TX);
+
+ } else {
+ /* Resume the transmission */
+ lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+ }
+
+ pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId;
+ /* change the channel immediatly only if
+ * the channel switch count is 0
+ */
+ if (psessionEntry->gLimChannelSwitch.switchCount == 0) {
+ lim_process_channel_switch_timeout(pMac);
+ return;
+ }
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId,
+ eLIM_CHANNEL_SWITCH_TIMER));
+
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
+ TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("tx_timer_activate failed"));
+ }
+ return;
+}
+
+/**------------------------------------------------------------
+ \fn lim_start_channel_switch
+ \brief Switches the channel if switch count == 0, otherwise
+ starts the timer for channel switch and stops BG scan
+ and heartbeat timer tempororily.
+
+ \param pMac
+ \param psessionEntry
+ \return NONE
+ ------------------------------------------------------------*/
+tSirRetStatus lim_start_channel_switch(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ PELOG1(lim_log(pMac, LOG1, FL("Starting the channel switch"));)
+
+ /*If channel switch is already running and it is on a different session, just return */
+ /*This need to be removed for MCC */
+ if ((lim_is_chan_switch_running(pMac) &&
+ psessionEntry->gLimSpecMgmt.dot11hChanSwState !=
+ eLIM_11H_CHANSW_RUNNING) || psessionEntry->csaOffloadEnable) {
+ lim_log(pMac, LOGW, FL("Ignoring channel switch on session %d"),
+ psessionEntry->peSessionId);
+ return eSIR_SUCCESS;
+ }
+
+ /* Deactivate and change reconfigure the timeout value */
+ /* lim_deactivate_and_change_timer(pMac, eLIM_CHANNEL_SWITCH_TIMER); */
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId,
+ eLIM_CHANNEL_SWITCH_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("tx_timer_deactivate failed!"));
+ return eSIR_FAILURE;
+ }
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer,
+ psessionEntry->gLimChannelSwitch.switchTimeoutValue,
+ 0) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("tx_timer_change failed "));
+ return eSIR_FAILURE;
+ }
+
+ /* Follow the channel switch, forget about the previous quiet. */
+ /* If quiet is running, chance is there to resume tx on its timeout. */
+ /* so stop timer for a safer side. */
+ if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ psessionEntry->peSessionId, eLIM_QUIET_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) !=
+ TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("tx_timer_deactivate failed"));
+ return eSIR_FAILURE;
+ }
+ } else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("tx_timer_deactivate failed"));
+ return eSIR_FAILURE;
+ }
+ }
+ psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+ /* Prepare for 11h channel switch */
+ lim_prepare_for11h_channel_switch(pMac, psessionEntry);
+
+ /** Dont add any more statements here as we posted finish scan request
+ * to HAL, wait till we get the response
+ */
+ return eSIR_SUCCESS;
+}
+
+/**
+ * __lim_process_channel_switch_action_frame() - to process channel switch
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to packet info structure
+ *
+ * This routine will be called to process channel switch action frame
+ *
+ * Return: None
+ */
+
+static void __lim_process_channel_switch_action_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+ tpSirMacMgmtHdr mac_hdr;
+ uint8_t *body_ptr;
+ tDot11fChannelSwitch *chnl_switch_frame;
+ uint16_t bcn_period;
+ uint32_t val, frame_len, status;
+ tLimChannelSwitchInfo *ch_switch_params;
+ struct sDot11fIEWiderBWChanSwitchAnn *wbw_chnlswitch_ie = NULL;
+ struct sLimWiderBWChannelSwitch *lim_wbw_chnlswitch_info = NULL;
+ struct sDot11fIEsec_chan_offset_ele *sec_chnl_offset = NULL;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ PELOG3(lim_log(mac_ctx, LOG3,
+ FL("Received Channel switch action frame"));)
+ if (!session->lim11hEnable)
+ return;
+
+ chnl_switch_frame = cdf_mem_malloc(sizeof(*chnl_switch_frame));
+ if (NULL == chnl_switch_frame) {
+ lim_log(mac_ctx, LOGE, FL("AllocateMemory failed"));
+ return;
+ }
+
+ /* Unpack channel switch frame */
+ status = dot11f_unpack_channel_switch(mac_ctx, body_ptr, frame_len,
+ chnl_switch_frame);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to unpack and parse (0x%08x, %d bytes)"),
+ status, frame_len);
+ cdf_mem_free(chnl_switch_frame);
+ return;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("warning: unpack 11h-CHANSW Req(0x%08x, %d bytes)"),
+ status, frame_len);
+ }
+
+ if (!(cdf_mem_compare((uint8_t *) &session->bssId,
+ (uint8_t *) &mac_hdr->sa, sizeof(tSirMacAddr)))) {
+ lim_log(mac_ctx, LOG1,
+ FL("Rcvd action frame not from our BSS, dropping..."));
+ cdf_mem_free(chnl_switch_frame);
+ return;
+ }
+ /* copy the beacon interval from session */
+ val = session->beaconParams.beaconInterval;
+ ch_switch_params = &session->gLimChannelSwitch;
+ bcn_period = (uint16_t)val;
+ ch_switch_params->primaryChannel =
+ chnl_switch_frame->ChanSwitchAnn.newChannel;
+ ch_switch_params->switchCount =
+ chnl_switch_frame->ChanSwitchAnn.switchCount;
+ ch_switch_params->switchTimeoutValue =
+ SYS_MS_TO_TICKS(bcn_period) *
+ session->gLimChannelSwitch.switchCount;
+ ch_switch_params->switchMode =
+ chnl_switch_frame->ChanSwitchAnn.switchMode;
+
+ /* Only primary channel switch element is present */
+ ch_switch_params->state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ ch_switch_params->ch_width = CH_WIDTH_20MHZ;
+
+ if (chnl_switch_frame->WiderBWChanSwitchAnn.present
+ && session->vhtCapability) {
+ wbw_chnlswitch_ie = &chnl_switch_frame->WiderBWChanSwitchAnn;
+ session->gLimWiderBWChannelSwitch.newChanWidth =
+ wbw_chnlswitch_ie->newChanWidth;
+ session->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
+ wbw_chnlswitch_ie->newCenterChanFreq0;
+ session->gLimWiderBWChannelSwitch.newCenterChanFreq1 =
+ wbw_chnlswitch_ie->newCenterChanFreq1;
+ }
+ lim_log(mac_ctx, LOG3,
+ FL("Rcv Chnl Swtch Frame: Timeout in %d ticks"),
+ session->gLimChannelSwitch.switchTimeoutValue);
+ if (session->htSupportedChannelWidthSet) {
+ sec_chnl_offset = &chnl_switch_frame->sec_chan_offset_ele;
+ if (sec_chnl_offset->secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
+ ch_switch_params->state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+ ch_switch_params->ch_center_freq_seg0 =
+ ch_switch_params->primaryChannel + 2;
+ } else if (sec_chnl_offset->secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
+ ch_switch_params->state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+ ch_switch_params->ch_center_freq_seg0 =
+ ch_switch_params->primaryChannel - 2;
+
+ }
+ if (session->vhtCapability &&
+ chnl_switch_frame->WiderBWChanSwitchAnn.present) {
+ wbw_chnlswitch_ie =
+ &chnl_switch_frame->WiderBWChanSwitchAnn;
+ ch_switch_params->ch_width =
+ wbw_chnlswitch_ie->newChanWidth + 1;
+ lim_wbw_chnlswitch_info =
+ &session->gLimWiderBWChannelSwitch;
+ ch_switch_params->ch_center_freq_seg0 =
+ lim_wbw_chnlswitch_info->newCenterChanFreq0;
+ ch_switch_params->ch_center_freq_seg1 =
+ lim_wbw_chnlswitch_info->newCenterChanFreq1;
+
+ }
+ }
+
+ if (CH_WIDTH_20MHZ == ch_switch_params->ch_width) {
+ session->htSupportedChannelWidthSet =
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ session->htRecommendedTxWidthSet =
+ session->htSupportedChannelWidthSet;
+ }
+
+ if (eSIR_SUCCESS != lim_start_channel_switch(mac_ctx, session))
+ lim_log(mac_ctx, LOG1,
+ FL("Could not start channel switch"));
+
+ cdf_mem_free(chnl_switch_frame);
+ return;
+}
+
+#ifdef WLAN_FEATURE_11AC
+/**
+ * __lim_process_operating_mode_action_frame() - To process op mode frames
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: pointer to received packet info
+ * @session: pointer to session
+ *
+ * This routine is called to process operating mode action frames
+ *
+ * Return: None
+ */
+static void __lim_process_operating_mode_action_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+
+ tpSirMacMgmtHdr mac_hdr;
+ uint8_t *body_ptr;
+ tDot11fOperatingMode *operating_mode_frm;
+ uint32_t frame_len;
+ uint32_t status;
+ tpDphHashNode sta_ptr;
+ uint16_t aid;
+ uint8_t oper_mode;
+ uint8_t cb_mode;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ lim_log(mac_ctx, LOG1,
+ FL("Received Operating Mode action frame"));
+ if (RF_CHAN_14 >= session->currentOperChannel)
+ cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
+ else
+ cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
+ /* Do not update the channel bonding mode if channel bonding
+ * mode is disabled in INI.
+ */
+ if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) {
+ lim_log(mac_ctx, LOGW, FL("channel bonding disabled"));
+ return;
+ }
+ operating_mode_frm = cdf_mem_malloc(sizeof(*operating_mode_frm));
+ if (NULL == operating_mode_frm) {
+ lim_log(mac_ctx, LOGE, FL("AllocateMemory failed"));
+ return;
+ }
+ /* Unpack channel switch frame */
+ status = dot11f_unpack_operating_mode(mac_ctx, body_ptr, frame_len,
+ operating_mode_frm);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to unpack and parse (0x%08x, %d bytes)"),
+ status, frame_len);
+ cdf_mem_free(operating_mode_frm);
+ return;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("warnings while unpacking (0x%08x, %d bytes):"),
+ status, frame_len);
+ }
+ sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+ &session->dph.dphHashTable);
+ if (sta_ptr->htSupportedChannelWidthSet) {
+ if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ <
+ sta_ptr->vhtSupportedChannelWidthSet)
+ oper_mode = eHT_CHANNEL_WIDTH_160MHZ;
+ else
+ oper_mode = sta_ptr->vhtSupportedChannelWidthSet + 1;
+ } else {
+ oper_mode = eHT_CHANNEL_WIDTH_20MHZ;
+ }
+ if (oper_mode != operating_mode_frm->OperatingMode.chanWidth) {
+ lim_log(mac_ctx, LOGE,
+ FL(" received Chanwidth %d, staIdx = %d"),
+ (operating_mode_frm->OperatingMode.chanWidth),
+ sta_ptr->staIndex);
+
+ lim_log(mac_ctx, LOGE,
+ FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"),
+ mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
+ mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);
+
+ if (operating_mode_frm->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_160MHZ) {
+ sta_ptr->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+ sta_ptr->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ } else if (operating_mode_frm->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_80MHZ) {
+ sta_ptr->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+ sta_ptr->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ } else if (operating_mode_frm->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_40MHZ) {
+ sta_ptr->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ sta_ptr->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ } else if (operating_mode_frm->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_20MHZ) {
+ sta_ptr->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ sta_ptr->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_20MHZ;
+ }
+ lim_check_vht_op_mode_change(mac_ctx, session,
+ operating_mode_frm->OperatingMode.chanWidth,
+ sta_ptr->staIndex, mac_hdr->sa);
+ }
+
+ if (sta_ptr->vhtSupportedRxNss !=
+ (operating_mode_frm->OperatingMode.rxNSS + 1)) {
+ sta_ptr->vhtSupportedRxNss =
+ operating_mode_frm->OperatingMode.rxNSS + 1;
+ lim_set_nss_change(mac_ctx, session, sta_ptr->vhtSupportedRxNss,
+ sta_ptr->staIndex, mac_hdr->sa);
+ }
+ cdf_mem_free(operating_mode_frm);
+ return;
+}
+
+/**
+ * __lim_process_gid_management_action_frame() - To process group-id mgmt frames
+ * @mac_ctx: Pointer to mac context
+ * @rx_pkt_info: Rx packet info
+ * @session: pointer to session
+ *
+ * This routine will be called to process group id management frames
+ *
+ * Return: none
+ */
+static void __lim_process_gid_management_action_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+
+ uint8_t *body_ptr;
+ uint16_t aid;
+ uint32_t frame_len, status, membership = 0, usr_position = 0;
+ uint32_t *mem_lower, *mem_upper, *mem_cur;
+ tpSirMacMgmtHdr mac_hdr;
+ tDot11fVHTGidManagementActionFrame *gid_mgmt_frame;
+ tpDphHashNode sta_ptr;
+ struct sDot11fFfVhtMembershipStatusArray *vht_member_status = NULL;
+ struct sDot11fFfVhtUserPositionArray *vht_user_position = NULL;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ lim_log(mac_ctx, LOG3, FL("Received GID Management action frame"));
+ gid_mgmt_frame = cdf_mem_malloc(sizeof(*gid_mgmt_frame));
+ if (NULL == gid_mgmt_frame) {
+ lim_log(mac_ctx, LOGE, FL("AllocateMemory failed"));
+ return;
+ }
+
+ /* Unpack Gid Mangement Action frame */
+ status = dot11f_unpack_vht_gid_management_action_frame(mac_ctx,
+ body_ptr, frame_len, gid_mgmt_frame);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Fail to parse an Grp id frame (0x%08x, %d bytes):"),
+ status, frame_len);
+ cdf_mem_free(gid_mgmt_frame);
+ return;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("warnings while unpacking Grp id frm (0x%08x, %d bytes):"),
+ status, frame_len);
+ }
+ sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+ &session->dph.dphHashTable);
+ lim_log(mac_ctx, LOGE,
+ FL("received Gid Management Action Frame , staIdx = %d"),
+ sta_ptr->staIndex);
+
+ lim_log(mac_ctx, LOGE,
+ FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"),
+ mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
+ mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);
+ vht_member_status = &gid_mgmt_frame->VhtMembershipStatusArray;
+ mem_lower = (uint32_t *) vht_member_status->membershipStatusArray;
+ mem_upper = (uint32_t *) &vht_member_status->membershipStatusArray[4];
+
+ if (*mem_lower && *mem_upper) {
+ lim_log(mac_ctx, LOGE,
+ FL("rcved frame with mult group ID set, staIdx = %d"),
+ sta_ptr->staIndex);
+ goto out;
+ }
+ if (*mem_lower) {
+ mem_cur = mem_lower;
+ } else if (*mem_upper) {
+ mem_cur = mem_upper;
+ membership += sizeof(uint32_t);
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("rcved Gid frame with no group ID set, staIdx = %d"),
+ sta_ptr->staIndex);
+ goto out;
+ }
+ while (!(*mem_cur & 1)) {
+ *mem_cur >>= 1;
+ ++membership;
+ }
+ if (*mem_cur) {
+ lim_log(mac_ctx, LOGE,
+ FL("rcved frame with mult group ID set, staIdx = %d"),
+ sta_ptr->staIndex);
+ goto out;
+ }
+
+ /*Just read the last two bits */
+ vht_user_position = &gid_mgmt_frame->VhtUserPositionArray;
+ usr_position = vht_user_position->userPositionArray[membership] & 0x3;
+ lim_check_membership_user_position(mac_ctx, session, membership,
+ usr_position, sta_ptr->staIndex);
+out:
+ cdf_mem_free(gid_mgmt_frame);
+ return;
+}
+
+#endif
+
+static void
+__lim_process_add_ts_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+}
+
+/**
+ * __lim_process_add_ts_rsp() - To process add ts response frame
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: Received packet info
+ * @session: pointer to session
+ *
+ * This routine is to handle add ts response frame
+ *
+ * Return: none
+ */
+static void __lim_process_add_ts_rsp(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+ tSirAddtsRspInfo addts;
+ tSirRetStatus retval;
+ tpSirMacMgmtHdr mac_hdr;
+ tpDphHashNode sta_ptr;
+ uint16_t aid;
+ uint32_t frameLen;
+ uint8_t *body_ptr;
+ tpLimTspecInfo tspec_info;
+ uint8_t ac;
+ tpDphHashNode sta_ds_ptr = NULL;
+ uint8_t rsp_reqd = 1;
+ uint32_t cfg_len;
+ tSirMacAddr peer_macaddr;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ lim_log(mac_ctx, LOGW, "Recv AddTs Response");
+ if (LIM_IS_AP_ROLE(session) ||
+ LIM_IS_BT_AMP_AP_ROLE(session)) {
+ lim_log(mac_ctx, LOGW,
+ FL("AddTsRsp recvd at AP: ignoring"));
+ return;
+ }
+
+ sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+ &session->dph.dphHashTable);
+ if (sta_ptr == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Station context not found - ignoring AddTsRsp"));
+ return;
+ }
+
+ retval = sir_convert_addts_rsp2_struct(mac_ctx, body_ptr,
+ frameLen, &addts);
+ if (retval != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGW,
+ FL("AddTsRsp parsing failed (error %d)"), retval);
+ return;
+ }
+ /*
+ * don't have to check for qos/wme capabilities since we wouldn't have
+ * this flag set otherwise
+ */
+ if (!mac_ctx->lim.gLimAddtsSent) {
+ /* we never sent an addts request! */
+ lim_log(mac_ctx, LOGW,
+ FL("rx AddTsRsp but no req was ever sent-ignoring"));
+ return;
+ }
+
+ if (mac_ctx->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken) {
+ lim_log(mac_ctx, LOGW,
+ FL("token mismatch (got %d, exp %d) - ignoring"),
+ addts.dialogToken,
+ mac_ctx->lim.gLimAddtsReq.req.dialogToken);
+ return;
+ }
+
+ /*
+ * for successful addts reponse, try to add the classifier.
+ * if this fails for any reason, we should send a delts request to the
+ * ap for now, its ok not to send a delts since we are going to add
+ * support for multiple tclas soon and until then we won't send any
+ * addts requests with multiple tclas elements anyway.
+ * In case of addClassifier failure, we just let the addts timer run out
+ */
+ if (((addts.tspec.tsinfo.traffic.accessPolicy ==
+ SIR_MAC_ACCESSPOLICY_HCCA) ||
+ (addts.tspec.tsinfo.traffic.accessPolicy ==
+ SIR_MAC_ACCESSPOLICY_BOTH)) &&
+ (addts.status == eSIR_MAC_SUCCESS_STATUS)) {
+ /* add the classifier - this should always succeed */
+ if (addts.numTclas > 1) {
+ /* currently no support for multiple tclas elements */
+ lim_log(mac_ctx, LOGE,
+ FL("Sta %d: Too many Tclas (%d), 1 supported"),
+ aid, addts.numTclas);
+ return;
+ } else if (addts.numTclas == 1) {
+ lim_log(mac_ctx, LOGW,
+ FL("Response from STA %d: tsid %d, UP %d, OK!"),
+ aid, addts.tspec.tsinfo.traffic.tsid,
+ addts.tspec.tsinfo.traffic.userPrio);
+ }
+ }
+ lim_log(mac_ctx, LOGW, FL("Recv AddTsRsp: tsid %d, UP %d, status %d "),
+ addts.tspec.tsinfo.traffic.tsid,
+ addts.tspec.tsinfo.traffic.userPrio, addts.status);
+
+ /* deactivate the response timer */
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_ADDTS_RSP_TIMER);
+
+ if (addts.status != eSIR_MAC_SUCCESS_STATUS) {
+ lim_log(mac_ctx, LOGW,
+ FL("Recv AddTsRsp: tsid %d, UP %d, status %d "),
+ addts.tspec.tsinfo.traffic.tsid,
+ addts.tspec.tsinfo.traffic.userPrio, addts.status);
+ lim_send_sme_addts_rsp(mac_ctx, true, addts.status, session,
+ addts.tspec, session->smeSessionId,
+ session->transactionId);
+
+ /* clear the addts flag */
+ mac_ctx->lim.gLimAddtsSent = false;
+
+ return;
+ }
+#ifdef FEATURE_WLAN_ESE
+ if (addts.tsmPresent) {
+ lim_log(mac_ctx, LOGW, "TSM IE Present");
+ session->eseContext.tsm.tid =
+ addts.tspec.tsinfo.traffic.userPrio;
+ cdf_mem_copy(&session->eseContext.tsm.tsmInfo,
+ &addts.tsmIE, sizeof(tSirMacESETSMIE));
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ lim_send_sme_tsm_ie_ind(mac_ctx, session, addts.tsmIE.tsid,
+ addts.tsmIE.state,
+ addts.tsmIE.msmt_interval);
+#else
+ limActivateTSMStatsTimer(mac_ctx, session);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+ }
+#endif
+ /*
+ * Since AddTS response was successful, check for the PSB flag
+ * and directional flag inside the TS Info field.
+ * An AC is trigger enabled AC if the PSB subfield is set to 1
+ * in the uplink direction.
+ * An AC is delivery enabled AC if the PSB subfield is set to 1
+ * in the downlink direction.
+ * An AC is trigger and delivery enabled AC if the PSB subfield
+ * is set to 1 in the bi-direction field.
+ */
+ if (addts.tspec.tsinfo.traffic.psb == 1)
+ lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
+ &addts.tspec.tsinfo,
+ SET_UAPSD_MASK);
+ else
+ lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
+ &addts.tspec.tsinfo,
+ CLEAR_UAPSD_MASK);
+
+ /*
+ * ADDTS success, so AC is now admitted. We shall now use the default
+ * EDCA parameters as advertised by AP and send the updated EDCA params
+ * to HAL.
+ */
+ ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
+ if (addts.tspec.tsinfo.traffic.direction ==
+ SIR_MAC_DIRECTION_UPLINK) {
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
+ (1 << ac);
+ } else if (addts.tspec.tsinfo.traffic.direction ==
+ SIR_MAC_DIRECTION_DNLINK) {
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
+ (1 << ac);
+ } else if (addts.tspec.tsinfo.traffic.direction ==
+ SIR_MAC_DIRECTION_BIDIR) {
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
+ (1 << ac);
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
+ (1 << ac);
+ }
+ lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
+ session);
+ sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session->dph.dphHashTable);
+ if (sta_ds_ptr != NULL)
+ lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
+ sta_ds_ptr->bssId);
+ else
+ lim_log(mac_ctx, LOGE, FL("Self entry missing in Hash Table "));
+ sir_copy_mac_addr(peer_macaddr, session->bssId);
+ /* if schedule is not present then add TSPEC with svcInterval as 0. */
+ if (!addts.schedulePresent)
+ addts.schedule.svcInterval = 0;
+ if (eSIR_SUCCESS !=
+ lim_tspec_add(mac_ctx, sta_ptr->staAddr, sta_ptr->assocId,
+ &addts.tspec, addts.schedule.svcInterval, &tspec_info)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Adding entry in lim Tspec Table failed "));
+ lim_send_delts_req_action_frame(mac_ctx, peer_macaddr, rsp_reqd,
+ &addts.tspec.tsinfo,
+ &addts.tspec, session);
+ mac_ctx->lim.gLimAddtsSent = false;
+ return;
+ /*
+ * Error handling. send the response with error status.
+ * need to send DelTS to tear down the TSPEC status.
+ */
+ }
+ if ((addts.tspec.tsinfo.traffic.accessPolicy !=
+ SIR_MAC_ACCESSPOLICY_EDCA) ||
+ ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC))) {
+#ifdef FEATURE_WLAN_ESE
+ retval = lim_send_hal_msg_add_ts(mac_ctx,
+ sta_ptr->staIndex, tspec_info->idx,
+ addts.tspec, session->peSessionId,
+ addts.tsmIE.msmt_interval);
+#else
+ retval = lim_send_hal_msg_add_ts(mac_ctx,
+ sta_ptr->staIndex, tspec_info->idx,
+ addts.tspec, session->peSessionId);
+#endif
+ if (eSIR_SUCCESS != retval) {
+ lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId,
+ &addts.tspec.tsinfo, NULL, &tspec_info->idx);
+
+ /* Send DELTS action frame to AP */
+ cfg_len = sizeof(tSirMacAddr);
+ lim_send_delts_req_action_frame(mac_ctx, peer_macaddr,
+ rsp_reqd, &addts.tspec.tsinfo,
+ &addts.tspec, session);
+ lim_send_sme_addts_rsp(mac_ctx, true, retval,
+ session, addts.tspec,
+ session->smeSessionId,
+ session->transactionId);
+ mac_ctx->lim.gLimAddtsSent = false;
+ return;
+ }
+ lim_log(mac_ctx, LOGW,
+ FL("AddTsRsp received successfully(UP %d, TSID %d)"),
+ addts.tspec.tsinfo.traffic.userPrio,
+ addts.tspec.tsinfo.traffic.tsid);
+ } else {
+ lim_log(mac_ctx, LOGW,
+ FL("AddTsRsp received successfully(UP %d, TSID %d)"),
+ addts.tspec.tsinfo.traffic.userPrio,
+ addts.tspec.tsinfo.traffic.tsid);
+ lim_log(mac_ctx, LOGW,
+ FL("no ACM: Bypass sending WMA_ADD_TS_REQ to HAL "));
+ /*
+ * Use the smesessionId and smetransactionId from the PE
+ * session context
+ */
+ lim_send_sme_addts_rsp(mac_ctx, true, eSIR_SME_SUCCESS,
+ session, addts.tspec, session->smeSessionId,
+ session->transactionId);
+ }
+ /* clear the addts flag */
+ mac_ctx->lim.gLimAddtsSent = false;
+ return;
+}
+
+/**
+ * __lim_process_del_ts_req() - To process del ts response frame
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: Received packet info
+ * @session: pointer to session
+ *
+ * This routine is to handle del ts request frame
+ *
+ * Return: none
+ */
+static void __lim_process_del_ts_req(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+ tSirRetStatus retval;
+ tSirDeltsReqInfo delts;
+ tpSirMacMgmtHdr mac_hdr;
+ tpDphHashNode sta_ptr;
+ uint32_t frame_len;
+ uint16_t aid;
+ uint8_t *body_ptr;
+ uint8_t ts_status;
+ tSirMacTSInfo *tsinfo;
+ uint8_t tspec_idx;
+ uint8_t ac;
+ tpDphHashNode sta_ds_ptr = NULL;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
+ &session->dph.dphHashTable);
+ if (sta_ptr == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Station context not found - ignoring DelTs"));
+ return;
+ }
+ /* parse the delts request */
+ retval = sir_convert_delts_req2_struct(mac_ctx, body_ptr,
+ frame_len, &delts);
+ if (retval != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGW,
+ FL("DelTs parsing failed (error %d)"), retval);
+ return;
+ }
+
+ if (delts.wmeTspecPresent) {
+ if ((!session->limWmeEnabled) || (!sta_ptr->wmeEnabled)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Ignore delts req: wme not enabled"));
+ return;
+ }
+ lim_log(mac_ctx, LOG2, FL("WME Delts received"));
+ } else if ((session->limQosEnabled) && sta_ptr->lleEnabled) {
+ lim_log(mac_ctx, LOG2, FL("11e QoS Delts received"));
+ } else if ((session->limWsmEnabled) && sta_ptr->wsmEnabled) {
+ lim_log(mac_ctx, LOG2, FL("WSM Delts received"));
+ } else {
+ lim_log(mac_ctx, LOGW,
+ FL("Ignoring delts request: qos not enabled/capable"));
+ return;
+ }
+
+ tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;
+
+ /* if no Admit Control, ignore the request */
+ if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)) {
+
+ if (upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) {
+ lim_log(mac_ctx, LOGW,
+ FL("DelTs with UP %d has no AC - ignoring req"),
+ tsinfo->traffic.userPrio);
+ return;
+ }
+ }
+
+ if (!LIM_IS_AP_ROLE(session) &&
+ !LIM_IS_BT_AMP_AP_ROLE(session))
+ lim_send_sme_delts_ind(mac_ctx, &delts, aid, session);
+
+ /* try to delete the TS */
+ if (eSIR_SUCCESS !=
+ lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId, tsinfo,
+ &ts_status, &tspec_idx)) {
+ lim_log(mac_ctx, LOGW, FL("Unable to Delete TS"));
+ return;
+ } else if (!((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
+ || (tsinfo->traffic.accessPolicy ==
+ SIR_MAC_ACCESSPOLICY_BOTH))){
+ /* send message to HAL to delete TS */
+ if (eSIR_SUCCESS != lim_send_hal_msg_del_ts(mac_ctx,
+ sta_ptr->staIndex, tspec_idx,
+ delts, session->peSessionId,
+ session->bssId)) {
+ lim_log(mac_ctx, LOGW,
+ FL("DelTs with UP %d failed ignoring request"),
+ tsinfo->traffic.userPrio);
+ return;
+ }
+ }
+ /*
+ * We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
+ * The AC for this TSPEC is no longer trigger enabled if this Tspec
+ * was set-up in uplink direction only.
+ * The AC for this TSPEC is no longer delivery enabled if this Tspec
+ * was set-up in downlink direction only.
+ * The AC for this TSPEC is no longer triiger enabled and delivery
+ * enabled if this Tspec was a bidirectional TSPEC.
+ */
+ lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
+ tsinfo, CLEAR_UAPSD_MASK);
+ /*
+ * We're deleting the TSPEC.
+ * The AC for this TSPEC is no longer admitted in uplink/downlink
+ * direction if this TSPEC was set-up in uplink/downlink direction only.
+ * The AC for this TSPEC is no longer admitted in both uplink and
+ * downlink directions if this TSPEC was a bi-directional TSPEC.
+ * If ACM is set for this AC and this AC is admitted only in downlink
+ * direction, PE needs to downgrade the EDCA parameter
+ * (for the AC for which TS is being deleted) to the
+ * next best AC for which ACM is not enabled, and send the
+ * updated values to HAL.
+ */
+ ac = upToAc(tsinfo->traffic.userPrio);
+ if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+ ~(1 << ac);
+ } else if (tsinfo->traffic.direction ==
+ SIR_MAC_DIRECTION_DNLINK) {
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+ ~(1 << ac);
+ } else if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) {
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+ ~(1 << ac);
+ session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+ ~(1 << ac);
+ }
+ lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
+ session);
+ sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session->dph.dphHashTable);
+ if (sta_ds_ptr != NULL)
+ lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
+ sta_ds_ptr->bssId);
+ else
+ lim_log(mac_ctx, LOGE, FL("Self entry missing in Hash Table "));
+
+ lim_log(mac_ctx, LOG1, FL("DeleteTS succeeded"));
+#ifdef FEATURE_WLAN_ESE
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ lim_send_sme_tsm_ie_ind(mac_ctx, session, 0, 0, 0);
+#else
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_TSM_TIMER);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+#endif
+}
+
+/**
+ * __lim_process_qos_map_configure_frame() - to process QoS map configure frame
+ * @mac_ctx: pointer to mac context
+ * @rx_pkt_info: pointer to received packet info
+ * @session: pointer to session
+ *
+ * This routine will called to process qos map configure frame
+ *
+ * Return: none
+ */
+static void __lim_process_qos_map_configure_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+ tpSirMacMgmtHdr mac_hdr;
+ uint32_t frame_len;
+ uint8_t *body_ptr;
+ tSirRetStatus retval;
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+ retval = sir_convert_qos_map_configure_frame2_struct(mac_ctx,
+ body_ptr, frame_len, &session->QosMapSet);
+ if (retval != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("QosMapConfigure frame parsing fail(error %d)"),
+ retval);
+ return;
+ }
+ lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
+ (uint8_t *) mac_hdr,
+ frame_len + sizeof(tSirMacMgmtHdr), 0,
+ WMA_GET_RX_CH(rx_pkt_info), session, 0);
+}
+
+#ifdef ANI_SUPPORT_11H
+static void
+__lim_process_basic_meas_req(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peerMacAddr, tpPESession psessionEntry)
+{
+ if (lim_send_meas_report_frame(pMac,
+ pMeasReqFrame,
+ peerMacAddr, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("fail to send Basic Meas report "));
+ )
+ return;
+ }
+}
+static void
+__lim_process_cca_meas_req(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peerMacAddr, tpPESession psessionEntry)
+{
+ if (lim_send_meas_report_frame(pMac,
+ pMeasReqFrame,
+ peerMacAddr, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(lim_log(pMac, LOGE, FL("fail to send CCA Meas report "));)
+ return;
+ }
+}
+static void
+__lim_process_rpi_meas_req(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peerMacAddr, tpPESession psessionEntry)
+{
+ if (lim_send_meas_report_frame(pMac,
+ pMeasReqFrame,
+ peerMacAddr, psessionEntry) != eSIR_SUCCESS)
+ {
+ PELOGE(lim_log(pMac, LOGE, FL("fail to send RPI Meas report "));)
+ return;
+ }
+}
+static void
+__lim_process_measurement_request_frame(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ uint8_t *pBody;
+ tpSirMacMeasReqActionFrame pMeasReqFrame;
+ uint32_t frameLen;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ pMeasReqFrame = cdf_mem_malloc(sizeof(tSirMacMeasReqActionFrame));
+ if (NULL == pMeasReqFrame) {
+ lim_log(pMac, LOGE,
+ FL
+ ("limProcessMeasurementRequestFrame: AllocateMemory failed "));
+ return;
+ }
+
+ if (sir_convert_meas_req_frame2_struct(pMac, pBody, pMeasReqFrame, frameLen)
+ != eSIR_SUCCESS) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Rcv invalid Measurement Request Action Frame "));
+ )
+ return;
+ }
+ switch (pMeasReqFrame->measReqIE.measType) {
+ case SIR_MAC_BASIC_MEASUREMENT_TYPE:
+ __lim_process_basic_meas_req(pMac, pMeasReqFrame, pHdr->sa,
+ psessionEntry);
+ break;
+ case SIR_MAC_CCA_MEASUREMENT_TYPE:
+ __lim_process_cca_meas_req(pMac, pMeasReqFrame, pHdr->sa,
+ psessionEntry);
+ break;
+ case SIR_MAC_RPI_MEASUREMENT_TYPE:
+ __lim_process_rpi_meas_req(pMac, pMeasReqFrame, pHdr->sa,
+ psessionEntry);
+ break;
+ default:
+ PELOG1(lim_log(pMac, LOG1, FL("Unknown Measurement Type %d "),
+ pMeasReqFrame->measReqIE.measType);
+ )
+ break;
+ }
+} /*** end limProcessMeasurementRequestFrame ***/
+static void
+__lim_process_tpc_request_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ uint8_t *pBody;
+ tpSirMacTpcReqActionFrame pTpcReqFrame;
+ uint32_t frameLen;
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("****LIM: Processing TPC Request from peer ****"));
+ )
+ pTpcReqFrame = cdf_mem_malloc(sizeof(tSirMacTpcReqActionFrame));
+ if (NULL == pTpcReqFrame) {
+ PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory failed "));)
+ return;
+ }
+ if (sir_convert_tpc_req_frame2_struct(pMac, pBody, pTpcReqFrame, frameLen) !=
+ eSIR_SUCCESS) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Rcv invalid TPC Req Action Frame "));
+ )
+ return;
+ }
+ if (lim_send_tpc_report_frame(pMac,
+ pTpcReqFrame,
+ pHdr->sa, psessionEntry) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("fail to send TPC Report Frame. "));
+ )
+ return;
+ }
+}
+#endif
+
+static void
+__lim_process_sm_power_save_update(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+
+ tpSirMacMgmtHdr pHdr;
+ tDot11fSMPowerSave frmSMPower;
+ tSirMacHTMIMOPowerSaveState state;
+ tpDphHashNode pSta;
+ uint16_t aid;
+ uint32_t frameLen, nStatus;
+ uint8_t *pBody;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ pSta =
+ dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL) {
+ lim_log(pMac, LOGE,
+ FL
+ ("STA context not found - ignoring UpdateSM PSave Mode from "));
+ lim_print_mac_addr(pMac, pHdr->sa, LOGW);
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus = dot11f_unpack_sm_power_save(pMac, pBody, frameLen, &frmSMPower);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ return;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ }
+
+ lim_log(pMac, LOGW,
+ FL("Received SM Power save Mode update Frame with PS_Enable:%d"
+ "PS Mode: %d"), frmSMPower.SMPowerModeSet.PowerSave_En,
+ frmSMPower.SMPowerModeSet.Mode);
+
+ /** Update in the DPH Table about the Update in the SM Power Save mode*/
+ if (frmSMPower.SMPowerModeSet.PowerSave_En
+ && frmSMPower.SMPowerModeSet.Mode)
+ state = eSIR_HT_MIMO_PS_DYNAMIC;
+ else if ((frmSMPower.SMPowerModeSet.PowerSave_En)
+ && (frmSMPower.SMPowerModeSet.Mode == 0))
+ state = eSIR_HT_MIMO_PS_STATIC;
+ else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0)
+ && (frmSMPower.SMPowerModeSet.Mode == 0))
+ state = eSIR_HT_MIMO_PS_NO_LIMIT;
+ else {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL
+ ("Received SM Power save Mode update Frame with invalid mode"));
+ )
+ return;
+ }
+
+ if (state == pSta->htMIMOPSState) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("The PEER is already set in the same mode"));
+ )
+ return;
+ }
+
+ /** Update in the HAL Station Table for the Update of the Protection Mode */
+ pSta->htMIMOPSState = state;
+ lim_post_sm_state_update(pMac, pSta->staIndex, pSta->htMIMOPSState,
+ pSta->staAddr, psessionEntry->smeSessionId);
+}
+
+#if defined WLAN_FEATURE_VOWIFI
+
+static void
+__lim_process_radio_measure_request(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tDot11fRadioMeasurementRequest frm;
+ uint32_t frameLen, nStatus;
+ uint8_t *pBody;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ if (psessionEntry == NULL) {
+ return;
+ }
+
+ lim_send_sme_mgmt_frame_ind(pMac, pHdr->fc.subType, (uint8_t *)pHdr,
+ frameLen + sizeof(tSirMacMgmtHdr), 0,
+ WMA_GET_RX_CH(pRxPacketInfo), psessionEntry, 0);
+
+ /**Unpack the received frame */
+ nStatus =
+ dot11f_unpack_radio_measurement_request(pMac, pBody, frameLen, &frm);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ return;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ }
+ /* Call rrm function to handle the request. */
+
+ rrm_process_radio_measurement_request(pMac, pHdr->sa, &frm, psessionEntry);
+}
+
+static void
+__lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tDot11fLinkMeasurementRequest frm;
+ uint32_t frameLen, nStatus;
+ uint8_t *pBody;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ if (psessionEntry == NULL) {
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus =
+ dot11f_unpack_link_measurement_request(pMac, pBody, frameLen, &frm);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ return;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ }
+ /* Call rrm function to handle the request. */
+
+ rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm,
+ psessionEntry);
+
+}
+
+static void
+__lim_process_neighbor_report(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ tDot11fNeighborReportResponse *pFrm;
+ uint32_t frameLen, nStatus;
+ uint8_t *pBody;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ pFrm = cdf_mem_malloc(sizeof(tDot11fNeighborReportResponse));
+ if (NULL == pFrm) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to allocate memory in __lim_process_neighbor_report"));
+ return;
+ }
+
+ if (psessionEntry == NULL) {
+ cdf_mem_free(pFrm);
+ return;
+ }
+
+ /**Unpack the received frame */
+ nStatus =
+ dot11f_unpack_neighbor_report_response(pMac, pBody, frameLen, pFrm);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ cdf_mem_free(pFrm);
+ return;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):"),
+ nStatus, frameLen);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
+ )
+ }
+ /* Call rrm function to handle the request. */
+ rrm_process_neighbor_report_response(pMac, pFrm, psessionEntry);
+
+ cdf_mem_free(pFrm);
+}
+
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * limProcessSAQueryRequestActionFrame
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_action_frame() upon
+ * SA query request Action frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - Handle to the Rx packet info
+ * @param psessionEntry - PE session entry
+ *
+ * @return None
+ */
+static void __lim_process_sa_query_request_action_frame(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ uint8_t *pBody;
+ uint8_t transId[2];
+
+ /* Prima --- Below Macro not available in prima
+ pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
+ pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ /* If this is an unprotected SA Query Request, then ignore it. */
+ if (pHdr->fc.wep == 0)
+ return;
+
+ /*Extract 11w trsansId from SA query request action frame
+ In SA query response action frame we will send same transId
+ In SA query request action frame:
+ Category : 1 byte
+ Action : 1 byte
+ Transaction ID : 2 bytes */
+ cdf_mem_copy(&transId[0], &pBody[2], 2);
+
+ /* Send 11w SA query response action frame */
+ if (lim_send_sa_query_response_frame(pMac,
+ transId,
+ pHdr->sa,
+ psessionEntry) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("fail to send SA query response action frame."));
+ )
+ return;
+ }
+}
+
+/**
+ * __lim_process_sa_query_response_action_frame
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_action_frame() upon
+ * SA query response Action frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - Handle to the Rx packet info
+ * @param psessionEntry - PE session entry
+ * @return None
+ */
+static void __lim_process_sa_query_response_action_frame(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ uint32_t frameLen;
+ uint8_t *pBody;
+ tpDphHashNode pSta;
+ uint16_t aid;
+ uint16_t transId;
+ uint8_t retryNum;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ ("SA Query Response received..."));
+
+ /* When a station, supplicant handles SA Query Response.
+ * Forward to SME to HDD to wpa_supplicant.
+ */
+ if (LIM_IS_STA_ROLE(psessionEntry)) {
+ lim_send_sme_mgmt_frame_ind(pMac, pHdr->fc.subType, (uint8_t *) pHdr,
+ frameLen + sizeof(tSirMacMgmtHdr), 0,
+ WMA_GET_RX_CH(pRxPacketInfo),
+ psessionEntry, 0);
+ return;
+ }
+
+ /* If this is an unprotected SA Query Response, then ignore it. */
+ if (pHdr->fc.wep == 0)
+ return;
+
+ pSta =
+ dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (NULL == pSta)
+ return;
+
+ lim_log(pMac, LOG1,
+ FL("SA Query Response source addr - %0x:%0x:%0x:%0x:%0x:%0x"),
+ pHdr->sa[0], pHdr->sa[1], pHdr->sa[2], pHdr->sa[3],
+ pHdr->sa[4], pHdr->sa[5]);
+ lim_log(pMac, LOG1,
+ FL("SA Query state for station - %d"), pSta->pmfSaQueryState);
+
+ if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
+ return;
+
+ /* Extract 11w trsansId from SA query reponse action frame
+ In SA query response action frame:
+ Category : 1 byte
+ Action : 1 byte
+ Transaction ID : 2 bytes */
+ cdf_mem_copy(&transId, &pBody[2], 2);
+
+ /* If SA Query is in progress with the station and the station
+ responds then the association request that triggered the SA
+ query is from a rogue station, just go back to initial state. */
+ for (retryNum = 0; retryNum <= pSta->pmfSaQueryRetryCount; retryNum++)
+ if (transId == pSta->pmfSaQueryStartTransId + retryNum) {
+ lim_log(pMac, LOG1,
+ FL
+ ("Found matching SA Query Request - transaction ID %d"),
+ transId);
+ tx_timer_deactivate(&pSta->pmfSaQueryTimer);
+ pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+ break;
+ }
+}
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_drop_unprotected_action_frame
+ *
+ ***FUNCTION:
+ * This function checks if an Action frame should be dropped since it is
+ * a Robust Managment Frame, it is unprotected, and it is received on a
+ * connection where PMF is enabled.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Global MAC structure
+ * @param psessionEntry - PE session entry
+ * @param pHdr - Frame header
+ * @param category - Action frame category
+ * @return true if frame should be dropped
+ */
+
+static bool
+lim_drop_unprotected_action_frame(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ tpSirMacMgmtHdr pHdr, uint8_t category)
+{
+ uint16_t aid;
+ tpDphHashNode pStaDs;
+ bool rmfConnection = false;
+
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL)
+ if (pStaDs->rmfEnabled)
+ rmfConnection = true;
+ } else if (psessionEntry->limRmfEnabled)
+ rmfConnection = true;
+
+ if (rmfConnection && (pHdr->fc.wep == 0)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Dropping unprotected Action category %d frame "
+ "since RMF is enabled."), category);
+ )
+ return true;
+ } else
+ return false;
+}
+#endif
+
+/**
+ * lim_process_action_frame() - to process action frames
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to packet info structure
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Action frame reception.
+ *
+ * Return: none
+ */
+
+void lim_process_action_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, tpPESession session)
+{
+ uint8_t *body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) body_ptr;
+#ifdef WLAN_FEATURE_11W
+ tpSirMacMgmtHdr mac_hdr_11w = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+#endif
+ tpSirMacMgmtHdr mac_hdr = NULL;
+ int8_t rssi;
+ uint32_t frame_len;
+ tpSirMacVendorSpecificFrameHdr vendor_specific;
+ uint8_t oui[] = { 0x00, 0x00, 0xf0 };
+ tpSirMacVendorSpecificPublicActionFrameHdr pub_action;
+ uint8_t p2p_oui[] = { 0x50, 0x6F, 0x9A, 0x09 };
+
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ switch (action_hdr->category) {
+ case SIR_MAC_ACTION_QOS_MGMT:
+#ifdef WLAN_FEATURE_11W
+ if (lim_drop_unprotected_action_frame(mac_ctx, session,
+ mac_hdr_11w, action_hdr->category))
+ break;
+#endif
+ if ((session->limQosEnabled) ||
+ (action_hdr->actionID == SIR_MAC_QOS_MAP_CONFIGURE)) {
+ switch (action_hdr->actionID) {
+ case SIR_MAC_QOS_ADD_TS_REQ:
+ __lim_process_add_ts_req(mac_ctx,
+ (uint8_t *) rx_pkt_info,
+ session);
+ break;
+
+ case SIR_MAC_QOS_ADD_TS_RSP:
+ __lim_process_add_ts_rsp(mac_ctx,
+ (uint8_t *) rx_pkt_info,
+ session);
+ break;
+
+ case SIR_MAC_QOS_DEL_TS_REQ:
+ __lim_process_del_ts_req(mac_ctx,
+ (uint8_t *) rx_pkt_info,
+ session);
+ break;
+
+ case SIR_MAC_QOS_MAP_CONFIGURE:
+ __lim_process_qos_map_configure_frame(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Qos action %d not handled"),
+ action_hdr->actionID);
+ break;
+ }
+ break;
+ }
+ break;
+
+ case SIR_MAC_ACTION_SPECTRUM_MGMT:
+#ifdef WLAN_FEATURE_11W
+ if (lim_drop_unprotected_action_frame(mac_ctx, session,
+ mac_hdr_11w, action_hdr->category))
+ break;
+#endif
+ switch (action_hdr->actionID) {
+#ifdef ANI_SUPPORT_11H
+ case SIR_MAC_ACTION_MEASURE_REQUEST_ID:
+ if (session->lim11hEnable)
+ __lim_process_measurement_request_frame(mac_ctx,
+ rx_pkt_info,
+ session);
+ break;
+ case SIR_MAC_ACTION_TPC_REQUEST_ID:
+ if ((LIM_IS_STA_ROLE(session) ||
+ LIM_IS_AP_ROLE(session)) &&
+ session->lim11hEnable)
+ __lim_process_tpc_request_frame(mac_ctx,
+ rx_pkt_info, session);
+ break;
+#endif
+ case SIR_MAC_ACTION_CHANNEL_SWITCH_ID:
+ if (LIM_IS_STA_ROLE(session))
+ __lim_process_channel_switch_action_frame(
+ mac_ctx, rx_pkt_info, session);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Spectrum mgmt action id %d not handled"),
+ action_hdr->actionID);
+ break;
+ }
+ break;
+
+ case SIR_MAC_ACTION_WME:
+ if (!session->limWmeEnabled) {
+ lim_log(mac_ctx, LOGW,
+ FL("WME mode disabled - dropping frame %d"),
+ action_hdr->actionID);
+ break;
+ }
+ switch (action_hdr->actionID) {
+ case SIR_MAC_QOS_ADD_TS_REQ:
+ __lim_process_add_ts_req(mac_ctx,
+ (uint8_t *) rx_pkt_info, session);
+ break;
+
+ case SIR_MAC_QOS_ADD_TS_RSP:
+ __lim_process_add_ts_rsp(mac_ctx,
+ (uint8_t *) rx_pkt_info, session);
+ break;
+
+ case SIR_MAC_QOS_DEL_TS_REQ:
+ __lim_process_del_ts_req(mac_ctx,
+ (uint8_t *) rx_pkt_info, session);
+ break;
+
+ case SIR_MAC_QOS_MAP_CONFIGURE:
+ __lim_process_qos_map_configure_frame(mac_ctx,
+ (uint8_t *)rx_pkt_info, session);
+ break;
+
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("WME action %d not handled"),
+ action_hdr->actionID);
+ break;
+ }
+ break;
+
+ case SIR_MAC_ACTION_HT:
+ /** Type of HT Action to be performed*/
+ switch (action_hdr->actionID) {
+ case SIR_MAC_SM_POWER_SAVE:
+ if (LIM_IS_AP_ROLE(session))
+ __lim_process_sm_power_save_update(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Action ID %d not handled in HT category"),
+ action_hdr->actionID);
+ break;
+ }
+ break;
+
+ case SIR_MAC_ACTION_WNM:
+#ifdef WLAN_FEATURE_11W
+ if ((session->limRmfEnabled) && (mac_hdr_11w->fc.wep == 0)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Dropping unprot action %d frm (PMF on)"),
+ action_hdr->category);
+ break;
+ }
+#endif
+ lim_log(mac_ctx, LOG1,
+ FL("WNM Action category %d action %d."),
+ action_hdr->category, action_hdr->actionID);
+ switch (action_hdr->actionID) {
+ case SIR_MAC_WNM_BSS_TM_QUERY:
+ case SIR_MAC_WNM_BSS_TM_REQUEST:
+ case SIR_MAC_WNM_BSS_TM_RESPONSE:
+ case SIR_MAC_WNM_NOTIF_REQUEST:
+ case SIR_MAC_WNM_NOTIF_RESPONSE:
+ rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ /* Forward to the SME to HDD to wpa_supplicant */
+ lim_send_sme_mgmt_frame_ind(mac_ctx,
+ mac_hdr->fc.subType,
+ (uint8_t *) mac_hdr,
+ frame_len + sizeof(tSirMacMgmtHdr),
+ session->smeSessionId,
+ WMA_GET_RX_CH(rx_pkt_info),
+ session, rssi);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Action ID %d not handled in WNM category"),
+ action_hdr->actionID);
+ break;
+ }
+ break;
+
+#if defined WLAN_FEATURE_VOWIFI
+ case SIR_MAC_ACTION_RRM:
+#ifdef WLAN_FEATURE_11W
+ if (lim_drop_unprotected_action_frame(mac_ctx, session,
+ mac_hdr_11w, action_hdr->category))
+ break;
+#endif
+ if (mac_ctx->rrm.rrmPEContext.rrmEnable) {
+ switch (action_hdr->actionID) {
+ case SIR_MAC_RRM_RADIO_MEASURE_REQ:
+ __lim_process_radio_measure_request(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
+ __lim_process_link_measurement_req(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ case SIR_MAC_RRM_NEIGHBOR_RPT:
+ __lim_process_neighbor_report(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Action ID %d not handled in RRM"),
+ action_hdr->actionID);
+ break;
+
+ }
+ } else {
+ /* Else we will just ignore the RRM messages. */
+ lim_log(mac_ctx, LOGE,
+ FL("RRM frm ignored, it is disabled in cfg"));
+ }
+ break;
+#endif
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
+ defined(FEATURE_WLAN_LFR)
+ case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY:
+ vendor_specific = (tpSirMacVendorSpecificFrameHdr) action_hdr;
+ mac_hdr = NULL;
+ frame_len = 0;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ /* Check if it is a vendor specific action frame. */
+ if (LIM_IS_STA_ROLE(session) &&
+ (true == cdf_mem_compare(session->selfMacAddr,
+ &mac_hdr->da[0], sizeof(tSirMacAddr)))
+ && IS_WES_MODE_ENABLED(mac_ctx)
+ && cdf_mem_compare(vendor_specific->Oui, oui, 3)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Rcvd Vendor specific frame, OUI %x %x %x"),
+ vendor_specific->Oui[0],
+ vendor_specific->Oui[1],
+ vendor_specific->Oui[2]);
+ /*
+ * Forward to the SME to HDD to wpa_supplicant
+ * type is ACTION
+ */
+ lim_send_sme_mgmt_frame_ind(mac_ctx,
+ mac_hdr->fc.subType,
+ (uint8_t *) mac_hdr,
+ frame_len +
+ sizeof(tSirMacMgmtHdr),
+ session->smeSessionId,
+ WMA_GET_RX_CH(rx_pkt_info),
+ session, 0);
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("Dropping the vendor specific action frame"
+ "beacause of (WES Mode not enabled "
+ "(WESMODE = %d) or OUI mismatch "
+ "(%02x %02x %02x) or not received with"
+ "SelfSta address) system role = %d"),
+ IS_WES_MODE_ENABLED(mac_ctx),
+ vendor_specific->Oui[0],
+ vendor_specific->Oui[1],
+ vendor_specific->Oui[2],
+ GET_LIM_SYSTEM_ROLE(session));
+ }
+ break;
+#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE ||
+ FEATURE_WLAN_LFR */
+ case SIR_MAC_ACTION_PUBLIC_USAGE:
+ switch (action_hdr->actionID) {
+ case SIR_MAC_ACTION_VENDOR_SPECIFIC:
+ pub_action =
+ (tpSirMacVendorSpecificPublicActionFrameHdr)
+ action_hdr;
+ mac_hdr = NULL;
+ frame_len = 0;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+ /* Check if it is a P2P public action frame. */
+ if (cdf_mem_compare(pub_action->Oui, p2p_oui, 4)) {
+ /*
+ * Forward to the SME to HDD to wpa_supplicant
+ * type is ACTION
+ */
+ lim_send_sme_mgmt_frame_ind(mac_ctx,
+ mac_hdr->fc.subType,
+ (uint8_t *) mac_hdr,
+ frame_len +
+ sizeof(tSirMacMgmtHdr),
+ session->smeSessionId,
+ WMA_GET_RX_CH(rx_pkt_info),
+ session, 0);
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x"),
+ pub_action->Oui[0], pub_action->Oui[1],
+ pub_action->Oui[2], pub_action->Oui[3]);
+ }
+ break;
+
+ case SIR_MAC_ACTION_2040_BSS_COEXISTENCE:
+ mac_hdr = NULL;
+ frame_len = 0;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ lim_send_sme_mgmt_frame_ind(mac_ctx,
+ mac_hdr->fc.subType,
+ (uint8_t *) mac_hdr,
+ frame_len + sizeof(tSirMacMgmtHdr),
+ session->smeSessionId,
+ WMA_GET_RX_CH(rx_pkt_info), session, 0);
+ break;
+#ifdef FEATURE_WLAN_TDLS
+ case SIR_MAC_TDLS_DIS_RSP:
+ mac_hdr = NULL;
+ frame_len = 0;
+ rssi = 0;
+
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+ rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ ("Public Action TDLS Discovery RSP .."));
+ lim_send_sme_mgmt_frame_ind(mac_ctx,
+ mac_hdr->fc.subType, (uint8_t *) mac_hdr,
+ frame_len + sizeof(tSirMacMgmtHdr),
+ session->smeSessionId,
+ WMA_GET_RX_CH(rx_pkt_info), session, rssi);
+ break;
+#endif
+
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Unhandled public action frame -- %x "),
+ action_hdr->actionID);
+ break;
+ }
+ break;
+
+#ifdef WLAN_FEATURE_11W
+ case SIR_MAC_ACTION_SA_QUERY:
+ lim_log(mac_ctx, LOG1,
+ FL("SA Query Action category %d action %d."),
+ action_hdr->category, action_hdr->actionID);
+ if (lim_drop_unprotected_action_frame(mac_ctx, session,
+ mac_hdr_11w, action_hdr->category))
+ break;
+ switch (action_hdr->actionID) {
+ case SIR_MAC_SA_QUERY_REQ:
+ /**11w SA query request action frame received**/
+ /* Respond directly to the incoming request in LIM */
+ __lim_process_sa_query_request_action_frame(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ case SIR_MAC_SA_QUERY_RSP:
+ /**11w SA query response action frame received**/
+ /* Handle based on the current SA Query state */
+ __lim_process_sa_query_response_action_frame(mac_ctx,
+ (uint8_t *)rx_pkt_info,
+ session);
+ break;
+ default:
+ break;
+ }
+ break;
+#endif
+#ifdef WLAN_FEATURE_11AC
+ case SIR_MAC_ACTION_VHT:
+ if (!session->vhtCapability)
+ break;
+ switch (action_hdr->actionID) {
+ case SIR_MAC_VHT_OPMODE_NOTIFICATION:
+ __lim_process_operating_mode_action_frame(mac_ctx,
+ rx_pkt_info, session);
+ break;
+ case SIR_MAC_VHT_GID_NOTIFICATION:
+ /* Only if ini supports it */
+ if (session->enableVhtGid)
+ __lim_process_gid_management_action_frame(
+ mac_ctx, rx_pkt_info, session);
+ break;
+ default:
+ break;
+ }
+ break;
+#endif
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("Action category %d not handled"),
+ action_hdr->category);
+ break;
+ }
+}
+
+/**
+ * lim_process_action_frame_no_session
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Action frame reception and no session.
+ * Currently only public action frames can be received from
+ * a non-associated station.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pBd - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+
+void lim_process_action_frame_no_session(tpAniSirGlobal pMac, uint8_t *pBd)
+{
+ uint8_t *pBody = WMA_GET_RX_MPDU_DATA(pBd);
+ tpSirMacVendorSpecificPublicActionFrameHdr pActionHdr =
+ (tpSirMacVendorSpecificPublicActionFrameHdr) pBody;
+
+ lim_log(pMac, LOG1, "Received a Action frame -- no session");
+
+ switch (pActionHdr->category) {
+ case SIR_MAC_ACTION_PUBLIC_USAGE:
+ switch (pActionHdr->actionID) {
+ case SIR_MAC_ACTION_VENDOR_SPECIFIC:
+ {
+ tpSirMacMgmtHdr pHdr;
+ uint32_t frameLen;
+ uint8_t P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 };
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pBd);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
+
+ /* Check if it is a P2P public action frame. */
+ if (cdf_mem_compare(pActionHdr->Oui, P2POui, 4)) {
+ /* Forward to the SME to HDD to wpa_supplicant */
+ /* type is ACTION */
+ lim_send_sme_mgmt_frame_ind(pMac,
+ pHdr->fc.subType,
+ (uint8_t *) pHdr,
+ frameLen +
+ sizeof
+ (tSirMacMgmtHdr),
+ 0,
+ WMA_GET_RX_CH
+ (pBd), NULL, 0);
+ } else {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unhandled public action frame (Vendor specific). OUI %x %x %x %x"),
+ pActionHdr->Oui[0],
+ pActionHdr->Oui[1],
+ pActionHdr->Oui[2],
+ pActionHdr->Oui[3]);
+ }
+ }
+ break;
+ default:
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Unhandled public action frame -- %x "),
+ pActionHdr->actionID);
+ )
+ break;
+ }
+ break;
+ default:
+ PELOGE(lim_log
+ (pMac, LOG1,
+ FL("Unhandled action frame without session -- %x "),
+ pActionHdr->category);
+ )
+ break;
+
+ }
+}
diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
new file mode 100644
index 0000000..1972461
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
@@ -0,0 +1,1921 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_process_assoc_req_frame.cc contains the code
+ * for processing Re/Association Request Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/18/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "sir_api.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_admit_control.h"
+#include "cds_packet.h"
+#include "lim_session_utils.h"
+
+#include "cdf_types.h"
+#include "cds_utils.h"
+
+/**
+ * lim_convert_supported_channels - Parses channel support IE
+ *
+ * @mac_ctx - A pointer to Global MAC structure
+ * @assoc_ind - A pointer to SME ASSOC/REASSOC IND
+ * @assoc_req - A pointer to ASSOC/REASSOC Request frame
+ *
+ * This function is called by lim_process_assoc_req_frame() to
+ * parse the channel support IE in the Assoc/Reassoc Request
+ * frame, and send relevant information in the SME_ASSOC_IND
+ *
+ * return None
+ */
+static void
+lim_convert_supported_channels(tpAniSirGlobal mac_ctx,
+ tpLimMlmAssocInd assoc_ind, tSirAssocReq *assoc_req)
+{
+ uint16_t i, j, index = 0;
+ uint8_t first_chn_no;
+ uint8_t chn_count;
+ uint8_t next_chn_no;
+ uint8_t channel_offset = 0;
+
+ if (assoc_req->supportedChannels.length >=
+ SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+ lim_log(mac_ctx, LOG1,
+ FL("Number of supported channels:%d is more than MAX"),
+ assoc_req->supportedChannels.length);
+ assoc_ind->supportedChannels.numChnl = 0;
+ return;
+ }
+
+ for (i = 0; i < (assoc_req->supportedChannels.length); i++) {
+ /* Get First Channel Number */
+ first_chn_no =
+ assoc_req->supportedChannels.supportedChannels[i];
+ assoc_ind->supportedChannels.channelList[index] =
+ first_chn_no;
+ i++;
+ index++;
+
+ /* Get Number of Channels in a Subband */
+ chn_count =
+ assoc_req->supportedChannels.supportedChannels[i];
+ PELOG2(lim_log(mac_ctx, LOG2,
+ FL("Rcv assoc_req: chnl=%d, numOfChnl=%d "),
+ first_chn_no, chn_count);)
+ if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+ PELOG2(lim_log(mac_ctx, LOGW,
+ FL("Channel count is more than max supported =%d "),
+ chn_count);)
+ assoc_ind->supportedChannels.numChnl = 0;
+ return;
+ }
+ if (chn_count <= 1)
+ continue;
+ next_chn_no = first_chn_no;
+ if (SIR_BAND_5_GHZ == lim_get_rf_band(first_chn_no))
+ channel_offset = SIR_11A_FREQUENCY_OFFSET;
+ else if (SIR_BAND_2_4_GHZ == lim_get_rf_band(first_chn_no))
+ channel_offset = SIR_11B_FREQUENCY_OFFSET;
+ else
+ continue;
+
+ for (j = 1; j < chn_count; j++) {
+ next_chn_no += channel_offset;
+ assoc_ind->supportedChannels.channelList[index]
+ = next_chn_no;
+ index++;
+ if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
+ PELOG2(lim_log(mac_ctx, LOGW,
+ FL("Channel count is more than supported =%d "),
+ chn_count);)
+ assoc_ind->supportedChannels.numChnl = 0;
+ return;
+ }
+ }
+ }
+
+ assoc_ind->supportedChannels.numChnl = (uint8_t) index;
+ PELOG2(lim_log(mac_ctx, LOG2,
+ FL("Send AssocInd to WSM: minPwr %d, maxPwr %d, numChnl %d"),
+ assoc_ind->powerCap.minTxPower,
+ assoc_ind->powerCap.maxTxPower,
+ assoc_ind->supportedChannels.numChnl);)
+}
+
+/**---------------------------------------------------------------
+ \fn lim_check_sta_in_pe_entries
+ \brief This function is called by lim_process_assoc_req_frame()
+ \ to check if STA entry already exists in any of the
+ \ PE entries of the AP. If it exists, deauth will be
+ \ sent on that session and the STA deletion will
+ \ happen. After this, the ASSOC request will be
+ \ processed
+ \
+ \param pMac - A pointer to Global MAC structure
+ \param pHdr - A pointer to the MAC header
+ \return None
+ ------------------------------------------------------------------*/
+void lim_check_sta_in_pe_entries(tpAniSirGlobal pMac, tpSirMacMgmtHdr pHdr)
+{
+ uint8_t i;
+ uint16_t assocId = 0;
+ tpDphHashNode pStaDs = NULL;
+ tpPESession psessionEntry = NULL;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if ((&pMac->lim.gpSession[i] != NULL) &&
+ (pMac->lim.gpSession[i].valid) &&
+ (pMac->lim.gpSession[i].pePersona == CDF_SAP_MODE)) {
+
+ psessionEntry = &pMac->lim.gpSession[i];
+ pStaDs = dph_lookup_hash_entry(pMac, pHdr->sa, &assocId,
+ &psessionEntry->dph.
+ dphHashTable);
+ if (pStaDs
+#ifdef WLAN_FEATURE_11W
+ && !pStaDs->rmfEnabled
+#endif
+ ) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Sending Deauth and Deleting existing STA entry: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(psessionEntry->
+ selfMacAddr));
+ lim_send_deauth_mgmt_frame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,
+ (uint8_t *) pHdr->sa,
+ psessionEntry, false);
+ lim_trigger_sta_deletion(pMac, pStaDs,
+ psessionEntry);
+ break;
+ }
+ }
+ }
+}
+
+/**---------------------------------------------------------------
+ \fn lim_process_assoc_req_frame
+ \brief This function is called by limProcessMessageQueue()
+ \ upon Re/Association Request frame reception in
+ \ BTAMP AP or Soft AP role.
+ \
+ \param pMac
+ \param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs
+ \param subType - Indicates whether it is Association Request(=0)
+ \ or Reassociation Request(=1) frame
+ \return None
+ ------------------------------------------------------------------*/
+void
+lim_process_assoc_req_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ uint8_t subType, tpPESession psessionEntry)
+{
+ uint8_t updateContext;
+ uint8_t *pBody;
+ uint16_t peerIdx, temp;
+ uint32_t val;
+ int32_t framelen;
+ tSirRetStatus status;
+ tpSirMacMgmtHdr pHdr;
+ struct tLimPreAuthNode *pStaPreAuthContext;
+ tAniAuthType authType;
+ tSirMacCapabilityInfo localCapabilities;
+ tpDphHashNode pStaDs = NULL;
+ tpSirAssocReq pAssocReq, pTempAssocReq;
+ tLimMlmStates mlmPrevState;
+ tDot11fIERSN Dot11fIERSN;
+ tDot11fIEWPA Dot11fIEWPA;
+ uint32_t phyMode;
+ tHalBitVal qosMode;
+ tHalBitVal wsmMode, wmeMode;
+ uint8_t *wpsIe = NULL;
+ uint8_t *ht_cap_ie = NULL;
+ tSirMacRateSet basicRates;
+ uint8_t i = 0, j = 0;
+ bool pmfConnection = false;
+#ifdef WLAN_FEATURE_11W
+ tPmfSaQueryTimerId timerId;
+ uint32_t retryInterval;
+#endif
+ uint16_t assoc_id = 0;
+ bool assoc_req_copied = false;
+
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ limGetQosMode(psessionEntry, &qosMode);
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ framelen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ lim_log(pMac, LOG1,
+ FL("Received %s Req Frame on sessionid: %d systemrole %d"
+ " limMlmState %d from: " MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ psessionEntry->peSessionId, GET_LIM_SYSTEM_ROLE(psessionEntry),
+ psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->sa));
+
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL("received unexpected ASSOC REQ on sessionid: %d "
+ "sys subType=%d for role=%d from: " MAC_ADDRESS_STR),
+ psessionEntry->peSessionId, subType,
+ GET_LIM_SYSTEM_ROLE(psessionEntry),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG3,
+ WMA_GET_RX_MPDU_DATA(pRxPacketInfo), framelen);
+ return;
+ }
+
+ /*
+ * If a STA is already present in DPH and it
+ * is initiating a Assoc re-transmit, do not
+ * process it. This can happen when first Assoc Req frame
+ * is received but ACK lost at STA side. The ACK for this
+ * dropped Assoc Req frame should be sent by HW. Host simply
+ * does not process it once the entry for the STA is already
+ * present in DPH.
+ */
+ pStaDs = dph_lookup_hash_entry(pMac, pHdr->sa, &assoc_id,
+ &psessionEntry->dph.dphHashTable);
+ if ((NULL != pStaDs) && (pHdr->fc.retry > 0)) {
+ lim_log(pMac, LOGE,
+ FL("STA is initiating Assoc Req after ACK lost. Do not process"
+ " sessionid: %d sys subType=%d for role=%d from: "
+ MAC_ADDRESS_STR), psessionEntry->peSessionId,
+ subType, GET_LIM_SYSTEM_ROLE(psessionEntry),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ return;
+ }
+
+ lim_check_sta_in_pe_entries(pMac, pHdr);
+
+ /* Get pointer to Re/Association Request frame body */
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (lim_is_group_addr(pHdr->sa)) {
+ /* Received Re/Assoc Req frame from a BC/MC address */
+ /* Log error and ignore it */
+ lim_log(pMac, LOGE,
+ FL("Received %s Req on sessionid: %d frame from a "
+ "BC/MC address" MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ psessionEntry->peSessionId, MAC_ADDR_ARRAY(pHdr->sa));
+ return;
+ }
+
+ sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG2, (uint8_t *) pBody, framelen);
+
+ if (cdf_mem_compare((uint8_t *) pHdr->sa, (uint8_t *) pHdr->da,
+ (uint8_t) (sizeof(tSirMacAddr)))) {
+ lim_log(pMac, LOGE,
+ FL("Rejected Assoc Req frame Since same mac as"
+ " SAP/GO"));
+ lim_send_assoc_rsp_mgmt_frame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ 1, pHdr->sa, subType, 0,
+ psessionEntry);
+ return;
+ }
+ /* If TKIP counter measures active send Assoc Rsp frame to station with eSIR_MAC_MIC_FAILURE_REASON */
+ if (psessionEntry->bTkipCntrMeasActive &&
+ LIM_IS_AP_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGE, FL("TKIP counter measure is active"));
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_MIC_FAILURE_REASON,
+ 1, pHdr->sa, subType,
+ 0, psessionEntry);
+ return;
+ }
+ /* Allocate memory for the Assoc Request frame */
+ pAssocReq = cdf_mem_malloc(sizeof(*pAssocReq));
+ if (NULL == pAssocReq) {
+ lim_log(pMac, LOGP, FL("Allocate Memory failed in assoc_req"));
+ return;
+ }
+ cdf_mem_set((void *)pAssocReq, sizeof(*pAssocReq), 0);
+
+ /* Parse Assoc Request frame */
+ if (subType == LIM_ASSOC)
+ status =
+ sir_convert_assoc_req_frame2_struct(pMac, pBody, framelen,
+ pAssocReq);
+ else
+ status =
+ sir_convert_reassoc_req_frame2_struct(pMac, pBody, framelen,
+ pAssocReq);
+
+ if (status != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("Parse error AssocRequest, length=%d from "
+ MAC_ADDRESS_STR), framelen, MAC_ADDR_ARRAY(pHdr->sa));
+ lim_send_assoc_rsp_mgmt_frame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ 1, pHdr->sa, subType, 0,
+ psessionEntry);
+ goto error;
+ }
+
+ pAssocReq->assocReqFrame = cdf_mem_malloc(framelen);
+ if (NULL == pAssocReq->assocReqFrame) {
+ lim_log(pMac, LOGE,
+ FL("Unable to allocate memory for the assoc req, "
+ "length=%d from "), framelen);
+ goto error;
+ }
+
+ cdf_mem_copy((uint8_t *) pAssocReq->assocReqFrame,
+ (uint8_t *) pBody, framelen);
+ pAssocReq->assocReqFrameLength = framelen;
+
+ if (cfg_get_capability_info(pMac, &temp, psessionEntry) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not retrieve Capabilities"));
+ goto error;
+ }
+ lim_copy_u16((uint8_t *) &localCapabilities, temp);
+
+ if (lim_compare_capabilities(pMac,
+ pAssocReq,
+ &localCapabilities, psessionEntry) == false)
+ {
+ lim_log(pMac, LOGE, FL("local caps mismatch received caps"));
+ lim_log(pMac, LOGE, FL("Received %s Req with unsupported "
+ "capabilities from" MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+ /**
+ * Capabilities of requesting STA does not match with
+ * local capabilities. Respond with 'unsupported capabilities'
+ * status code.
+ */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1,
+ pHdr->sa, subType, 0, psessionEntry);
+
+ goto error;
+ }
+
+ updateContext = false;
+
+ if (lim_cmp_s_sid(pMac, &pAssocReq->ssId, psessionEntry) == false) {
+ lim_log(pMac, LOGE,
+ FL("Received %s Req with unmatched ssid ( Received"
+ " SSID: %.*s current SSID: %.*s ) from "
+ MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ pAssocReq->ssId.length, pAssocReq->ssId.ssId,
+ psessionEntry->ssId.length, psessionEntry->ssId.ssId,
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ /**
+ * Received Re/Association Request with either
+ * Broadcast SSID OR with SSID that does not
+ * match with local one.
+ * Respond with unspecified status code.
+ */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ 1,
+ pHdr->sa, subType, 0, psessionEntry);
+
+ goto error;
+ }
+
+ /***************************************************************
+ ** Verify if the requested rates are available in supported rate
+ ** set or Extended rate set. Some APs are adding basic rates in
+ ** Extended rateset IE
+ ***************************************************************/
+ basicRates.numRates = 0;
+
+ for (i = 0;
+ i < pAssocReq->supportedRates.numRates
+ && (i < SIR_MAC_RATESET_EID_MAX); i++) {
+ basicRates.rate[i] = pAssocReq->supportedRates.rate[i];
+ basicRates.numRates++;
+ }
+
+ for (j = 0;
+ (j < pAssocReq->extendedRates.numRates)
+ && (i < SIR_MAC_RATESET_EID_MAX); i++, j++) {
+ basicRates.rate[i] = pAssocReq->extendedRates.rate[j];
+ basicRates.numRates++;
+ }
+ if (lim_check_rx_basic_rates(pMac, basicRates, psessionEntry) == false) {
+ lim_log(pMac, LOGE, FL("Received %s Req with unsupported "
+ "rates from" MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+ /**
+ * Requesting STA does not support ALL BSS basic
+ * rates. Respond with 'basic rates not supported'
+ * status code.
+ */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
+ 1,
+ pHdr->sa, subType, 0, psessionEntry);
+
+ goto error;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
+ (pAssocReq->HTCaps.present))
+ {
+ lim_log(pMac, LOGE,
+ FL("SOFTAP was in 11G only mode, rejecting legacy "
+ "STA : " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1, pHdr->sa, subType, 0,
+ psessionEntry);
+ goto error;
+
+ } /* end if phyMode == 11G_only */
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) &&
+ (!pAssocReq->HTCaps.present)) {
+ lim_log(pMac, LOGE,
+ FL("SOFTAP was in 11N only mode, rejecting legacy "
+ "STA : " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1, pHdr->sa, subType, 0,
+ psessionEntry);
+ goto error;
+ } /* end if PhyMode == 11N_only */
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC_ONLY) &&
+ (!pAssocReq->VHTCaps.present)) {
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
+ 1, pHdr->sa, subType, 0,
+ psessionEntry);
+ lim_log(pMac, LOGE, FL("SOFTAP was in 11AC only mode, reject"));
+ goto error;
+ } /* end if PhyMode == 11AC_only */
+
+ /* Spectrum Management (11h) specific checks */
+ if (localCapabilities.spectrumMgt) {
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ /* If station is 11h capable, then it SHOULD send all mandatory
+ * IEs in assoc request frame. Let us verify that
+ */
+ if (pAssocReq->capabilityInfo.spectrumMgt) {
+ if (!
+ ((pAssocReq->powerCapabilityPresent)
+ && (pAssocReq->supportedChannelsPresent))) {
+ /* One or more required information elements are missing, log the peers error */
+ if (!pAssocReq->powerCapabilityPresent) {
+ lim_log(pMac, LOG1,
+ FL
+ ("LIM Info: Missing Power capability "
+ "IE in %s Req from "
+ MAC_ADDRESS_STR),
+ (LIM_ASSOC ==
+ subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+ }
+ if (!pAssocReq->supportedChannelsPresent) {
+ lim_log(pMac, LOGW,
+ FL
+ ("LIM Info: Missing Supported channel "
+ "IE in %s Req from "
+ MAC_ADDRESS_STR),
+ (LIM_ASSOC ==
+ subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ }
+ } else {
+ /* Assoc request has mandatory fields */
+ status =
+ lim_is_dot11h_power_capabilities_in_range(pMac,
+ pAssocReq,
+ psessionEntry);
+ if (eSIR_SUCCESS != status) {
+ lim_log(pMac, LOGW,
+ FL("LIM Info: MinTxPower(STA) > "
+ "MaxTxPower(AP) in %s Req from "
+ MAC_ADDRESS_STR),
+ (LIM_ASSOC ==
+ subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ }
+ status =
+ lim_is_dot11h_supported_channels_valid(pMac,
+ pAssocReq);
+ if (eSIR_SUCCESS != status) {
+ lim_log(pMac, LOGW,
+ FL("LIM Info: wrong supported "
+ "channels (STA) in %s Req from "
+ MAC_ADDRESS_STR),
+ (LIM_ASSOC ==
+ subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ }
+ /* IEs are valid, use them if needed */
+ }
+ } /* if(assoc.capabilityInfo.spectrumMgt) */
+ else {
+ /* As per the capabiities, the spectrum management is not enabled on the station
+ * The AP may allow the associations to happen even if spectrum management is not
+ * allowed, if the transmit power of station is below the regulatory maximum
+ */
+
+ /* TODO: presently, this is not handled. In the current implemetation, the AP would
+ * allow the station to associate even if it doesn't support spectrum management.
+ */
+ }
+ } /* end of spectrum management related processing */
+
+ if ((pAssocReq->HTCaps.present)
+ && (lim_check_mcs_set(pMac, pAssocReq->HTCaps.supportedMCSSet) ==
+ false)) {
+ lim_log(pMac, LOGE,
+ FL("received %s req with unsupported"
+ "MCS Rate Set from " MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ /**
+ * Requesting STA does not support ALL BSS MCS basic Rate set rates.
+ * Spec does not define any status code for this scenario.
+ */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
+ 1,
+ pHdr->sa, subType, 0, psessionEntry);
+
+ goto error;
+ }
+
+ if (phyMode == WNI_CFG_PHY_MODE_11G) {
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_11G_ONLY_POLICY, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not retrieve 11g-only flag"));
+ goto error;
+ }
+
+ if (!pAssocReq->extendedRatesPresent && val) {
+ /**
+ * Received Re/Association Request from
+ * 11b STA when 11g only policy option
+ * is set.
+ * Reject with unspecified status code.
+ */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0, psessionEntry);
+
+ lim_log(pMac, LOGE,
+ FL("Rejecting Re/Assoc req from 11b STA: "));
+ lim_print_mac_addr(pMac, pHdr->sa, LOGW);
+
+#ifdef WLAN_DEBUG
+ pMac->lim.gLim11bStaAssocRejectCount++;
+#endif
+ goto error;
+ }
+ }
+
+ /* Check for 802.11n HT caps compatibility; are HT Capabilities */
+ /* turned on in lim? */
+ if (psessionEntry->htCapability) {
+ /* There are; are they turned on in the STA? */
+ if (pAssocReq->HTCaps.present) {
+ /* The station *does* support 802.11n HT capability... */
+
+ lim_log(pMac, LOG1, FL("AdvCodingCap:%d ChaWidthSet:%d "
+ "PowerSave:%d greenField:%d "
+ "shortGI20:%d shortGI40:%d"
+ "txSTBC:%d rxSTBC:%d delayBA:%d"
+ "maxAMSDUsize:%d DSSS/CCK:%d "
+ "PSMP:%d stbcCntl:%d lsigTXProt:%d"),
+ pAssocReq->HTCaps.advCodingCap,
+ pAssocReq->HTCaps.supportedChannelWidthSet,
+ pAssocReq->HTCaps.mimoPowerSave,
+ pAssocReq->HTCaps.greenField,
+ pAssocReq->HTCaps.shortGI20MHz,
+ pAssocReq->HTCaps.shortGI40MHz,
+ pAssocReq->HTCaps.txSTBC,
+ pAssocReq->HTCaps.rxSTBC,
+ pAssocReq->HTCaps.delayedBA,
+ pAssocReq->HTCaps.maximalAMSDUsize,
+ pAssocReq->HTCaps.dsssCckMode40MHz,
+ pAssocReq->HTCaps.psmp,
+ pAssocReq->HTCaps.stbcControlFrame,
+ pAssocReq->HTCaps.lsigTXOPProtection);
+
+ /* Make sure the STA's caps are compatible with our own: */
+ /* 11.15.2 Support of DSSS/CCK in 40 MHz */
+ /* the AP shall refuse association requests from an HT STA that has the DSSS/CCK */
+ /* Mode in 40 MHz subfield set to 1; */
+ }
+ } /* End if on HT caps turned on in lim. */
+
+ /* Clear the buffers so that frame parser knows that there isn't a previously decoded IE in these buffers */
+ cdf_mem_set((uint8_t *) &Dot11fIERSN, sizeof(Dot11fIERSN), 0);
+ cdf_mem_set((uint8_t *) &Dot11fIEWPA, sizeof(Dot11fIEWPA), 0);
+
+ /* if additional IE is present, check if it has WscIE */
+ if (pAssocReq->addIEPresent && pAssocReq->addIE.length)
+ wpsIe =
+ limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata,
+ pAssocReq->addIE.length);
+ else {
+ lim_log(pMac, LOG1, FL("Assoc req addIEPresent = %d "
+ "addIE length = %d"),
+ pAssocReq->addIEPresent, pAssocReq->addIE.length);
+ }
+ /* when wpsIe is present, RSN/WPA IE is ignored */
+ if (wpsIe == NULL) {
+ /** check whether as RSN IE is present */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ psessionEntry->pLimStartBssReq->privacy &&
+ psessionEntry->pLimStartBssReq->rsnIE.length) {
+ lim_log(pMac, LOG1,
+ FL("RSN enabled auth, Re/Assoc req from STA: "
+ MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
+ if (pAssocReq->rsnPresent) {
+ if (pAssocReq->rsn.length) {
+ /* Unpack the RSN IE */
+ dot11f_unpack_ie_rsn(pMac,
+ &pAssocReq->rsn.
+ info[0],
+ pAssocReq->rsn.length,
+ &Dot11fIERSN);
+
+ /* Check RSN version is supported or not */
+ if (SIR_MAC_OUI_VERSION_1 ==
+ Dot11fIERSN.version) {
+ /* check the groupwise and pairwise cipher suites */
+ if (eSIR_SUCCESS !=
+ (status =
+ lim_check_rx_rsn_ie_match(pMac,
+ Dot11fIERSN,
+ psessionEntry,
+ pAssocReq->
+ HTCaps.
+ present,
+ &pmfConnection)))
+ {
+ lim_log(pMac, LOGE,
+ FL("RSN Mismatch."
+ "Rejecting Re/Assoc req from "
+ "STA: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY
+ (pHdr->sa));
+
+ /* some IE is not properly sent */
+ /* received Association req frame with RSN IE but length is 0 */
+ lim_send_assoc_rsp_mgmt_frame
+ (pMac, status, 1,
+ pHdr->sa, subType,
+ 0, psessionEntry);
+
+ goto error;
+
+ }
+ } else {
+ lim_log(pMac, LOGE,
+ FL("RSN length not correct."
+ "Rejecting Re/Assoc req from "
+ "STA: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->
+ sa));
+
+ /* received Association req frame with RSN IE version wrong */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
+ 1,
+ pHdr->
+ sa,
+ subType,
+ 0,
+ psessionEntry);
+ goto error;
+
+ }
+ } else {
+ lim_log(pMac, LOGW,
+ FL
+ ("Rejecting Re/Assoc req from STA:"
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ /* received Association req frame with RSN IE but length is 0 */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,
+ psessionEntry);
+
+ goto error;
+
+ }
+ } /* end - if(pAssocReq->rsnPresent) */
+ if ((!pAssocReq->rsnPresent) && pAssocReq->wpaPresent) {
+ /* Unpack the WPA IE */
+ if (pAssocReq->wpa.length) {
+ dot11f_unpack_ie_wpa(pMac, &pAssocReq->wpa.info[4], /* OUI is not taken care */
+ pAssocReq->wpa.length,
+ &Dot11fIEWPA);
+ /* check the groupwise and pairwise cipher suites */
+ if (eSIR_SUCCESS !=
+ (status =
+ lim_check_rx_wpa_ie_match(pMac,
+ Dot11fIEWPA,
+ psessionEntry,
+ pAssocReq->
+ HTCaps.
+ present))) {
+ lim_log(pMac, LOGW,
+ FL("WPA IE mismatch"
+ "Rejecting Re/Assoc req from "
+ "STA: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->
+ sa));
+ /* received Association req frame with WPA IE but mismatch */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ status,
+ 1,
+ pHdr->
+ sa,
+ subType,
+ 0,
+ psessionEntry);
+ goto error;
+
+ }
+ } else {
+ lim_log(pMac, LOGW,
+ FL("WPA len incorrect."
+ "Rejecting Re/Assoc req from"
+ "STA: "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ /* received Association req frame with invalid WPA IE */
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
+ 1,
+ pHdr->sa,
+ subType, 0,
+ psessionEntry);
+
+ goto error;
+ } /* end - if(pAssocReq->wpa.length) */
+ } /* end - if(pAssocReq->wpaPresent) */
+ }
+ /* end of if(psessionEntry->pLimStartBssReq->privacy
+ && psessionEntry->pLimStartBssReq->rsnIE->length) */
+ } /* end of if( ! pAssocReq->wscInfo.present ) */
+ else {
+ lim_log(pMac, LOG1, FL("Assoc req WSE IE is present"));
+ }
+
+ /**
+ * Extract 'associated' context for STA, if any.
+ * This is maintained by DPH and created by LIM.
+ */
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pHdr->sa, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+
+ /* / Extract pre-auth context for the STA, if any. */
+ pStaPreAuthContext = lim_search_pre_auth_list(pMac, pHdr->sa);
+
+ if (pStaDs == NULL) {
+ /* / Requesting STA is not currently associated */
+ if (pe_get_current_stas_count(pMac) ==
+ pMac->lim.gLimAssocStaLimit) {
+ /**
+ * Maximum number of STAs that AP can handle reached.
+ * Send Association response to peer MAC entity
+ */
+ lim_log(pMac, LOGE, FL("Max Sta count reached : %d"),
+ pMac->lim.maxStation);
+ lim_reject_association(pMac, pHdr->sa,
+ subType, false,
+ (tAniAuthType) 0, 0,
+ false,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ goto error;
+ }
+ /* / Check if STA is pre-authenticated. */
+ if ((pStaPreAuthContext == NULL) ||
+ (pStaPreAuthContext &&
+ (pStaPreAuthContext->mlmState !=
+ eLIM_MLM_AUTHENTICATED_STATE))) {
+ /**
+ * STA is not pre-authenticated yet requesting
+ * Re/Association before Authentication.
+ * OR STA is in the process of getting authenticated
+ * and sent Re/Association request.
+ * Send Deauthentication frame with 'prior
+ * authentication required' reason code.
+ */
+ lim_send_deauth_mgmt_frame(pMac, eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON, /* =9 */
+ pHdr->sa, psessionEntry, false);
+
+ lim_log(pMac, LOGE,
+ FL("received %s req on sessionid: %d from STA "
+ "that does not have pre-auth context"
+ MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ psessionEntry->peSessionId,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ goto error;
+ }
+ /* / Delete 'pre-auth' context of STA */
+ authType = pStaPreAuthContext->authType;
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+
+ /* All is well. Assign AID (after else part) */
+
+ } /* if (pStaDs == NULL) */
+ else {
+ /* STA context does exist for this STA */
+
+ if (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) {
+ /**
+ * Requesting STA is in some 'transient' state?
+ * Ignore the Re/Assoc Req frame by incrementing
+ * debug counter & logging error.
+ */
+ if (subType == LIM_ASSOC) {
+
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumAssocReqDropInvldState++;
+#endif
+ lim_log(pMac, LOGE,
+ FL("received Assoc req in state "
+ "%X from "),
+ pStaDs->mlmStaContext.mlmState);
+ } else {
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumReassocReqDropInvldState++;
+#endif
+ lim_log(pMac, LOGE,
+ FL("received ReAssoc req in state %X"
+ " from "),
+ pStaDs->mlmStaContext.mlmState);
+ }
+ lim_print_mac_addr(pMac, pHdr->sa, LOG1);
+ lim_print_mlm_state(pMac, LOG1,
+ (tLimMlmStates) pStaDs->mlmStaContext.
+ mlmState);
+
+ goto error;
+ } /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */
+
+ /* STA sent association Request frame while already in
+ * 'associated' state */
+
+#ifdef WLAN_FEATURE_11W
+ lim_log(pMac, LOG1,
+ FL
+ ("Re/Assoc request from station that is already associated"));
+ lim_log(pMac, LOG1, FL("PMF enabled %d, SA Query state %d"),
+ pStaDs->rmfEnabled, pStaDs->pmfSaQueryState);
+ if (pStaDs->rmfEnabled) {
+ switch (pStaDs->pmfSaQueryState) {
+
+ /* start SA Query procedure, respond to Association Request */
+ /* with try again later */
+ case DPH_SA_QUERY_NOT_IN_PROGRESS:
+ /*
+ * We should reset the retry counter before we start
+ * the SA query procedure, otherwise in next set of SA query
+ * procedure we will end up using the stale value.
+ */
+ pStaDs->pmfSaQueryRetryCount = 0;
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_TRY_AGAIN_LATER,
+ 1, pHdr->sa, subType,
+ pStaDs, psessionEntry);
+ lim_send_sa_query_request_frame(pMac,
+ (uint8_t *) &
+ (pStaDs->
+ pmfSaQueryCurrentTransId),
+ pHdr->sa,
+ psessionEntry);
+ pStaDs->pmfSaQueryStartTransId =
+ pStaDs->pmfSaQueryCurrentTransId;
+ pStaDs->pmfSaQueryCurrentTransId++;
+
+ /* start timer for SA Query retry */
+ if (tx_timer_activate(&pStaDs->pmfSaQueryTimer)
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL
+ ("PMF SA Query timer activation failed!"));
+ goto error;
+ }
+
+ pStaDs->pmfSaQueryState =
+ DPH_SA_QUERY_IN_PROGRESS;
+ goto error;
+
+ /* SA Query procedure still going, respond to Association */
+ /* Request with try again later */
+ case DPH_SA_QUERY_IN_PROGRESS:
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_TRY_AGAIN_LATER,
+ 1, pHdr->sa, subType,
+ 0, psessionEntry);
+ goto error;
+
+ /* SA Query procedure timed out, accept Association Request */
+ /* normally */
+ case DPH_SA_QUERY_TIMED_OUT:
+ pStaDs->pmfSaQueryState =
+ DPH_SA_QUERY_NOT_IN_PROGRESS;
+ break;
+ }
+ }
+#endif
+
+ /* no change in the capability so drop the frame */
+ if ((true ==
+ cdf_mem_compare(&pStaDs->mlmStaContext.capabilityInfo,
+ &pAssocReq->capabilityInfo,
+ sizeof(tSirMacCapabilityInfo)))
+ && (subType == LIM_ASSOC)) {
+ lim_log(pMac, LOGE,
+ FL(" Received Assoc req in state %X STAid=%d"),
+ pStaDs->mlmStaContext.mlmState, peerIdx);
+ goto error;
+ } else {
+ /**
+ * STA sent Re/association Request frame while already in
+ * 'associated' state. Update STA capabilities and
+ * send Association response frame with same AID
+ */
+ lim_log(pMac, LOG1,
+ FL("Recved Assoc req from STA already connected"
+ " UpdateConext"));
+ pStaDs->mlmStaContext.capabilityInfo =
+ pAssocReq->capabilityInfo;
+ if (pStaPreAuthContext
+ && (pStaPreAuthContext->mlmState ==
+ eLIM_MLM_AUTHENTICATED_STATE)) {
+ /* / STA has triggered pre-auth again */
+ authType = pStaPreAuthContext->authType;
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+ } else
+ authType = pStaDs->mlmStaContext.authType;
+
+ updateContext = true;
+ if (dph_init_sta_state
+ (pMac, pHdr->sa, peerIdx, true,
+ &psessionEntry->dph.dphHashTable)
+ == NULL) {
+ lim_log(pMac, LOGE,
+ FL("could not Init STAid=%d"), peerIdx);
+ goto error;
+ }
+ }
+ goto sendIndToSme;
+ } /* end if (lookup for STA in perStaDs fails) */
+
+ /* check if sta is allowed per QoS AC rules */
+ limGetWmeMode(psessionEntry, &wmeMode);
+ if ((qosMode == eHAL_SET) || (wmeMode == eHAL_SET)) {
+ /* for a qsta, check if the requested Traffic spec */
+ /* is admissible */
+ /* for a non-qsta check if the sta can be admitted */
+ if (pAssocReq->addtsPresent) {
+ uint8_t tspecIdx = 0; /* index in the sch tspec table. */
+ if (lim_admit_control_add_ts
+ (pMac, pHdr->sa, &(pAssocReq->addtsReq),
+ &(pAssocReq->qosCapability), 0, false, NULL,
+ &tspecIdx, psessionEntry) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("AdmitControl: TSPEC rejected"));
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
+ 1, pHdr->sa, subType,
+ 0, psessionEntry);
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumAssocReqDropACRejectTS++;
+#endif
+ goto error;
+ }
+ } else if (lim_admit_control_add_sta(pMac, pHdr->sa, false)
+ != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, FL("AdmitControl: Sta rejected"));
+ lim_send_assoc_rsp_mgmt_frame(pMac,
+ eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
+ 1,
+ pHdr->sa,
+ subType, 0, psessionEntry);
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimNumAssocReqDropACRejectSta++;
+#endif
+ goto error;
+ }
+ /* else all ok */
+ lim_log(pMac, LOG1, FL("AdmitControl: Sta OK!"));
+ }
+
+ /**
+ * STA is Associated !
+ */
+ lim_log(pMac, LOGE,
+ FL("Received %s Req successful from " MAC_ADDRESS_STR),
+ (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ /**
+ * AID for this association will be same as the peer Index used in DPH table.
+ * Assign unused/least recently used peer Index from perStaDs.
+ * NOTE: lim_assign_peer_idx() assigns AID values ranging
+ * between 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT)
+ */
+
+ peerIdx = lim_assign_peer_idx(pMac, psessionEntry);
+
+ if (!peerIdx) {
+ /* Could not assign AID */
+ /* Reject association */
+ lim_log(pMac, LOGE,
+ FL("PeerIdx not avaialble. Reject associaton"));
+ lim_reject_association(pMac, pHdr->sa,
+ subType, true, authType,
+ peerIdx, false,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ goto error;
+ }
+
+ /**
+ * Add an entry to hash table maintained by DPH module
+ */
+
+ pStaDs =
+ dph_add_hash_entry(pMac, pHdr->sa, peerIdx,
+ &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL) {
+ /* Could not add hash table entry at DPH */
+ lim_log(pMac, LOGE,
+ FL("could not add hash entry at DPH for aid=%d, MacAddr:"
+ MAC_ADDRESS_STR), peerIdx, MAC_ADDR_ARRAY(pHdr->sa));
+
+ /* Release AID */
+ lim_release_peer_idx(pMac, peerIdx, psessionEntry);
+
+ lim_reject_association(pMac, pHdr->sa,
+ subType, true, authType, peerIdx, false,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ goto error;
+ }
+
+sendIndToSme:
+ /*
+ * check here if the parsedAssocReq already
+ * pointing to the assoc_req and free it before
+ * assigning this new pAssocReq
+ */
+ if (psessionEntry->parsedAssocReq != NULL) {
+ pTempAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId];
+ if (pTempAssocReq != NULL) {
+ if (pTempAssocReq->assocReqFrame) {
+ cdf_mem_free(pTempAssocReq->assocReqFrame);
+ pTempAssocReq->assocReqFrame = NULL;
+ pTempAssocReq->assocReqFrameLength = 0;
+ }
+ cdf_mem_free(pTempAssocReq);
+ pTempAssocReq = NULL;
+ }
+
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
+ assoc_req_copied = true;
+ }
+
+ pStaDs->mlmStaContext.htCapability = pAssocReq->HTCaps.present;
+#ifdef WLAN_FEATURE_11AC
+ pStaDs->mlmStaContext.vhtCapability = pAssocReq->VHTCaps.present;
+#endif
+ pStaDs->qos.addtsPresent =
+ (pAssocReq->addtsPresent == 0) ? false : true;
+ pStaDs->qos.addts = pAssocReq->addtsReq;
+ pStaDs->qos.capability = pAssocReq->qosCapability;
+ pStaDs->versionPresent = 0;
+ /* short slot and short preamble should be updated before doing limaddsta */
+ pStaDs->shortPreambleEnabled =
+ (uint8_t) pAssocReq->capabilityInfo.shortPreamble;
+ pStaDs->shortSlotTimeEnabled =
+ (uint8_t) pAssocReq->capabilityInfo.shortSlotTime;
+
+ pStaDs->valid = 0;
+ pStaDs->mlmStaContext.authType = authType;
+ pStaDs->staType = STA_ENTRY_PEER;
+
+ /* TODO: If listen interval is more than certain limit, reject the association. */
+ /* Need to check customer requirements and then implement. */
+ pStaDs->mlmStaContext.listenInterval = pAssocReq->listenInterval;
+ pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo;
+
+ /* The following count will be used to knock-off the station if it doesn't
+ * come back to receive the buffered data. The AP will wait for numTimSent number
+ * of beacons after sending TIM information for the station, before assuming that
+ * the station is no more associated and disassociates it
+ */
+
+ /** timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/
+ pStaDs->timWaitCount =
+ (uint8_t) GET_TIM_WAIT_COUNT(pAssocReq->listenInterval);
+
+ /** Initialise the Current successful MPDU's tranfered to this STA count as 0 */
+ pStaDs->curTxMpduCnt = 0;
+
+ if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+ pAssocReq->HTCaps.present && pAssocReq->wmeInfoPresent) {
+ pStaDs->htGreenfield = (uint8_t) pAssocReq->HTCaps.greenField;
+ pStaDs->htAMpduDensity = pAssocReq->HTCaps.mpduDensity;
+ pStaDs->htDsssCckRate40MHzSupport =
+ (uint8_t) pAssocReq->HTCaps.dsssCckMode40MHz;
+ pStaDs->htLsigTXOPProtection =
+ (uint8_t) pAssocReq->HTCaps.lsigTXOPProtection;
+ pStaDs->htMaxAmsduLength =
+ (uint8_t) pAssocReq->HTCaps.maximalAMSDUsize;
+ pStaDs->htMaxRxAMpduFactor = pAssocReq->HTCaps.maxRxAMPDUFactor;
+ pStaDs->htMIMOPSState = pAssocReq->HTCaps.mimoPowerSave;
+
+ /* pAssocReq will be copied to psessionEntry->parsedAssocReq
+ * later
+ */
+ ht_cap_ie = ((uint8_t *) &pAssocReq->HTCaps) + 1;
+
+ /* check whether AP is enabled with shortGI */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_20MHZ, &val) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("could not retrieve shortGI 20Mhz CFG"));)
+ goto error;
+ }
+ if (val) {
+ pStaDs->htShortGI20Mhz =
+ (uint8_t)pAssocReq->HTCaps.shortGI20MHz;
+ } else {
+ /* Unset htShortGI20Mhz in ht_caps*/
+ *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI20MHZ_S);
+ pStaDs->htShortGI20Mhz = 0;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_40MHZ, &val) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("could not retrieve shortGI 40Mhz CFG"));)
+ goto error;
+ }
+ if (val) {
+ pStaDs->htShortGI40Mhz =
+ (uint8_t)pAssocReq->HTCaps.shortGI40MHz;
+ } else {
+ /* Unset htShortGI40Mhz in ht_caps */
+ *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI40MHZ_S);
+ pStaDs->htShortGI40Mhz = 0;
+ }
+
+ pStaDs->htSupportedChannelWidthSet =
+ (uint8_t) pAssocReq->HTCaps.supportedChannelWidthSet;
+ /*
+ * peer just follows AP; so when we are softAP/GO,
+ * we just store our session entry's secondary channel offset
+ * here in peer INFRA STA. However, if peer's 40MHz channel
+ * width support is disabled then secondary channel will be zero
+ */
+ pStaDs->htSecondaryChannelOffset =
+ (pStaDs->htSupportedChannelWidthSet) ? psessionEntry->
+ htSecondaryChannelOffset : 0;
+#ifdef WLAN_FEATURE_11AC
+ if (pAssocReq->operMode.present) {
+ pStaDs->vhtSupportedChannelWidthSet =
+ (uint8_t) ((pAssocReq->operMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_80MHZ) ?
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
+ pStaDs->htSupportedChannelWidthSet =
+ (uint8_t) (pAssocReq->operMode.
+ chanWidth ? eHT_CHANNEL_WIDTH_40MHZ :
+ eHT_CHANNEL_WIDTH_20MHZ);
+ } else if (pAssocReq->VHTCaps.present) {
+ /* Check if STA has enabled it's channel bonding mode. */
+ /* If channel bonding mode is enabled, we decide based on SAP's current configuration. */
+ /* else, we set it to VHT20. */
+ pStaDs->vhtSupportedChannelWidthSet =
+ (uint8_t) ((pStaDs->htSupportedChannelWidthSet ==
+ eHT_CHANNEL_WIDTH_20MHZ) ?
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
+ psessionEntry->ch_width - 1);
+ pStaDs->htMaxRxAMpduFactor =
+ pAssocReq->VHTCaps.maxAMPDULenExp;
+ }
+ /* Lesser among the AP and STA bandwidth of operation. */
+ pStaDs->htSupportedChannelWidthSet =
+ (pStaDs->htSupportedChannelWidthSet <
+ psessionEntry->htSupportedChannelWidthSet) ?
+ pStaDs->htSupportedChannelWidthSet :
+ psessionEntry->htSupportedChannelWidthSet;
+
+#endif
+ pStaDs->baPolicyFlag = 0xFF;
+ pStaDs->htLdpcCapable =
+ (uint8_t) pAssocReq->HTCaps.advCodingCap;
+ }
+
+ if (pAssocReq->VHTCaps.present && pAssocReq->wmeInfoPresent) {
+ pStaDs->vhtLdpcCapable =
+ (uint8_t) pAssocReq->VHTCaps.ldpcCodingCap;
+ }
+
+ if (!pAssocReq->wmeInfoPresent) {
+ pStaDs->mlmStaContext.htCapability = 0;
+ pStaDs->mlmStaContext.vhtCapability = 0;
+ }
+ if (pStaDs->mlmStaContext.vhtCapability) {
+ if (psessionEntry->txBFIniFeatureEnabled &&
+ pAssocReq->VHTCaps.suBeamFormerCap)
+ pStaDs->vhtBeamFormerCapable = 1;
+ else
+ pStaDs->vhtBeamFormerCapable = 0;
+ if (psessionEntry->enable_su_tx_bformer &&
+ pAssocReq->VHTCaps.suBeamformeeCap)
+ pStaDs->vht_su_bfee_capable = 1;
+ else
+ pStaDs->vht_su_bfee_capable = 0;
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (lim_populate_matching_rate_set(pMac,
+ pStaDs,
+ &(pAssocReq->supportedRates),
+ &(pAssocReq->extendedRates),
+ pAssocReq->HTCaps.supportedMCSSet,
+ psessionEntry, &pAssocReq->VHTCaps)
+ != eSIR_SUCCESS)
+#else
+
+ if (lim_populate_matching_rate_set(pMac,
+ pStaDs,
+ &(pAssocReq->supportedRates),
+ &(pAssocReq->extendedRates),
+ pAssocReq->HTCaps.supportedMCSSet,
+ psessionEntry) != eSIR_SUCCESS)
+#endif
+ {
+ /* Could not update hash table entry at DPH with rateset */
+ lim_log(pMac, LOGE,
+ FL
+ ("could not update hash entry at DPH for aid=%d, MacAddr: "
+ MAC_ADDRESS_STR), peerIdx, MAC_ADDR_ARRAY(pHdr->sa));
+
+ /* Release AID */
+ lim_release_peer_idx(pMac, peerIdx, psessionEntry);
+
+ lim_reject_association(pMac, pHdr->sa,
+ subType, true, authType, peerIdx, true,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ if (psessionEntry->parsedAssocReq)
+ pAssocReq =
+ psessionEntry->parsedAssocReq[pStaDs->assocId];
+ goto error;
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pAssocReq->operMode.present) {
+ pStaDs->vhtSupportedRxNss = pAssocReq->operMode.rxNSS + 1;
+ } else {
+ pStaDs->vhtSupportedRxNss =
+ ((pStaDs->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
+ == MCSMAPMASK2x2) ? 1 : 2;
+ }
+#endif
+
+ /* / Add STA context at MAC HW (BMU, RHP & TFP) */
+
+ pStaDs->qosMode = false;
+ pStaDs->lleEnabled = false;
+ if (pAssocReq->capabilityInfo.qos && (qosMode == eHAL_SET)) {
+ pStaDs->lleEnabled = true;
+ pStaDs->qosMode = true;
+ }
+
+ pStaDs->wmeEnabled = false;
+ pStaDs->wsmEnabled = false;
+ limGetWmeMode(psessionEntry, &wmeMode);
+ if ((!pStaDs->lleEnabled) && pAssocReq->wmeInfoPresent
+ && (wmeMode == eHAL_SET)) {
+ pStaDs->wmeEnabled = true;
+ pStaDs->qosMode = true;
+ limGetWsmMode(psessionEntry, &wsmMode);
+ /* WMM_APSD - WMM_SA related processing should be separate; WMM_SA and WMM_APSD
+ can coexist */
+ if (pAssocReq->WMMInfoStation.present) {
+ /* check whether AP supports or not */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ (psessionEntry->apUapsdEnable == 0) &&
+ (pAssocReq->WMMInfoStation.acbe_uapsd ||
+ pAssocReq->WMMInfoStation.acbk_uapsd ||
+ pAssocReq->WMMInfoStation.acvo_uapsd ||
+ pAssocReq->WMMInfoStation.acvi_uapsd)) {
+
+ /**
+ * Received Re/Association Request from
+ * STA when UPASD is not supported.
+ */
+ lim_log(pMac, LOGE,
+ FL("AP do not support UAPSD so reply "
+ "to STA accordingly"));
+ /* update UAPSD and send it to LIM to add STA */
+ pStaDs->qos.capability.qosInfo.acbe_uapsd = 0;
+ pStaDs->qos.capability.qosInfo.acbk_uapsd = 0;
+ pStaDs->qos.capability.qosInfo.acvo_uapsd = 0;
+ pStaDs->qos.capability.qosInfo.acvi_uapsd = 0;
+ pStaDs->qos.capability.qosInfo.maxSpLen = 0;
+
+ } else {
+ /* update UAPSD and send it to LIM to add STA */
+ pStaDs->qos.capability.qosInfo.acbe_uapsd =
+ pAssocReq->WMMInfoStation.acbe_uapsd;
+ pStaDs->qos.capability.qosInfo.acbk_uapsd =
+ pAssocReq->WMMInfoStation.acbk_uapsd;
+ pStaDs->qos.capability.qosInfo.acvo_uapsd =
+ pAssocReq->WMMInfoStation.acvo_uapsd;
+ pStaDs->qos.capability.qosInfo.acvi_uapsd =
+ pAssocReq->WMMInfoStation.acvi_uapsd;
+ pStaDs->qos.capability.qosInfo.maxSpLen =
+ pAssocReq->WMMInfoStation.max_sp_length;
+ }
+ }
+ if (pAssocReq->wsmCapablePresent && (wsmMode == eHAL_SET))
+ pStaDs->wsmEnabled = true;
+
+ }
+ /* Re/Assoc Response frame to requesting STA */
+ pStaDs->mlmStaContext.subType = subType;
+
+#ifdef WLAN_FEATURE_11W
+ pStaDs->rmfEnabled = (pmfConnection) ? 1 : 0;
+ pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+ timerId.fields.sessionId = psessionEntry->peSessionId;
+ timerId.fields.peerIdx = peerIdx;
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
+ &retryInterval) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Could not retrieve PMF SA Query retry interval value"));
+ lim_reject_association(pMac, pHdr->sa, subType, true, authType,
+ peerIdx, false,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ goto error;
+ }
+ if (WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN > retryInterval) {
+ retryInterval = WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF;
+ }
+ if (tx_timer_create(&pStaDs->pmfSaQueryTimer, "PMF SA Query timer",
+ lim_pmf_sa_query_timer_handler, timerId.value,
+ SYS_MS_TO_TICKS((retryInterval * 1024) / 1000),
+ 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGE, FL("could not create PMF SA Query timer"));
+ lim_reject_association(pMac, pHdr->sa,
+ subType, true, authType,
+ peerIdx, false,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ goto error;
+ }
+#endif
+
+ if (pAssocReq->ExtCap.present) {
+ lim_set_stads_rtt_cap(pStaDs,
+ (struct s_ext_cap *) pAssocReq->ExtCap.bytes, pMac);
+ } else {
+ pStaDs->timingMeasCap = 0;
+ PELOG1(lim_log(pMac, LOG1, FL("ExtCap not present"));)
+ }
+
+ /* BTAMP: Storing the parsed assoc request in the psessionEntry array */
+ if (psessionEntry->parsedAssocReq)
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
+ assoc_req_copied = true;
+
+ /* BTAMP: If STA context already exist (ie. updateContext = 1)
+ * for this STA, then we should delete the old one, and add
+ * the new STA. This is taken care of in the lim_del_sta() routine.
+ *
+ * Prior to BTAMP, we were setting this flag so that when
+ * PE receives SME_ASSOC_CNF, and if this flag is set, then
+ * PE shall delete the old station and then add. But now in
+ * BTAMP, we're directly adding station before waiting for
+ * SME_ASSOC_CNF, so we can do this now.
+ */
+ if (!updateContext) {
+ pStaDs->mlmStaContext.updateContext = 0;
+
+ /* BTAMP: Add STA context at HW - issue WMA_ADD_STA_REQ to HAL */
+ if (lim_add_sta(pMac, pStaDs, false, psessionEntry) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("could not Add STA with assocId=%d"),
+ pStaDs->assocId);
+ lim_reject_association(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true,
+ pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ if (psessionEntry->parsedAssocReq)
+ pAssocReq = psessionEntry->parsedAssocReq[
+ pStaDs->assocId];
+ goto error;
+ }
+ } else {
+ pStaDs->mlmStaContext.updateContext = 1;
+
+ mlmPrevState = pStaDs->mlmStaContext.mlmState;
+
+ /* As per the HAL/FW needs the reassoc req need not be calling lim_del_sta */
+ if (subType != LIM_REASSOC) {
+ /* we need to set the mlmState here in order differentiate in lim_del_sta. */
+ pStaDs->mlmStaContext.mlmState =
+ eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
+ if (lim_del_sta(pMac, pStaDs, true, psessionEntry) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL
+ ("could not DEL STA with assocId=%d staId %d"),
+ pStaDs->assocId, pStaDs->staIndex);
+ lim_reject_association(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.
+ subType, true,
+ pStaDs->mlmStaContext.
+ authType, pStaDs->assocId,
+ true,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+
+ /* Restoring the state back. */
+ pStaDs->mlmStaContext.mlmState = mlmPrevState;
+ if (psessionEntry->parsedAssocReq)
+ pAssocReq =
+ psessionEntry->parsedAssocReq[
+ pStaDs->assocId];
+ goto error;
+ }
+ } else {
+ /* mlmState is changed in lim_add_sta context */
+ /* use the same AID, already allocated */
+ if (lim_add_sta(pMac, pStaDs, false, psessionEntry) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("Could not AddSta with assocId= %d"
+ "staId %d"),
+ pStaDs->assocId, pStaDs->staIndex);
+ lim_reject_association(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.
+ subType, true,
+ pStaDs->mlmStaContext.
+ authType, pStaDs->assocId,
+ true,
+ (tSirResultCodes)
+ eSIR_MAC_WME_REFUSED_STATUS,
+ psessionEntry);
+
+ /* Restoring the state back. */
+ pStaDs->mlmStaContext.mlmState = mlmPrevState;
+ if (psessionEntry->parsedAssocReq)
+ pAssocReq =
+ psessionEntry->parsedAssocReq[
+ pStaDs->assocId];
+ goto error;
+ }
+
+ }
+
+ }
+
+ /* AddSta is sucess here */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
+ pAssocReq->HTCaps.present && pAssocReq->wmeInfoPresent) {
+ /** Update in the HAL Station Table for the Update of the Protection Mode */
+ lim_post_sm_state_update(pMac, pStaDs->staIndex,
+ pStaDs->htMIMOPSState,
+ pStaDs->staAddr,
+ psessionEntry->smeSessionId);
+ }
+
+ return;
+
+error:
+ if (pAssocReq != NULL) {
+ if (pAssocReq->assocReqFrame) {
+ cdf_mem_free(pAssocReq->assocReqFrame);
+ pAssocReq->assocReqFrame = NULL;
+ pAssocReq->assocReqFrameLength = 0;
+ }
+
+ cdf_mem_free(pAssocReq);
+ /* to avoid double free */
+ if (assoc_req_copied && psessionEntry->parsedAssocReq)
+ psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
+ }
+
+ /* If it is not duplicate Assoc request then only make to Null */
+ if ((pStaDs != NULL) &&
+ (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) {
+ if (psessionEntry->parsedAssocReq != NULL) {
+ pTempAssocReq =
+ psessionEntry->parsedAssocReq[pStaDs->assocId];
+ if (pTempAssocReq != NULL) {
+ if (pTempAssocReq->assocReqFrame) {
+ cdf_mem_free(pTempAssocReq->
+ assocReqFrame);
+ pTempAssocReq->assocReqFrame = NULL;
+ pTempAssocReq->assocReqFrameLength = 0;
+ }
+ cdf_mem_free(pTempAssocReq);
+ psessionEntry->
+ parsedAssocReq[pStaDs->assocId] = NULL;
+ }
+ }
+ }
+
+ return;
+
+} /*** end lim_process_assoc_req_frame() ***/
+
+#ifdef FEATURE_WLAN_WAPI
+/**
+ * lim_fill_assoc_ind_wapi_info()- Updates WAPI data in assoc indication
+ * @mac_ctx: Global Mac context
+ * @assoc_req: pointer to association request
+ * @assoc_ind: Pointer to association indication
+ * @wpsie: WPS IE
+ *
+ * This function updates WAPI meta data in association indication message
+ * sent to SME.
+ *
+ * Return: None
+ */
+static void lim_fill_assoc_ind_wapi_info(tpAniSirGlobal mac_ctx,
+ tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind,
+ uint8_t *wpsie)
+{
+ if (assoc_req->wapiPresent && (NULL == wpsie)) {
+ lim_log(mac_ctx, LOG2,
+ FL("Received WAPI IE length in Assoc Req is %d"),
+ assoc_req->wapi.length);
+ assoc_ind->wapiIE.wapiIEdata[0] = SIR_MAC_WAPI_EID;
+ assoc_ind->wapiIE.wapiIEdata[1] = assoc_req->wapi.length;
+ cdf_mem_copy(&assoc_ind->wapiIE.wapiIEdata[2],
+ assoc_req->wapi.info, assoc_req->wapi.length);
+ assoc_ind->wapiIE.length =
+ 2 + assoc_req->wapi.length;
+ }
+ return;
+}
+#endif
+
+/**
+ * lim_fill_assoc_ind_vht_info() - Updates VHT information in assoc indication
+ * @mac_ctx: Global Mac context
+ * @assoc_req: pointer to association request
+ * @session_entry: PE session entry
+ * @assoc_ind: Pointer to association indication
+ *
+ * This function updates VHT information in association indication message
+ * sent to SME.
+ *
+ * Return: None
+ */
+static void lim_fill_assoc_ind_vht_info(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tpSirAssocReq assoc_req,
+ tpLimMlmAssocInd assoc_ind)
+{
+ uint8_t chan;
+
+ if (session_entry->limRFBand == SIR_BAND_2_4_GHZ) {
+ if (session_entry->vhtCapability
+ && assoc_req->VHTCaps.present)
+ assoc_ind->chan_info.info = MODE_11AC_VHT20;
+ else if (session_entry->htCapability
+ && assoc_req->HTCaps.present)
+ assoc_ind->chan_info.info = MODE_11NG_HT20;
+ else
+ assoc_ind->chan_info.info = MODE_11G;
+ } else {
+ if (session_entry->vhtCapability
+ && assoc_req->VHTCaps.present) {
+ if ((session_entry->ch_width > CH_WIDTH_40MHZ)
+ && assoc_req->HTCaps.supportedChannelWidthSet) {
+ chan = session_entry->ch_center_freq_seg0;
+ assoc_ind->chan_info.band_center_freq1 =
+ cds_chan_to_freq(chan);
+ assoc_ind->chan_info.info = MODE_11AC_VHT80;
+ } else if ((session_entry->ch_width == CH_WIDTH_40MHZ)
+ && assoc_req->HTCaps.supportedChannelWidthSet) {
+ assoc_ind->chan_info.info = MODE_11AC_VHT40;
+ if (session_entry->htSecondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ assoc_ind->chan_info.band_center_freq1
+ += 10;
+ else
+ assoc_ind->chan_info.band_center_freq1
+ -= 10;
+ } else {
+ assoc_ind->chan_info.info = MODE_11AC_VHT20;
+ }
+ } else if (session_entry->htCapability
+ && assoc_req->HTCaps.present) {
+ if ((session_entry->ch_width == CH_WIDTH_40MHZ)
+ && assoc_req->HTCaps.supportedChannelWidthSet) {
+ assoc_ind->chan_info.info = MODE_11NA_HT40;
+ if (session_entry->htSecondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
+ assoc_ind->chan_info.band_center_freq1
+ += 10;
+ else
+ assoc_ind->chan_info.band_center_freq1
+ -= 10;
+ } else {
+ assoc_ind->chan_info.info = MODE_11NA_HT20;
+ }
+ } else {
+ assoc_ind->chan_info.info = MODE_11A;
+ }
+ }
+ return;
+}
+
+/**
+ * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
+ * @mac_ctx: Global Mac context
+ * @sta_ds: Station DPH hash entry
+ * @session_entry: PE session entry
+ *
+ * This function sends either LIM_MLM_ASSOC_IND
+ * or LIM_MLM_REASSOC_IND to SME.
+ *
+ * Return: None
+ */
+void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds, tpPESession session_entry)
+{
+ tpLimMlmAssocInd assoc_ind = NULL;
+ tpSirAssocReq assoc_req;
+ uint16_t temp, rsn_len;
+ uint32_t phy_mode;
+ uint8_t sub_type;
+ uint8_t *wpsie = NULL;
+ uint32_t tmp;
+
+ /* Get a copy of the already parsed Assoc Request */
+ assoc_req =
+ (tpSirAssocReq) session_entry->parsedAssocReq[sta_ds->assocId];
+
+ /* Get the phy_mode */
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+ /* Determine if its Assoc or ReAssoc Request */
+ if (assoc_req->reassocRequest == 1)
+ sub_type = LIM_REASSOC;
+ else
+ sub_type = LIM_ASSOC;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Sessionid %d ssid %s sub_type %d Associd %d staAddr "
+ MAC_ADDRESS_STR), session_entry->peSessionId,
+ assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
+ MAC_ADDR_ARRAY(sta_ds->staAddr));
+
+ if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) {
+ temp = sizeof(tLimMlmAssocInd);
+
+ assoc_ind = cdf_mem_malloc(temp);
+ if (NULL == assoc_ind) {
+ lim_release_peer_idx(mac_ctx, sta_ds->assocId,
+ session_entry);
+ lim_log(mac_ctx, LOGP,
+ FL("AllocateMemory failed for assoc_ind"));
+ return;
+ }
+ cdf_mem_set(assoc_ind, temp, 0);
+ cdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr,
+ (uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
+ assoc_ind->aid = sta_ds->assocId;
+ cdf_mem_copy((uint8_t *) &assoc_ind->ssId,
+ (uint8_t *) &(assoc_req->ssId),
+ assoc_req->ssId.length + 1);
+ assoc_ind->sessionId = session_entry->peSessionId;
+ assoc_ind->authType = sta_ds->mlmStaContext.authType;
+ assoc_ind->capabilityInfo = assoc_req->capabilityInfo;
+
+ /* Fill in RSN IE information */
+ assoc_ind->rsnIE.length = 0;
+ /* if WPS IE is present, ignore RSN IE */
+ if (assoc_req->addIEPresent && assoc_req->addIE.length) {
+ wpsie = limGetWscIEPtr(mac_ctx,
+ assoc_req->addIE.addIEdata,
+ assoc_req->addIE.length);
+ }
+ if (assoc_req->rsnPresent && (NULL == wpsie)) {
+ lim_log(mac_ctx, LOG2, FL("Assoc Req RSN IE len = %d"),
+ assoc_req->rsn.length);
+ assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
+ assoc_ind->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
+ assoc_ind->rsnIE.rsnIEdata[1] =
+ assoc_req->rsn.length;
+ cdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2],
+ assoc_req->rsn.info,
+ assoc_req->rsn.length);
+ }
+ /* Fill in 802.11h related info */
+ if (assoc_req->powerCapabilityPresent
+ && assoc_req->supportedChannelsPresent) {
+ assoc_ind->spectrumMgtIndicator = eSIR_TRUE;
+ assoc_ind->powerCap.minTxPower =
+ assoc_req->powerCapability.minTxPower;
+ assoc_ind->powerCap.maxTxPower =
+ assoc_req->powerCapability.maxTxPower;
+ lim_convert_supported_channels(mac_ctx, assoc_ind,
+ assoc_req);
+ } else {
+ assoc_ind->spectrumMgtIndicator = eSIR_FALSE;
+ }
+
+ /* This check is to avoid extra Sec IEs present incase of WPS */
+ if (assoc_req->wpaPresent && (NULL == wpsie)) {
+ rsn_len = assoc_ind->rsnIE.length;
+ if ((rsn_len + assoc_req->wpa.length)
+ >= SIR_MAC_MAX_IE_LENGTH) {
+ lim_log(mac_ctx, LOGE,
+ FL("rsnIEdata index out of bounds %d"),
+ rsn_len);
+ cdf_mem_free(assoc_ind);
+ return;
+ }
+ assoc_ind->rsnIE.rsnIEdata[rsn_len] =
+ SIR_MAC_WPA_EID;
+ assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
+ = assoc_req->wpa.length;
+ cdf_mem_copy(
+ &assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
+ assoc_req->wpa.info, assoc_req->wpa.length);
+ assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
+ }
+#ifdef FEATURE_WLAN_WAPI
+ lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind,
+ wpsie);
+#endif
+
+ assoc_ind->addIE.length = 0;
+ if (assoc_req->addIEPresent) {
+ cdf_mem_copy(&assoc_ind->addIE.addIEdata,
+ assoc_req->addIE.addIEdata,
+ assoc_req->addIE.length);
+ assoc_ind->addIE.length = assoc_req->addIE.length;
+ }
+ /*
+ * Add HT Capabilities into addIE for OBSS
+ * processing in hostapd
+ */
+ if (assoc_req->HTCaps.present) {
+ rsn_len = assoc_ind->addIE.length;
+ if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
+ + 2 < SIR_MAC_MAX_IE_LENGTH) {
+ assoc_ind->addIE.addIEdata[rsn_len] =
+ SIR_MAC_HT_CAPABILITIES_EID;
+ assoc_ind->addIE.addIEdata[rsn_len + 1] =
+ DOT11F_IE_HTCAPS_MIN_LEN;
+ cdf_mem_copy(
+ &assoc_ind->addIE.addIEdata[rsn_len+2],
+ ((uint8_t *)&assoc_req->HTCaps) + 1,
+ DOT11F_IE_HTCAPS_MIN_LEN);
+ assoc_ind->addIE.length +=
+ 2 + DOT11F_IE_HTCAPS_MIN_LEN;
+ } else {
+ lim_log(mac_ctx, LOGP,
+ FL("Fail:HT capabilities IE to addIE"));
+ }
+ }
+
+ if (assoc_req->wmeInfoPresent) {
+ if (wlan_cfg_get_int (mac_ctx,
+ (uint16_t) WNI_CFG_WME_ENABLED, &tmp)
+ != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("wlan_cfg_get_int failed for id %d"),
+ WNI_CFG_WME_ENABLED);
+
+ /* check whether AP is enabled with WMM */
+ if (tmp)
+ assoc_ind->WmmStaInfoPresent = 1;
+ else
+ assoc_ind->WmmStaInfoPresent = 0;
+ /*
+ * Note: we are not rejecting association here
+ * because IOT will fail
+ */
+ }
+ /* Required for indicating the frames to upper layer */
+ assoc_ind->assocReqLength = assoc_req->assocReqFrameLength;
+ assoc_ind->assocReqPtr = assoc_req->assocReqFrame;
+
+ assoc_ind->beaconPtr = session_entry->beacon;
+ assoc_ind->beaconLength = session_entry->bcnLen;
+
+ assoc_ind->chan_info.chan_id =
+ session_entry->currentOperChannel;
+ assoc_ind->chan_info.mhz =
+ cds_chan_to_freq(session_entry->currentOperChannel);
+ assoc_ind->chan_info.band_center_freq1 =
+ cds_chan_to_freq(session_entry->currentOperChannel);
+ assoc_ind->chan_info.band_center_freq2 = 0;
+ assoc_ind->chan_info.reg_info_1 =
+ (session_entry->maxTxPower << 16);
+ assoc_ind->chan_info.reg_info_2 =
+ (session_entry->maxTxPower << 8);
+ /* updates VHT information in assoc indication */
+ lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
+ assoc_ind);
+ lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
+ (uint32_t *) assoc_ind);
+ cdf_mem_free(assoc_ind);
+ }
+ return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
new file mode 100644
index 0000000..e4c672b
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c
@@ -0,0 +1,1109 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_process_assoc_rsp_frame.cc contains the code
+ * for processing Re/Association Response Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/18/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sta_hash_api.h"
+#include "lim_send_messages.h"
+
+
+extern tSirRetStatus sch_beacon_edca_process(tpAniSirGlobal pMac,
+ tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry);
+
+/**
+ * lim_update_stads_htcap() - Updates station Descriptor HT capability
+ * @mac_ctx: Pointer to Global MAC structure
+ * @sta_ds: Station Descriptor in DPH
+ * @assoc_rsp: Pointer to Association Response Structure
+ *
+ * This function is called to Update the HT capabilities in
+ * Station Descriptor (dph) Details from
+ * Association / ReAssociation Response Frame
+ *
+ * Return: None
+ */
+static void lim_update_stads_htcap(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp)
+{
+ uint16_t highest_rxrate = 0;
+ tDot11fIEHTCaps *ht_caps;
+
+ ht_caps = &assoc_rsp->HTCaps;
+ sta_ds->mlmStaContext.htCapability = assoc_rsp->HTCaps.present;
+ if (assoc_rsp->HTCaps.present) {
+ sta_ds->htGreenfield =
+ (uint8_t) ht_caps->greenField;
+ sta_ds->htSupportedChannelWidthSet =
+ (uint8_t) (ht_caps->supportedChannelWidthSet ?
+ assoc_rsp->HTInfo.recommendedTxWidthSet :
+ ht_caps->supportedChannelWidthSet);
+ sta_ds->htLsigTXOPProtection =
+ (uint8_t) ht_caps->lsigTXOPProtection;
+ sta_ds->htMIMOPSState =
+ (tSirMacHTMIMOPowerSaveState)ht_caps->mimoPowerSave;
+ sta_ds->htMaxAmsduLength =
+ (uint8_t) ht_caps->maximalAMSDUsize;
+ sta_ds->htAMpduDensity = ht_caps->mpduDensity;
+ sta_ds->htDsssCckRate40MHzSupport =
+ (uint8_t) ht_caps->dsssCckMode40MHz;
+ sta_ds->htShortGI20Mhz =
+ (uint8_t) ht_caps->shortGI20MHz;
+ sta_ds->htShortGI40Mhz =
+ (uint8_t) ht_caps->shortGI40MHz;
+ sta_ds->htMaxRxAMpduFactor =
+ ht_caps->maxRxAMPDUFactor;
+ lim_fill_rx_highest_supported_rate(mac_ctx, &highest_rxrate,
+ ht_caps->supportedMCSSet);
+ sta_ds->supportedRates.rxHighestDataRate =
+ highest_rxrate;
+ /*
+ * This is for AP as peer STA and we are INFRA STA
+ *.We will put APs offset in dph node which is peer STA
+ */
+ sta_ds->htSecondaryChannelOffset =
+ (uint8_t) assoc_rsp->HTInfo.secondaryChannelOffset;
+ /*
+ * FIXME_AMPDU
+ * In the future, may need to check for
+ * "assoc.HTCaps.delayedBA"
+ * For now, it is IMMEDIATE BA only on ALL TID's
+ */
+ sta_ds->baPolicyFlag = 0xFF;
+ }
+}
+
+/**
+ * lim_update_assoc_sta_datas() - Updates station Descriptor
+ * mac_ctx: Pointer to Global MAC structure
+ * sta_ds: Station Descriptor in DPH
+ * assoc_rsp: Pointer to Association Response Structure
+ * session_entry : PE session Entry
+ *
+ * This function is called to Update the Station Descriptor (dph) Details from
+ * Association / ReAssociation Response Frame
+ *
+ * Return: None
+ */
+void lim_update_assoc_sta_datas(tpAniSirGlobal mac_ctx,
+ tpDphHashNode sta_ds, tpSirAssocRsp assoc_rsp,
+ tpPESession session_entry)
+{
+ uint32_t phy_mode;
+ bool qos_mode;
+ tDot11fIEVHTCaps *vht_caps = NULL;
+
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+ sta_ds->staType = STA_ENTRY_SELF;
+ limGetQosMode(session_entry, &qos_mode);
+ sta_ds->mlmStaContext.authType = session_entry->limCurrentAuthType;
+
+ /* Add capabilities information, rates and AID */
+ sta_ds->mlmStaContext.capabilityInfo = assoc_rsp->capabilityInfo;
+ sta_ds->shortPreambleEnabled =
+ (uint8_t) assoc_rsp->capabilityInfo.shortPreamble;
+
+ /* Update HT Capabilites only when the self mode supports HT */
+ if (IS_DOT11_MODE_HT(session_entry->dot11mode))
+ lim_update_stads_htcap(mac_ctx, sta_ds, assoc_rsp);
+
+#ifdef WLAN_FEATURE_11AC
+ if (assoc_rsp->VHTCaps.present)
+ vht_caps = &assoc_rsp->VHTCaps;
+ else if (assoc_rsp->vendor2_ie.VHTCaps.present)
+ vht_caps = &assoc_rsp->vendor2_ie.VHTCaps;
+
+ if (IS_DOT11_MODE_VHT(session_entry->dot11mode)) {
+ if ((vht_caps != NULL) && vht_caps->present) {
+ sta_ds->mlmStaContext.vhtCapability =
+ vht_caps->present;
+ /*
+ * If 11ac is supported and if the peer is
+ * sending VHT capabilities,
+ * then htMaxRxAMpduFactor should be
+ * overloaded with VHT maxAMPDULenExp
+ */
+ sta_ds->htMaxRxAMpduFactor = vht_caps->maxAMPDULenExp;
+ if (session_entry->htSupportedChannelWidthSet) {
+ if (assoc_rsp->VHTOperation.present)
+ sta_ds->vhtSupportedChannelWidthSet =
+ assoc_rsp->VHTOperation.chanWidth;
+ else
+ sta_ds->vhtSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ }
+ }
+ }
+ if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates,
+ assoc_rsp->HTCaps.supportedMCSSet,
+ false, session_entry,
+ vht_caps) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("could not get rateset and extended rate set"));
+ return;
+ }
+#else
+ if (lim_populate_peer_rate_set(mac_ctx, &sta_ds->supportedRates,
+ assoc_rsp->HTCaps.supportedMCSSet,
+ false, session_entry) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("could not get rateset and extended rate set"));
+ return;
+ }
+#endif
+#ifdef WLAN_FEATURE_11AC
+ sta_ds->vhtSupportedRxNss =
+ ((sta_ds->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
+ == MCSMAPMASK2x2) ? 1 : 2;
+#endif
+ /* If one of the rates is 11g rates, set the ERP mode. */
+ if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
+ sirIsArate(sta_ds->supportedRates.llaRates[0] & 0x7f))
+ sta_ds->erpEnabled = eHAL_SET;
+
+ /* Could not get prop rateset from CFG. Log error. */
+ sta_ds->qosMode = 0;
+ sta_ds->lleEnabled = 0;
+
+ /* update TSID to UP mapping */
+ if (qos_mode) {
+ if (assoc_rsp->edcaPresent) {
+ tSirRetStatus status;
+ status =
+ sch_beacon_edca_process(mac_ctx,
+ &assoc_rsp->edca, session_entry);
+ lim_log(mac_ctx, LOG2,
+ "Edca set update based on AssocRsp: status %d",
+ status);
+ if (status != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("Edca error in AssocResp "));
+ } else {
+ /* update default tidmap based on ACM */
+ sta_ds->qosMode = 1;
+ sta_ds->lleEnabled = 1;
+ }
+ }
+ }
+
+ sta_ds->wmeEnabled = 0;
+ sta_ds->wsmEnabled = 0;
+ if (session_entry->limWmeEnabled && assoc_rsp->wmeEdcaPresent) {
+ tSirRetStatus status;
+ status = sch_beacon_edca_process(mac_ctx, &assoc_rsp->edca,
+ session_entry);
+ lim_log(mac_ctx, LOGW,
+ "WME Edca set update based on AssocRsp: status %d",
+ status);
+
+ if (status != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ FL("WME Edca error in AssocResp - ignoring"));
+
+ else {
+ /* update default tidmap based on HashACM */
+ sta_ds->qosMode = 1;
+ sta_ds->wmeEnabled = 1;
+ }
+ } else {
+ /*
+ * We received assoc rsp from a legacy AP.
+ * So fill in the default local EDCA params.
+ * This is needed (refer to bug #14989) as we'll
+ * be passing the gLimEdcaParams to HAL in
+ * lim_process_sta_mlm_add_bss_rsp().
+ */
+ sch_set_default_edca_params(mac_ctx, session_entry);
+ }
+
+ if (qos_mode && (!sta_ds->qosMode) &&
+ sta_ds->mlmStaContext.htCapability) {
+ /*
+ * Enable QOS for all HT AP's even though WMM
+ * or 802.11E IE is not present
+ */
+ sta_ds->qosMode = 1;
+ sta_ds->wmeEnabled = 1;
+ }
+#ifdef WLAN_FEATURE_11W
+ if (session_entry->limRmfEnabled)
+ sta_ds->rmfEnabled = 1;
+#endif
+}
+
+/**
+ * @function : lim_update_re_assoc_globals
+ *
+ * @brief : This function is called to Update the Globals (LIM) during ReAssoc.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAssocRsp - Pointer to Association Response Structure
+ *
+ * @return None
+ */
+
+void lim_update_re_assoc_globals(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
+ tpPESession psessionEntry)
+{
+ /* Update the current Bss Information */
+ cdf_mem_copy(psessionEntry->bssId,
+ psessionEntry->limReAssocbssId, sizeof(tSirMacAddr));
+ psessionEntry->currentOperChannel = psessionEntry->limReassocChannelId;
+ psessionEntry->htSecondaryChannelOffset =
+ psessionEntry->reAssocHtSupportedChannelWidthSet;
+ psessionEntry->htRecommendedTxWidthSet =
+ psessionEntry->reAssocHtRecommendedTxWidthSet;
+ psessionEntry->htSecondaryChannelOffset =
+ psessionEntry->reAssocHtSecondaryChannelOffset;
+ psessionEntry->limCurrentBssCaps = psessionEntry->limReassocBssCaps;
+ psessionEntry->limCurrentBssQosCaps =
+ psessionEntry->limReassocBssQosCaps;
+ psessionEntry->limCurrentBssPropCap =
+ psessionEntry->limReassocBssPropCap;
+
+ cdf_mem_copy((uint8_t *) &psessionEntry->ssId,
+ (uint8_t *) &psessionEntry->limReassocSSID,
+ psessionEntry->limReassocSSID.length + 1);
+
+ /* Store assigned AID for TIM processing */
+ psessionEntry->limAID = pAssocRsp->aid & 0x3FFF;
+ /** Set the State Back to ReAssoc Rsp*/
+ psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+
+}
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/**
+ * lim_update_ric_data() - update session with ric data
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp: pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update PE session context with RIC data.
+ *
+ * Return: None
+ */
+static void lim_update_ric_data(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp)
+{
+ if (session_entry->ricData != NULL) {
+ cdf_mem_free(session_entry->ricData);
+ session_entry->ricData = NULL;
+ }
+ if (assoc_rsp->ricPresent) {
+ session_entry->RICDataLen =
+ assoc_rsp->num_RICData * sizeof(tDot11fIERICDataDesc);
+ session_entry->ricData =
+ cdf_mem_malloc(session_entry->RICDataLen);
+ if (NULL == session_entry->ricData) {
+ lim_log(mac_ctx, LOGE,
+ FL("Assoc res/RIC: Unable to allocate memory"));
+ session_entry->RICDataLen = 0;
+ } else {
+ cdf_mem_copy(session_entry->ricData,
+ &assoc_rsp->RICData[0],
+ session_entry->RICDataLen);
+ }
+ } else {
+ lim_log(mac_ctx, LOG1,
+ FL("Ric is not present,Set RICDataLen & RicData to 0"));
+ session_entry->RICDataLen = 0;
+ session_entry->ricData = NULL;
+ }
+ return;
+}
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+
+/**
+ * lim_update_ese_tspec() - update session with Tspec info.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp: pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update PE session context with Tspec data.
+ *
+ * Return: None
+ */
+static void lim_update_ese_tspec(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp)
+{
+ if (session_entry->tspecIes != NULL) {
+ cdf_mem_free(session_entry->tspecIes);
+ session_entry->tspecIes = NULL;
+ }
+ if (assoc_rsp->tspecPresent) {
+ session_entry->tspecLen =
+ assoc_rsp->num_tspecs * sizeof(tDot11fIEWMMTSPEC);
+ session_entry->tspecIes =
+ cdf_mem_malloc(session_entry->tspecLen);
+ if (NULL == session_entry->tspecIes) {
+ lim_log(mac_ctx, LOGE,
+ FL("Assoc Rsp/Tspec:Fail to allocate memory"));
+ session_entry->tspecLen = 0;
+ } else {
+ cdf_mem_copy(session_entry->tspecIes,
+ &assoc_rsp->TSPECInfo[0],
+ session_entry->tspecLen);
+ }
+ lim_log(mac_ctx, LOG1, FL(" Tspec EID present in assoc rsp "));
+ } else {
+ session_entry->tspecLen = 0;
+ session_entry->tspecIes = NULL;
+ lim_log(mac_ctx, LOG1,
+ FL(" Tspec EID *NOT* present in assoc rsp "));
+ }
+ return;
+}
+
+/**
+ * lim_update_ese_tsm() - update session with TSM info.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp: pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update PE session context with TSM IE data and send
+ * eWNI_TSM_IE_IND to SME.
+ *
+ * Return: None
+ */
+static void lim_update_ese_tsm(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp)
+{
+ uint8_t cnt = 0;
+ tpEseTSMContext tsm_ctx;
+
+ lim_log(mac_ctx, LOG1,
+ FL("TSM IE Present in Reassoc Rsp"));
+ /*
+ * Start the TSM timer only if the TSPEC
+ * Ie is present in the reassoc rsp
+ */
+ if (!assoc_rsp->tspecPresent) {
+ lim_log(mac_ctx, LOGE,
+ FL("TSM present but TSPEC IE not present"));
+ return;
+ }
+ tsm_ctx = &session_entry->eseContext.tsm;
+ /* Find the TSPEC IE with VO user priority */
+ for (cnt = 0; cnt < assoc_rsp->num_tspecs; cnt++) {
+ if (upToAc(assoc_rsp->TSPECInfo[cnt].user_priority) ==
+ EDCA_AC_VO) {
+ tsm_ctx->tid =
+ assoc_rsp->TSPECInfo[cnt].user_priority;
+ cdf_mem_copy(&tsm_ctx->tsmInfo,
+ &assoc_rsp->tsmIE, sizeof(tSirMacESETSMIE));
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ lim_send_sme_tsm_ie_ind(mac_ctx,
+ session_entry, assoc_rsp->tsmIE.tsid,
+ assoc_rsp->tsmIE.state,
+ assoc_rsp->tsmIE.msmt_interval);
+#else
+ limActivateTSMStatsTimer(mac_ctx, session_entry);
+#endif
+ if (tsm_ctx->tsmInfo.state)
+ tsm_ctx->tsmMetrics.RoamingCount++;
+ break;
+ }
+ }
+}
+#endif
+
+/**
+ * lim_update_stads_ext_cap() - update sta ds with ext cap
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE session handle
+ * @assoc_rsp: pointer to assoc response
+ *
+ * This function is called by lim_process_assoc_rsp_frame() to
+ * update STA DS with ext capablities.
+ *
+ * Return: None
+ */
+static void lim_update_stads_ext_cap(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tpSirAssocRsp assoc_rsp,
+ tpDphHashNode sta_ds)
+{
+ struct s_ext_cap *ext_cap;
+ if (!assoc_rsp->ExtCap.present) {
+ sta_ds->timingMeasCap = 0;
+#ifdef FEATURE_WLAN_TDLS
+ session_entry->tdls_prohibited = false;
+ session_entry->tdls_chan_swit_prohibited = false;
+#endif
+ lim_log(mac_ctx, LOG1, FL("ExtCap not present"));
+ return;
+ }
+
+ ext_cap = (struct s_ext_cap *)assoc_rsp->ExtCap.bytes;
+ lim_set_stads_rtt_cap(sta_ds, ext_cap, mac_ctx);
+#ifdef FEATURE_WLAN_TDLS
+ session_entry->tdls_prohibited = ext_cap->tdls_prohibited;
+ session_entry->tdls_chan_swit_prohibited =
+ ext_cap->tdls_chan_swit_prohibited;
+ lim_log(mac_ctx, LOG1,
+ FL("ExtCap: tdls_prohibited:%d, tdls_chan_swit_prohibited: %d"),
+ ext_cap->tdls_prohibited,
+ ext_cap->tdls_chan_swit_prohibited);
+#endif
+}
+
+/**
+ * lim_process_assoc_rsp_frame() - Processes assoc response
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_packet_info - A pointer to Rx packet info structure
+ * @sub_type - Indicates whether it is Association Response (=0) or
+ * Reassociation Response (=1) frame
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Re/Association Response frame reception.
+ *
+ * Return: None
+ */
+
+void
+lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_pkt_info, uint8_t subtype, tpPESession session_entry)
+{
+ uint8_t *body;
+ uint16_t caps, ie_len;
+ uint32_t frame_len;
+ tSirMacAddr current_bssid;
+ tpSirMacMgmtHdr hdr = NULL;
+ tSirMacCapabilityInfo mac_capab;
+ tpDphHashNode sta_ds;
+ tpSirAssocRsp assoc_rsp;
+ tLimMlmAssocCnf assoc_cnf;
+ tSchBeaconStruct *beacon;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ uint8_t sme_sessionid = 0;
+#endif
+ tCsrRoamSession *roam_session;
+
+ /* Initialize status code to success. */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (session_entry->bRoamSynchInProgress)
+ hdr = (tpSirMacMgmtHdr) mac_ctx->roam.pReassocResp;
+ else
+#endif
+ hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ sme_sessionid = session_entry->smeSessionId;
+#endif
+ assoc_cnf.resultCode = eSIR_SME_SUCCESS;
+ /* Update PE session Id */
+ assoc_cnf.sessionId = session_entry->peSessionId;
+ if (hdr == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("LFR3: Reassoc response packet header is NULL"));
+ return;
+ } else if (hdr->sa == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("LFR3: Reassoc resp packet source address is NULL"));
+ return;
+ }
+
+ lim_log(mac_ctx, LOG1,
+ FL("received Re/Assoc(%d) resp on sessionid: %d systemrole: %d"
+ "and mlmstate: %d RSSI %d from " MAC_ADDRESS_STR), subtype,
+ session_entry->peSessionId, GET_LIM_SYSTEM_ROLE(session_entry),
+ session_entry->limMlmState,
+ (uint) abs((int8_t) WMA_GET_RX_RSSI_DB(rx_pkt_info)),
+ MAC_ADDR_ARRAY(hdr->sa));
+
+ beacon = cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == beacon) {
+ lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ /*
+ * Should not have received Re/Association
+ * Response frame on AP. Log error
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("Should not recieved Re/Assoc Response in role %d "),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ cdf_mem_free(beacon);
+ return;
+ }
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (session_entry->bRoamSynchInProgress) {
+ hdr = (tpSirMacMgmtHdr) mac_ctx->roam.pReassocResp;
+ frame_len = mac_ctx->roam.reassocRespLen - SIR_MAC_HDR_LEN_3A;
+ } else {
+#endif
+ hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+}
+#endif
+ if (((subtype == LIM_ASSOC) &&
+ (session_entry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) ||
+ ((subtype == LIM_REASSOC) &&
+ ((session_entry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE)
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ && (session_entry->limMlmState !=
+ eLIM_MLM_WT_FT_REASSOC_RSP_STATE)
+#endif
+ ))) {
+ /* Received unexpected Re/Association Response frame */
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1,
+ FL("Recieved Re/Assoc rsp in unexpected "
+ "state %d on session=%d"),
+ session_entry->limMlmState, session_entry->peSessionId);
+#endif
+ if (!hdr->fc.retry) {
+ if (!(mac_ctx->lim.retry_packet_cnt & 0xf)) {
+ lim_log(mac_ctx, LOGE,
+ FL("recvd Re/Assoc rsp:not a retry frame"));
+ lim_print_mlm_state(mac_ctx, LOGE,
+ session_entry->limMlmState);
+ } else {
+ mac_ctx->lim.retry_packet_cnt++;
+ }
+ }
+ cdf_mem_free(beacon);
+ return;
+ }
+ sir_copy_mac_addr(current_bssid, session_entry->bssId);
+ if (subtype == LIM_ASSOC) {
+ if (!cdf_mem_compare
+ (hdr->sa, current_bssid, sizeof(tSirMacAddr))) {
+ /*
+ * Received Association Response frame from an entity
+ * other than one to which request was initiated.
+ * Ignore this and wait until Assoc Failure Timeout
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("received AssocRsp from unexpected peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(hdr->sa));
+ cdf_mem_free(beacon);
+ return;
+ }
+ } else {
+ if (!cdf_mem_compare
+ (hdr->sa, session_entry->limReAssocbssId,
+ sizeof(tSirMacAddr))) {
+ /*
+ * Received Reassociation Response frame from an entity
+ * other than one to which request was initiated.
+ * Ignore this and wait until Reassoc Failure Timeout.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("received ReassocRsp from unexpected peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(hdr->sa));
+ cdf_mem_free(beacon);
+ return;
+ }
+ }
+
+ assoc_rsp = cdf_mem_malloc(sizeof(*assoc_rsp));
+ if (NULL == assoc_rsp) {
+ lim_log(mac_ctx, LOGP,
+ FL("Allocate Memory failed in AssocRsp"));
+ cdf_mem_free(beacon);
+ return;
+ }
+ /* Get pointer to Re/Association Response frame body */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (session_entry->bRoamSynchInProgress)
+ body = mac_ctx->roam.pReassocResp + SIR_MAC_HDR_LEN_3A;
+ else
+#endif
+ body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ /* parse Re/Association Response frame. */
+ if (sir_convert_assoc_resp_frame2_struct(mac_ctx, body,
+ frame_len, assoc_rsp) == eSIR_FAILURE) {
+ cdf_mem_free(assoc_rsp);
+ lim_log(mac_ctx, LOGE,
+ FL("Parse error Assoc resp subtype %d," "length=%d"),
+ frame_len, subtype);
+ cdf_mem_free(beacon);
+ return;
+ }
+
+ if (!assoc_rsp->suppRatesPresent) {
+ lim_log(mac_ctx, LOGE,
+ FL("assoc response does not have supported rate set"));
+ cdf_mem_copy(&assoc_rsp->supportedRates,
+ &session_entry->rateSet,
+ sizeof(tSirMacRateSet));
+ }
+
+ assoc_cnf.protStatusCode = assoc_rsp->statusCode;
+ if (session_entry->assocRsp != NULL) {
+ lim_log(mac_ctx, LOGW,
+ FL("session_entry->assocRsp is not NULL freeing it "
+ "and setting NULL"));
+ cdf_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+ }
+
+ session_entry->assocRsp = cdf_mem_malloc(frame_len);
+ if (NULL == session_entry->assocRsp) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to allocate memory for assoc res,len=%d"),
+ frame_len);
+ } else {
+ /*
+ * Store the Assoc response. This is sent
+ * to csr/hdd in join cnf response.
+ */
+ cdf_mem_copy(session_entry->assocRsp, body, frame_len);
+ session_entry->assocRspLen = frame_len;
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ lim_update_ric_data(mac_ctx, session_entry, assoc_rsp);
+#endif
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ roam_session =
+ &mac_ctx->roam.roamSession[sme_sessionid];
+ if (assoc_rsp->FTInfo.R0KH_ID.present) {
+ roam_session->ftSmeContext.r0kh_id_len =
+ assoc_rsp->FTInfo.R0KH_ID.num_PMK_R0_ID;
+ cdf_mem_copy(roam_session->ftSmeContext.r0kh_id,
+ assoc_rsp->FTInfo.R0KH_ID.PMK_R0_ID,
+ roam_session->ftSmeContext.r0kh_id_len);
+ } else {
+ roam_session->ftSmeContext.r0kh_id_len = 0;
+ cdf_mem_zero(roam_session->ftSmeContext.r0kh_id,
+ SIR_ROAM_R0KH_ID_MAX_LEN);
+ }
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ lim_update_ese_tspec(mac_ctx, session_entry, assoc_rsp);
+#endif
+
+ if (assoc_rsp->capabilityInfo.ibss) {
+ /*
+ * Received Re/Association Response from peer
+ * with IBSS capability set.
+ * Ignore the frame and wait until Re/assoc
+ * failure timeout.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("received Re/AssocRsp frame with IBSS capability"));
+ cdf_mem_free(assoc_rsp);
+ cdf_mem_free(beacon);
+ return;
+ }
+
+ if (cfg_get_capability_info(mac_ctx, &caps, session_entry)
+ != eSIR_SUCCESS) {
+ cdf_mem_free(assoc_rsp);
+ cdf_mem_free(beacon);
+ lim_log(mac_ctx, LOGP, FL("could not retrieve Capabilities "));
+ return;
+ }
+ lim_copy_u16((uint8_t *) &mac_capab, caps);
+
+ /* Stop Association failure timer */
+ if (subtype == LIM_ASSOC)
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER);
+ else
+ {
+ /* Stop Reassociation failure timer */
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ mac_ctx->lim.reAssocRetryAttempt = 0;
+ if ((NULL != mac_ctx->lim.pSessionEntry)
+ && (NULL !=
+ mac_ctx->lim.pSessionEntry->pLimMlmReassocRetryReq)) {
+ cdf_mem_free(
+ mac_ctx->lim.pSessionEntry->pLimMlmReassocRetryReq);
+ mac_ctx->lim.pSessionEntry->pLimMlmReassocRetryReq =
+ NULL;
+ }
+#endif
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_REASSOC_FAIL_TIMER);
+ }
+
+ if (assoc_rsp->statusCode != eSIR_MAC_SUCCESS_STATUS
+#ifdef WLAN_FEATURE_11W
+ && assoc_rsp->statusCode != eSIR_MAC_TRY_AGAIN_LATER
+#endif
+ ) {
+ /*
+ *Re/Association response was received
+ * either with failure code.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("received Re/AssocRsp frame failure code %d"),
+ assoc_rsp->statusCode);
+ /*
+ * Need to update 'association failure' error counter
+ * along with STATUS CODE
+ * Return Assoc confirm to SME with received failure code
+ */
+ assoc_cnf.resultCode = eSIR_SME_ASSOC_REFUSED;
+ /* Delete Pre-auth context for the associated BSS */
+ if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
+ lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+ goto assocReject;
+ } else if ((assoc_rsp->aid & 0x3FFF) > 2007) {
+ /*
+ * Re/Association response was received
+ * with invalid AID value
+ */
+ lim_log(mac_ctx, LOGE, FL("received Re/AssocRsp frame with"
+ "invalid aid %X"), assoc_rsp->aid);
+ assoc_cnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED;
+ assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Send advisory Disassociation frame to AP */
+ lim_send_disassoc_mgmt_frame(mac_ctx,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,
+ hdr->sa, session_entry, false);
+ goto assocReject;
+ }
+ /*
+ * Association Response received with success code
+ * Set the link state to POSTASSOC now that we have received
+ * assoc/reassoc response
+ * NOTE: for BTAMP case, it is being handled in
+ * lim_process_mlm_assoc_req
+ */
+#ifdef WLAN_FEATURE_11W
+ if (assoc_rsp->statusCode == eSIR_MAC_TRY_AGAIN_LATER) {
+ if (assoc_rsp->TimeoutInterval.present &&
+ (assoc_rsp->TimeoutInterval.timeoutType ==
+ SIR_MAC_TI_TYPE_ASSOC_COMEBACK)) {
+ uint16_t timeout_value =
+ assoc_rsp->TimeoutInterval.timeoutValue;
+ if (timeout_value < 10) {
+ /*
+ * if this value is less than 10 then our timer
+ * will fail to start and due to this we will
+ * never re-attempt. Better modify the timer
+ * value here.
+ */
+ timeout_value = 10;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("ASSOC res with eSIR_MAC_TRY_AGAIN_LATER "
+ " recvd.Starting timer to wait timeout=%d."),
+ timeout_value);
+ if (CDF_STATUS_SUCCESS !=
+ cdf_mc_timer_start(
+ &session_entry->pmfComebackTimer,
+ timeout_value)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to start comeback timer."));
+ }
+ } else {
+ lim_log(mac_ctx, LOGW,
+ FL("ASSOC resp with try again event recvd. "
+ "But try again time interval IE is wrong."));
+ }
+ cdf_mem_free(beacon);
+ cdf_mem_free(assoc_rsp);
+ return;
+ }
+#endif
+ if (!((session_entry->bssType == eSIR_BTAMP_STA_MODE) ||
+ ((session_entry->bssType == eSIR_BTAMP_AP_MODE) &&
+ LIM_IS_BT_AMP_STA_ROLE(session_entry)))) {
+ if (lim_set_link_state
+ (mac_ctx, eSIR_LINK_POSTASSOC_STATE,
+ session_entry->bssId,
+ session_entry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("Set link state to POSTASSOC failed"));
+ cdf_mem_free(beacon);
+ cdf_mem_free(assoc_rsp);
+ return;
+ }
+ }
+ if (subtype == LIM_REASSOC) {
+ lim_log
+ (mac_ctx, LOG1, FL("Successfully Reassociated with BSS"));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
+ session_entry, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+#ifdef FEATURE_WLAN_ESE
+ if (assoc_rsp->tsmPresent)
+ lim_update_ese_tsm(mac_ctx, session_entry, assoc_rsp);
+#endif
+ if (session_entry->pLimMlmJoinReq) {
+ cdf_mem_free(session_entry->pLimMlmJoinReq);
+ session_entry->pLimMlmJoinReq = NULL;
+ }
+
+ session_entry->limAssocResponseData = (void *)assoc_rsp;
+ /*
+ * Store the ReAssocRsp Frame in DphTable
+ * to be used during processing DelSta and
+ * DelBss to send AddBss again
+ */
+ sta_ds =
+ dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+
+ if (!sta_ds) {
+ lim_log(mac_ctx, LOGE,
+ FL("could not get hash entry at DPH for"));
+ lim_print_mac_addr(mac_ctx, hdr->sa, LOGE);
+ assoc_cnf.resultCode =
+ eSIR_SME_INVALID_ASSOC_RSP_RXED;
+ assoc_cnf.protStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ /* Send advisory Disassociation frame to AP */
+ lim_send_disassoc_mgmt_frame(mac_ctx,
+ eSIR_MAC_UNSPEC_FAILURE_REASON, hdr->sa,
+ session_entry, false);
+ goto assocReject;
+ }
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ if (session_entry->limMlmState ==
+ eLIM_MLM_WT_FT_REASSOC_RSP_STATE) {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("Sending self sta"));
+#endif
+ lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp,
+ session_entry);
+ /* Store assigned AID for TIM processing */
+ session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+ /* Downgrade the EDCA parameters if needed */
+ lim_set_active_edca_params(mac_ctx,
+ session_entry->gLimEdcaParams,
+ session_entry);
+ /* Send the active EDCA parameters to HAL */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (!session_entry->bRoamSynchInProgress) {
+#endif
+ lim_send_edca_params(mac_ctx,
+ session_entry->gLimEdcaParamsActive,
+ sta_ds->bssId);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ }
+#endif
+ lim_add_ft_sta_self(mac_ctx, (assoc_rsp->aid & 0x3FFF),
+ session_entry);
+ cdf_mem_free(beacon);
+ return;
+ }
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+ /*
+ * If we're re-associating to the same BSS,
+ * we don't want to invoke delete STA, delete
+ * BSS, as that would remove the already
+ * established TSPEC. Just go ahead and re-add
+ * the BSS, STA with new capability information.
+ * However, if we're re-associating to a different
+ * BSS, then follow thru with del STA, del BSS,
+ * add BSS, add STA.
+ */
+ if (sir_compare_mac_addr(session_entry->bssId,
+ session_entry->limReAssocbssId))
+ lim_handle_add_bss_in_re_assoc_context(mac_ctx, sta_ds,
+ session_entry);
+ else {
+ /*
+ * reset the uapsd mask settings since
+ * we're re-associating to new AP
+ */
+ session_entry->gUapsdPerAcDeliveryEnableMask = 0;
+ session_entry->gUapsdPerAcTriggerEnableMask = 0;
+
+ if (lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry)
+ != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("Could not cleanup the rx path"));
+ goto assocReject;
+ }
+ }
+ cdf_mem_free(beacon);
+ return;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("Successfully Associated with BSS " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(hdr->sa));
+#ifdef FEATURE_WLAN_ESE
+ if (session_entry->eseContext.tsm.tsmInfo.state)
+ session_entry->eseContext.tsm.tsmMetrics.RoamingCount = 0;
+#endif
+ /* Store assigned AID for TIM processing */
+ session_entry->limAID = assoc_rsp->aid & 0x3FFF;
+
+ /* STA entry was created during pre-assoc state. */
+ sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ /* Could not add hash table entry */
+ lim_log(mac_ctx, LOGE, FL("could not get hash entry at DPH "));
+ lim_print_mac_addr(mac_ctx, hdr->sa, LOGE);
+ assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ assoc_cnf.protStatusCode = eSIR_SME_SUCCESS;
+ lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+ (uint32_t *) &assoc_cnf);
+ cdf_mem_free(assoc_rsp);
+ cdf_mem_free(beacon);
+ return;
+ }
+ /* Delete Pre-auth context for the associated BSS */
+ if (lim_search_pre_auth_list(mac_ctx, hdr->sa))
+ lim_delete_pre_auth_node(mac_ctx, hdr->sa);
+
+ lim_update_assoc_sta_datas(mac_ctx, sta_ds, assoc_rsp, session_entry);
+ /*
+ * Extract the AP capabilities from the beacon that
+ * was received earlier
+ */
+ ie_len = lim_get_ielen_from_bss_description(
+ &session_entry->pLimJoinReq->bssDescription);
+ lim_extract_ap_capabilities(mac_ctx,
+ (uint8_t *) session_entry->pLimJoinReq->bssDescription.ieFields,
+ ie_len,
+ beacon);
+
+ if (mac_ctx->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_sta_protection_on_assoc(mac_ctx, beacon,
+ session_entry);
+
+ if (beacon->erpPresent) {
+ if (beacon->erpIEInfo.barkerPreambleMode)
+ session_entry->beaconParams.fShortPreamble = false;
+ else
+ session_entry->beaconParams.fShortPreamble = true;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_CONNECTED, session_entry,
+ eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ if (assoc_rsp->QosMapSet.present)
+ cdf_mem_copy(&session_entry->QosMapSet,
+ &assoc_rsp->QosMapSet, sizeof(tSirQosMapSet));
+ else
+ cdf_mem_zero(&session_entry->QosMapSet, sizeof(tSirQosMapSet));
+
+ lim_update_stads_ext_cap(mac_ctx, session_entry, assoc_rsp, sta_ds);
+ /* Update the BSS Entry, this entry was added during preassoc. */
+ if (eSIR_SUCCESS == lim_sta_send_add_bss(mac_ctx, assoc_rsp,
+ beacon,
+ &session_entry->pLimJoinReq->bssDescription, true,
+ session_entry)) {
+ cdf_mem_free(assoc_rsp);
+ cdf_mem_free(beacon);
+ return;
+ } else {
+ lim_log(mac_ctx, LOGE, FL("could not update the bss entry"));
+ assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ }
+
+assocReject:
+ if ((subtype == LIM_ASSOC)
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ || ((subtype == LIM_REASSOC)
+ && (session_entry->limMlmState ==
+ eLIM_MLM_WT_FT_REASSOC_RSP_STATE))
+#endif
+ ) {
+ lim_log(mac_ctx, LOGE, FL("Assoc Rejected by the peer. "
+ "mlmestate: %d sessionid %d Reason: %d MACADDR:"
+ MAC_ADDRESS_STR),
+ session_entry->limMlmState,
+ session_entry->peSessionId,
+ assoc_cnf.resultCode, MAC_ADDR_ARRAY(hdr->sa));
+ session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId,
+ session_entry->limMlmState));
+ if (session_entry->pLimMlmJoinReq) {
+ cdf_mem_free(session_entry->pLimMlmJoinReq);
+ session_entry->pLimMlmJoinReq = NULL;
+ }
+ if (subtype == LIM_ASSOC) {
+ lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+ (uint32_t *) &assoc_cnf);
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ else {
+ assoc_cnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+ lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
+ (uint32_t *)&assoc_cnf);
+ }
+#endif
+ } else {
+ lim_restore_pre_reassoc_state(mac_ctx,
+ eSIR_SME_REASSOC_REFUSED,
+ assoc_cnf.protStatusCode,
+ session_entry);
+ }
+
+ cdf_mem_free(beacon);
+ cdf_mem_free(assoc_rsp);
+ return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
new file mode 100644
index 0000000..9871cff
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -0,0 +1,1929 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_process_auth_frame.cc contains the code
+ * for processing received Authentication Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/12/2010 js To support Shared key authentication at AP side
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft.h"
+#endif
+#include "cds_utils.h"
+
+/**
+ * is_auth_valid
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_auth_frame() upon Authentication
+ * frame reception.
+ *
+ ***LOGIC:
+ * This function is used to test validity of auth frame:
+ * - AUTH1 and AUTH3 must be received in AP mode
+ * - AUTH2 and AUTH4 must be received in STA mode
+ * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to
+ * SIR_MAC_CHALLENGE_TEXT_EID by parser
+ * -
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param *auth - Pointer to extracted auth frame body
+ *
+ * @return 0 or 1 (Valid)
+ */
+
+static inline unsigned int is_auth_valid(tpAniSirGlobal pMac,
+ tpSirMacAuthFrameBody auth,
+ tpPESession sessionEntry)
+{
+ unsigned int valid = 1;
+
+ if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1) ||
+ (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3)) &&
+ (LIM_IS_STA_ROLE(sessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(sessionEntry)))
+ valid = 0;
+
+ if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_2) ||
+ (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
+ (LIM_IS_AP_ROLE(sessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(sessionEntry)))
+ valid = 0;
+
+ if (((auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_3) ||
+ (auth->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_4)) &&
+ (auth->type != SIR_MAC_CHALLENGE_TEXT_EID) &&
+ (auth->authAlgoNumber != eSIR_SHARED_KEY))
+ valid = 0;
+
+ return valid;
+}
+
+/**
+ * lim_process_auth_frame
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon Authentication
+ * frame reception.
+ *
+ ***LOGIC:
+ * This function processes received Authentication frame and responds
+ * with either next Authentication frame in sequence to peer MAC entity
+ * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA.
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * 1. Authentication failures are reported to SME with same status code
+ * received from the peer MAC entity.
+ * 2. Authentication frame2/4 received with alogirthm number other than
+ * one requested in frame1/3 are logged with an error and auth confirm
+ * will be sent to SME only after auth failure timeout.
+ * 3. Inconsistency in the spec:
+ * On receiving Auth frame2, specs says that if WEP key mapping key
+ * or default key is NULL, Auth frame3 with a status code 15 (challenge
+ * failure to be returned to peer entity. However, section 7.2.3.10,
+ * table 14 says that status code field is 'reserved' for frame3 !
+ * In the current implementation, Auth frame3 is returned with status
+ * code 15 overriding section 7.2.3.10.
+ * 4. If number pre-authentications reach configrable max limit,
+ * Authentication frame with 'unspecified failure' status code is
+ * returned to requesting entity.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Rx packet info structure
+ * @return None
+ */
+
+void
+lim_process_auth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ uint8_t *pBody, keyId, cfgPrivacyOptImp,
+ defaultKey[SIR_MAC_KEY_LENGTH],
+ encrAuthFrame[LIM_ENCR_AUTH_BODY_LEN], plainBody[256];
+ uint16_t frameLen;
+ uint32_t maxNumPreAuth, val;
+ tSirMacAuthFrameBody *pRxAuthFrameBody, rxAuthFrame, authFrame;
+ tpSirMacMgmtHdr pHdr;
+ struct tLimPreAuthNode *pAuthNode;
+ uint8_t decryptResult;
+ uint8_t *pChallenge;
+ uint32_t key_length = 8;
+ uint8_t challengeTextArray[SIR_MAC_AUTH_CHALLENGE_LENGTH];
+ tpDphHashNode pStaDs = NULL;
+ uint16_t assocId = 0;
+ uint16_t curr_seq_num = 0;
+
+ /* Get pointer to Authentication frame header and body */
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ if (!frameLen) {
+ /* Log error */
+ lim_log(pMac, LOGE,
+ FL("received Authentication frame with no body from "));
+ lim_print_mac_addr(pMac, pHdr->sa, LOGE);
+
+ return;
+ }
+
+ if (lim_is_group_addr(pHdr->sa)) {
+ /* Received Auth frame from a BC/MC address */
+ /* Log error and ignore it */
+ lim_log(pMac, LOGE, FL (
+ "received Auth frame from a BC/MC addr - "));
+ PELOGE(lim_print_mac_addr(pMac, pHdr->sa, LOGE);)
+
+ return;
+ }
+ curr_seq_num = (pHdr->seqControl.seqNumHi << 4) |
+ (pHdr->seqControl.seqNumLo);
+
+ lim_log(pMac, LOG1,
+ FL("Sessionid: %d System role : %d limMlmState: %d :Auth "
+ "Frame Received: BSSID: " MAC_ADDRESS_STR " (RSSI %d)"),
+ psessionEntry->peSessionId, GET_LIM_SYSTEM_ROLE(psessionEntry),
+ psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->bssId),
+ (uint) abs((int8_t) WMA_GET_RX_RSSI_DB(pRxPacketInfo)));
+
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ /* Restore default failure timeout */
+ if (CDF_P2P_CLIENT_MODE == psessionEntry->pePersona
+ && psessionEntry->defaultAuthFailureTimeout) {
+ lim_log(pMac, LOG1, FL("Restore default failure timeout"));
+ cfg_set_int(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ psessionEntry->defaultAuthFailureTimeout);
+ }
+ /* / Determine if WEP bit is set in the FC or received MAC header */
+ if (pHdr->fc.wep) {
+ /**
+ * WEP bit is set in FC of MAC header.
+ */
+
+ /* If TKIP counter measures enabled issue Deauth frame to station */
+ if (psessionEntry->bTkipCntrMeasActive &&
+ LIM_IS_AP_ROLE(psessionEntry)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("Tkip counter measures Enabled, sending Deauth frame to"));
+ )
+ lim_print_mac_addr(pMac, pHdr->sa, LOGE);
+
+ lim_send_deauth_mgmt_frame(pMac,
+ eSIR_MAC_MIC_FAILURE_REASON,
+ pHdr->sa, psessionEntry, false);
+ return;
+ }
+ /* Extract key ID from IV (most 2 bits of 4th byte of IV) */
+
+ keyId = (*(pBody + 3)) >> 6;
+
+ /**
+ * On STA in infrastructure BSS, Authentication frames received
+ * with WEP bit set in the FC must be rejected with challenge
+ * failure status code (wierd thing in the spec - this should have
+ * been rejected with unspecified failure or unexpected assertion
+ * of wep bit (this status code does not exist though) or
+ * Out-of-sequence-Authentication-Frame status code.
+ */
+
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame with wep bit set on role=%d "
+ MAC_ADDRESS_STR),
+ GET_LIM_SYSTEM_ROLE(psessionEntry),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ }
+
+ if (frameLen < LIM_ENCR_AUTH_BODY_LEN) {
+ /* Log error */
+ lim_log(pMac, LOGE,
+ FL
+ ("Not enough size [%d] to decrypt received Auth frame"),
+ frameLen);
+ lim_print_mac_addr(pMac, pHdr->sa, LOGE);
+
+ return;
+ }
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ val = psessionEntry->privacy;
+ } else
+ /* Accept Authentication frame only if Privacy is implemented */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get Privacy option
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL("could not retrieve Privacy option"));
+ }
+
+ cfgPrivacyOptImp = (uint8_t) val;
+ if (cfgPrivacyOptImp) {
+ /**
+ * Privacy option is implemented.
+ * Check if the received frame is Authentication
+ * frame3 and there is a context for requesting STA.
+ * If not, reject with unspecified failure status code
+ */
+ pAuthNode = lim_search_pre_auth_list(pMac, pHdr->sa);
+
+ if (pAuthNode == NULL) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame from peer that has no preauth context with WEP bit set "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ /**
+ * No 'pre-auth' context exists for this STA that sent
+ * an Authentication frame with FC bit set.
+ * Send Auth frame4 with 'out of sequence' status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ } else {
+ /* / Change the auth-response timeout */
+ lim_deactivate_and_change_per_sta_id_timer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pAuthNode->
+ authNodeIdx);
+
+ /* / 'Pre-auth' status exists for STA */
+ if ((pAuthNode->mlmState !=
+ eLIM_MLM_WT_AUTH_FRAME3_STATE) &&
+ (pAuthNode->mlmState !=
+ eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame from peer that is in state %d "
+ MAC_ADDRESS_STR),
+ pAuthNode->mlmState,
+ MAC_ADDR_ARRAY(pHdr->sa));)
+ /**
+ * Should not have received Authentication frame
+ * with WEP bit set in FC in other states.
+ * Reject by sending Authenticaton frame with
+ * out of sequence Auth frame status code.
+ */
+ authFrame.authAlgoNumber =
+ eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ }
+ }
+
+ val = SIR_MAC_KEY_LENGTH;
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ tpSirKeys pKey;
+ pKey =
+ &psessionEntry->
+ WEPKeyMaterial[keyId].key[0];
+ cdf_mem_copy(defaultKey, pKey->key,
+ pKey->keyLength);
+ val = pKey->keyLength;
+ } else if (wlan_cfg_get_str(pMac,
+ (uint16_t) (WNI_CFG_WEP_DEFAULT_KEY_1 +
+ keyId), defaultKey,
+ &val) != eSIR_SUCCESS) {
+ /* / Could not get Default key from CFG. */
+ /* Log error. */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Default key"));
+
+ /**
+ * Send Authentication frame
+ * with challenge failure status code
+ */
+
+ authFrame.authAlgoNumber =
+ eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+
+ return;
+ }
+
+ key_length = val;
+
+ decryptResult = lim_decrypt_auth_frame(pMac, defaultKey,
+ pBody, plainBody, key_length,
+ (uint16_t) (frameLen -
+ SIR_MAC_WEP_IV_LENGTH));
+ if (decryptResult == LIM_DECRYPT_ICV_FAIL) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame from peer that failed decryption: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ /* / ICV failure */
+ lim_delete_pre_auth_node(pMac,
+ pHdr->sa);
+ authFrame.authAlgoNumber =
+ eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ }
+ if ((sir_convert_auth_frame2_struct
+ (pMac, plainBody, frameLen - 8,
+ &rxAuthFrame) != eSIR_SUCCESS) ||
+ (!is_auth_valid
+ (pMac, &rxAuthFrame, psessionEntry))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("failed to convert Auth Frame to structure or Auth is not valid "));
+ return;
+ }
+ } else {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame3 from peer that while privacy option is turned OFF "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ /**
+ * Privacy option is not implemented.
+ * So reject Authentication frame received with
+ * WEP bit set by sending Authentication frame
+ * with 'challenge failure' status code. This is
+ * another strange thing in the spec. Status code
+ * should have been 'unsupported algorithm' status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC, psessionEntry);
+ return;
+ } /* else if (wlan_cfg_get_int(CFG_PRIVACY_OPTION_IMPLEMENTED)) */
+ } /* if (fc.wep) */
+ else {
+ if ((sir_convert_auth_frame2_struct(pMac, pBody,
+ frameLen,
+ &rxAuthFrame) != eSIR_SUCCESS)
+ || (!is_auth_valid(pMac, &rxAuthFrame, psessionEntry))) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("failed to convert Auth Frame to structure or Auth is not valid "));
+ )
+ return;
+ }
+ }
+
+ pRxAuthFrameBody = &rxAuthFrame;
+
+ PELOGW(lim_log(pMac, LOGW,
+ FL
+ ("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"),
+ (uint32_t) pRxAuthFrameBody->authAlgoNumber,
+ (uint32_t) pRxAuthFrameBody->authTransactionSeqNumber,
+ (uint32_t) pRxAuthFrameBody->authStatusCode,
+ (uint32_t) pMac->lim.gLimNumPreAuthContexts);
+ )
+
+ switch (pRxAuthFrameBody->authTransactionSeqNumber) {
+ case SIR_MAC_AUTH_FRAME_1:
+ /* AuthFrame 1 */
+
+ pStaDs = dph_lookup_hash_entry(pMac, pHdr->sa,
+ &assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs) {
+ tLimMlmDisassocReq *pMlmDisassocReq = NULL;
+ tLimMlmDeauthReq *pMlmDeauthReq = NULL;
+ tAniBool isConnected = eSIR_TRUE;
+
+ pMlmDisassocReq =
+ pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+ if (pMlmDisassocReq
+ &&
+ (cdf_mem_compare
+ ((uint8_t *) pHdr->sa,
+ (uint8_t *) &pMlmDisassocReq->peerMacAddr,
+ sizeof(tSirMacAddr)))) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("TODO:Ack for disassoc "
+ "frame is pending Issue delsta for "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pMlmDisassocReq->
+ peerMacAddr));
+ )
+ lim_process_disassoc_ack_timeout(pMac);
+ isConnected = eSIR_FALSE;
+ }
+ pMlmDeauthReq =
+ pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+ if (pMlmDeauthReq
+ &&
+ (cdf_mem_compare
+ ((uint8_t *) pHdr->sa,
+ (uint8_t *) &pMlmDeauthReq->peerMacAddr,
+ sizeof(tSirMacAddr)))) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("TODO:Ack for deauth frame "
+ "is pending Issue delsta for "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pMlmDeauthReq->
+ peerMacAddr));
+ )
+ lim_process_deauth_ack_timeout(pMac);
+ isConnected = eSIR_FALSE;
+ }
+
+ /* pStaDS != NULL and isConnected = 1 means the STA is already
+ * connected, But SAP received the Auth from that station.
+ * For non PMF connection send Deauth frame as STA will retry
+ * to connect back.
+ *
+ * For PMF connection the AP should not tear down or otherwise
+ * modify the state of the existing association until the
+ * SA-Query procedure determines that the original SA is
+ * invalid.
+ */
+ if (isConnected
+#ifdef WLAN_FEATURE_11W
+ && !pStaDs->rmfEnabled
+#endif
+ ) {
+ lim_log(pMac, LOGE,
+ FL
+ ("STA is already connected but received auth frame"
+ "Send the Deauth and lim Delete Station Context"
+ "(staId: %d, assocId: %d) "),
+ pStaDs->staIndex, assocId);
+ lim_send_deauth_mgmt_frame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,
+ (uint8_t *) pHdr->sa,
+ psessionEntry, false);
+ lim_trigger_sta_deletion(pMac, pStaDs,
+ psessionEntry);
+ return;
+ }
+ }
+ /* / Check if there exists pre-auth context for this STA */
+ pAuthNode = lim_search_pre_auth_list(pMac, pHdr->sa);
+ if (pAuthNode) {
+ /* / Pre-auth context exists for the STA */
+ if (pHdr->fc.retry == 0 ||
+ pAuthNode->seq_num != curr_seq_num) {
+ /**
+ * STA is initiating brand-new Authentication
+ * sequence after local Auth Response timeout.
+ * Or STA retrying to transmit First Auth frame due to packet drop OTA
+ * Delete Pre-auth node and fall through.
+ */
+ if (pAuthNode->fTimerStarted) {
+ lim_deactivate_and_change_per_sta_id_timer
+ (pMac, eLIM_AUTH_RSP_TIMER,
+ pAuthNode->authNodeIdx);
+ }
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("STA is initiating brand-new Authentication ..."));
+ )
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+ /**
+ * SAP Mode:Disassociate the station and
+ * delete its entry if we have its entry
+ * already and received "auth" from the
+ * same station.
+ */
+
+ for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++) /* Softap dphHashTable.size = 8 */
+ {
+ pStaDs =
+ dph_get_hash_entry(pMac, assocId,
+ &psessionEntry->dph.
+ dphHashTable);
+
+ if (NULL == pStaDs)
+ continue;
+
+ if (pStaDs->valid) {
+ if (cdf_mem_compare
+ ((uint8_t *) &pStaDs->
+ staAddr,
+ (uint8_t *) &(pHdr->sa),
+ (uint8_t) (sizeof
+ (tSirMacAddr))))
+ break;
+ }
+
+ pStaDs = NULL;
+ }
+
+ if (NULL != pStaDs
+#ifdef WLAN_FEATURE_11W
+ && !pStaDs->rmfEnabled
+#endif
+ ) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("lim Delete Station Context (staId: %d, assocId: %d) "),
+ pStaDs->staIndex,
+ assocId);
+ )
+ lim_send_deauth_mgmt_frame(pMac,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,
+ (uint8_t *)
+ pAuthNode->
+ peerMacAddr,
+ psessionEntry,
+ false);
+ lim_trigger_sta_deletion(pMac, pStaDs,
+ psessionEntry);
+ return;
+ }
+ } else {
+ /*
+ * This can happen when first authentication frame is received
+ * but ACK lost at STA side, in this case 2nd auth frame is already
+ * in transmission queue
+ * */
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("STA is initiating Authentication after ACK lost..."));
+ )
+ return;
+ }
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
+ (uint32_t *) &maxNumPreAuth) !=
+ eSIR_SUCCESS) {
+ /**
+ * Could not get MaxNumPreAuth
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL("could not retrieve MaxNumPreAuth"));
+ }
+ if (pMac->lim.gLimNumPreAuthContexts == maxNumPreAuth &&
+ !lim_delete_open_auth_pre_auth_node(pMac)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Max number of preauth context reached"));
+ )
+ /**
+ * Maximum number of pre-auth contexts
+ * reached. Send Authentication frame
+ * with unspecified failure
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC, psessionEntry);
+
+ return;
+ }
+ /* / No Pre-auth context exists for the STA. */
+ if (lim_is_auth_algo_supported(pMac, (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber,
+ psessionEntry)) {
+ switch (pRxAuthFrameBody->authAlgoNumber) {
+ case eSIR_OPEN_SYSTEM:
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("=======> eSIR_OPEN_SYSTEM ..."));
+ )
+ /* / Create entry for this STA in pre-auth list */
+ pAuthNode =
+ lim_acquire_free_pre_auth_node(pMac,
+ &pMac->lim.
+ gLimPreAuthTimerTable);
+ if (pAuthNode == NULL) {
+ /* Log error */
+ lim_log(pMac, LOGW,
+ FL
+ ("Max pre-auth nodes reached "));
+ lim_print_mac_addr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Alloc new data: %x peer "),
+ pAuthNode);
+ lim_print_mac_addr(pMac, pHdr->sa, LOG1);
+ )
+
+ cdf_mem_copy((uint8_t *) pAuthNode->
+ peerMacAddr, pHdr->sa,
+ sizeof(tSirMacAddr));
+
+ pAuthNode->mlmState =
+ eLIM_MLM_AUTHENTICATED_STATE;
+ pAuthNode->authType = (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber;
+ pAuthNode->fSeen = 0;
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->seq_num =
+ ((pHdr->seqControl.seqNumHi << 4) |
+ (pHdr->seqControl.seqNumLo));
+ pAuthNode->timestamp =
+ cdf_mc_timer_get_system_ticks();
+ lim_add_pre_auth_node(pMac, pAuthNode);
+
+ /**
+ * Send Authenticaton frame with Success
+ * status code.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber +
+ 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_SUCCESS_STATUS;
+ lim_send_auth_mgmt_frame(pMac, &authFrame, pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ break;
+
+ case eSIR_SHARED_KEY:
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("=======> eSIR_SHARED_KEY ..."));
+ )
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ val = psessionEntry->privacy;
+ } else
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_PRIVACY_ENABLED,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get Privacy option
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Privacy option"));
+ }
+ cfgPrivacyOptImp = (uint8_t) val;
+ if (!cfgPrivacyOptImp) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame for unsupported auth algorithm %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->
+ authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ /**
+ * Authenticator does not have WEP
+ * implemented.
+ * Reject by sending Authentication frame
+ * with Auth algorithm not supported status
+ * code.
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->
+ authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ } else {
+ /* Create entry for this STA */
+ /* in pre-auth list */
+ pAuthNode =
+ lim_acquire_free_pre_auth_node(pMac,
+ &pMac->
+ lim.
+ gLimPreAuthTimerTable);
+ if (pAuthNode == NULL) {
+ /* Log error */
+ lim_log(pMac, LOGW,
+ FL
+ ("Max pre-auth nodes reached "));
+ lim_print_mac_addr(pMac, pHdr->sa,
+ LOGW);
+
+ return;
+ }
+
+ cdf_mem_copy((uint8_t *) pAuthNode->
+ peerMacAddr, pHdr->sa,
+ sizeof(tSirMacAddr));
+
+ pAuthNode->mlmState =
+ eLIM_MLM_WT_AUTH_FRAME3_STATE;
+ pAuthNode->authType = (tAniAuthType)
+ pRxAuthFrameBody->authAlgoNumber;
+ pAuthNode->fSeen = 0;
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->seq_num =
+ ((pHdr->seqControl.seqNumHi <<
+ 4) |
+ (pHdr->seqControl.seqNumLo));
+ pAuthNode->timestamp =
+ cdf_mc_timer_get_system_ticks();
+ lim_add_pre_auth_node(pMac, pAuthNode);
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("Alloc new data: %x id %d peer "),
+ pAuthNode,
+ pAuthNode->authNodeIdx);
+ )
+ PELOG1(lim_print_mac_addr
+ (pMac, pHdr->sa, LOG1);
+ )
+ /* / Create and activate Auth Response timer */
+ if (tx_timer_change_context
+ (&pAuthNode->timer,
+ pAuthNode->authNodeIdx) !=
+ TX_SUCCESS) {
+ /* / Could not start Auth response timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to chg context auth response timer for peer "));
+ lim_print_mac_addr(pMac, pHdr->sa,
+ LOGP);
+
+ /**
+ * Send Authenticaton frame with
+ * unspecified failure status code.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->
+ authAlgoNumber;
+ authFrame.
+ authTransactionSeqNumber =
+ pRxAuthFrameBody->
+ authTransactionSeqNumber +
+ 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac,
+ &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+
+ lim_delete_pre_auth_node(pMac,
+ pHdr->sa);
+ return;
+ }
+
+ lim_activate_auth_rsp_timer(pMac,
+ pAuthNode);
+
+ pAuthNode->fTimerStarted = 1;
+
+ /* get random bytes and use as */
+ /* challenge text. If it fails we already have random stack bytes. */
+ if (!CDF_IS_STATUS_SUCCESS
+ (cds_rand_get_bytes
+ (0, (uint8_t *) challengeTextArray,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Challenge text preparation failed in lim_process_auth_frame"));
+ }
+
+ pChallenge = pAuthNode->challengeText;
+
+ cdf_mem_copy(pChallenge,
+ (uint8_t *)
+ challengeTextArray,
+ sizeof
+ (challengeTextArray));
+
+ /**
+ * Sending Authenticaton frame with challenge.
+ */
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->
+ authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_SUCCESS_STATUS;
+ authFrame.type =
+ SIR_MAC_CHALLENGE_TEXT_EID;
+ authFrame.length =
+ SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ cdf_mem_copy(authFrame.challengeText,
+ pAuthNode->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH);
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ } /* if (wlan_cfg_get_int(CFG_PRIVACY_OPTION_IMPLEMENTED)) */
+
+ break;
+
+ default:
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame for unsupported auth algorithm %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ /**
+ * Responding party does not support the
+ * authentication algorithm requested by
+ * sending party.
+ * Reject by sending Authentication frame
+ * with auth algorithm not supported status code
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber +
+ 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ } /* end switch(pRxAuthFrameBody->authAlgoNumber) */
+ } /* if (lim_is_auth_algo_supported(pRxAuthFrameBody->authAlgoNumber)) */
+ else {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame for unsupported auth algorithm %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ /**
+ * Responding party does not support the
+ * authentication algorithm requested by sending party.
+ * Reject Authentication with StatusCode=13.
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC, psessionEntry);
+ return;
+ } /* end if (lim_is_auth_algo_supported(pRxAuthFrameBody->authAlgoNumber)) */
+ break;
+
+ case SIR_MAC_AUTH_FRAME_2:
+ /* AuthFrame 2 */
+
+ if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE) {
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ /**
+ * Check if a Reassociation is in progress and this is a
+ * Pre-Auth frame
+ */
+ if ((LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
+ && (psessionEntry->limSmeState ==
+ eLIM_SME_WT_REASSOC_STATE)
+ && (pRxAuthFrameBody->authStatusCode ==
+ eSIR_MAC_SUCCESS_STATUS)
+ && (psessionEntry->ftPEContext.pFTPreAuthReq !=
+ NULL)
+ &&
+ (cdf_mem_compare
+ (psessionEntry->ftPEContext.pFTPreAuthReq->
+ preAuthbssId, pHdr->sa, sizeof(tSirMacAddr)))) {
+ /* Update the FTIEs in the saved auth response */
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("received another PreAuth frame2"
+ " from peer " MAC_ADDRESS_STR
+ " in Smestate %d"),
+ MAC_ADDR_ARRAY(pHdr->sa),
+ psessionEntry->limSmeState);
+ )
+
+ psessionEntry->ftPEContext.
+ saved_auth_rsp_length = 0;
+ if ((pBody != NULL)
+ && (frameLen < MAX_FTIE_SIZE)) {
+ cdf_mem_copy(psessionEntry->ftPEContext.
+ saved_auth_rsp, pBody,
+ frameLen);
+ psessionEntry->ftPEContext.
+ saved_auth_rsp_length = frameLen;
+ }
+ } else
+#endif
+ {
+ /**
+ * Received Authentication frame2 in an unexpected state.
+ * Log error and ignore the frame.
+ */
+
+ /* Log error */
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("received Auth frame2 from peer in state %d, addr "),
+ psessionEntry->limMlmState);
+ )
+ PELOG1(lim_print_mac_addr
+ (pMac, pHdr->sa, LOG1);
+ )
+ }
+
+ return;
+
+ }
+
+ if (!cdf_mem_compare((uint8_t *) pHdr->sa,
+ (uint8_t *) &pMac->lim.gpLimMlmAuthReq->
+ peerMacAddr, sizeof(tSirMacAddr))) {
+ /**
+ * Received Authentication frame from an entity
+ * other than one request was initiated.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ /* Log error */
+ PELOGW(lim_log(pMac, LOGW,
+ FL
+ ("received Auth frame2 from unexpected peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authStatusCode ==
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS) {
+ /**
+ * Interoperability workaround: Linksys WAP4400N is returning
+ * wrong authType in OpenAuth response in case of
+ * SharedKey AP configuration. Pretend we don't see that,
+ * so upper layer can fallback to SharedKey authType,
+ * and successfully connect to the AP.
+ */
+ if (pRxAuthFrameBody->authAlgoNumber !=
+ pMac->lim.gpLimMlmAuthReq->authType) {
+ pRxAuthFrameBody->authAlgoNumber =
+ pMac->lim.gpLimMlmAuthReq->authType;
+ }
+ }
+
+ if (pRxAuthFrameBody->authAlgoNumber !=
+ pMac->lim.gpLimMlmAuthReq->authType) {
+ /**
+ * Received Authentication frame with an auth
+ * algorithm other than one requested.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ /* Log error */
+ PELOGW(lim_log(pMac, LOGW,
+ FL
+ ("received Auth frame2 for unexpected auth algo number %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) {
+ if (pRxAuthFrameBody->authAlgoNumber ==
+ eSIR_OPEN_SYSTEM) {
+ psessionEntry->limCurrentAuthType =
+ eSIR_OPEN_SYSTEM;
+
+ pAuthNode =
+ lim_acquire_free_pre_auth_node(pMac,
+ &pMac->lim.
+ gLimPreAuthTimerTable);
+
+ if (pAuthNode == NULL) {
+ /* Log error */
+ lim_log(pMac, LOGW,
+ FL
+ ("Max pre-auth nodes reached "));
+ lim_print_mac_addr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Alloc new data: %x peer "),
+ pAuthNode);
+ )
+ PELOG1(lim_print_mac_addr
+ (pMac, pHdr->sa, LOG1);
+ )
+
+ cdf_mem_copy((uint8_t *) pAuthNode->
+ peerMacAddr,
+ pMac->lim.gpLimMlmAuthReq->
+ peerMacAddr,
+ sizeof(tSirMacAddr));
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->authType =
+ pMac->lim.gpLimMlmAuthReq->authType;
+ pAuthNode->seq_num =
+ ((pHdr->seqControl.seqNumHi << 4) |
+ (pHdr->seqControl.seqNumLo));
+ pAuthNode->timestamp =
+ cdf_mc_timer_get_system_ticks();
+ lim_add_pre_auth_node(pMac, pAuthNode);
+
+ lim_restore_from_auth_state(pMac, eSIR_SME_SUCCESS,
+ pRxAuthFrameBody->
+ authStatusCode,
+ psessionEntry);
+ } /* if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) */
+ else {
+ /* Shared key authentication */
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ val = psessionEntry->privacy;
+ } else
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_PRIVACY_ENABLED,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get Privacy option
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Privacy option"));
+ }
+ cfgPrivacyOptImp = (uint8_t) val;
+ if (!cfgPrivacyOptImp) {
+ /**
+ * Requesting STA does not have WEP implemented.
+ * Reject with unsupported authentication algorithm
+ * Status code and wait until auth failure timeout
+ */
+
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame from peer for unsupported auth algo %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->
+ authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ pRxAuthFrameBody->
+ authTransactionSeqNumber + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ } else {
+
+ if (pRxAuthFrameBody->type !=
+ SIR_MAC_CHALLENGE_TEXT_EID) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame with invalid challenge text IE"));
+ )
+
+ return;
+ }
+
+ if (wlan_cfg_get_int
+ (pMac,
+ WNI_CFG_WEP_DEFAULT_KEYID,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get Default keyId
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Default keyId"));
+ }
+ keyId = (uint8_t) val;
+
+ val = SIR_MAC_KEY_LENGTH;
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ tpSirKeys pKey;
+ pKey =
+ &psessionEntry->
+ WEPKeyMaterial
+ [keyId].key[0];
+ cdf_mem_copy(defaultKey,
+ pKey->key,
+ pKey->
+ keyLength);
+ } else
+ if (wlan_cfg_get_str
+ (pMac,
+ (uint16_t)
+ (WNI_CFG_WEP_DEFAULT_KEY_1
+ + keyId), defaultKey,
+ &val)
+ != eSIR_SUCCESS) {
+ /* / Could not get Default key from CFG. */
+ /* Log error. */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Default key"));
+
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->
+ authAlgoNumber;
+ authFrame.
+ authTransactionSeqNumber =
+ pRxAuthFrameBody->
+ authTransactionSeqNumber
+ + 1;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame
+ (pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+
+ lim_restore_from_auth_state
+ (pMac,
+ eSIR_SME_INVALID_WEP_DEFAULT_KEY,
+ eSIR_MAC_UNSPEC_FAILURE_REASON,
+ psessionEntry);
+
+ break;
+ }
+ key_length = val;
+ ((tpSirMacAuthFrameBody)
+ plainBody)->authAlgoNumber =
+ sir_swap_u16if_needed(pRxAuthFrameBody->
+ authAlgoNumber);
+ ((tpSirMacAuthFrameBody)
+ plainBody)->
+ authTransactionSeqNumber =
+ sir_swap_u16if_needed((uint16_t)
+ (pRxAuthFrameBody->
+ authTransactionSeqNumber + 1));
+ ((tpSirMacAuthFrameBody)
+ plainBody)->authStatusCode =
+ eSIR_MAC_SUCCESS_STATUS;
+ ((tpSirMacAuthFrameBody)
+ plainBody)->type =
+ SIR_MAC_CHALLENGE_TEXT_EID;
+ ((tpSirMacAuthFrameBody)
+ plainBody)->length =
+ SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ cdf_mem_copy((uint8_t*) ((tpSirMacAuthFrameBody) plainBody)->challengeText,
+ pRxAuthFrameBody->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH);
+
+ lim_encrypt_auth_frame(pMac, keyId,
+ defaultKey,
+ plainBody,
+ encrAuthFrame,
+ key_length);
+
+ psessionEntry->limMlmState =
+ eLIM_MLM_WT_AUTH_FRAME4_STATE;
+ MTRACE(mac_trace
+ (pMac,
+ TRACE_CODE_MLM_STATE,
+ psessionEntry->
+ peSessionId,
+ psessionEntry->
+ limMlmState));
+
+ lim_send_auth_mgmt_frame(pMac,
+ (tpSirMacAuthFrameBody)
+ encrAuthFrame,
+ pHdr->sa,
+ LIM_WEP_IN_FC,
+ psessionEntry);
+
+ break;
+ } /* end if (!wlan_cfg_get_int(CFG_PRIVACY_OPTION_IMPLEMENTED)) */
+ } /* end if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) */
+ } /* if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) */
+ else {
+ /**
+ * Authentication failure.
+ * Return Auth confirm with received failure code to SME
+ */
+
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame from peer with failure code %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authStatusCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ lim_restore_from_auth_state(pMac, eSIR_SME_AUTH_REFUSED,
+ pRxAuthFrameBody->
+ authStatusCode,
+ psessionEntry);
+ } /* end if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) */
+
+ break;
+
+ case SIR_MAC_AUTH_FRAME_3:
+ /* AuthFrame 3 */
+
+ if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame3 from peer with auth algo number %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ /**
+ * Received Authentication frame3 with algorithm other than
+ * Shared Key authentication type. Reject with Auth frame4
+ * with 'out of sequence' status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC, psessionEntry);
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_IBSS_ROLE(psessionEntry)) {
+ /**
+ * Check if wep bit was set in FC. If not set,
+ * reject with Authentication frame4 with
+ * 'challenge failure' status code.
+ */
+ if (!pHdr->fc.wep) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame3 from peer with no WEP bit set "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ /* / WEP bit is not set in FC of Auth Frame3 */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ }
+
+ pAuthNode = lim_search_pre_auth_list(pMac, pHdr->sa);
+ if (pAuthNode == NULL) {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGW,
+ FL
+ ("received AuthFrame3 from peer that has no preauth context "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ /**
+ * No 'pre-auth' context exists for
+ * this STA that sent an Authentication
+ * frame3.
+ * Send Auth frame4 with 'out of sequence'
+ * status code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ }
+
+ if (pAuthNode->mlmState ==
+ eLIM_MLM_AUTH_RSP_TIMEOUT_STATE) {
+ /* Log error */
+ lim_log(pMac, LOGW,
+ FL
+ ("auth response timer timedout for peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ /**
+ * Received Auth Frame3 after Auth Response timeout.
+ * Reject by sending Auth Frame4 with
+ * Auth respone timeout Status Code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+
+ /* / Delete pre-auth context of STA */
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+
+ return;
+ } /* end switch (pAuthNode->mlmState) */
+
+ if (pRxAuthFrameBody->authStatusCode !=
+ eSIR_MAC_SUCCESS_STATUS) {
+ /**
+ * Received Authenetication Frame 3 with status code
+ * other than success. Wait until Auth response timeout
+ * to delete STA context.
+ */
+
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame3 from peer with status code %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authStatusCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ return;
+ }
+
+ /**
+ * Check if received challenge text is same as one sent in
+ * Authentication frame3
+ */
+
+ if (cdf_mem_compare(pRxAuthFrameBody->challengeText,
+ pAuthNode->challengeText,
+ SIR_MAC_AUTH_CHALLENGE_LENGTH)) {
+ /* / Challenge match. STA is autheticated ! */
+
+ /* / Delete Authentication response timer if running */
+ lim_deactivate_and_change_per_sta_id_timer(pMac,
+ eLIM_AUTH_RSP_TIMER,
+ pAuthNode->
+ authNodeIdx);
+
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->mlmState =
+ eLIM_MLM_AUTHENTICATED_STATE;
+
+ /**
+ * Send Authentication Frame4 with 'success' Status Code.
+ */
+ authFrame.authAlgoNumber = eSIR_SHARED_KEY;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_SUCCESS_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ break;
+ } else {
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGW,
+ FL("Challenge failure for peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ /**
+ * Challenge Failure.
+ * Send Authentication frame4 with 'challenge failure'
+ * status code and wait until Auth response timeout to
+ * delete STA context.
+ */
+ authFrame.authAlgoNumber =
+ pRxAuthFrameBody->authAlgoNumber;
+ authFrame.authTransactionSeqNumber =
+ SIR_MAC_AUTH_FRAME_4;
+ authFrame.authStatusCode =
+ eSIR_MAC_CHALLENGE_FAILURE_STATUS;
+
+ lim_send_auth_mgmt_frame(pMac, &authFrame,
+ pHdr->sa,
+ LIM_NO_WEP_IN_FC,
+ psessionEntry);
+ return;
+ }
+ } /* if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE || ... */
+
+ break;
+
+ case SIR_MAC_AUTH_FRAME_4:
+ /* AuthFrame 4 */
+ if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE) {
+ /**
+ * Received Authentication frame4 in an unexpected state.
+ * Log error and ignore the frame.
+ */
+
+ /* Log error */
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("received unexpected Auth frame4 from peer in state %d, addr "
+ MAC_ADDRESS_STR),
+ psessionEntry->limMlmState,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ return;
+ }
+
+ if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY) {
+ /**
+ * Received Authentication frame4 with algorithm other than
+ * Shared Key authentication type.
+ * Wait until Auth failure timeout to report authentication
+ * failure to SME.
+ */
+
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame4 from peer with invalid auth algo %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authAlgoNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ return;
+ }
+
+ if (!cdf_mem_compare((uint8_t *) pHdr->sa,
+ (uint8_t *) &pMac->lim.gpLimMlmAuthReq->
+ peerMacAddr, sizeof(tSirMacAddr))) {
+ /**
+ * Received Authentication frame from an entity
+ * other than one to which request was initiated.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGW,
+ FL
+ ("received Auth frame4 from unexpected peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authAlgoNumber !=
+ pMac->lim.gpLimMlmAuthReq->authType) {
+ /**
+ * Received Authentication frame with an auth algorithm
+ * other than one requested.
+ * Wait until Authentication Failure Timeout.
+ */
+
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Authentication frame from peer with invalid auth seq number %d "
+ MAC_ADDRESS_STR),
+ pRxAuthFrameBody->
+ authTransactionSeqNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ }
+
+ if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) {
+ /**
+ * Authentication Success !
+ * Inform SME of same.
+ */
+ psessionEntry->limCurrentAuthType = eSIR_SHARED_KEY;
+
+ pAuthNode =
+ lim_acquire_free_pre_auth_node(pMac,
+ &pMac->lim.
+ gLimPreAuthTimerTable);
+ if (pAuthNode == NULL) {
+ /* Log error */
+ lim_log(pMac, LOGW,
+ FL("Max pre-auth nodes reached "));
+ lim_print_mac_addr(pMac, pHdr->sa, LOGW);
+
+ return;
+ }
+ PELOG1(lim_log
+ (pMac, LOG1, FL("Alloc new data: %x peer "),
+ pAuthNode);
+ lim_print_mac_addr(pMac, pHdr->sa, LOG1);
+ )
+
+ cdf_mem_copy((uint8_t *) pAuthNode->peerMacAddr,
+ pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ pAuthNode->fTimerStarted = 0;
+ pAuthNode->authType =
+ pMac->lim.gpLimMlmAuthReq->authType;
+ pAuthNode->seq_num =
+ ((pHdr->seqControl.seqNumHi << 4) |
+ (pHdr->seqControl.seqNumLo));
+ pAuthNode->timestamp = cdf_mc_timer_get_system_ticks();
+ lim_add_pre_auth_node(pMac, pAuthNode);
+
+ lim_restore_from_auth_state(pMac, eSIR_SME_SUCCESS,
+ pRxAuthFrameBody->
+ authStatusCode, psessionEntry);
+
+ } /* if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) */
+ else {
+ /**
+ * Authentication failure.
+ * Return Auth confirm with received failure code to SME
+ */
+
+ /* Log error */
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Authentication failure from peer "
+ MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ lim_restore_from_auth_state(pMac, eSIR_SME_AUTH_REFUSED,
+ pRxAuthFrameBody->
+ authStatusCode,
+ psessionEntry);
+ } /* end if (pRxAuthFrameBody->Status == 0) */
+
+ break;
+
+ default:
+ /* / Invalid Authentication Frame received. Ignore it. */
+
+ /* Log error */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Auth frame from peer with invalid auth seq "
+ "number %d " MAC_ADDRESS_STR),
+ pRxAuthFrameBody->authTransactionSeqNumber,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ } /* end switch (pRxAuthFrameBody->authTransactionSeqNumber) */
+} /*** end lim_process_auth_frame() ***/
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+
+/*----------------------------------------------------------------------
+ *
+ * Pass the received Auth frame. This is possibly the pre-auth from the
+ * neighbor AP, in the same mobility domain.
+ * This will be used in case of 11r FT.
+ *
+ * !!!! This is going to be renoved for the next checkin. We will be creating
+ * the session before sending out the Auth. Thus when auth response
+ * is received we will have a session in progress. !!!!!
+ ***----------------------------------------------------------------------
+ */
+tSirRetStatus lim_process_auth_frame_no_session(tpAniSirGlobal pMac, uint8_t *pBd,
+ void *body)
+{
+ tpSirMacMgmtHdr pHdr;
+ tpPESession psessionEntry = NULL;
+ uint8_t *pBody;
+ uint16_t frameLen;
+ tSirMacAuthFrameBody rxAuthFrame;
+ tSirMacAuthFrameBody *pRxAuthFrameBody = NULL;
+ tSirRetStatus ret_status = eSIR_FAILURE;
+ int i;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pBd);
+ pBody = WMA_GET_RX_MPDU_DATA(pBd);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
+
+ lim_log(pMac, LOG1,
+ FL("Auth Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"),
+ MAC_ADDR_ARRAY(pHdr->bssId),
+ (uint) abs((int8_t) WMA_GET_RX_RSSI_DB(pBd)));
+
+ /* Auth frame has come on a new BSS, however, we need to find the session
+ * from where the auth-req was sent to the new AP
+ */
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ /* Find first free room in session table */
+ if (pMac->lim.gpSession[i].valid == true &&
+ pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession ==
+ true) {
+ /* Found the session */
+ psessionEntry = &pMac->lim.gpSession[i];
+ pMac->lim.gpSession[i].ftPEContext.ftPreAuthSession =
+ false;
+ }
+ }
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Error: Unable to find session id while in pre-auth phase for FT"));
+ return eSIR_FAILURE;
+ }
+
+ if (psessionEntry->ftPEContext.pFTPreAuthReq == NULL) {
+ lim_log(pMac, LOGE, FL("Error: No FT"));
+ /* No FT in progress. */
+ return eSIR_FAILURE;
+ }
+
+ if (frameLen == 0) {
+ lim_log(pMac, LOGE, FL("Error: Frame len = 0"));
+ return eSIR_FAILURE;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_print_mac_addr(pMac, pHdr->bssId, LOG2);
+ lim_print_mac_addr(pMac,
+ psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
+ LOG2);
+ lim_log(pMac, LOG2, FL("seqControl 0x%X"),
+ ((pHdr->seqControl.seqNumHi << 8) | (pHdr->seqControl.
+ seqNumLo << 4) | (pHdr->
+ seqControl.
+ fragNum)));
+#endif
+
+ /* Check that its the same bssId we have for preAuth */
+ if (!cdf_mem_compare
+ (psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId,
+ pHdr->bssId, sizeof(tSirMacAddr))) {
+ lim_log(pMac, LOGE, FL("Error: Same bssid as preauth BSSID"));
+ /* In this case SME if indeed has triggered a */
+ /* pre auth it will time out. */
+ return eSIR_FAILURE;
+ }
+
+ if (true ==
+ psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) {
+ /*
+ * This is likely a duplicate for the same pre-auth request.
+ * PE/LIM already posted a response to SME. Hence, drop it.
+ * TBD:
+ * 1) How did we even receive multiple auth responses?
+ * 2) Do we need to delete pre-auth session? Suppose we
+ * previously received an auth resp with failure which
+ * would not have created the session and forwarded to SME.
+ * And, we subsequently received an auth resp with success
+ * which would have created the session. This will now be
+ * dropped without being forwarded to SME! However, it is
+ * very unlikely to receive auth responses from the same
+ * AP with different reason codes.
+ * NOTE: return eSIR_SUCCESS so that the packet is dropped
+ * as this was indeed a response from the BSSID we tried to
+ * pre-auth.
+ */
+ PELOGE(lim_log(pMac, LOG1, "Auth rsp already posted to SME"
+ " (session %p, FT session %p)", psessionEntry,
+ psessionEntry);
+ );
+ return eSIR_SUCCESS;
+ } else {
+ PELOGE(lim_log(pMac, LOGW, "Auth rsp not yet posted to SME"
+ " (session %p, FT session %p)", psessionEntry,
+ psessionEntry);
+ );
+ psessionEntry->ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed =
+ true;
+ }
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1, FL("Pre-Auth response received from neighbor"));
+ lim_log(pMac, LOG1, FL("Pre-Auth done state"));
+#endif
+ /* Stopping timer now, that we have our unicast from the AP */
+ /* of our choice. */
+ lim_deactivate_and_change_timer(pMac, eLIM_FT_PREAUTH_RSP_TIMER);
+
+ /* Save off the auth resp. */
+ if ((sir_convert_auth_frame2_struct(pMac, pBody, frameLen, &rxAuthFrame) !=
+ eSIR_SUCCESS)) {
+ lim_log(pMac, LOGE,
+ FL("failed to convert Auth frame to struct"));
+ lim_handle_ft_pre_auth_rsp(pMac, eSIR_FAILURE, NULL, 0,
+ psessionEntry);
+ return eSIR_FAILURE;
+ }
+ pRxAuthFrameBody = &rxAuthFrame;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log(pMac, LOG1,
+ FL
+ ("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"),
+ (uint32_t) pRxAuthFrameBody->authAlgoNumber,
+ (uint32_t) pRxAuthFrameBody->authTransactionSeqNumber,
+ (uint32_t) pRxAuthFrameBody->authStatusCode,
+ (uint32_t) pMac->lim.gLimNumPreAuthContexts);
+ )
+#endif
+ switch (pRxAuthFrameBody->authTransactionSeqNumber) {
+ case SIR_MAC_AUTH_FRAME_2:
+ if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS) {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, "Auth status code received is %d",
+ (uint32_t) pRxAuthFrameBody->authStatusCode);
+ );
+#endif
+ if (eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS ==
+ pRxAuthFrameBody->authStatusCode)
+ ret_status = eSIR_LIM_MAX_STA_REACHED_ERROR;
+ } else {
+ ret_status = eSIR_SUCCESS;
+ }
+ break;
+
+ default:
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log
+ (pMac, LOGE, "Seq. no incorrect expected 2 received %d",
+ (uint32_t) pRxAuthFrameBody->authTransactionSeqNumber);
+ )
+#endif
+ break;
+ }
+
+ /* Send the Auth response to SME */
+ lim_handle_ft_pre_auth_rsp(pMac, ret_status, pBody, frameLen, psessionEntry);
+
+ return ret_status;
+}
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
diff --git a/core/mac/src/pe/lim/lim_process_beacon_frame.c b/core/mac/src/pe/lim/lim_process_beacon_frame.c
new file mode 100644
index 0000000..3a72a69
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_beacon_frame.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_process_beacon_frame.cc contains the code
+ * for processing Received Beacon Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+
+/**
+ * lim_process_beacon_frame() - to process beacon frames
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to RX packet info structure
+ * @session: A pointer to session
+ *
+ * This function is called by limProcessMessageQueue() upon Beacon
+ * frame reception.
+ * Note:
+ * 1. Beacons received in 'normal' state in IBSS are handled by
+ * Beacon Processing module.
+ *
+ * Return: none
+ */
+
+void
+lim_process_beacon_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+ tpPESession session)
+{
+ tpSirMacMgmtHdr mac_hdr;
+ tSchBeaconStruct *bcn_ptr;
+
+ mac_ctx->lim.gLimNumBeaconsRcvd++;
+
+ /*
+ * here is it required to increment session specific heartBeat
+ * beacon counter
+ */
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ lim_log(mac_ctx, LOG2,
+ FL("Received Beacon frame with length=%d from "),
+ WMA_GET_RX_MPDU_LEN(rx_pkt_info));
+ lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOG2);
+
+ /* Expect Beacon in any state as Scan is independent of LIM state */
+ bcn_ptr = cdf_mem_malloc(sizeof(*bcn_ptr));
+ if (NULL == bcn_ptr) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to allocate memory"));
+ return;
+ }
+ /* Parse received Beacon */
+ if (sir_convert_beacon_frame2_struct(mac_ctx,
+ rx_pkt_info, bcn_ptr) !=
+ eSIR_SUCCESS) {
+ /*
+ * Received wrongly formatted/invalid Beacon.
+ * Ignore it and move on.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("Received invalid Beacon in state %X"),
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOGW,
+ session->limMlmState);
+ cdf_mem_free(bcn_ptr);
+ return;
+ }
+ /*
+ * during scanning, when any session is active, and
+ * beacon/Pr belongs to one of the session, fill up the
+ * following, TBD - HB couter
+ */
+ if ((!session->lastBeaconDtimPeriod) &&
+ (sir_compare_mac_addr(session->bssId,
+ bcn_ptr->bssid))) {
+ cdf_mem_copy((uint8_t *)&session->lastBeaconTimeStamp,
+ (uint8_t *) bcn_ptr->timeStamp,
+ sizeof(uint64_t));
+ session->lastBeaconDtimCount =
+ bcn_ptr->tim.dtimCount;
+ session->lastBeaconDtimPeriod =
+ bcn_ptr->tim.dtimPeriod;
+ session->currentBssBeaconCnt++;
+ }
+ MTRACE(mac_trace(mac_ctx,
+ TRACE_CODE_RX_MGMT_TSF, 0, bcn_ptr->timeStamp[0]);)
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF, 0,
+ bcn_ptr->timeStamp[1]);)
+ lim_check_and_add_bss_description(mac_ctx, bcn_ptr,
+ rx_pkt_info, false, true);
+
+ if ((mac_ctx->lim.gLimMlmState ==
+ eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (mac_ctx->lim.gLimMlmState ==
+ eLIM_MLM_PASSIVE_SCAN_STATE)) {
+ lim_check_and_add_bss_description(mac_ctx, bcn_ptr,
+ rx_pkt_info,
+ ((mac_ctx->lim.gLimHalScanState ==
+ eLIM_HAL_SCANNING_STATE) ? true : false),
+ false);
+ /*
+ * Calling dfsChannelList which will convert DFS channel
+ * to active channel for x secs if this channel is DFS
+ */
+ lim_set_dfs_channel_list(mac_ctx,
+ bcn_ptr->channelNumber,
+ &mac_ctx->lim.dfschannelList);
+ } else if (session->limMlmState ==
+ eLIM_MLM_WT_JOIN_BEACON_STATE) {
+ if (session->beacon != NULL) {
+ cdf_mem_free(session->beacon);
+ session->beacon = NULL;
+ }
+ session->bcnLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+ session->beacon = cdf_mem_malloc(session->bcnLen);
+ if (NULL == session->beacon) {
+ lim_log(mac_ctx, LOGE,
+ FL("fail to alloc mem to store bcn"));
+ } else {
+ /*
+ * Store the Beacon/ProbeRsp. This is sent to
+ * csr/hdd in join cnf response.
+ */
+ cdf_mem_copy(session->beacon,
+ WMA_GET_RX_MPDU_DATA(rx_pkt_info),
+ session->bcnLen);
+ }
+ lim_check_and_announce_join_success(mac_ctx, bcn_ptr,
+ mac_hdr, session);
+ }
+ cdf_mem_free(bcn_ptr);
+ return;
+}
+
+/**---------------------------------------------------------------
+ \fn lim_process_beacon_frame_no_session
+ \brief This function is called by limProcessMessageQueue()
+ \ upon Beacon reception.
+ \
+ \param pMac
+ \param *pRxPacketInfo - A pointer to Rx packet info structure
+ \return None
+ ------------------------------------------------------------------*/
+void
+lim_process_beacon_frame_no_session(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo)
+{
+ tpSirMacMgmtHdr pHdr;
+ tSchBeaconStruct *pBeacon;
+
+ pMac->lim.gLimNumBeaconsRcvd++;
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ lim_log(pMac, LOG2, FL("Received Beacon frame with length=%d from "),
+ WMA_GET_RX_MPDU_LEN(pRxPacketInfo));
+ lim_print_mac_addr(pMac, pHdr->sa, LOG2);
+
+
+ /**
+ * No session has been established. Expect Beacon only when
+ * 1. STA is in Scan mode waiting for Beacon/Probe response or
+ * 2. STA/AP is in Learn mode
+ */
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)) {
+ pBeacon = cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == pBeacon) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to allocate memory in lim_process_beacon_frame_no_session"));
+ return;
+ }
+
+ if (sir_convert_beacon_frame2_struct
+ (pMac, (uint8_t *) pRxPacketInfo,
+ pBeacon) != eSIR_SUCCESS) {
+ /* Received wrongly formatted/invalid Beacon. Ignore and move on. */
+ lim_log(pMac, LOGW,
+ FL
+ ("Received invalid Beacon in global MLM state %X"),
+ pMac->lim.gLimMlmState);
+ lim_print_mlm_state(pMac, LOGW, pMac->lim.gLimMlmState);
+ cdf_mem_free(pBeacon);
+ return;
+ }
+
+ if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)) {
+ lim_check_and_add_bss_description(pMac, pBeacon,
+ pRxPacketInfo, true,
+ false);
+ /* Calling dfsChannelList which will convert DFS channel
+ * to Active channel for x secs if this channel is DFS channel */
+ lim_set_dfs_channel_list(pMac, pBeacon->channelNumber,
+ &pMac->lim.dfschannelList);
+ } else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) {
+ } /* end of eLIM_MLM_LEARN_STATE) */
+ cdf_mem_free(pBeacon);
+ } /* end of (eLIM_MLM_WT_PROBE_RESP_STATE) || (eLIM_MLM_PASSIVE_SCAN_STATE) */
+ else {
+ lim_log(pMac, LOG1, FL("Rcvd Beacon in unexpected MLM state %d"),
+ pMac->lim.gLimMlmState);
+ lim_print_mlm_state(pMac, LOG1, pMac->lim.gLimMlmState);
+#ifdef WLAN_DEBUG
+ pMac->lim.gLimUnexpBcnCnt++;
+#endif
+ }
+
+ return;
+} /*** end lim_process_beacon_frame_no_session() ***/
diff --git a/core/mac/src/pe/lim/lim_process_cfg_updates.c b/core/mac/src/pe/lim/lim_process_cfg_updates.c
new file mode 100644
index 0000000..e1a645e
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_cfg_updates.c
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_process_cfg_updates.cc contains the utility functions
+ * to handle various CFG parameter update events
+ * Author: Chandra Modumudi
+ * Date: 01/20/03
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "ani_global.h"
+
+#include "wni_cfg.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "sch_api.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+static void lim_update_config(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+static void lim_set_default_key_id_and_keys(tpAniSirGlobal pMac)
+{
+#ifdef FIXME_GEN6
+ uint32_t val;
+ uint32_t dkCfgId;
+ PELOG1(lim_log(pMac, LOG1, FL("Setting default keys at SP"));)
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WEP_DEFAULT_KEYID,
+ &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to retrieve defaultKeyId from CFG"));
+ }
+ dkCfgId = limGetCfgIdOfDefaultKeyid(val);
+#endif
+
+} /*** end lim_set_default_key_id_and_keys() ***/
+/** -------------------------------------------------------------
+ \fn lim_set_cfg_protection
+ \brief sets lim global cfg cache from the config.
+ \param tpAniSirGlobal pMac
+ \return None
+ -------------------------------------------------------------*/
+void lim_set_cfg_protection(tpAniSirGlobal pMac, tpPESession pesessionEntry)
+{
+ uint32_t val = 0;
+
+ if (pesessionEntry != NULL && LIM_IS_AP_ROLE(pesessionEntry)) {
+ if (pesessionEntry->gLimProtectionControl ==
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ cdf_mem_set((void *)&pesessionEntry->cfgProtection,
+ sizeof(tCfgProtection), 0);
+ else {
+ lim_log(pMac, LOG1,
+ FL(" frm11a = %d, from11b = %d, frm11g = %d, "
+ "ht20 = %d, nongf = %d, lsigTxop = %d, "
+ "rifs = %d, obss = %d"),
+ pesessionEntry->cfgProtection.fromlla,
+ pesessionEntry->cfgProtection.fromllb,
+ pesessionEntry->cfgProtection.fromllg,
+ pesessionEntry->cfgProtection.ht20,
+ pesessionEntry->cfgProtection.nonGf,
+ pesessionEntry->cfgProtection.lsigTxop,
+ pesessionEntry->cfgProtection.rifs,
+ pesessionEntry->cfgProtection.obss);
+ }
+ } else {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, &val)
+ != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("reading WNI_CFG_FORCE_POLICY_PROTECTION cfg failed"));
+ return;
+ } else
+ pMac->lim.gLimProtectionControl = (uint8_t) val;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PROTECTION_ENABLED, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("reading protection cfg failed"));
+ return;
+ }
+
+ if (pMac->lim.gLimProtectionControl ==
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ cdf_mem_set((void *)&pMac->lim.cfgProtection,
+ sizeof(tCfgProtection), 0);
+ else {
+ pMac->lim.cfgProtection.fromlla =
+ (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llA) & 1;
+ pMac->lim.cfgProtection.fromllb =
+ (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llB) & 1;
+ pMac->lim.cfgProtection.fromllg =
+ (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llG) & 1;
+ pMac->lim.cfgProtection.ht20 =
+ (val >> WNI_CFG_PROTECTION_ENABLED_HT_20) & 1;
+ pMac->lim.cfgProtection.nonGf =
+ (val >> WNI_CFG_PROTECTION_ENABLED_NON_GF) & 1;
+ pMac->lim.cfgProtection.lsigTxop =
+ (val >> WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP) & 1;
+ pMac->lim.cfgProtection.rifs =
+ (val >> WNI_CFG_PROTECTION_ENABLED_RIFS) & 1;
+ pMac->lim.cfgProtection.obss =
+ (val >> WNI_CFG_PROTECTION_ENABLED_OBSS) & 1;
+
+ }
+ }
+}
+
+/**
+ * lim_handle_param_update()
+ *
+ ***FUNCTION:
+ * This function is use to post a message whenever need indicate
+ * there is update of config parameter.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param cfgId - ID of CFG parameter that got updated
+ * @return None
+ */
+void lim_handle_param_update(tpAniSirGlobal pMac, eUpdateIEsType cfgId)
+{
+ tSirMsgQ msg = { 0 };
+ uint32_t status;
+
+ PELOG3(lim_log
+ (pMac, LOG3, FL("Handling CFG parameter id %X update"), cfgId);
+ )
+ switch (cfgId) {
+ case eUPDATE_IE_PROBE_BCN:
+ {
+ msg.type = SIR_LIM_UPDATE_BEACON;
+ status = lim_post_msg_api(pMac, &msg);
+
+ if (status != TX_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Failed lim_post_msg_api %u"), status);
+ )
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * lim_handle_cf_gparam_update()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_messages() to
+ * whenever SIR_CFG_PARAM_UPDATE_IND message is posted
+ * to LIM (due to a set operation on a CFG parameter).
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param cfgId - ID of CFG parameter that got updated
+ * @return None
+ */
+
+void lim_handle_cf_gparam_update(tpAniSirGlobal pMac, uint32_t cfgId)
+{
+ uint32_t val1, val2;
+ uint16_t val16;
+ tSirMacHTCapabilityInfo *pHTCapabilityInfo;
+ tSirMacHTParametersInfo *pAmpduParamInfo;
+
+ PELOG3(lim_log
+ (pMac, LOG3, FL("Handling CFG parameter id %X update"), cfgId);
+ )
+ switch (cfgId) {
+ case WNI_CFG_WEP_DEFAULT_KEYID:
+
+ /* !!LAC - when the default KeyID is changed, force all of the */
+ /* keys and the keyID to be reprogrammed. this allows the */
+ /* keys to change after the initial setting of the keys when the CFG was */
+ /* applied at association time through CFG changes of the keys. */
+ lim_set_default_key_id_and_keys(pMac);
+
+ break;
+
+ case WNI_CFG_EXCLUDE_UNENCRYPTED:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_EXCLUDE_UNENCRYPTED,
+ &val1) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to retrieve excludeUnencr from CFG"));
+ }
+ lim_log(pMac, LOGE,
+ FL("Unsupported CFG: WNI_CFG_EXCLUDE_UNENCRYPTED"));
+
+ break;
+
+ case WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT:
+ if (pMac->lim.gLimMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) {
+ /* 'Change' timer for future activations */
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_ASSOC_FAIL_TIMER);
+ }
+
+ break;
+
+ case WNI_CFG_PROTECTION_ENABLED:
+ lim_set_cfg_protection(pMac, NULL);
+ break;
+ case WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG:
+ {
+ tSirMsgQ msg = { 0 };
+ uint32_t status;
+
+ msg.type = SIR_LIM_UPDATE_BEACON;
+
+ status = lim_post_msg_api(pMac, &msg);
+
+ if (status != TX_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Failed lim_post_msg_api %u"), status);
+ )
+ break;
+ }
+ case WNI_CFG_GREENFIELD_CAPABILITY:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT Cap Info CFG"));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_GREENFIELD_CAPABILITY, &val2)
+ != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve GreenField CFG"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+ pHTCapabilityInfo->greenField = (uint16_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO,
+ *(uint16_t *) pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT Cap Info CFG"));
+ )
+ break;
+
+ case WNI_CFG_HT_RX_STBC:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve WNI_CFG_HT_CAP_INFO "));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_RX_STBC, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve WNI_CFG_HT_RX_STBC"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+ pHTCapabilityInfo->rxSTBC = (uint16_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO,
+ *(uint16_t *) pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT Cap Info CFG"));
+ )
+ break;
+
+ case WNI_CFG_MAX_AMSDU_LENGTH:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT Cap Info CFG"));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_AMSDU_LENGTH, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve Max AMSDU Length CFG"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+ pHTCapabilityInfo->maximalAMSDUsize = (uint16_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO,
+ *(uint16_t *) pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT Cap Info CFG"));
+ )
+ break;
+
+ case WNI_CFG_SHORT_GI_20MHZ:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT Cap CFG"));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve shortGI 20Mhz CFG"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+ pHTCapabilityInfo->shortGI20MHz = (uint16_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO,
+ *(uint16_t *) pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT Cap Info CFG"));
+ )
+ break;
+ case WNI_CFG_SHORT_GI_40MHZ:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT Cap CFG"));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_40MHZ, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve shortGI 40Mhz CFG"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &val16;
+ pHTCapabilityInfo->shortGI40MHz = (uint16_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_CAP_INFO,
+ *(uint16_t *) pHTCapabilityInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT Cap Info CFG"));
+ )
+ break;
+ case WNI_CFG_MPDU_DENSITY:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT AMPDU Param CFG"));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MPDU_DENSITY, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve MPDU Density CFG"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pAmpduParamInfo = (tSirMacHTParametersInfo *) &val16;
+ pAmpduParamInfo->mpduDensity = (uint8_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_AMPDU_PARAMS,
+ *(uint8_t *) pAmpduParamInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT AMPDU Param CFG"));
+ )
+
+ break;
+ case WNI_CFG_MAX_RX_AMPDU_FACTOR:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve HT AMPDU Param CFG"));
+ )
+ break;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve AMPDU Factor CFG"));
+ )
+ break;
+ }
+ val16 = (uint16_t) val1;
+ pAmpduParamInfo = (tSirMacHTParametersInfo *) &val16;
+ pAmpduParamInfo->maxRxAMPDUFactor = (uint8_t) val2;
+ if (cfg_set_int
+ (pMac, WNI_CFG_HT_AMPDU_PARAMS,
+ *(uint8_t *) pAmpduParamInfo) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not update HT AMPDU Param CFG"));
+ )
+ break;
+
+ case WNI_CFG_DOT11_MODE:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &val1) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve Dot11 Mode CFG"));
+ )
+ break;
+ }
+ break;
+
+ case WNI_CFG_SCAN_IN_POWERSAVE:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val1) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("Unable to get WNI_CFG_SCAN_IN_POWERSAVE "));
+ break;
+ }
+ pMac->lim.gScanInPowersave = (uint8_t) val1;
+ break;
+
+ case WNI_CFG_ASSOC_STA_LIMIT:
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val1) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("Unable to get WNI_CFG_ASSOC_STA_LIMIT"));
+ break;
+ }
+ pMac->lim.gLimAssocStaLimit = (uint16_t) val1;
+ break;
+ default:
+ break;
+ }
+} /*** end lim_handle_cf_gparam_update() ***/
+
+/**
+ * lim_apply_configuration()
+ *
+ ***FUNCTION:
+ * This function is called to apply the configured parameters
+ * before joining or reassociating with a BSS or starting a BSS.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_apply_configuration(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ uint32_t val = 0, phyMode;
+
+ PELOG2(lim_log(pMac, LOG2, FL("Applying config"));)
+
+ psessionEntry->limSentCapsChangeNtf = false;
+
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ /* Set default keyId and keys */
+ lim_set_default_key_id_and_keys(pMac);
+
+ lim_update_config(pMac, psessionEntry);
+
+ lim_get_short_slot_from_phy_mode(pMac, psessionEntry, phyMode,
+ &psessionEntry->shortSlotTimeSupported);
+
+ lim_set_cfg_protection(pMac, psessionEntry);
+
+ /* Added for BT - AMP Support */
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_IBSS_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ /* This check is required to ensure the beacon generation is not done
+ as a part of join request for a BT-AMP station */
+
+ if (psessionEntry->statypeForBss == STA_ENTRY_SELF) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Initializing BT-AMP beacon generation"));
+ )
+ sch_set_beacon_interval(pMac, psessionEntry);
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ }
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not retrieve WNI_CFG_SCAN_IN_POWERSAVE"));
+ return;
+ }
+
+ PELOG1(lim_log(pMac, LOG1, FL("pMac->lim.gScanInPowersave = %hu"),
+ pMac->lim.gScanInPowersave);
+ )
+ pMac->lim.gScanInPowersave = (uint8_t) val;
+
+} /*** end lim_apply_configuration() ***/
+
+/**
+ * lim_update_config
+ *
+ * FUNCTION:
+ * Update the local state from CFG database
+ * (This used to be dphUpdateConfig)
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+static void lim_update_config(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ uint32_t val;
+
+ sir_copy_mac_addr(pMac->lim.gLimMyMacAddr, psessionEntry->selfMacAddr);
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get short preamble failed"));
+ psessionEntry->beaconParams.fShortPreamble = (val) ? 1 : 0;
+
+ /* In STA case this parameter is filled during the join request */
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_IBSS_ROLE(psessionEntry)) {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WME_ENABLED, &val) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get wme enabled failed"));
+ psessionEntry->limWmeEnabled = (val) ? 1 : 0;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WSM_ENABLED, &val) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get wsm enabled failed"));
+ psessionEntry->limWsmEnabled = (val) ? 1 : 0;
+
+ if ((!psessionEntry->limWmeEnabled) && (psessionEntry->limWsmEnabled)) {
+ PELOGE(lim_log(pMac, LOGE, FL("Can't enable WSM without WME"));)
+ psessionEntry->limWsmEnabled = 0;
+ }
+ /* In STA , this parameter is filled during the join request */
+ if (LIM_IS_AP_ROLE(psessionEntry) || LIM_IS_IBSS_ROLE(psessionEntry)) {
+ if (wlan_cfg_get_int(pMac, WNI_CFG_QOS_ENABLED, &val) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get qos enabled failed"));
+ psessionEntry->limQosEnabled = (val) ? 1 : 0;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HCF_ENABLED, &val) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get hcf enabled failed"));
+ psessionEntry->limHcfEnabled = (val) ? 1 : 0;
+
+ /* AP: WSM should enable HCF as well, for STA enable WSM only after */
+ /* association response is received */
+ if (psessionEntry->limWsmEnabled && LIM_IS_AP_ROLE(psessionEntry))
+ psessionEntry->limHcfEnabled = 1;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_11D_ENABLED, &val) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("cfg get 11d enabled failed"));
+ psessionEntry->lim11dEnabled = (val) ? 1 : 0;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("cfg get assoc sta limit failed"));
+ }
+ pMac->lim.gLimAssocStaLimit = (uint16_t) val;
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrm_update_config(pMac, psessionEntry);
+#endif
+ PELOG1(lim_log(pMac, LOG1, FL("Updated Lim shadow state based on CFG"));)
+}
diff --git a/core/mac/src/pe/lim/lim_process_deauth_frame.c b/core/mac/src/pe/lim/lim_process_deauth_frame.c
new file mode 100644
index 0000000..e64058d
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_deauth_frame.c
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_process_deauth_frame.cc contains the code
+ * for processing Deauthentication Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/24/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+
+/**
+ * lim_process_deauth_frame
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Deauthentication frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs
+ * @return None
+ */
+
+void
+lim_process_deauth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ uint8_t *pBody;
+ uint16_t aid, reasonCode;
+ tpSirMacMgmtHdr pHdr;
+ tLimMlmAssocCnf mlmAssocCnf;
+ tLimMlmDeauthInd mlmDeauthInd;
+ tpDphHashNode pStaDs;
+ tpPESession pRoamSessionEntry = NULL;
+ uint8_t roamSessionId;
+#ifdef WLAN_FEATURE_11W
+ uint32_t frameLen;
+#endif
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (LIM_IS_STA_ROLE(psessionEntry) &&
+ ((eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState) ||
+ (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) {
+ /*Every 15th deauth frame will be logged in kmsg */
+ if (!(pMac->lim.deauthMsgCnt & 0xF)) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame in DEAUTH_WT_STATE"
+ "(already processing previously received DEAUTH frame).."
+ "Dropping this.. Deauth Failed %d"),
+ ++pMac->lim.deauthMsgCnt);
+ )
+ } else {
+ pMac->lim.deauthMsgCnt++;
+ }
+ return;
+ }
+
+ if (lim_is_group_addr(pHdr->sa)) {
+ /* Received Deauth frame from a BC/MC address */
+ /* Log error and ignore it */
+ PELOGE(lim_log(pMac, LOGE,
+ FL("received Deauth frame from a BC/MC address"));
+ )
+
+ return;
+ }
+
+ if (lim_is_group_addr(pHdr->da) && !lim_is_addr_bc(pHdr->da)) {
+ /* Received Deauth frame for a MC address */
+ /* Log error and ignore it */
+ PELOGE(lim_log(pMac, LOGE,
+ FL("received Deauth frame for a MC address"));
+ )
+
+ return;
+ }
+ if (!lim_validate_received_frame_a1_addr(pMac,
+ pHdr->da, psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL("rx frame doesn't have valid a1 address, drop it"));
+ return;
+ }
+#ifdef WLAN_FEATURE_11W
+ /* PMF: If this session is a PMF session, then ensure that this frame was protected */
+ if (psessionEntry->limRmfEnabled
+ && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
+ DPU_FEEDBACK_UNPROTECTED_ERROR)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("received an unprotected deauth from AP"));
+ )
+ /* If the frame received is unprotected, forward it to the supplicant to initiate */
+ /* an SA query */
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ /* send the unprotected frame indication to SME */
+ lim_send_sme_unprotected_mgmt_frame_ind(pMac, pHdr->fc.subType,
+ (uint8_t *) pHdr,
+ (frameLen +
+ sizeof(tSirMacMgmtHdr)),
+ psessionEntry->smeSessionId,
+ psessionEntry);
+ return;
+ }
+#endif
+
+ /* Get reasonCode from Deauthentication frame body */
+ reasonCode = sir_read_u16(pBody);
+
+ PELOGE(lim_log(pMac, LOGE,
+ FL("Received Deauth frame for Addr: " MAC_ADDRESS_STR
+ " (mlm state = %s,"
+ " sme state = %d systemrole = %d) with reason code %d [%s] from "
+ MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da),
+ lim_mlm_state_str(psessionEntry->limMlmState),
+ psessionEntry->limSmeState,
+ GET_LIM_SYSTEM_ROLE(psessionEntry),
+ reasonCode, lim_dot11_reason_str(reasonCode),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ if (lim_check_disassoc_deauth_ack_pending(pMac, (uint8_t *) pHdr->sa)) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("Ignore the Deauth received, while waiting for ack of "
+ "disassoc/deauth"));
+ )
+ lim_clean_up_disassoc_deauth_req(pMac, (uint8_t *) pHdr->sa, 1);
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ switch (reasonCode) {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+ /* Valid reasonCode in received Deauthentication frame */
+ break;
+
+ default:
+ /* Invalid reasonCode in received Deauthentication frame */
+ /* Log error and ignore the frame */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame with invalid reasonCode %d from "
+ MAC_ADDRESS_STR), reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ }
+ } else if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ switch (reasonCode) {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
+ case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+ case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
+ case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
+ case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON:
+ /* Valid reasonCode in received Deauth frame */
+ break;
+
+ default:
+ /* Invalid reasonCode in received Deauth frame */
+ /* Log error and ignore the frame */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame with invalid reasonCode %d from "
+ MAC_ADDRESS_STR), reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ break;
+ }
+ } else {
+ /* Received Deauth frame in either IBSS */
+ /* or un-known role. Log and ignore it */
+ lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame with reasonCode %d in role %d from "
+ MAC_ADDRESS_STR), reasonCode,
+ GET_LIM_SYSTEM_ROLE(psessionEntry),
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ return;
+ }
+
+ /** If we are in the middle of ReAssoc, a few things could happen:
+ * - STA is reassociating to current AP, and receives deauth from:
+ * a) current AP
+ * b) other AP
+ * - STA is reassociating to a new AP, and receives deauth from:
+ * c) current AP
+ * d) reassoc AP
+ * e) other AP
+ *
+ * The logic is:
+ * 1) If rcv deauth from an AP other than the one we're trying to
+ * reassociate with, then drop the deauth frame (case b, c, e)
+ * 2) If rcv deauth from the "new" reassoc AP (case d), then restore
+ * context with previous AP and send SME_REASSOC_RSP failure.
+ * 3) If rcv deauth from the reassoc AP, which is also the same
+ * AP we're currently associated with (case a), then proceed
+ * with normal deauth processing.
+ */
+ if (psessionEntry->limReAssocbssId != NULL) {
+ pRoamSessionEntry =
+ pe_find_session_by_bssid(pMac, psessionEntry->limReAssocbssId,
+ &roamSessionId);
+ }
+ if (lim_is_reassoc_in_progress(pMac, psessionEntry)
+ || lim_is_reassoc_in_progress(pMac, pRoamSessionEntry)) {
+ if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Rcv Deauth from unknown/different "
+ "AP while ReAssoc. Ignore " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL(" limReAssocbssId : " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(psessionEntry->
+ limReAssocbssId));
+ )
+ return;
+ }
+
+ /** Received deauth from the new AP to which we tried to ReAssociate.
+ * Drop ReAssoc and Restore the Previous context( current connected AP).
+ */
+ if (!IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("received DeAuth from the New AP to "
+ "which ReAssoc is sent " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL(" psessionEntry->bssId: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(psessionEntry->bssId));
+ )
+ lim_restore_pre_reassoc_state(pMac,
+ eSIR_SME_REASSOC_REFUSED,
+ reasonCode,
+ psessionEntry);
+ return;
+ }
+ }
+
+ /* If received DeAuth from AP other than the one we're trying to join with
+ * nor associated with, then ignore deauth and delete Pre-auth entry.
+ */
+ if (!LIM_IS_AP_ROLE(psessionEntry)) {
+ if (!IS_CURRENT_BSSID(pMac, pHdr->bssId, psessionEntry)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("received DeAuth from an AP other "
+ "than we're trying to join. Ignore. "
+ MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ if (lim_search_pre_auth_list(pMac, pHdr->sa)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Preauth entry exist. "
+ "Deleting... "));
+ )
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+ }
+ return;
+ }
+ }
+
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+ &psessionEntry->dph.dphHashTable);
+
+ /* Check for pre-assoc states */
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ switch (psessionEntry->limMlmState) {
+ case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+ /**
+ * AP sent Deauth frame while waiting
+ * for Auth frame2. Report Auth failure
+ * to SME.
+ */
+
+ /* Log error */
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("received Deauth frame state %X with failure "
+ "code %d from " MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ lim_restore_from_auth_state(pMac,
+ eSIR_SME_DEAUTH_WHILE_JOIN,
+ reasonCode, psessionEntry);
+
+ return;
+
+ case eLIM_MLM_AUTHENTICATED_STATE:
+ lim_log(pMac, LOG1,
+ FL("received Deauth frame state %X with "
+ "reasonCode=%d from " MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ /* / Issue Deauth Indication to SME. */
+ cdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr,
+ pHdr->sa, sizeof(tSirMacAddr));
+ mlmDeauthInd.reasonCode = reasonCode;
+
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_DEAUTH_IND,
+ (uint32_t *) &mlmDeauthInd);
+ return;
+
+ case eLIM_MLM_WT_ASSOC_RSP_STATE:
+ /**
+ * AP may have 'aged-out' our Pre-auth
+ * context. Delete local pre-auth context
+ * if any and issue ASSOC_CNF to SME.
+ */
+ lim_log(pMac, LOG1,
+ FL("received Deauth frame state %X with "
+ "reasonCode=%d from " MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ if (lim_search_pre_auth_list(pMac, pHdr->sa))
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+
+ if (psessionEntry->pLimMlmJoinReq) {
+ cdf_mem_free(psessionEntry->pLimMlmJoinReq);
+ psessionEntry->pLimMlmJoinReq = NULL;
+ }
+
+ mlmAssocCnf.resultCode = eSIR_SME_DEAUTH_WHILE_JOIN;
+ mlmAssocCnf.protStatusCode = reasonCode;
+
+ /* PE session Id */
+ mlmAssocCnf.sessionId = psessionEntry->peSessionId;
+
+ psessionEntry->limMlmState =
+ psessionEntry->limPrevMlmState;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+
+ /* Deactive Association response timeout */
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_ASSOC_FAIL_TIMER);
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_ASSOC_CNF,
+ (uint32_t *) &mlmAssocCnf);
+
+ return;
+
+ case eLIM_MLM_WT_ADD_STA_RSP_STATE:
+ psessionEntry->fDeauthReceived = true;
+ PELOGW(lim_log(pMac, LOGW,
+ FL
+ ("Received Deauth frame in state %X with Reason "
+ "Code %d from Peer" MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ return;
+
+ case eLIM_MLM_IDLE_STATE:
+ case eLIM_MLM_LINK_ESTABLISHED_STATE:
+#ifdef FEATURE_WLAN_TDLS
+ if ((NULL != pStaDs)
+ && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("received Deauth frame in state %X with "
+ "reason code %d from Tdls peer"
+ MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ lim_send_sme_tdls_del_sta_ind(pMac, pStaDs,
+ psessionEntry,
+ reasonCode);
+ return;
+ } else {
+
+ /*
+ * Delete all the TDLS peers only if Deauth
+ * is received from the AP
+ */
+ if (IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry))
+ lim_delete_tdls_peers(pMac, psessionEntry);
+#endif
+ /**
+ * This could be Deauthentication frame from
+ * a BSS with which pre-authentication was
+ * performed. Delete Pre-auth entry if found.
+ */
+ if (lim_search_pre_auth_list(pMac, pHdr->sa))
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+#ifdef FEATURE_WLAN_TDLS
+ }
+#endif
+ break;
+
+ case eLIM_MLM_WT_REASSOC_RSP_STATE:
+ lim_log(pMac, LOGE,
+ FL("received Deauth frame state %X with "
+ "reasonCode=%d from " MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ break;
+
+ case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame in FT state %X with "
+ "reasonCode=%d from " MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ break;
+
+ default:
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame in state %X with "
+ "reasonCode=%d from " MAC_ADDRESS_STR),
+ psessionEntry->limMlmState, reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ return;
+ }
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+
+ case eLIM_AP_ROLE:
+ break;
+
+ default: /* eLIM_AP_ROLE or eLIM_BT_AMP_AP_ROLE */
+
+ return;
+ } /* end switch (pMac->lim.gLimSystemRole) */
+
+ /**
+ * Extract 'associated' context for STA, if any.
+ * This is maintained by DPH and created by LIM.
+ */
+ if (NULL == pStaDs) {
+ lim_log(pMac, LOGE, FL("pStaDs is NULL"));
+ return;
+ }
+
+ if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+ (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) {
+ /**
+ * Already in the process of deleting context for the peer
+ * and received Deauthentication frame. Log and Ignore.
+ */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Deauth frame from peer that is in state %X, addr "
+ MAC_ADDRESS_STR), pStaDs->mlmStaContext.mlmState,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ return;
+ }
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH;
+
+ /* / Issue Deauth Indication to SME. */
+ cdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr,
+ pStaDs->staAddr, sizeof(tSirMacAddr));
+ mlmDeauthInd.reasonCode =
+ (uint8_t) pStaDs->mlmStaContext.disassocReason;
+ mlmDeauthInd.deauthTrigger = eLIM_PEER_ENTITY_DEAUTH;
+
+ /*
+ * If we're in the middle of ReAssoc and received deauth from
+ * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
+ * failure result code. SME will post the disconnect to the
+ * supplicant and the latter would start a fresh assoc.
+ */
+ if (lim_is_reassoc_in_progress(pMac, psessionEntry)) {
+ /**
+ * AP may have 'aged-out' our Pre-auth
+ * context. Delete local pre-auth context
+ * if any and issue REASSOC_CNF to SME.
+ */
+ if (lim_search_pre_auth_list(pMac, pHdr->sa))
+ lim_delete_pre_auth_node(pMac, pHdr->sa);
+
+ if (psessionEntry->limAssocResponseData) {
+ cdf_mem_free(psessionEntry->limAssocResponseData);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+
+ PELOGE(lim_log(pMac, LOGE, FL("Rcv Deauth from ReAssoc AP. "
+ "Issue REASSOC_CNF. "));
+ )
+ /*
+ * TODO: Instead of overloading eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE
+ * it would have been good to define/use a different failure type.
+ * Using eSIR_SME_FT_REASSOC_FAILURE does not seem to clean-up
+ * properly and we end up seeing "transmit queue timeout".
+ */
+ lim_post_reassoc_failure(pMac,
+ eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ return;
+ }
+ /* reset the deauthMsgCnt here since we are able to Process
+ * the deauth frame and sending up the indication as well */
+ if (pMac->lim.deauthMsgCnt != 0) {
+ pMac->lim.deauthMsgCnt = 0;
+ }
+ if (LIM_IS_STA_ROLE(psessionEntry))
+ wma_tx_abort(psessionEntry->smeSessionId);
+
+ /* / Deauthentication from peer MAC entity */
+ lim_post_sme_message(pMac, LIM_MLM_DEAUTH_IND,
+ (uint32_t *) &mlmDeauthInd);
+
+ /* send eWNI_SME_DEAUTH_IND to SME */
+ lim_send_sme_deauth_ind(pMac, pStaDs, psessionEntry);
+ return;
+
+} /*** end lim_process_deauth_frame() ***/
diff --git a/core/mac/src/pe/lim/lim_process_disassoc_frame.c b/core/mac/src/pe/lim/lim_process_disassoc_frame.c
new file mode 100644
index 0000000..33a1c08
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_disassoc_frame.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_process_disassoc_frame.cc contains the code
+ * for processing Disassocation Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/24/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_messages.h"
+#include "sch_api.h"
+
+/**
+ * lim_process_disassoc_frame
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue() upon
+ * Disassociation frame reception.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param *pRxPacketInfo - A pointer to Rx packet info structure
+ * @return None
+ */
+void
+lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
+ tpPESession psessionEntry)
+{
+ uint8_t *pBody;
+ uint16_t aid, reasonCode;
+ tpSirMacMgmtHdr pHdr;
+ tpDphHashNode pStaDs;
+ tLimMlmDisassocInd mlmDisassocInd;
+#ifdef WLAN_FEATURE_11W
+ uint32_t frameLen;
+#endif
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+
+ if (lim_is_group_addr(pHdr->sa)) {
+ /* Received Disassoc frame from a BC/MC address */
+ /* Log error and ignore it */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Disassoc frame from a BC/MC address"));
+ )
+
+ return;
+ }
+
+ if (lim_is_group_addr(pHdr->da) && !lim_is_addr_bc(pHdr->da)) {
+ /* Received Disassoc frame for a MC address */
+ /* Log error and ignore it */
+ PELOGE(lim_log(pMac, LOGE,
+ FL("received Disassoc frame for a MC address"));
+ )
+
+ return;
+ }
+ if (!lim_validate_received_frame_a1_addr(pMac,
+ pHdr->da, psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL("rx frame doesn't have valid a1 address, drop it"));
+ return;
+ }
+
+ if (LIM_IS_STA_ROLE(psessionEntry) &&
+ (eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState)) {
+ if (pHdr->fc.retry > 0) {
+ /*
+ * This can happen when first disassoc frame is received
+ * but ACK from this STA is lost, in this case 2nd
+ * disassoc frame is already in transmission queue
+ */
+ lim_log(pMac, LOGE,
+ FL("AP is sending disassoc after ACK lost..."));
+ return;
+ }
+ }
+#ifdef WLAN_FEATURE_11W
+ /* PMF: If this session is a PMF session, then ensure that this frame was protected */
+ if (psessionEntry->limRmfEnabled
+ && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
+ DPU_FEEDBACK_UNPROTECTED_ERROR)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("received an unprotected disassoc from AP"));
+ )
+ /* If the frame received is unprotected, forward it to the supplicant to initiate */
+ /* an SA query */
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ /* send the unprotected frame indication to SME */
+ lim_send_sme_unprotected_mgmt_frame_ind(pMac, pHdr->fc.subType,
+ (uint8_t *) pHdr,
+ (frameLen +
+ sizeof(tSirMacMgmtHdr)),
+ psessionEntry->smeSessionId,
+ psessionEntry);
+ return;
+ }
+#endif
+
+ /* Get reasonCode from Disassociation frame body */
+ reasonCode = sir_read_u16(pBody);
+
+ PELOG2(lim_log(pMac, LOGE,
+ FL("Received Disassoc frame for Addr: " MAC_ADDRESS_STR
+ "(mlm state=%s, sme state=%d),"
+ "with reason code %d [%s] from " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->da),
+ lim_mlm_state_str(psessionEntry->limMlmState),
+ psessionEntry->limSmeState, reasonCode,
+ lim_dot11_reason_str(reasonCode), MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ /**
+ * Extract 'associated' context for STA, if any.
+ * This is maintained by DPH and created by LIM.
+ */
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
+ &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL) {
+ /**
+ * Disassociating STA is not associated.
+ * Log error.
+ */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Disassoc frame from STA that does not have context "
+ "reasonCode=%d, addr " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ return;
+ }
+
+ if (lim_check_disassoc_deauth_ack_pending(pMac, (uint8_t *) pHdr->sa)) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("Ignore the DisAssoc received, while waiting "
+ "for ack of disassoc/deauth"));
+ )
+ lim_clean_up_disassoc_deauth_req(pMac, (uint8_t *) pHdr->sa, 1);
+ return;
+ }
+
+ /** If we are in the Wait for ReAssoc Rsp state */
+ if (lim_is_reassoc_in_progress(pMac, psessionEntry)) {
+ /** If we had received the DisAssoc from,
+ * a. the Current AP during ReAssociate to different AP in same ESS
+ * b. Unknown AP
+ * drop/ignore the DisAssoc received
+ */
+ if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Ignore the DisAssoc received, while "
+ "Processing ReAssoc with different/unknown AP"));
+ )
+ return;
+ }
+ /** If the Disassoc is received from the new AP to which we tried to ReAssociate
+ * Drop ReAssoc and Restore the Previous context( current connected AP).
+ */
+ if (!IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL
+ ("received Disassoc from the New AP to which ReAssoc is sent "));
+ )
+ lim_restore_pre_reassoc_state(pMac,
+ eSIR_SME_REASSOC_REFUSED,
+ reasonCode,
+ psessionEntry);
+ return;
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ switch (reasonCode) {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
+ case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
+ case eSIR_MAC_MIC_FAILURE_REASON:
+ case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
+ case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
+ case eSIR_MAC_RSN_IE_MISMATCH_REASON:
+ case eSIR_MAC_1X_AUTH_FAILURE_REASON:
+ /* Valid reasonCode in received Disassociation frame */
+ break;
+
+ default:
+ /* Invalid reasonCode in received Disassociation frame */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Disassoc frame with invalid reasonCode "
+ "%d from " MAC_ADDRESS_STR), reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ break;
+ }
+ } else if ((LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
+ ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE))) {
+ switch (reasonCode) {
+ case eSIR_MAC_UNSPEC_FAILURE_REASON:
+ case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
+ case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON:
+ case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
+ case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
+ case eSIR_MAC_MIC_FAILURE_REASON:
+ case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
+ case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
+ case eSIR_MAC_RSN_IE_MISMATCH_REASON:
+ case eSIR_MAC_1X_AUTH_FAILURE_REASON:
+ case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
+ /* Valid reasonCode in received Disassociation frame */
+ break;
+
+ case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
+ case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
+ /* Valid reasonCode in received Disassociation frame */
+ /* as long as we're not about to channel switch */
+ if (psessionEntry->gLimChannelSwitch.state !=
+ eLIM_CHANNEL_SWITCH_IDLE) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Ignoring disassoc frame due to upcoming "
+ "channel switch, from "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pHdr->sa));
+ return;
+ }
+ break;
+
+ default:
+ /* Invalid reasonCode in received Disassociation frame */
+ /* Log error and ignore the frame */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Disassoc frame with invalid reasonCode "
+ "%d from " MAC_ADDRESS_STR), reasonCode,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+ return;
+ }
+ } else {
+ /* Received Disassociation frame in either IBSS */
+ /* or un-known role. Log and ignore it */
+ lim_log(pMac, LOGE,
+ FL
+ ("received Disassoc frame with invalid reasonCode %d in role "
+ "%d in sme state %d from " MAC_ADDRESS_STR), reasonCode,
+ GET_LIM_SYSTEM_ROLE(psessionEntry), psessionEntry->limSmeState,
+ MAC_ADDR_ARRAY(pHdr->sa));
+
+ return;
+ }
+
+ if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
+ (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) {
+ /**
+ * Already in the process of deleting context for the peer
+ * and received Disassociation frame. Log and Ignore.
+ */
+ PELOGE(lim_log(pMac, LOGE,
+ FL("received Disassoc frame in state %d from "
+ MAC_ADDRESS_STR),
+ pStaDs->mlmStaContext.mlmState,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ return;
+ }
+
+ if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
+ /**
+ * Requesting STA is in some 'transient' state?
+ * Log error.
+ */
+ if (pStaDs->mlmStaContext.mlmState ==
+ eLIM_MLM_WT_ASSOC_CNF_STATE)
+ pStaDs->mlmStaContext.updateContext = 1;
+
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received Disassoc frame from peer that is in state %X, addr "
+ MAC_ADDRESS_STR), pStaDs->mlmStaContext.mlmState,
+ MAC_ADDR_ARRAY(pHdr->sa));
+ )
+
+ } /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */
+
+ pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
+ pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
+
+ /* Issue Disassoc Indication to SME. */
+ cdf_mem_copy((uint8_t *) &mlmDisassocInd.peerMacAddr,
+ (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr));
+ mlmDisassocInd.reasonCode =
+ (uint8_t) pStaDs->mlmStaContext.disassocReason;
+ mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
+
+ /* Update PE session Id */
+ mlmDisassocInd.sessionId = psessionEntry->peSessionId;
+
+ if (lim_is_reassoc_in_progress(pMac, psessionEntry)) {
+
+ /* If we're in the middle of ReAssoc and received disassoc from
+ * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
+ * failure result code. By design, SME will then issue "Disassoc"
+ * and cleanup will happen at that time.
+ */
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("received Disassoc from AP while waiting "
+ "for Reassoc Rsp"));
+ )
+
+ if (psessionEntry->limAssocResponseData) {
+ cdf_mem_free(psessionEntry->limAssocResponseData);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+
+ lim_restore_pre_reassoc_state(pMac, eSIR_SME_REASSOC_REFUSED,
+ reasonCode, psessionEntry);
+ return;
+ }
+
+ lim_post_sme_message(pMac, LIM_MLM_DISASSOC_IND,
+ (uint32_t *) &mlmDisassocInd);
+
+ /* send eWNI_SME_DISASSOC_IND to SME */
+ lim_send_sme_disassoc_ind(pMac, pStaDs, psessionEntry);
+
+ return;
+} /*** end lim_process_disassoc_frame() ***/
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
new file mode 100644
index 0000000..25e7ed1
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -0,0 +1,2098 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim ProcessMessageQueue.cc contains the code
+ * for processing LIM message Queue.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "wni_api.h"
+#include "wma_types.h"
+
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_common.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+
+#include "lim_admit_control.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "sch_api.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "lim_send_messages.h"
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft.h"
+#endif
+
+#include "cdf_types.h"
+#include "cds_packet.h"
+#include "cdf_memory.h"
+
+void lim_log_session_states(tpAniSirGlobal pMac);
+static void lim_process_normal_hdd_msg(tpAniSirGlobal mac_ctx,
+ struct sSirMsgQ *msg, uint8_t rsp_reqd);
+
+/**
+ * lim_process_dual_mac_cfg_resp() - Process set dual mac config response
+ * @mac: Global MAC pointer
+ * @body: Set dual mac config response in sir_dual_mac_config_resp format
+ *
+ * Process the set dual mac config response and post the message
+ * to SME to process this further and release the active
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_dual_mac_cfg_resp(tpAniSirGlobal mac, void *body)
+{
+ struct sir_dual_mac_config_resp *resp, *param;
+ uint32_t len, fail_resp = 0;
+ tSirMsgQ msg;
+
+ resp = (struct sir_dual_mac_config_resp *)body;
+ if (!resp) {
+ lim_log(mac, LOGE, FL("Set dual mac cfg param is NULL"));
+ fail_resp = 1;
+ /* Not returning here. If possible, let us proceed
+ * and send fail response to SME
+ */
+ }
+
+ len = sizeof(*param);
+
+ param = cdf_mem_malloc(len);
+ if (!param) {
+ lim_log(mac, LOGE, FL("Fail to allocate memory"));
+ /* Memory allocation for param failed.
+ * Cannot send fail status back to SME
+ */
+ return;
+ }
+
+ if (fail_resp) {
+ lim_log(mac, LOGE, FL("Send fail status to SME"));
+ param->status = SET_HW_MODE_STATUS_ECANCELED;
+ } else {
+ param->status = resp->status;
+ /*
+ * TODO: Update this HW mode info in any UMAC params, if needed
+ */
+ }
+
+ msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
+ msg.bodyptr = param;
+ msg.bodyval = 0;
+ lim_log(mac, LOG1, FL("Send eWNI_SME_SET_DUAL_MAC_CFG_RESP to SME"));
+ lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+ return;
+}
+
+/**
+ * lim_process_set_hw_mode_resp() - Process set HW mode response
+ * @mac: Global MAC pointer
+ * @body: Set HW mode response in sir_set_hw_mode_resp format
+ *
+ * Process the set HW mode response and post the message
+ * to SME to process this further and release the active
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_set_hw_mode_resp(tpAniSirGlobal mac, void *body)
+{
+ struct sir_set_hw_mode_resp *resp, *param;
+ uint32_t len, i, fail_resp = 0;
+ tSirMsgQ msg;
+
+ resp = (struct sir_set_hw_mode_resp *)body;
+ if (!resp) {
+ lim_log(mac, LOGE, FL("Set HW mode param is NULL"));
+ fail_resp = 1;
+ /* Not returning here. If possible, let us proceed
+ * and send fail response to SME */
+ }
+
+ len = sizeof(*param);
+
+ param = cdf_mem_malloc(len);
+ if (!param) {
+ lim_log(mac, LOGE, FL("Fail to allocate memory"));
+ /* Memory allocation for param failed.
+ * Cannot send fail status back to SME
+ */
+ return;
+ }
+
+ if (fail_resp) {
+ lim_log(mac, LOGE, FL("Send fail status to SME"));
+ param->status = SET_HW_MODE_STATUS_ECANCELED;
+ param->cfgd_hw_mode_index = 0;
+ param->num_vdev_mac_entries = 0;
+ } else {
+ param->status = resp->status;
+ param->cfgd_hw_mode_index = resp->cfgd_hw_mode_index;
+ param->num_vdev_mac_entries = resp->num_vdev_mac_entries;
+
+ for (i = 0; i < resp->num_vdev_mac_entries; i++) {
+ param->vdev_mac_map[i].vdev_id =
+ resp->vdev_mac_map[i].vdev_id;
+ param->vdev_mac_map[i].mac_id =
+ resp->vdev_mac_map[i].mac_id;
+ }
+ /*
+ * TODO: Update this HW mode info in any UMAC params, if needed
+ */
+ }
+
+ msg.type = eWNI_SME_SET_HW_MODE_RESP;
+ msg.bodyptr = param;
+ msg.bodyval = 0;
+ lim_log(mac, LOGE, FL("Send eWNI_SME_SET_HW_MODE_RESP to SME"));
+ lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+ return;
+}
+
+/**
+ * lim_process_hw_mode_trans_ind() - Process set HW mode transition indication
+ * @mac: Global MAC pointer
+ * @body: Set HW mode response in sir_hw_mode_trans_ind format
+ *
+ * Process the set HW mode transition indication and post the message
+ * to SME to invoke the HDD callback
+ * command list
+ *
+ * Return: None
+ */
+static void lim_process_hw_mode_trans_ind(tpAniSirGlobal mac, void *body)
+{
+ struct sir_hw_mode_trans_ind *ind, *param;
+ uint32_t len, i;
+ tSirMsgQ msg;
+
+ ind = (struct sir_hw_mode_trans_ind *)body;
+ if (!ind) {
+ lim_log(mac, LOGE, FL("Set HW mode trans ind param is NULL"));
+ return;
+ }
+
+ len = sizeof(*param);
+
+ param = cdf_mem_malloc(len);
+ if (!param) {
+ lim_log(mac, LOGE, FL("Fail to allocate memory"));
+ return;
+ }
+
+ param->old_hw_mode_index = ind->old_hw_mode_index;
+ param->new_hw_mode_index = ind->new_hw_mode_index;
+ param->num_vdev_mac_entries = ind->num_vdev_mac_entries;
+
+ for (i = 0; i < ind->num_vdev_mac_entries; i++) {
+ param->vdev_mac_map[i].vdev_id =
+ ind->vdev_mac_map[i].vdev_id;
+ param->vdev_mac_map[i].mac_id =
+ ind->vdev_mac_map[i].mac_id;
+ }
+
+ /* TODO: Update this HW mode info in any UMAC params, if needed */
+
+ msg.type = eWNI_SME_HW_MODE_TRANS_IND;
+ msg.bodyptr = param;
+ msg.bodyval = 0;
+ lim_log(mac, LOGE, FL("Send eWNI_SME_HW_MODE_TRANS_IND to SME"));
+ lim_sys_process_mmh_msg_api(mac, &msg, ePROT);
+ return;
+}
+
+/** -------------------------------------------------------------
+ \fn def_msg_decision
+ \brief The function decides whether to defer a message or not in limProcessMessage function
+ \param tpAniSirGlobal pMac
+ \param tSirMsgQ limMsg
+ \param tSirMacTspecIE *ppInfo
+ \return none
+ -------------------------------------------------------------*/
+
+uint8_t static def_msg_decision(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+
+/* this function should not changed */
+ if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) {
+ /* Defer processsing this message */
+ if (lim_defer_msg(pMac, limMsg) != TX_SUCCESS) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGE,
+ FL("Unable to Defer Msg"));
+ lim_log_session_states(pMac);
+ lim_handle_defer_msg_error(pMac, limMsg);
+ }
+ return true;
+ }
+ /* When defer is requested then defer all the messages except HAL responses. */
+ if ((!lim_is_system_in_scan_state(pMac))
+ && (true != GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ && !pMac->lim.gLimSystemInScanLearnMode) {
+ if ((limMsg->type != WMA_ADD_BSS_RSP)
+ && (limMsg->type != WMA_DELETE_BSS_RSP)
+ && (limMsg->type != WMA_ADD_STA_RSP)
+ && (limMsg->type != WMA_DELETE_STA_RSP)
+ && (limMsg->type != WMA_SET_BSSKEY_RSP)
+ && (limMsg->type != WMA_SET_STAKEY_RSP)
+ && (limMsg->type != WMA_SET_STA_BCASTKEY_RSP)
+ && (limMsg->type != WMA_AGGR_QOS_RSP)
+ && (limMsg->type != WMA_SET_MIMOPS_RSP)
+ && (limMsg->type != WMA_SWITCH_CHANNEL_RSP)
+ && (limMsg->type != WMA_P2P_NOA_ATTR_IND)
+ && (limMsg->type != WMA_P2P_NOA_START_IND) &&
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ (limMsg->type != WMA_START_OEM_DATA_RSP) &&
+#endif
+ (limMsg->type != WMA_ADD_TS_RSP)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode"),
+ lim_msg_str(limMsg->type));
+ )
+ /* Defer processsing this message */
+ if (lim_defer_msg(pMac, limMsg) != TX_SUCCESS) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGE,
+ FL("Unable to Defer Msg"));
+ lim_log_session_states(pMac);
+ lim_handle_defer_msg_error(pMac, limMsg);
+
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef FEATURE_WLAN_EXTSCAN
+static void
+__lim_pno_match_fwd_bcn_probepsp(tpAniSirGlobal pmac, uint8_t *rx_pkt_info,
+ tSirProbeRespBeacon *frame, uint32_t ie_len,
+ uint32_t msg_type)
+{
+ struct pno_match_found *result;
+ uint8_t *body;
+ tSirMsgQ mmh_msg;
+ tpSirMacMgmtHdr hdr;
+ uint32_t num_results = 1, len, i;
+
+ /* Upon receiving every matched beacon, bss info is forwarded to the
+ * the upper layer, hence num_results is set to 1 */
+ len = sizeof(*result) + (num_results * sizeof(tSirWifiScanResult)) +
+ ie_len;
+
+ result = cdf_mem_malloc(len);
+ if (NULL == result) {
+ lim_log(pmac, LOGE, FL("Memory allocation failed"));
+ return;
+ }
+ hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ cdf_mem_zero(result, sizeof(*result) + ie_len);
+
+ /* Received frame does not have request id, hence set 0 */
+ result->request_id = 0;
+ result->more_data = 0;
+ result->num_results = num_results;
+
+ for (i = 0; i < result->num_results; i++) {
+ result->ap[i].ts = cdf_mc_timer_get_system_time();
+ result->ap[i].beaconPeriod = frame->beaconInterval;
+ result->ap[i].capability =
+ lim_get_u16((uint8_t *) &frame->capabilityInfo);
+ result->ap[i].channel = WMA_GET_RX_CH(rx_pkt_info);
+ result->ap[i].rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+ result->ap[i].rtt = 0;
+ result->ap[i].rtt_sd = 0;
+ result->ap[i].ieLength = ie_len;
+ cdf_mem_copy((uint8_t *) &result->ap[i].ssid[0],
+ (uint8_t *) frame->ssId.ssId, frame->ssId.length);
+ result->ap[i].ssid[frame->ssId.length] = '\0';
+ cdf_mem_copy((uint8_t *) &result->ap[i].bssid,
+ (uint8_t *) hdr->bssId,
+ sizeof(tSirMacAddr));
+ /* Copy IE fields */
+ cdf_mem_copy((uint8_t *) &result->ap[i].ieData,
+ body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
+ }
+
+ mmh_msg.type = msg_type;
+ mmh_msg.bodyptr = result;
+ mmh_msg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pmac, &mmh_msg, ePROT);
+}
+
+
+static void
+__lim_ext_scan_forward_bcn_probe_rsp(tpAniSirGlobal pmac, uint8_t *rx_pkt_info,
+ tSirProbeRespBeacon *frame,
+ uint32_t ie_len,
+ uint32_t msg_type)
+{
+ tpSirWifiFullScanResultEvent result;
+ uint8_t *body;
+ tSirMsgQ mmh_msg;
+ tpSirMacMgmtHdr hdr;
+
+ result = cdf_mem_malloc(sizeof(*result) + ie_len);
+ if (NULL == result) {
+ lim_log(pmac, LOGE, FL("Memory allocation failed"));
+ return;
+ }
+ hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ cdf_mem_zero(result, sizeof(*result) + ie_len);
+
+ /* Received frame does not have request id, hence set 0 */
+ result->requestId = 0;
+
+ result->moreData = 0;
+ result->ap.ts = cdf_mc_timer_get_system_time();
+ result->ap.beaconPeriod = frame->beaconInterval;
+ result->ap.capability =
+ lim_get_u16((uint8_t *) &frame->capabilityInfo);
+ result->ap.channel = WMA_GET_RX_CH(rx_pkt_info);
+ result->ap.rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+ result->ap.rtt = 0;
+ result->ap.rtt_sd = 0;
+ result->ap.ieLength = ie_len;
+
+ cdf_mem_copy((uint8_t *) &result->ap.ssid[0],
+ (uint8_t *) frame->ssId.ssId, frame->ssId.length);
+ result->ap.ssid[frame->ssId.length] = '\0';
+ cdf_mem_copy((uint8_t *) &result->ap.bssid.bytes,
+ (uint8_t *) hdr->bssId,
+ CDF_MAC_ADDR_SIZE);
+ /* Copy IE fields */
+ cdf_mem_copy((uint8_t *) &result->ap.ieData,
+ body + SIR_MAC_B_PR_SSID_OFFSET, ie_len);
+
+ mmh_msg.type = msg_type;
+ mmh_msg.bodyptr = result;
+ mmh_msg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pmac, &mmh_msg, ePROT);
+}
+
+static void
+__lim_process_ext_scan_beacon_probe_rsp(tpAniSirGlobal pmac,
+ uint8_t *rx_pkt_info,
+ uint8_t sub_type)
+{
+ tSirProbeRespBeacon *frame;
+ uint8_t *body;
+ uint32_t frm_len;
+ tSirRetStatus status;
+
+ frm_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+ if (frm_len <= SIR_MAC_B_PR_SSID_OFFSET) {
+ lim_log(pmac, LOGP,
+ FL("RX packet has invalid length %d"), frm_len);
+ return;
+ }
+
+ frame = cdf_mem_malloc(sizeof(*frame));
+ if (NULL == frame) {
+ lim_log(pmac, LOGE, FL("Memory allocation failed"));
+ return;
+ }
+
+ if (sub_type == SIR_MAC_MGMT_BEACON) {
+ lim_log(pmac, LOG2, FL("Beacon due to ExtScan/epno"));
+ status = sir_convert_beacon_frame2_struct(pmac,
+ (uint8_t *)rx_pkt_info,
+ frame);
+ } else if (sub_type == SIR_MAC_MGMT_PROBE_RSP) {
+ lim_log(pmac, LOG2, FL("Probe Rsp due to ExtScan/epno"));
+ body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+ status = sir_convert_probe_frame2_struct(pmac, body,
+ frm_len, frame);
+ } else {
+ cdf_mem_free(frame);
+ return;
+ }
+
+ if (status != eSIR_SUCCESS) {
+ lim_log(pmac, LOGE, FL("Frame parsing failed"));
+ cdf_mem_free(frame);
+ return;
+ }
+
+ if (WMA_IS_EXTSCAN_SCAN_SRC(rx_pkt_info))
+ __lim_ext_scan_forward_bcn_probe_rsp(pmac, rx_pkt_info, frame,
+ (frm_len - SIR_MAC_B_PR_SSID_OFFSET),
+ eWNI_SME_EXTSCAN_FULL_SCAN_RESULT_IND);
+
+ if (WMA_IS_EPNO_SCAN_SRC(rx_pkt_info))
+ __lim_pno_match_fwd_bcn_probepsp(pmac, rx_pkt_info, frame,
+ (frm_len - SIR_MAC_B_PR_SSID_OFFSET),
+ eWNI_SME_EPNO_NETWORK_FOUND_IND);
+
+ cdf_mem_free(frame);
+}
+#endif
+
+/*
+ * Beacon Handling Cases:
+ * during scanning, when no session is active:
+ * handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
+ * during scanning, when any session is active, but beacon/Pr does not belong to that session, psessionEntry will be null.
+ * handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
+ * during scanning, when any session is active, and beacon/Pr belongs to one of the session, psessionEntry will not be null.
+ * handled by lim_handle_frames_in_scan_state before __lim_handle_beacon call is invoked.
+ * Not scanning, no session:
+ * there should not be any beacon coming, if coming, should be dropped.
+ * Not Scanning,
+ */
+static void
+__lim_handle_beacon(tpAniSirGlobal pMac, tpSirMsgQ pMsg,
+ tpPESession psessionEntry)
+{
+ /* checking for global SME state... */
+ uint8_t *pRxPacketInfo;
+ lim_get_b_dfrom_rx_packet(pMac, pMsg->bodyptr,
+ (uint32_t * *) &pRxPacketInfo);
+
+ /* This function should not be called if beacon is received in scan state. */
+ /* So not doing any checks for the global state. */
+
+ if (psessionEntry == NULL) {
+ sch_beacon_process(pMac, pRxPacketInfo, NULL);
+ } else if ((psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)) {
+ sch_beacon_process(pMac, pRxPacketInfo, psessionEntry);
+ } else
+ lim_process_beacon_frame(pMac, pRxPacketInfo, psessionEntry);
+
+ return;
+}
+
+/**
+ * lim_defer_msg()
+ *
+ ***FUNCTION:
+ * This function is called to defer the messages received
+ * during Learn mode
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMsg of type tSirMsgQ - Pointer to the message structure
+ * @return None
+ */
+
+uint32_t lim_defer_msg(tpAniSirGlobal pMac, tSirMsgQ *pMsg)
+{
+ uint32_t retCode = TX_SUCCESS;
+
+ retCode = lim_write_deferred_msg_q(pMac, pMsg);
+
+ if (retCode == TX_SUCCESS) {
+ MTRACE(mac_trace_msg_rx
+ (pMac, NO_SESSION,
+ LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED));
+ )
+ } else {
+ lim_log(pMac, LOGE, FL("Dropped lim message (0x%X)"),
+ pMsg->type);
+ MTRACE(mac_trace_msg_rx
+ (pMac, NO_SESSION,
+ LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED));
+ )
+ }
+
+ return retCode;
+} /*** end lim_defer_msg() ***/
+
+/**
+ * lim_handle_unknown_a2_index_frames() - This function handles Unknown Unicast
+ * (A2 Index) packets
+ * @mac_ctx: Pointer to the Global Mac Context.
+ * @rx_pkt_buffer: Pointer to the packet Buffer descriptor.
+ * @session_entry: Pointer to the PE Session Entry.
+ *
+ * This routine will handle public action frames.
+ *
+ * Return: None.
+ */
+static void lim_handle_unknown_a2_index_frames(tpAniSirGlobal mac_ctx,
+ void *rx_pkt_buffer, tpPESession session_entry)
+{
+#ifdef FEATURE_WLAN_TDLS
+ tpSirMacDataHdr3a mac_hdr;
+#endif
+ if (LIM_IS_P2P_DEVICE_ROLE(session_entry))
+ lim_process_action_frame_no_session(mac_ctx,
+ (uint8_t *) rx_pkt_buffer);
+#ifdef FEATURE_WLAN_TDLS
+ mac_hdr = WMA_GET_RX_MPDUHEADER3A(rx_pkt_buffer);
+
+ if (lim_is_group_addr(mac_hdr->addr2)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_HIGH,
+ FL("Ignoring A2 Invalid Packet received for MC/BC:"));
+ lim_print_mac_addr(mac_ctx, mac_hdr->addr2, LOG2);
+ return;
+ }
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("type=0x%x, subtype=0x%x"),
+ mac_hdr->fc.type, mac_hdr->fc.subType);
+ /* Currently only following type and subtype are handled.
+ * If there are more combinations, then add switch-case
+ * statements.
+ */
+ if (LIM_IS_STA_ROLE(session_entry) &&
+ (mac_hdr->fc.type == SIR_MAC_MGMT_FRAME) &&
+ (mac_hdr->fc.subType == SIR_MAC_MGMT_ACTION))
+ lim_process_action_frame(mac_ctx, rx_pkt_buffer, session_entry);
+#endif
+ return;
+}
+
+/**
+ * lim_check_mgmt_registered_frames() - This function handles registered
+ * management frames.
+ *
+ * @mac_ctx: Pointer to the Global Mac Context.
+ * @buff_desc: Pointer to the packet Buffer descriptor.
+ * @session_entry: Pointer to the PE Session Entry.
+ *
+ * This function is called to process to check if received frame match with
+ * any of the registered frame from HDD. If yes pass this frame to SME.
+ *
+ * Return: True or False for Match or Mismatch respectively.
+ */
+static bool
+lim_check_mgmt_registered_frames(tpAniSirGlobal mac_ctx, uint8_t *buff_desc,
+ tpPESession session_entry)
+{
+ tSirMacFrameCtl fc;
+ tpSirMacMgmtHdr hdr;
+ uint8_t *body;
+ struct mgmt_frm_reg_info *mgmt_frame = NULL;
+ struct mgmt_frm_reg_info *next_frm = NULL;
+ uint16_t frm_type;
+ uint16_t frm_len;
+ uint8_t type, sub_type;
+ bool match = false;
+ CDF_STATUS cdf_status;
+
+ hdr = WMA_GET_RX_MAC_HEADER(buff_desc);
+ fc = hdr->fc;
+ frm_type = (fc.type << 2) | (fc.subType << 4);
+ body = WMA_GET_RX_MPDU_DATA(buff_desc);
+ frm_len = WMA_GET_RX_PAYLOAD_LEN(buff_desc);
+
+ cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+ cdf_list_peek_front(&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+ (cdf_list_node_t **) &mgmt_frame);
+ cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+
+ while (mgmt_frame != NULL) {
+ type = (mgmt_frame->frameType >> 2) & 0x03;
+ sub_type = (mgmt_frame->frameType >> 4) & 0x0f;
+ if ((type == SIR_MAC_MGMT_FRAME)
+ && (fc.type == SIR_MAC_MGMT_FRAME)
+ && (sub_type == SIR_MAC_MGMT_RESERVED15)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_HIGH,
+ FL
+ ("rcvd frm match for SIR_MAC_MGMT_RESERVED15"));
+ match = true;
+ break;
+ }
+ if (mgmt_frame->frameType == frm_type) {
+ if (mgmt_frame->matchLen <= 0) {
+ match = true;
+ break;
+ }
+ if (mgmt_frame->matchLen <= frm_len &&
+ cdf_mem_compare(mgmt_frame->matchData, body,
+ mgmt_frame->matchLen)) {
+ /* found match! */
+ match = true;
+ break;
+ }
+ }
+
+ cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+ cdf_status =
+ cdf_list_peek_next(
+ &mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+ (cdf_list_node_t *) mgmt_frame,
+ (cdf_list_node_t **) &next_frm);
+ cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+ mgmt_frame = next_frm;
+ next_frm = NULL;
+ }
+
+ if (match) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("rcvd frame match with registered frame params"));
+ /* Indicate this to SME */
+ lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
+ (uint8_t *) hdr,
+ WMA_GET_RX_PAYLOAD_LEN(buff_desc) +
+ sizeof(tSirMacMgmtHdr), mgmt_frame->sessionId,
+ WMA_GET_RX_CH(buff_desc), session_entry, 0);
+
+ if ((type == SIR_MAC_MGMT_FRAME)
+ && (fc.type == SIR_MAC_MGMT_FRAME)
+ && (sub_type == SIR_MAC_MGMT_RESERVED15))
+ /* These packets needs to be processed by PE/SME
+ * as well as HDD.If it returns true here,
+ * the packet is forwarded to HDD only.
+ */
+ match = false;
+ }
+
+ return match;
+}
+
+/**
+ * lim_handle80211_frames()
+ *
+ ***FUNCTION:
+ * This function is called to process 802.11 frames
+ * received by LIM.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pMsg of type tSirMsgQ - Pointer to the message structure
+ * @return None
+ */
+
+static void
+lim_handle80211_frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, uint8_t *pDeferMsg)
+{
+ uint8_t *pRxPacketInfo = NULL;
+ tSirMacFrameCtl fc;
+ tpSirMacMgmtHdr pHdr = NULL;
+ tpPESession psessionEntry = NULL;
+ uint8_t sessionId;
+ tAniBool isFrmFt = false;
+
+ *pDeferMsg = false;
+ lim_get_b_dfrom_rx_packet(pMac, limMsg->bodyptr,
+ (uint32_t * *) &pRxPacketInfo);
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ isFrmFt = WMA_GET_RX_FT_DONE(pRxPacketInfo);
+ fc = pHdr->fc;
+
+#ifdef WLAN_DUMP_MGMTFRAMES
+ lim_log(pMac, LOGE,
+ FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"),
+ fc.protVer, fc.type, fc.subType,
+ WMA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
+ CDF_TRACE_HEX_DUMP(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR, pHdr,
+ WMA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo));
+#endif
+ if (pMac->fEnableDebugLog & 0x1) {
+ if ((fc.type == SIR_MAC_MGMT_FRAME) &&
+ (fc.subType != SIR_MAC_MGMT_PROBE_REQ) &&
+ (fc.subType != SIR_MAC_MGMT_PROBE_RSP) &&
+ (fc.subType != SIR_MAC_MGMT_BEACON)) {
+ lim_log(pMac, LOGE,
+ FL("RX MGMT - Type %hu, SubType %hu, seq num[%d]"),
+ fc.type,
+ fc.subType,
+ ((pHdr->seqControl.seqNumHi <<
+ HIGH_SEQ_NUM_OFFSET) |
+ pHdr->seqControl.seqNumLo));
+ }
+ }
+#ifdef FEATURE_WLAN_EXTSCAN
+ if (WMA_IS_EXTSCAN_SCAN_SRC(pRxPacketInfo) ||
+ WMA_IS_EPNO_SCAN_SRC(pRxPacketInfo)) {
+ if (fc.subType == SIR_MAC_MGMT_BEACON ||
+ fc.subType == SIR_MAC_MGMT_PROBE_RSP) {
+ __lim_process_ext_scan_beacon_probe_rsp(pMac,
+ pRxPacketInfo,
+ fc.subType);
+ } else {
+ lim_log(pMac, LOGE,
+ FL("Wrong frameType %d, Subtype %d for %d"),
+ fc.type, fc.subType,
+ WMA_GET_SCAN_SRC(pRxPacketInfo));
+ }
+ goto end;
+ }
+#endif
+ if (WMA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) {
+ if (fc.subType == SIR_MAC_MGMT_BEACON) {
+ lim_log(pMac, LOG2, FL("Learning scan beacon"));
+ __lim_handle_beacon(pMac, limMsg, NULL);
+ } else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP) {
+ lim_log(pMac, LOG2, FL("Learning scan probe rsp"));
+ lim_process_probe_rsp_frame_no_session(pMac, pRxPacketInfo);
+ } else {
+ lim_log(pMac, LOGE,
+ FL("Wrong frame Type %d, Subtype %d for LFR"),
+ fc.type, fc.subType);
+ }
+ goto end;
+ }
+ /* Added For BT-AMP Support */
+ if ((psessionEntry =
+ pe_find_session_by_bssid(pMac, pHdr->bssId,
+ &sessionId)) == NULL) {
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (fc.subType == SIR_MAC_MGMT_AUTH) {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1,
+ FL
+ ("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"),
+ fc.protVer, fc.type, fc.subType,
+ WMA_GET_RX_MAC_RATE_IDX(pRxPacketInfo));
+ lim_print_mac_addr(pMac, pHdr->bssId, LOG1);
+#endif
+ if (lim_process_auth_frame_no_session
+ (pMac, pRxPacketInfo,
+ limMsg->bodyptr) == eSIR_SUCCESS) {
+ lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT,
+ pRxPacketInfo, limMsg->bodyptr);
+ return;
+ }
+ }
+#endif
+ if ((fc.subType != SIR_MAC_MGMT_PROBE_RSP) &&
+ (fc.subType != SIR_MAC_MGMT_BEACON) &&
+ (fc.subType != SIR_MAC_MGMT_PROBE_REQ)
+ && (fc.subType != SIR_MAC_MGMT_ACTION) /* Public action frame can be received from non-associated stations. */
+ ) {
+
+ if ((psessionEntry =
+ pe_find_session_by_peer_sta(pMac, pHdr->sa,
+ &sessionId)) == NULL) {
+ lim_log(pMac, LOG1,
+ FL
+ ("session does not exist for given bssId"));
+ lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT,
+ pRxPacketInfo, limMsg->bodyptr);
+ return;
+ } else
+ lim_log(pMac, LOG1,
+ "SessionId:%d Session Exist for given Bssid",
+ psessionEntry->peSessionId);
+ }
+ /* For p2p resp frames search for valid session with DA as */
+ /* BSSID will be SA and session will be present with DA only */
+ if (fc.subType == SIR_MAC_MGMT_ACTION) {
+ psessionEntry =
+ pe_find_session_by_bssid(pMac, pHdr->da, &sessionId);
+ }
+ }
+
+ /* Check if frame is registered by HDD */
+ if (lim_check_mgmt_registered_frames(pMac, pRxPacketInfo, psessionEntry)) {
+ lim_log(pMac, LOG1, FL("Received frame is passed to SME"));
+ lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
+ limMsg->bodyptr);
+ return;
+ }
+
+ if (fc.protVer != SIR_MAC_PROTOCOL_VERSION) { /* Received Frame with non-zero Protocol Version */
+ lim_log(pMac, LOGE,
+ FL("Unexpected frame with protVersion %d received"),
+ fc.protVer);
+ lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
+ (void *)limMsg->bodyptr);
+#ifdef WLAN_DEBUG
+ pMac->lim.numProtErr++;
+#endif
+ return;
+ }
+
+/* Chance of crashing : to be done BT-AMP ........happens when broadcast probe req is received */
+
+#ifdef WLAN_DEBUG
+ pMac->lim.numMAC[fc.type][fc.subType]++;
+#endif
+
+ switch (fc.type) {
+ case SIR_MAC_MGMT_FRAME:
+ {
+ /* Received Management frame */
+ switch (fc.subType) {
+ case SIR_MAC_MGMT_ASSOC_REQ:
+ /* Make sure the role supports Association */
+ if (LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_AP_ROLE(psessionEntry))
+ lim_process_assoc_req_frame(pMac,
+ pRxPacketInfo,
+ LIM_ASSOC,
+ psessionEntry);
+ else {
+ /* Unwanted messages - Log error */
+ lim_log(pMac, LOGE,
+ FL
+ ("unexpected message received %X"),
+ limMsg->type);
+ lim_print_msg_name(pMac, LOGE,
+ limMsg->type);
+ }
+ break;
+
+ case SIR_MAC_MGMT_ASSOC_RSP:
+ lim_process_assoc_rsp_frame(pMac, pRxPacketInfo,
+ LIM_ASSOC,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_REASSOC_REQ:
+ /* Make sure the role supports Reassociation */
+ if (LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_AP_ROLE(psessionEntry)) {
+ lim_process_assoc_req_frame(pMac,
+ pRxPacketInfo,
+ LIM_REASSOC,
+ psessionEntry);
+ } else {
+ /* Unwanted messages - Log error */
+ lim_log(pMac, LOGE,
+ FL
+ ("unexpected message received %X"),
+ limMsg->type);
+ lim_print_msg_name(pMac, LOGE,
+ limMsg->type);
+ }
+ break;
+
+ case SIR_MAC_MGMT_REASSOC_RSP:
+ lim_process_assoc_rsp_frame(pMac, pRxPacketInfo,
+ LIM_REASSOC,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_PROBE_REQ:
+ lim_process_probe_req_frame_multiple_bss(pMac,
+ pRxPacketInfo,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_PROBE_RSP:
+ if (psessionEntry == NULL)
+ lim_process_probe_rsp_frame_no_session(pMac,
+ pRxPacketInfo);
+ else
+ lim_process_probe_rsp_frame(pMac,
+ pRxPacketInfo,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_BEACON:
+ __lim_handle_beacon(pMac, limMsg, psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_DISASSOC:
+ lim_process_disassoc_frame(pMac, pRxPacketInfo,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_AUTH:
+ lim_process_auth_frame(pMac, pRxPacketInfo,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_DEAUTH:
+ lim_process_deauth_frame(pMac, pRxPacketInfo,
+ psessionEntry);
+ break;
+
+ case SIR_MAC_MGMT_ACTION:
+ if (psessionEntry == NULL)
+ lim_process_action_frame_no_session(pMac,
+ pRxPacketInfo);
+ else {
+ if (WMA_GET_RX_UNKNOWN_UCAST
+ (pRxPacketInfo))
+ lim_handle_unknown_a2_index_frames
+ (pMac, pRxPacketInfo,
+ psessionEntry);
+ else
+ lim_process_action_frame(pMac,
+ pRxPacketInfo,
+ psessionEntry);
+ }
+ break;
+ default:
+ /* Received Management frame of 'reserved' subtype */
+ break;
+ } /* switch (fc.subType) */
+
+ }
+ break;
+ case SIR_MAC_DATA_FRAME:
+ {
+ }
+ break;
+ default:
+ /* Received frame of type 'reserved' */
+ break;
+
+ } /* switch (fc.type) */
+
+end:
+ lim_pkt_free(pMac, TXRX_FRM_802_11_MGMT, pRxPacketInfo,
+ (void *)limMsg->bodyptr);
+ return;
+} /*** end lim_handle80211_frames() ***/
+
+/**
+ * lim_send_stop_scan_offload_req()
+ *
+ ***FUNCTION:
+ * This function will be called to abort the ongoing offloaded scan
+ * request.
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return CDF_STATUS_SUCCESS or CDF_STATUS_E_FAILURE
+ */
+CDF_STATUS lim_send_stop_scan_offload_req(tpAniSirGlobal pMac,
+ uint8_t SessionId, uint32_t scan_id)
+{
+ tSirMsgQ msg;
+ tSirRetStatus rc = eSIR_SUCCESS;
+ tAbortScanParams *pAbortScanParams;
+
+ pAbortScanParams = cdf_mem_malloc(sizeof(tAbortScanParams));
+ if (NULL == pAbortScanParams) {
+ lim_log(pMac, LOGP,
+ FL("Memory allocation failed for AbortScanParams"));
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ pAbortScanParams->SessionId = SessionId;
+ pAbortScanParams->scan_id = scan_id;
+ msg.type = WMA_STOP_SCAN_OFFLOAD_REQ;
+ msg.bodyptr = pAbortScanParams;
+ msg.bodyval = 0;
+
+ rc = wma_post_ctrl_msg(pMac, &msg);
+ if (rc != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure"));
+ cdf_mem_free(pAbortScanParams);
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ lim_log(pMac, LOG1, FL("Abort ongoing offload scan."));
+ return CDF_STATUS_SUCCESS;
+
+}
+
+/**
+ * lim_process_abort_scan_ind()
+ *
+ ***FUNCTION:
+ * This function is called from HDD to abort the scan which is presently being run
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+void lim_process_abort_scan_ind(tpAniSirGlobal mac_ctx,
+ uint8_t session_id, uint32_t scan_id)
+{
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT, NULL, 0, 0);
+#endif
+
+ lim_log(mac_ctx, LOG2, FL("Processing AbortScan Ind scan_id %d"),
+ scan_id);
+
+ /* send stop scan cmd to fw if scan offload is enabled. */
+ lim_send_stop_scan_offload_req(mac_ctx, session_id, scan_id);
+ return;
+}
+
+/**
+ * lim_message_processor() - Process messages from LIM.
+ *
+ * @mac_ctx: Pointer to the Global Mac Context.
+ * @msg: Received LIM message.
+ *
+ * Wrapper function for lim_process_messages when handling messages received by
+ * LIM.Could either defer messages or process them.
+ *
+ * Return: None.
+ */
+void lim_message_processor(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+ if (eLIM_MLM_OFFLINE_STATE == mac_ctx->lim.gLimMlmState) {
+ pe_free_msg(mac_ctx, msg);
+ return;
+ }
+
+ if (!def_msg_decision(mac_ctx, msg)) {
+ lim_process_messages(mac_ctx, msg);
+ /* process deferred message queue if allowed */
+ if ((!(mac_ctx->lim.gLimAddtsSent)) &&
+ (!(lim_is_system_in_scan_state(mac_ctx))) &&
+ (true == GET_LIM_PROCESS_DEFD_MESGS(mac_ctx)))
+ lim_process_deferred_message_queue(mac_ctx);
+ }
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+void lim_oem_data_rsp_handle_resume_link_rsp(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *mlmOemDataRsp)
+{
+ if (status != CDF_STATUS_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL
+ ("OEM Data Rsp failed to get the response for resume link"));
+ }
+
+ if (NULL != pMac->lim.gpLimMlmOemDataReq) {
+ cdf_mem_free(pMac->lim.gpLimMlmOemDataReq);
+ pMac->lim.gpLimMlmOemDataReq = NULL;
+ }
+ /* "Failure" status doesn't mean that Oem Data Rsp did not happen */
+ /* and hence we need to respond to upper layers. Only Resume link is failed, but */
+ /* we got the oem data response already. */
+ /* Post the meessage to MLM */
+ lim_post_sme_message(pMac, LIM_MLM_OEM_DATA_CNF,
+ (uint32_t *) (mlmOemDataRsp));
+
+ return;
+}
+
+void lim_process_oem_data_rsp(tpAniSirGlobal pMac, uint32_t *body)
+{
+ tpLimMlmOemDataRsp mlmOemDataRsp = NULL;
+
+ /* Process all the messages for the lim queue */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+
+ mlmOemDataRsp = (tpLimMlmOemDataRsp) body;
+
+ PELOG1(lim_log
+ (pMac, LOG1, FL("%s: sending oem data response msg to sme"),
+ __func__);
+ )
+ lim_post_sme_message(pMac, LIM_MLM_OEM_DATA_CNF,
+ (uint32_t *) (mlmOemDataRsp));
+
+ return;
+}
+
+#endif
+
+/**
+ * lim_process_messages() - Process messages from upper layers.
+ *
+ * @mac_ctx: Pointer to the Global Mac Context.
+ * @msg: Received message.
+ *
+ * Return: None.
+ */
+void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ uint8_t vdev_id = 0;
+ tUpdateBeaconParams beacon_params;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+ uint8_t i;
+ uint8_t p2p_go_exists = 0;
+ tpPESession session_entry = NULL;
+ uint8_t defer_msg = false;
+ tLinkStateParams *link_state_param;
+ uint16_t pkt_len = 0;
+ cds_pkt_t *body_ptr = NULL;
+ CDF_STATUS cdf_status;
+ tSirMsgQ new_msg;
+ tSirSmeScanAbortReq *req_msg = NULL;
+ uint8_t session_id;
+ uint32_t scan_id;
+
+#ifdef FEATURE_WLAN_TDLS
+ tSirTdlsInd *tdls_ind = NULL;
+ tpDphHashNode sta_ds = NULL;
+ tTdlsLinkEstablishParams *tdls_link_params = NULL;
+#endif
+ tSirMbMsgP2p *p2p_msg = NULL;
+ if (ANI_DRIVER_TYPE(mac_ctx) == eDRIVER_TYPE_MFG) {
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ return;
+ }
+ if (msg == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Message pointer is Null"));
+ CDF_ASSERT(0);
+ return;
+ }
+#ifdef WLAN_DEBUG
+ mac_ctx->lim.numTot++;
+#endif
+ MTRACE(mac_trace_msg_rx(mac_ctx, NO_SESSION,
+ LIM_TRACE_MAKE_RXMSG(msg->type, LIM_MSG_PROCESSED));)
+
+ switch (msg->type) {
+
+ case SIR_LIM_UPDATE_BEACON:
+ lim_update_beacon(mac_ctx);
+ break;
+ case SIR_CFG_PARAM_UPDATE_IND:
+ if (!lim_is_system_in_scan_state(mac_ctx)) {
+ lim_handle_cf_gparam_update(mac_ctx, msg->bodyval);
+ break;
+ }
+ /* System is in DFS (Learn) mode.
+ * Defer processsing this message
+ */
+ if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
+ if (!(mac_ctx->lim.deferredMsgCnt & 0xF))
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGE,
+ FL("Unable to Defer Msg"));
+ lim_log_session_states(mac_ctx);
+ lim_print_msg_name(mac_ctx, LOGE, msg->type);
+ }
+ break;
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case WMA_START_OEM_DATA_RSP:
+ lim_process_oem_data_rsp(mac_ctx, msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#endif
+ case WMA_SWITCH_CHANNEL_RSP:
+ lim_process_switch_channel_rsp(mac_ctx, msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#ifdef ANI_SIR_IBSS_PEER_CACHING
+ case WMA_IBSS_STA_ADD:
+ lim_ibss_sta_add(mac_ctx, msg->bodyptr);
+ break;
+#endif
+ case SIR_BB_XPORT_MGMT_MSG:
+ /* These messages are from Peer MAC entity. */
+#ifdef WLAN_DEBUG
+ mac_ctx->lim.numBbt++;
+#endif
+ /* The original msg which we were deferring have the
+ * bodyPointer point to 'BD' instead of 'cds pkt'. If we
+ * don't make a copy of msg, then overwrite the
+ * msg->bodyPointer and next time when we try to
+ * process the msg, we will try to use 'BD' as
+ * 'cds Pkt' which will cause a crash
+ */
+ if (msg->bodyptr == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Message bodyptr is Null"));
+ CDF_ASSERT(0);
+ break;
+ }
+ cdf_mem_copy((uint8_t *) &new_msg,
+ (uint8_t *) msg, sizeof(tSirMsgQ));
+ body_ptr = (cds_pkt_t *) new_msg.bodyptr;
+ cds_pkt_get_packet_length(body_ptr, &pkt_len);
+
+ cdf_status = wma_ds_peek_rx_packet_info(body_ptr,
+ (void **) &new_msg.bodyptr, false);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ cds_pkt_return_packet(body_ptr);
+ break;
+ }
+
+ if (WMA_GET_ROAMCANDIDATEIND(new_msg.bodyptr))
+ lim_log(mac_ctx, LOG1, FL("roamCandidateInd %d"),
+ WMA_GET_ROAMCANDIDATEIND(new_msg.bodyptr));
+
+ if (WMA_GET_OFFLOADSCANLEARN(new_msg.bodyptr))
+ lim_log(mac_ctx, LOG1, FL("offloadScanLearn %d"),
+ WMA_GET_OFFLOADSCANLEARN(new_msg.bodyptr));
+
+ lim_handle80211_frames(mac_ctx, &new_msg, &defer_msg);
+
+ if (defer_msg == true) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOG1,
+ FL("Defer Msg type=%x"), msg->type);
+ if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGE,
+ FL("Unable to Defer Msg"));
+ lim_log_session_states(mac_ctx);
+ cds_pkt_return_packet(body_ptr);
+ }
+ } else
+ /* PE is not deferring this 802.11 frame so we need to
+ * call cds_pkt_return. Asumption here is when Rx mgmt
+ * frame processing is done, cds packet could be
+ * freed here.
+ */
+ cds_pkt_return_packet(body_ptr);
+ break;
+ case eWNI_SME_SCAN_REQ:
+ case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
+ case eWNI_SME_DISASSOC_REQ:
+ case eWNI_SME_DEAUTH_REQ:
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case eWNI_SME_OEM_DATA_REQ:
+#endif
+#ifdef FEATURE_WLAN_TDLS
+ case eWNI_SME_TDLS_SEND_MGMT_REQ:
+ case eWNI_SME_TDLS_ADD_STA_REQ:
+ case eWNI_SME_TDLS_DEL_STA_REQ:
+ case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
+#endif
+ case eWNI_SME_RESET_AP_CAPS_CHANGED:
+ case eWNI_SME_SET_HW_MODE_REQ:
+ case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
+ /* These messages are from HDD. Need to respond to HDD */
+ lim_process_normal_hdd_msg(mac_ctx, msg, true);
+ break;
+
+ case eWNI_SME_SCAN_ABORT_IND:
+ req_msg = msg->bodyptr;
+ if (req_msg) {
+ session_id = req_msg->sessionId;
+ scan_id = req_msg->scan_id;
+ lim_process_abort_scan_ind(mac_ctx, session_id,
+ scan_id);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ }
+ break;
+ case eWNI_SME_SYS_READY_IND:
+ case eWNI_SME_JOIN_REQ:
+ case eWNI_SME_REASSOC_REQ:
+ case eWNI_SME_START_BSS_REQ:
+ case eWNI_SME_STOP_BSS_REQ:
+ case eWNI_SME_SWITCH_CHL_IND:
+ case eWNI_SME_SETCONTEXT_REQ:
+ case eWNI_SME_DISASSOC_CNF:
+ case eWNI_SME_DEAUTH_CNF:
+ case eWNI_SME_ASSOC_CNF:
+ case eWNI_SME_ADDTS_REQ:
+ case eWNI_SME_DELTS_REQ:
+ case eWNI_SME_GET_ASSOC_STAS_REQ:
+ case eWNI_SME_TKIP_CNTR_MEAS_REQ:
+ case eWNI_SME_UPDATE_APWPSIE_REQ:
+ case eWNI_SME_HIDE_SSID_REQ:
+ case eWNI_SME_GET_WPSPBC_SESSION_REQ:
+ case eWNI_SME_SET_APWPARSNIEs_REQ:
+ case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
+#if defined WLAN_FEATURE_VOWIFI
+ case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+ case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+#endif
+#if defined FEATURE_WLAN_ESE
+ case eWNI_SME_ESE_ADJACENT_AP_REPORT:
+#endif
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case eWNI_SME_FT_UPDATE_KEY:
+ case eWNI_SME_FT_PRE_AUTH_REQ:
+ case eWNI_SME_FT_AGGR_QOS_REQ:
+#endif
+ case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
+ case eWNI_SME_UPDATE_NOA:
+ case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
+ case eWNI_SME_GET_STATISTICS_REQ:
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+ case eWNI_SME_GET_TSM_STATS_REQ:
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+ /* These messages are from HDD.No need to respond to HDD */
+ lim_process_normal_hdd_msg(mac_ctx, msg, false);
+ break;
+
+ case eWNI_PMC_SMPS_STATE_IND:
+ if (msg->bodyptr) {
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ }
+ break;
+ case eWNI_SME_SEND_ACTION_FRAME_IND:
+ lim_send_p2p_action_frame(mac_ctx, msg);
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_ABORT_REMAIN_ON_CHAN_IND:
+ p2p_msg = (tSirMbMsgP2p *) msg->bodyptr;
+ lim_abort_remain_on_chan(mac_ctx, p2p_msg->sessionId,
+ p2p_msg->scan_id);
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case SIR_HAL_P2P_NOA_START_IND:
+ session_entry = &mac_ctx->lim.gpSession[0];
+ lim_log(mac_ctx, LOG1, "LIM received NOA start %x", msg->type);
+
+ /* Since insert NOA is done and NOA start msg received,
+ * we should deactivate the Insert NOA timer
+ */
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_INSERT_SINGLESHOT_NOA_TIMER);
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ session_entry = &mac_ctx->lim.gpSession[i];
+ if ((session_entry != NULL) && (session_entry->valid) &&
+ (session_entry->pePersona == CDF_P2P_GO_MODE)) {
+ /* Save P2P NOA start attribute for Go persona*/
+ p2p_go_exists = 1;
+ cdf_mem_copy(&session_entry->p2pGoPsNoaStartInd,
+ msg->bodyptr, sizeof(tSirP2PNoaStart));
+ cdf_status =
+ session_entry->p2pGoPsNoaStartInd.status;
+ if (cdf_status != CDF_STATUS_SUCCESS)
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGW,
+ FL(
+ "GO NOA start status %d by FW"),
+ cdf_status);
+ break;
+ }
+ }
+
+ if (p2p_go_exists == 0)
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGW,
+ FL(
+ "GO is removed by the time NOA start recvd"));
+
+ /* We received the NOA start indication. Now we can send down
+ * the SME request which requires off-channel operation */
+ lim_process_regd_defd_sme_req_after_noa_start(mac_ctx);
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#ifdef FEATURE_WLAN_TDLS
+ case SIR_HAL_TDLS_IND:
+ tdls_ind = (tpSirTdlsInd) msg->bodyptr;
+ session_entry = pe_find_session_by_sta_id(mac_ctx,
+ tdls_ind->staIdx, &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOG1,
+ FL("No session exist for given bssId"));
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ return;
+ }
+ sta_ds = dph_get_hash_entry(mac_ctx, tdls_ind->assocId,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOG1,
+ FL("No sta_ds exist for given staId"));
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ return;
+ }
+
+ if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
+ lim_log(mac_ctx, LOGE,
+ FL("rcvd TDLS IND from FW with RC %d "),
+ tdls_ind->reasonCode);
+ lim_send_sme_tdls_del_sta_ind(mac_ctx, sta_ds,
+ session_entry, tdls_ind->reasonCode);
+ }
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#endif
+ case SIR_HAL_P2P_NOA_ATTR_IND:
+ session_entry = &mac_ctx->lim.gpSession[0];
+ lim_log(mac_ctx, LOG1, FL("Received message Noa_ATTR %x"),
+ msg->type);
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ session_entry = &mac_ctx->lim.gpSession[i];
+ if ((session_entry != NULL) && (session_entry->valid)
+ && (session_entry->pePersona ==
+ CDF_P2P_GO_MODE)) { /* Save P2P attr for Go */
+ cdf_mem_copy(
+ &session_entry->p2pGoPsUpdate,
+ msg->bodyptr,
+ sizeof(tSirP2PNoaAttr));
+ lim_log(mac_ctx, LOG2,
+ FL("bssId"
+ MAC_ADDRESS_STR
+ " ctWin=%d oppPsFlag=%d"),
+ MAC_ADDR_ARRAY(
+ session_entry->bssId),
+ session_entry->p2pGoPsUpdate.ctWin,
+ session_entry->p2pGoPsUpdate.oppPsFlag);
+ lim_log(mac_ctx, LOG2,
+ FL
+ (" uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d"),
+ session_entry->p2pGoPsUpdate.uNoa1IntervalCnt,
+ session_entry->p2pGoPsUpdate.uNoa1Duration,
+ session_entry->p2pGoPsUpdate.uNoa1Interval,
+ session_entry->p2pGoPsUpdate.uNoa1StartTime);
+ break;
+ }
+ }
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case WMA_MISSED_BEACON_IND:
+ lim_ps_offload_handle_missed_beacon_ind(mac_ctx, msg);
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ case WMA_ROAM_OFFLOAD_SYNCH_IND:
+ lim_roam_offload_synch_ind(mac_ctx, msg);
+ /* bodyPtr is freed after handling
+ * eWNI_SME_ROAM_OFFLOAD_SYNCH_IND in sme_ProcessMsg */
+ break;
+#endif
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ break;
+#ifdef FEATURE_WLAN_ESE
+ case SIR_LIM_ESE_TSM_TIMEOUT:
+#ifndef FEATURE_WLAN_ESE_UPLOAD
+ limProcessTsmTimeoutHandler(mac_ctx, msg);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+ break;
+ case WMA_TSM_STATS_RSP:
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ lim_send_sme_pe_ese_tsm_rsp(mac_ctx,
+ (tAniGetTsmStatsRsp *) msg->bodyptr);
+#else
+ limProcessHalEseTsmRsp(mac_ctx, msg);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+ break;
+#endif
+ case WMA_ADD_TS_RSP:
+ lim_process_hal_add_ts_rsp(mac_ctx, msg);
+ break;
+ case SIR_LIM_DEL_TS_IND:
+ lim_process_del_ts_ind(mac_ctx, msg);
+ break;
+ case SIR_LIM_BEACON_GEN_IND:
+ if (mac_ctx->lim.gLimSystemRole != eLIM_AP_ROLE)
+ sch_process_pre_beacon_ind(mac_ctx, msg);
+ break;
+ case SIR_LIM_DELETE_STA_CONTEXT_IND:
+ lim_delete_sta_context(mac_ctx, msg);
+ break;
+ case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
+ case SIR_LIM_JOIN_FAIL_TIMEOUT:
+ case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
+ case SIR_LIM_AUTH_FAIL_TIMEOUT:
+ case SIR_LIM_AUTH_RSP_TIMEOUT:
+ case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+ case SIR_LIM_REASSOC_FAIL_TIMEOUT:
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+#endif
+ case SIR_LIM_REMAIN_CHN_TIMEOUT:
+ case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:
+ case SIR_LIM_DISASSOC_ACK_TIMEOUT:
+ case SIR_LIM_DEAUTH_ACK_TIMEOUT:
+ case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
+ /* These timeout messages are handled by MLM sub module */
+ lim_process_mlm_req_messages(mac_ctx, msg);
+ break;
+ case SIR_LIM_HEART_BEAT_TIMEOUT:
+ /** check if heart beat failed, even if one Beacon
+ * is rcvd within the Heart Beat interval continue
+ * normal processing
+ */
+ if (NULL == msg->bodyptr)
+ lim_log(mac_ctx, LOGE,
+ FL("Can't Process HB TO - bodyptr is Null"));
+ else {
+ session_entry = (tpPESession) msg->bodyptr;
+ lim_log(mac_ctx, LOGE,
+ FL
+ ("SIR_LIM_HEART_BEAT_TIMEOUT, Session %d"),
+ ((tpPESession) msg->bodyptr)->peSessionId);
+ limResetHBPktCount(session_entry);
+ lim_handle_heart_beat_timeout_for_session(mac_ctx,
+ session_entry);
+ }
+ break;
+ case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT:
+ lim_handle_heart_beat_failure_timeout(mac_ctx);
+ break;
+ case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
+ mac_ctx->lim.gLimDisassocFrameCredit = 0;
+ break;
+ case SIR_LIM_CNF_WAIT_TIMEOUT:
+ /* Does not receive CNF or dummy packet */
+ lim_handle_cnf_wait_timeout(mac_ctx, (uint16_t) msg->bodyval);
+ break;
+ case SIR_LIM_RETRY_INTERRUPT_MSG:
+ /* Message from ISR upon TFP's max retry limit interrupt */
+ break;
+ case SIR_LIM_INV_KEY_INTERRUPT_MSG:
+ /* Message from ISR upon SP's Invalid session key interrupt */
+ break;
+ case SIR_LIM_KEY_ID_INTERRUPT_MSG:
+ /* Message from ISR upon SP's Invalid key ID interrupt */
+ break;
+ case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
+ /* Message from ISR upon SP's Replay threshold interrupt */
+ break;
+ case SIR_LIM_CHANNEL_SWITCH_TIMEOUT:
+ lim_process_channel_switch_timeout(mac_ctx);
+ break;
+ case SIR_LIM_QUIET_TIMEOUT:
+ lim_process_quiet_timeout(mac_ctx);
+ break;
+ case SIR_LIM_QUIET_BSS_TIMEOUT:
+ lim_process_quiet_bss_timeout(mac_ctx);
+ break;
+ case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
+ lim_handle_update_olbc_cache(mac_ctx);
+ break;
+#ifdef FEATURE_WLAN_TDLS
+ case SIR_HAL_TDLS_SHOULD_DISCOVER:
+ case SIR_HAL_TDLS_SHOULD_TEARDOWN:
+ case SIR_HAL_TDLS_PEER_DISCONNECTED:
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ ("%s received tdls event: 0x%x"), __func__, msg->type);
+ lim_send_sme_tdls_event_notify(mac_ctx, msg->type,
+ (void *)msg->bodyptr);
+ break;
+#endif
+ case WMA_ADD_BSS_RSP:
+ lim_process_mlm_add_bss_rsp(mac_ctx, msg);
+ break;
+ case WMA_ADD_STA_RSP:
+ lim_process_add_sta_rsp(mac_ctx, msg);
+ break;
+ case WMA_DELETE_STA_RSP:
+ lim_process_mlm_del_sta_rsp(mac_ctx, msg);
+ break;
+ case WMA_DELETE_BSS_RSP:
+ lim_handle_delete_bss_rsp(mac_ctx, msg);
+ break;
+ case WMA_CSA_OFFLOAD_EVENT:
+ lim_handle_csa_offload_msg(mac_ctx, msg);
+ break;
+ case WMA_SET_BSSKEY_RSP:
+ case WMA_SET_STA_BCASTKEY_RSP:
+ lim_process_mlm_set_bss_key_rsp(mac_ctx, msg);
+ break;
+ case WMA_SET_STAKEY_RSP:
+ lim_process_mlm_set_sta_key_rsp(mac_ctx, msg);
+ break;
+ case WMA_GET_STATISTICS_RSP:
+ lim_send_sme_pe_statistics_rsp(mac_ctx, msg->type,
+ (void *)msg->bodyptr);
+ break;
+ case WMA_SET_MIMOPS_RSP:
+ case WMA_SET_TX_POWER_RSP:
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case WMA_SET_MAX_TX_POWER_RSP:
+#if defined WLAN_FEATURE_VOWIFI
+ rrm_set_max_tx_power_rsp(mac_ctx, msg);
+#endif
+ if (msg->bodyptr != NULL) {
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ }
+ break;
+ case SIR_LIM_ADDR2_MISS_IND:
+ lim_log(mac_ctx, LOGE,
+ FL("Addr2 mismatch interrupt received %X"), msg->type);
+ /* message from HAL indicating addr2 mismatch interrupt occurred
+ * msg->bodyptr contains only pointer to 48-bit addr2 field
+ */
+ cdf_mem_free((void *)(msg->bodyptr));
+ msg->bodyptr = NULL;
+ break;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case WMA_AGGR_QOS_RSP:
+ lim_process_ft_aggr_qo_s_rsp(mac_ctx, msg);
+ break;
+#endif
+ case WMA_SET_LINK_STATE_RSP:
+ link_state_param = (tLinkStateParams *) msg->bodyptr;
+#if defined WLAN_FEATURE_VOWIFI_11R
+ session_entry = link_state_param->session;
+ if (link_state_param->ft
+#if defined WLAN_FEATURE_ROAM_OFFLOAD
+ && !session_entry->bRoamSynchInProgress
+#endif
+ )
+ lim_send_reassoc_req_with_ft_ies_mgmt_frame(mac_ctx,
+ session_entry->pLimMlmReassocReq,
+ session_entry);
+#endif
+ if (link_state_param->callback)
+ link_state_param->callback(mac_ctx,
+ link_state_param->callbackArg,
+ link_state_param->status);
+ cdf_mem_free((void *)(msg->bodyptr));
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_SET_BCN_FILTER_REQ:
+ session_id = (uint8_t) msg->bodyval;
+ session_entry = &mac_ctx->lim.gpSession[session_id];
+ if ((session_entry != NULL) &&
+ (lim_send_beacon_filter_info(mac_ctx, session_entry) !=
+ eSIR_SUCCESS))
+ lim_log(mac_ctx, LOGE,
+ FL("Failied to send Beacon Filter Info "));
+ cdf_mem_free((void *)(msg->bodyptr));
+ msg->bodyptr = NULL;
+ break;
+#ifdef FEATURE_WLAN_TDLS
+ case WMA_SET_TDLS_LINK_ESTABLISH_REQ_RSP:
+ tdls_link_params = (tTdlsLinkEstablishParams *) msg->bodyptr;
+ session_entry = pe_find_session_by_sta_id(mac_ctx,
+ tdls_link_params->staIdx, &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session %u does not exist"), session_id);
+ /* Still send the eWNI_SME_TDLS_LINK_ESTABLISH_RSP
+ * message to SME with session id as zero and status
+ * as FAILURE so, that message queued in SME queue
+ * can be freed to prevent the SME cmd buffer leak
+ */
+ lim_send_sme_tdls_link_establish_req_rsp(mac_ctx, 0,
+ NULL, NULL, eSIR_FAILURE);
+ } else {
+ lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
+ session_entry->smeSessionId, NULL, NULL,
+ tdls_link_params->status);
+ }
+ cdf_mem_free((void *)(msg->bodyptr));
+ msg->bodyptr = NULL;
+ break;
+#endif
+ case WMA_RX_SCAN_EVENT:
+ lim_process_rx_scan_event(mac_ctx, msg->bodyptr);
+ break;
+ case WMA_IBSS_PEER_INACTIVITY_IND:
+ lim_process_ibss_peer_inactivity(mac_ctx, msg->bodyptr);
+ cdf_mem_free((void *)(msg->bodyptr));
+ msg->bodyptr = NULL;
+ break;
+ case WMA_DFS_RADAR_IND:
+ lim_send_sme_dfs_event_notify(mac_ctx, msg->type,
+ (void *)msg->bodyptr);
+ /* msg->bodyptr will be freed up by SME/CSR */
+ break;
+ case WMA_DFS_BEACON_TX_SUCCESS_IND:
+ lim_process_beacon_tx_success_ind(mac_ctx, msg->type,
+ (void *)msg->bodyptr);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case WMA_DISASSOC_TX_COMP:
+ lim_disassoc_tx_complete_cnf(mac_ctx, msg->bodyval);
+ break;
+ case WMA_DEAUTH_TX_COMP:
+ lim_deauth_tx_complete_cnf(mac_ctx, msg->bodyval);
+ break;
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ case WMA_UPDATE_Q2Q_IE_IND:
+ cdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+ beacon_params.paramChangeBitmap = 0;
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ vdev_id = ((uint8_t *)msg->bodyptr)[i];
+ session_entry = pe_find_session_by_sme_session_id(
+ mac_ctx, vdev_id);
+ if (session_entry == NULL)
+ continue;
+ session_entry->sap_advertise_avoid_ch_ie =
+ (uint8_t)msg->bodyval;
+ /*
+ * if message comes for DFS channel, no need to update:
+ * 1) We wont have MCC with DFS channels. so no need to
+ * add Q2Q IE
+ * 2) We cannot end up in DFS channel SCC by channel
+ * switch from non DFS MCC scenario, so no need to
+ * remove Q2Q IE
+ * 3) There is however a case where device start MCC and
+ * then user modifies hostapd.conf and does SAP
+ * restart, in such a case, beacon params will be
+ * reset and thus will not contain Q2Q IE, by default
+ */
+ if (cds_get_channel_state(
+ session_entry->currentOperChannel)
+ != CHANNEL_STATE_DFS) {
+ beacon_params.bssIdx = session_entry->bssIdx;
+ beacon_params.beaconInterval =
+ session_entry->beaconParams.beaconInterval;
+ beacon_params.paramChangeBitmap |=
+ PARAM_BCN_INTERVAL_CHANGED;
+ sch_set_fixed_beacon_fields(mac_ctx,
+ session_entry);
+ lim_send_beacon_params(mac_ctx, &beacon_params,
+ session_entry);
+ }
+ }
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+ case eWNI_SME_NSS_UPDATE_REQ:
+ case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_CHANNEL_CHANGE_REQ:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_START_BEACON_REQ:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_UPDATE_ADDITIONAL_IES:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_MODIFY_ADDITIONAL_IES:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#ifdef QCA_HT_2040_COEX
+ case eWNI_SME_SET_HT_2040_MODE:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+#endif
+ case SIR_HAL_SOC_SET_HW_MODE_RESP:
+ lim_process_set_hw_mode_resp(mac_ctx, msg->bodyptr);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case SIR_HAL_SOC_HW_MODE_TRANS_IND:
+ lim_process_hw_mode_trans_ind(mac_ctx, msg->bodyptr);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case SIR_HAL_SOC_DUAL_MAC_CFG_RESP:
+ lim_process_dual_mac_cfg_resp(mac_ctx, msg->bodyptr);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ case eWNI_SME_SET_IE_REQ:
+ lim_process_sme_req_messages(mac_ctx, msg);
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ break;
+ default:
+ cdf_mem_free((void *)msg->bodyptr);
+ msg->bodyptr = NULL;
+ /* Unwanted messages */
+ /* Log error */
+ lim_log(mac_ctx, LOGE,
+ FL("Discarding unexpected message received %X"),
+ msg->type);
+ lim_print_msg_name(mac_ctx, LOGE, msg->type);
+ break;
+
+ } /* switch (msg->type) */
+} /*** end lim_process_messages() ***/
+
+/**
+ * lim_process_deferred_message_queue
+ *
+ ***FUNCTION:
+ * This function is called by LIM while exiting from Learn
+ * mode. This function fetches messages posted to the LIM
+ * deferred message queue limDeferredMsgQ.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_process_deferred_message_queue(tpAniSirGlobal pMac)
+{
+ tSirMsgQ limMsg = { 0, 0, 0 };
+
+ tSirMsgQ *readMsg;
+ uint16_t size;
+
+ /*
+ ** check any deferred messages need to be processed
+ **/
+ size = pMac->lim.gLimDeferredMsgQ.size;
+ if (size > 0) {
+ while ((readMsg = lim_read_deferred_msg_q(pMac)) != NULL) {
+ cdf_mem_copy((uint8_t *) &limMsg,
+ (uint8_t *) readMsg, sizeof(tSirMsgQ));
+ size--;
+ lim_process_messages(pMac, &limMsg);
+
+ if ((lim_is_system_in_scan_state(pMac))
+ || (true != GET_LIM_PROCESS_DEFD_MESGS(pMac))
+ || (pMac->lim.gLimSystemInScanLearnMode))
+ break;
+ }
+ }
+} /*** end lim_process_deferred_message_queue() ***/
+
+/**
+ * lim_process_normal_hdd_msg() - Process the message and defer if needed
+ * @mac_ctx : Pointer to Global MAC structure
+ * @msg : The message need to be processed
+ * @rsp_reqd: whether return result to hdd
+ *
+ * This function checks the current lim state and decide whether the message
+ * passed will be deferred or not.
+ *
+ * Return: None
+ */
+static void lim_process_normal_hdd_msg(tpAniSirGlobal mac_ctx, tSirMsgQ *msg,
+ uint8_t rsp_reqd)
+{
+ bool defer_msg = true;
+
+ /* Added For BT-AMP Support */
+ if ((mac_ctx->lim.gLimSystemRole == eLIM_AP_ROLE)
+ || (mac_ctx->lim.gLimSystemRole == eLIM_BT_AMP_AP_ROLE)
+ || (mac_ctx->lim.gLimSystemRole == eLIM_BT_AMP_STA_ROLE)
+ || (mac_ctx->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)) {
+ /*
+ * This check is required only for the AP and in 2 cases.
+ * 1. If we are in learn mode and we receive any of these
+ * messages, you have to come out of scan and process the
+ * message, hence dont defer the message here. In handler,
+ * these message could be defered till we actually come out of
+ * scan mode.
+ * 2. If radar is detected, you might have to defer all of
+ * these messages except Stop BSS request/ Switch channel
+ * request. This decision is also made inside its handler.
+ *
+ * Please be careful while using the flag defer_msg. Possibly
+ * you might end up in an infinite loop.
+ */
+ if ((msg->type == eWNI_SME_START_BSS_REQ) ||
+ (msg->type == eWNI_SME_STOP_BSS_REQ) ||
+ (msg->type == eWNI_SME_SWITCH_CHL_IND))
+ defer_msg = false;
+ }
+
+ if (((mac_ctx->lim.gLimAddtsSent) ||
+ (lim_is_system_in_scan_state(mac_ctx))) && defer_msg) {
+ /*
+ * System is in DFS (Learn) mode or awaiting addts response or
+ * if radar is detected, Defer processsing this message
+ */
+ if (lim_defer_msg(mac_ctx, msg) != TX_SUCCESS) {
+#ifdef WLAN_DEBUG
+ mac_ctx->lim.numSme++;
+#endif
+ lim_log_session_states(mac_ctx);
+ /* Release body */
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ }
+ } else {
+ /*
+ * These messages are from HDD.Since these requests may also be
+ * generated internally within LIM module, need to distinquish
+ * and send response to host
+ */
+ if (rsp_reqd)
+ mac_ctx->lim.gLimRspReqd = true;
+#ifdef WLAN_DEBUG
+ mac_ctx->lim.numSme++;
+#endif
+ if (lim_process_sme_req_messages(mac_ctx, msg)) {
+ /*
+ * Release body. limProcessSmeReqMessage consumed the
+ * buffer. We can free it.
+ */
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ }
+ }
+}
+
+void
+handle_ht_capabilityand_ht_info(struct sAniSirGlobal *pMac,
+ tpPESession psessionEntry)
+{
+ tSirMacHTCapabilityInfo macHTCapabilityInfo;
+ tSirMacHTParametersInfo macHTParametersInfo;
+ tSirMacHTInfoField1 macHTInfoField1;
+ tSirMacHTInfoField2 macHTInfoField2;
+ tSirMacHTInfoField3 macHTInfoField3;
+ uint32_t cfgValue;
+ uint8_t *ptr;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO, &cfgValue) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Fail to retrieve WNI_CFG_HT_CAP_INFO value"));
+ return;
+ }
+ ptr = (uint8_t *) &macHTCapabilityInfo;
+ *((uint16_t *) ptr) = (uint16_t) (cfgValue & 0xffff);
+ pMac->lim.gHTLsigTXOPProtection =
+ (uint8_t) macHTCapabilityInfo.lsigTXOPProtection;
+ pMac->lim.gHTMIMOPSState =
+ (tSirMacHTMIMOPowerSaveState) macHTCapabilityInfo.mimoPowerSave;
+ pMac->lim.gHTGreenfield = (uint8_t) macHTCapabilityInfo.greenField;
+ pMac->lim.gHTMaxAmsduLength =
+ (uint8_t) macHTCapabilityInfo.maximalAMSDUsize;
+ pMac->lim.gHTShortGI20Mhz = (uint8_t) macHTCapabilityInfo.shortGI20MHz;
+ pMac->lim.gHTShortGI40Mhz = (uint8_t) macHTCapabilityInfo.shortGI40MHz;
+ pMac->lim.gHTPSMPSupport = (uint8_t) macHTCapabilityInfo.psmp;
+ pMac->lim.gHTDsssCckRate40MHzSupport =
+ (uint8_t) macHTCapabilityInfo.dsssCckMode40MHz;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_AMPDU_PARAMS, &cfgValue) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Fail to retrieve WNI_CFG_HT_PARAM_INFO value"));
+ return;
+ }
+ ptr = (uint8_t *) &macHTParametersInfo;
+ *ptr = (uint8_t) (cfgValue & 0xff);
+ pMac->lim.gHTAMpduDensity = (uint8_t) macHTParametersInfo.mpduDensity;
+ pMac->lim.gHTMaxRxAMpduFactor =
+ (uint8_t) macHTParametersInfo.maxRxAMPDUFactor;
+
+ /* Get HT IE Info */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_INFO_FIELD1, &cfgValue) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD1 value"));
+ return;
+ }
+ ptr = (uint8_t *) &macHTInfoField1;
+ *((uint8_t *) ptr) = (uint8_t) (cfgValue & 0xff);
+ pMac->lim.gHTServiceIntervalGranularity =
+ (uint8_t) macHTInfoField1.serviceIntervalGranularity;
+ pMac->lim.gHTControlledAccessOnly =
+ (uint8_t) macHTInfoField1.controlledAccessOnly;
+ pMac->lim.gHTRifsMode = (uint8_t) macHTInfoField1.rifsMode;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_INFO_FIELD2, &cfgValue) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD2 value"));
+ return;
+ }
+ ptr = (uint8_t *) &macHTInfoField2;
+ *((uint16_t *) ptr) = (uint16_t) (cfgValue & 0xffff);
+ pMac->lim.gHTOperMode = (tSirMacHTOperatingMode) macHTInfoField2.opMode;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_HT_INFO_FIELD3, &cfgValue) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD3 value"));
+ return;
+ }
+ ptr = (uint8_t *) &macHTInfoField3;
+ *((uint16_t *) ptr) = (uint16_t) (cfgValue & 0xffff);
+ pMac->lim.gHTPCOActive = (uint8_t) macHTInfoField3.pcoActive;
+ pMac->lim.gHTPCOPhase = (uint8_t) macHTInfoField3.pcoPhase;
+ pMac->lim.gHTSecondaryBeacon =
+ (uint8_t) macHTInfoField3.secondaryBeacon;
+ pMac->lim.gHTDualCTSProtection =
+ (uint8_t) macHTInfoField3.dualCTSProtection;
+ pMac->lim.gHTSTBCBasicMCS = (uint8_t) macHTInfoField3.basicSTBCMCS;
+
+ /* The lim globals for channelwidth and secondary chnl have been removed and should not be used during no session;
+ * instead direct cfg is read and used when no session for transmission of mgmt frames (same as old);
+ * For now, we might come here during init and join with sessionEntry = NULL; in that case just fill the globals which exist
+ * Sessionized entries values will be filled in join or add bss req. The ones which are missed in join are filled below
+ */
+ if (psessionEntry != NULL) {
+ psessionEntry->htCapability =
+ IS_DOT11_MODE_HT(psessionEntry->dot11mode);
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+ (uint8_t) macHTInfoField3.lsigTXOPProtectionFullSupport;
+ }
+}
+
+void lim_log_session_states(tpAniSirGlobal mac_ctx)
+{
+#ifdef WLAN_DEBUG
+ int i;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ if (mac_ctx->lim.gpSession[i].valid) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOG1,
+ FL("sysRole(%d) Session (%d)"),
+ mac_ctx->lim.gLimSystemRole, i);
+ CDF_TRACE(CDF_MODULE_ID_PE, LOG1,
+ FL("SME: Curr %s,Prev %s,MLM: Curr %s,Prev %s"),
+ lim_sme_state_str(
+ mac_ctx->lim.gpSession[i].limSmeState),
+ lim_sme_state_str(
+ mac_ctx->lim.gpSession[i].limPrevSmeState),
+ lim_mlm_state_str(
+ mac_ctx->lim.gpSession[i].limMlmState),
+ lim_mlm_state_str(
+ mac_ctx->lim.gpSession[i].limPrevMlmState));
+ }
+ }
+#endif
+}
diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
new file mode 100644
index 0000000..73f4bf0
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -0,0 +1,2868 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sir_api.h"
+#include "sir_params.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_security_utils.h"
+#include "lim_send_messages.h"
+#include "lim_send_messages.h"
+#include "lim_session_utils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include <lim_ft.h>
+#endif
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+#include "host_diag_core_log.h"
+#endif
+#include "wma_if.h"
+
+static void lim_process_mlm_start_req(tpAniSirGlobal, uint32_t *);
+#ifdef FEATURE_OEM_DATA_SUPPORT
+static void lim_process_mlm_oem_data_req(tpAniSirGlobal, uint32_t *);
+#endif
+static void lim_process_mlm_join_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_auth_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_assoc_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_reassoc_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_disassoc_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_deauth_req(tpAniSirGlobal, uint32_t *);
+static void lim_process_mlm_set_keys_req(tpAniSirGlobal, uint32_t *);
+
+/* MLM Timeout event handler templates */
+static void lim_process_periodic_probe_req_timer(tpAniSirGlobal mac_ctx);
+static void lim_process_join_failure_timeout(tpAniSirGlobal);
+static void lim_process_auth_failure_timeout(tpAniSirGlobal);
+static void lim_process_auth_rsp_timeout(tpAniSirGlobal, uint32_t);
+static void lim_process_assoc_failure_timeout(tpAniSirGlobal, uint32_t);
+static void lim_process_periodic_join_probe_req_timer(tpAniSirGlobal);
+
+/**
+ * lim_process_mlm_req_messages() - process mlm request messages
+ * @mac_ctx: global MAC context
+ * @msg: mlm request message
+ *
+ * This function is called by lim_post_mlm_message(). This
+ * function handles MLM primitives invoked by SME.
+ * Depending on the message type, corresponding function will be
+ * called.
+ * ASSUMPTIONS:
+ * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes
+ * APIs exposed by Beacon Processing module for setting parameters
+ * at MAC hardware.
+ * 2. If attempt to Reassociate with an AP fails, link with current
+ * AP is restored back.
+ *
+ * Return: None
+ */
+void lim_process_mlm_req_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+ MTRACE(mac_trace_msg_rx(mac_ctx, NO_SESSION, msg->type));
+ switch (msg->type) {
+ case LIM_MLM_START_REQ:
+ lim_process_mlm_start_req(mac_ctx, msg->bodyptr);
+ break;
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case LIM_MLM_OEM_DATA_REQ:
+ lim_process_mlm_oem_data_req(mac_ctx, msg->bodyptr);
+ break;
+#endif
+ case LIM_MLM_JOIN_REQ:
+ lim_process_mlm_join_req(mac_ctx, msg->bodyptr);
+ break;
+ case LIM_MLM_AUTH_REQ:
+ lim_process_mlm_auth_req(mac_ctx, msg->bodyptr);
+ break;
+ case LIM_MLM_ASSOC_REQ:
+ lim_process_mlm_assoc_req(mac_ctx, msg->bodyptr);
+ break;
+ case LIM_MLM_REASSOC_REQ:
+ lim_process_mlm_reassoc_req(mac_ctx, msg->bodyptr);
+ break;
+ case LIM_MLM_DISASSOC_REQ:
+ lim_process_mlm_disassoc_req(mac_ctx, msg->bodyptr);
+ break;
+ case LIM_MLM_DEAUTH_REQ:
+ lim_process_mlm_deauth_req(mac_ctx, msg->bodyptr);
+ break;
+ case LIM_MLM_SETKEYS_REQ:
+ lim_process_mlm_set_keys_req(mac_ctx, msg->bodyptr);
+ break;
+ case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT:
+ lim_process_periodic_probe_req_timer(mac_ctx);
+ break;
+ case SIR_LIM_JOIN_FAIL_TIMEOUT:
+ lim_process_join_failure_timeout(mac_ctx);
+ break;
+ case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT:
+ lim_process_periodic_join_probe_req_timer(mac_ctx);
+ break;
+ case SIR_LIM_AUTH_FAIL_TIMEOUT:
+ lim_process_auth_failure_timeout(mac_ctx);
+ break;
+ case SIR_LIM_AUTH_RSP_TIMEOUT:
+ lim_process_auth_rsp_timeout(mac_ctx, msg->bodyval);
+ break;
+ case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+ lim_process_assoc_failure_timeout(mac_ctx, msg->bodyval);
+ break;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+ lim_process_ft_preauth_rsp_timeout(mac_ctx);
+ break;
+#endif
+ case SIR_LIM_REMAIN_CHN_TIMEOUT:
+ lim_process_remain_on_chn_timeout(mac_ctx);
+ break;
+ case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT:
+ lim_process_insert_single_shot_noa_timeout(mac_ctx);
+ break;
+ case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
+ lim_convert_active_channel_to_passive_channel(mac_ctx);
+ break;
+ case SIR_LIM_DISASSOC_ACK_TIMEOUT:
+ lim_process_disassoc_ack_timeout(mac_ctx);
+ break;
+ case SIR_LIM_DEAUTH_ACK_TIMEOUT:
+ lim_process_deauth_ack_timeout(mac_ctx);
+ break;
+ case LIM_MLM_TSPEC_REQ:
+ default:
+ break;
+ } /* switch (msg->type) */
+}
+
+/* WLAN_SUSPEND_LINK Related */
+
+/**
+ * lim_is_link_suspended()- check if link is suspended
+ * @mac_ctx: global MAC context
+ *
+ * This function returns is link is suspended or not.
+ * Since Suspend link uses init scan, it just returns
+ * gLimSystemInScanLearnMode flag.
+ *
+ * Return: uint8_t(gLimSystemInScanLearnMode flag)
+ */
+uint8_t lim_is_link_suspended(tpAniSirGlobal mac_ctx)
+{
+ return mac_ctx->lim.gLimSystemInScanLearnMode;
+}
+
+/**
+ * lim_change_channel_with_callback() - change channel and register callback
+ * @mac_ctx: global MAC context
+ * @new_chan: new channel to switch
+ * @callback: Callback function
+ * @cbdata: callback data
+ * @session_entry: PE session pointer
+ *
+ * This function is called to change channel and perform off channel operation
+ * if required. The caller registers a callback to be called at the end of the
+ * channel change.
+ *
+ * Return: None
+ */
+void
+lim_change_channel_with_callback(tpAniSirGlobal mac_ctx, uint8_t new_chan,
+ CHANGE_CHANNEL_CALLBACK callback,
+ uint32_t *cbdata, tpPESession session_entry)
+{
+ /* Sanity checks for the current and new channel */
+#if defined WLAN_VOWIFI_DEBUG
+ lim_log(mac_ctx, LOGE, FL("Switching channel to %d"), new_chan);
+#endif
+ session_entry->channelChangeReasonCode =
+ LIM_SWITCH_CHANNEL_OPERATION;
+
+ mac_ctx->lim.gpchangeChannelCallback = callback;
+ mac_ctx->lim.gpchangeChannelData = cbdata;
+
+ lim_send_switch_chnl_params(mac_ctx, new_chan, 0, 0,
+ CH_WIDTH_20MHZ, session_entry->maxTxPower,
+ session_entry->peSessionId, false);
+
+ return;
+}
+
+/**
+ * lim_covert_channel_scan_type() - switch between ACTIVE and PASSIVE scan type
+ * @mac_ctx: global MAC context
+ * @chan_num: channel number to change the scan type
+ * @passive_to_active: flag to indicate if switch allowed
+ *
+ * This function is called to get the list,
+ * change the channel type and set again.
+ * NOTE: If a channel is ACTIVE, this function will make it as PASSIVE
+ * If a channel is PASSIVE, this fucntion will make it as ACTIVE
+ *
+ * Return: None
+ */
+
+void lim_covert_channel_scan_type(tpAniSirGlobal mac_ctx, uint8_t chan_num,
+ bool passive_to_active)
+{
+
+ uint32_t i;
+ uint8_t chan_pair[WNI_CFG_SCAN_CONTROL_LIST_LEN];
+ uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
+ tSirRetStatus status;
+
+ status = wlan_cfg_get_str(mac_ctx, WNI_CFG_SCAN_CONTROL_LIST,
+ chan_pair, &len);
+ if (eSIR_SUCCESS != status) {
+ lim_log(mac_ctx, LOGE, FL("Unable to get scan control list"));
+ return;
+ }
+ if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid scan control list length:%d"), len);
+ return;
+ }
+ for (i = 0; (i + 1) < len; i += 2) {
+ if (chan_pair[i] != chan_num) /* skip this channel */
+ continue;
+ if ((eSIR_PASSIVE_SCAN == chan_pair[i + 1]) &&
+ true == passive_to_active) {
+ lim_log(mac_ctx, LOG1, FL
+ ("Channel %d changed from Passive to Active"),
+ chan_num);
+ chan_pair[i + 1] = eSIR_ACTIVE_SCAN;
+ break;
+ }
+ if ((eSIR_ACTIVE_SCAN == chan_pair[i + 1]) &&
+ false == passive_to_active) {
+ lim_log(mac_ctx, LOG1, FL
+ ("Channel %d changed from Active to Passive"),
+ chan_num);
+ chan_pair[i + 1] = eSIR_PASSIVE_SCAN;
+ break;
+ }
+ }
+
+ cfg_set_str_notify(mac_ctx, WNI_CFG_SCAN_CONTROL_LIST,
+ (uint8_t *) chan_pair, len, false);
+ return;
+}
+
+/**
+ * lim_set_dfs_channel_list() - convert dfs channel list to active channel list
+ * @mac_ctx: global MAC context.
+ * @chan_num: channel number
+ * @dfs_ch_list: list of DFS channels
+ *
+ * This function is called to convert DFS channel list to active channel list
+ * when any beacon is present on that channel. This function store time for
+ * passive channels which help to know that for how much time channel has been
+ * passive.
+ *
+ * NOTE: If a channel is ACTIVE, it won't store any time
+ * If a channel is PAssive, it will store time as timestamp
+ *
+ * Return: None
+ */
+void lim_set_dfs_channel_list(tpAniSirGlobal mac_ctx, uint8_t chan_num,
+ tSirDFSChannelList *dfs_ch_list)
+{
+ bool pass_to_active = true;
+
+ if (!((1 <= chan_num) && (165 >= chan_num))) {
+ lim_log(mac_ctx, LOGE, FL("Invalid Channel: %d"), chan_num);
+ return;
+ }
+
+ if (true == lim_isconnected_on_dfs_channel(chan_num)) {
+ if (dfs_ch_list->timeStamp[chan_num] == 0) {
+ /*
+ * Received first beacon;
+ * Convert DFS channel to Active channel.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("Received first beacon on DFS channel: %d"),
+ chan_num);
+ lim_covert_channel_scan_type(mac_ctx, chan_num,
+ pass_to_active);
+ }
+ dfs_ch_list->timeStamp[chan_num] =
+ cdf_mc_timer_get_system_time();
+ } else {
+ lim_log(mac_ctx, LOG1, FL("Channel %d is Active"), chan_num);
+ return;
+ }
+
+ if (!tx_timer_running
+ (&mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer)) {
+ tx_timer_activate(
+ &mac_ctx->lim.limTimers.gLimActiveToPassiveChannelTimer);
+ }
+
+ return;
+}
+
+/**
+ * lim_restore_pre_scan_state() - restore HW state prior to scan
+ *
+ * @mac_ctx: global MAC context
+ *
+ * This function is called by lim_continue_channel_scan()
+ * to restore HW state prior to entering 'scan state'
+ *
+ * Return: None
+ */
+void lim_restore_pre_scan_state(tpAniSirGlobal mac_ctx)
+{
+ /* Deactivate MIN/MAX channel timers if running */
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_MIN_CHANNEL_TIMER);
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_MAX_CHANNEL_TIMER);
+
+ mac_ctx->lim.gLimSystemInScanLearnMode = 0;
+ lim_log(mac_ctx, LOG1, FL("Scan ended, took %llu tu"),
+ (tx_time_get() - mac_ctx->lim.scanStartTime));
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/**
+ * lim_send_hal_oem_data_req() - send oem data request
+ * @mac_ctx: global MAC context
+ *
+ * This function is used to send OEM data request to HAL.
+ *
+ * Return: None
+ */
+void lim_send_hal_oem_data_req(tpAniSirGlobal mac_ctx)
+{
+ tSirMsgQ msg;
+ tpStartOemDataReq start_oem_data_req = NULL;
+ tSirRetStatus rc = eSIR_SUCCESS;
+ tpLimMlmOemDataRsp mlm_oem_data_rsp;
+ uint32_t reqlen = 0;
+
+ if (NULL == mac_ctx->lim.gpLimMlmOemDataReq) {
+ lim_log(mac_ctx, LOGE, FL("Null pointer"));
+ goto error;
+ }
+
+ reqlen = sizeof(tStartOemDataReq);
+
+ start_oem_data_req = cdf_mem_malloc(reqlen);
+ if (NULL == start_oem_data_req) {
+ lim_log(mac_ctx, LOGE, FL
+ ("Could not allocate memory for start_oem_data_req"));
+ goto error;
+ }
+
+ cdf_mem_set((uint8_t *) (start_oem_data_req), reqlen, 0);
+
+ /* Now copy over the information to the OEM DATA REQ to HAL */
+ cdf_mem_copy(start_oem_data_req->selfMacAddr,
+ mac_ctx->lim.gpLimMlmOemDataReq->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy(start_oem_data_req->oemDataReq,
+ mac_ctx->lim.gpLimMlmOemDataReq->oemDataReq,
+ OEM_DATA_REQ_SIZE);
+
+ /* Create the message to be passed to HAL */
+ msg.type = WMA_START_OEM_DATA_REQ;
+ msg.bodyptr = start_oem_data_req;
+ msg.bodyval = 0;
+
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false);
+ MTRACE(mac_trace_msg_tx(mac_ctx, NO_SESSION, msg.type));
+
+ rc = wma_post_ctrl_msg(mac_ctx, &msg);
+ if (rc == eSIR_SUCCESS)
+ return;
+
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+ cdf_mem_free(start_oem_data_req);
+ lim_log(mac_ctx, LOGE,
+ FL("OEM_DATA: posting WMA_START_OEM_DATA_REQ to HAL failed"));
+
+error:
+ mac_ctx->lim.gLimMlmState = mac_ctx->lim.gLimPrevMlmState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, NO_SESSION,
+ mac_ctx->lim.gLimMlmState));
+
+ mlm_oem_data_rsp = cdf_mem_malloc(sizeof(tLimMlmOemDataRsp));
+ if (NULL == mlm_oem_data_rsp) {
+ lim_log(mac_ctx->hHdd, LOGP, FL
+ ("memory allocation for mlm_oem_data_rsp"));
+ return;
+ }
+
+ if (NULL != mac_ctx->lim.gpLimMlmOemDataReq) {
+ cdf_mem_free(mac_ctx->lim.gpLimMlmOemDataReq);
+ mac_ctx->lim.gpLimMlmOemDataReq = NULL;
+ }
+
+ lim_post_sme_message(mac_ctx, LIM_MLM_OEM_DATA_CNF,
+ (uint32_t *) mlm_oem_data_rsp);
+
+ return;
+}
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+/**
+ * mlm_add_sta() - MLM add sta
+ * @mac_ctx: global MAC context
+ * @sta_param: Add sta params
+ * @bssid: BSSID
+ * @ht_capable: HT capability
+ * @session_entry: PE session entry
+ *
+ * This function is called to update station parameters
+ *
+ * Return: None
+ */
+static void mlm_add_sta(tpAniSirGlobal mac_ctx, tpAddStaParams sta_param,
+ uint8_t *bssid, uint8_t ht_capable, tpPESession session_entry)
+{
+ uint32_t val;
+ uint32_t self_dot11mode = 0;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_dot11mode);
+ sta_param->staType = STA_ENTRY_SELF; /* Identifying self */
+
+ cdf_mem_copy(sta_param->bssId, bssid, sizeof(tSirMacAddr));
+ cdf_mem_copy(sta_param->staMac, session_entry->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ /* Configuration related parameters to be changed to support BT-AMP */
+
+ if (eSIR_SUCCESS != wlan_cfg_get_int(mac_ctx, WNI_CFG_LISTEN_INTERVAL,
+ &val))
+ lim_log(mac_ctx, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
+ sta_param->listenInterval = (uint16_t) val;
+
+ if (eSIR_SUCCESS != wlan_cfg_get_int(mac_ctx, WNI_CFG_SHORT_PREAMBLE,
+ &val))
+ lim_log(mac_ctx, LOGP, FL("Couldn't get SHORT_PREAMBLE"));
+ sta_param->shortPreambleSupported = (uint8_t) val;
+
+ sta_param->assocId = 0; /* Is SMAC OK with this? */
+ sta_param->wmmEnabled = 0;
+ sta_param->uAPSD = 0;
+ sta_param->maxSPLen = 0;
+ sta_param->us32MaxAmpduDuration = 0;
+ sta_param->maxAmpduSize = 0; /* 0: 8k, 1: 16k,2: 32k,3: 64k, 4:128k */
+
+ /* For Self STA get the LDPC capability from config.ini */
+ sta_param->htLdpcCapable =
+ (session_entry->txLdpcIniFeatureEnabled & 0x01);
+ sta_param->vhtLdpcCapable =
+ ((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
+
+ if (IS_DOT11_MODE_HT(session_entry->dot11mode)) {
+ sta_param->htCapable = ht_capable;
+ sta_param->greenFieldCapable =
+ lim_get_ht_capability(mac_ctx, eHT_GREENFIELD,
+ session_entry);
+ sta_param->ch_width =
+ lim_get_ht_capability(mac_ctx,
+ eHT_SUPPORTED_CHANNEL_WIDTH_SET, session_entry);
+ sta_param->mimoPS =
+ (tSirMacHTMIMOPowerSaveState)lim_get_ht_capability(
+ mac_ctx, eHT_MIMO_POWER_SAVE, session_entry);
+ sta_param->rifsMode =
+ lim_get_ht_capability(mac_ctx, eHT_RIFS_MODE,
+ session_entry);
+ sta_param->lsigTxopProtection =
+ lim_get_ht_capability(mac_ctx, eHT_LSIG_TXOP_PROTECTION,
+ session_entry);
+ sta_param->maxAmpduDensity =
+ lim_get_ht_capability(mac_ctx, eHT_MPDU_DENSITY,
+ session_entry);
+ sta_param->maxAmsduSize =
+ lim_get_ht_capability(mac_ctx, eHT_MAX_AMSDU_LENGTH,
+ session_entry);
+ sta_param->fDsssCckMode40Mhz =
+ lim_get_ht_capability(mac_ctx, eHT_DSSS_CCK_MODE_40MHZ,
+ session_entry);
+ sta_param->fShortGI20Mhz =
+ lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_20MHZ,
+ session_entry);
+ sta_param->fShortGI40Mhz =
+ lim_get_ht_capability(mac_ctx, eHT_SHORT_GI_40MHZ,
+ session_entry);
+ }
+ if (session_entry->vhtCapability) {
+ sta_param->vhtCapable = true;
+ sta_param->vhtTxBFCapable =
+ session_entry->txBFIniFeatureEnabled;
+ sta_param->vhtTxMUBformeeCapable = session_entry->txMuBformee;
+ sta_param->enable_su_tx_bformer =
+ session_entry->enable_su_tx_bformer;
+ }
+ /*
+ * Since this is Self-STA, need to populate Self MAX_AMPDU_SIZE
+ * capabilities
+ */
+ if (IS_DOT11_MODE_VHT(self_dot11mode)) {
+ val = 0; /* Default 8K AMPDU size */
+ if (eSIR_SUCCESS != wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &val))
+ lim_log(mac_ctx, LOGE, FL
+ ("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT"));
+ sta_param->maxAmpduSize = (uint8_t) val;
+ }
+ sta_param->enableVhtpAid = session_entry->enableVhtpAid;
+ sta_param->enableAmpduPs = session_entry->enableAmpduPs;
+ sta_param->enableHtSmps = session_entry->enableHtSmps;
+ sta_param->htSmpsconfig = session_entry->htSmpsvalue;
+
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
+ false, session_entry, NULL);
+#else
+ lim_populate_own_rate_set(mac_ctx, &sta_param->supportedRates, NULL,
+ false, session_entry);
+#endif
+ lim_fill_supported_rates_info(mac_ctx, NULL, &sta_param->supportedRates,
+ session_entry);
+
+ lim_log(mac_ctx, LOGE, FL(
+ "GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d,"
+ " SGI20: %d, SGI40%d"), sta_param->greenFieldCapable,
+ sta_param->ch_width, sta_param->mimoPS,
+ sta_param->lsigTxopProtection, sta_param->fDsssCckMode40Mhz,
+ sta_param->fShortGI20Mhz, sta_param->fShortGI40Mhz);
+
+ if (CDF_P2P_GO_MODE == session_entry->pePersona)
+ sta_param->p2pCapableSta = 1;
+}
+
+/**
+ * lim_mlm_add_bss() - HAL interface for WMA_ADD_BSS_REQ
+ * @mac_ctx: global MAC context
+ * @mlm_start_req: MLM start request
+ * @session: PE session entry
+ *
+ * Package WMA_ADD_BSS_REQ to HAL, in order to start a BSS
+ *
+ * Return: eSIR_SME_SUCCESS on success, other error codes otherwise
+ */
+tSirResultCodes
+lim_mlm_add_bss(tpAniSirGlobal mac_ctx,
+ tLimMlmStartReq *mlm_start_req, tpPESession session)
+{
+ tSirMsgQ msg_buf;
+ tpAddBssParams addbss_param = NULL;
+ uint32_t retcode;
+
+ /* Package WMA_ADD_BSS_REQ message parameters */
+ addbss_param = cdf_mem_malloc(sizeof(tAddBssParams));
+ if (NULL == addbss_param) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to allocate memory during ADD_BSS"));
+ /* Respond to SME with LIM_MLM_START_CNF */
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set(addbss_param, sizeof(tAddBssParams), 0);
+ /* Fill in tAddBssParams members */
+ cdf_mem_copy(addbss_param->bssId, mlm_start_req->bssId,
+ sizeof(tSirMacAddr));
+
+ /* Fill in tAddBssParams selfMacAddr */
+ cdf_mem_copy(addbss_param->selfMacAddr,
+ session->selfMacAddr, sizeof(tSirMacAddr));
+
+ addbss_param->bssType = mlm_start_req->bssType;
+ if ((mlm_start_req->bssType == eSIR_IBSS_MODE) ||
+ (mlm_start_req->bssType == eSIR_BTAMP_AP_MODE) ||
+ (mlm_start_req->bssType == eSIR_BTAMP_STA_MODE)) {
+ addbss_param->operMode = BSS_OPERATIONAL_MODE_STA;
+ } else if (mlm_start_req->bssType == eSIR_INFRA_AP_MODE) {
+ addbss_param->operMode = BSS_OPERATIONAL_MODE_AP;
+ }
+
+ addbss_param->shortSlotTimeSupported = session->shortSlotTimeSupported;
+ addbss_param->beaconInterval = mlm_start_req->beaconPeriod;
+ addbss_param->dtimPeriod = mlm_start_req->dtimPeriod;
+ addbss_param->wps_state = mlm_start_req->wps_state;
+ addbss_param->cfParamSet.cfpCount = mlm_start_req->cfParamSet.cfpCount;
+ addbss_param->cfParamSet.cfpPeriod =
+ mlm_start_req->cfParamSet.cfpPeriod;
+ addbss_param->cfParamSet.cfpMaxDuration =
+ mlm_start_req->cfParamSet.cfpMaxDuration;
+ addbss_param->cfParamSet.cfpDurRemaining =
+ mlm_start_req->cfParamSet.cfpDurRemaining;
+
+ addbss_param->rateSet.numRates = mlm_start_req->rateSet.numRates;
+ cdf_mem_copy(addbss_param->rateSet.rate, mlm_start_req->rateSet.rate,
+ mlm_start_req->rateSet.numRates);
+
+ addbss_param->nwType = mlm_start_req->nwType;
+ addbss_param->htCapable = mlm_start_req->htCapable;
+ addbss_param->vhtCapable = session->vhtCapability;
+ addbss_param->ch_width = session->ch_width;
+ addbss_param->ch_center_freq_seg0 =
+ session->ch_center_freq_seg0;
+ addbss_param->ch_center_freq_seg1 =
+ session->ch_center_freq_seg1;
+ addbss_param->htOperMode = mlm_start_req->htOperMode;
+ addbss_param->dualCTSProtection = mlm_start_req->dualCTSProtection;
+ addbss_param->txChannelWidthSet = mlm_start_req->txChannelWidthSet;
+
+ addbss_param->currentOperChannel = mlm_start_req->channelNumber;
+#ifdef WLAN_FEATURE_11W
+ addbss_param->rmfEnabled = session->limRmfEnabled;
+#endif
+
+ /* Update PE sessionId */
+ addbss_param->sessionId = mlm_start_req->sessionId;
+
+ /* Send the SSID to HAL to enable SSID matching for IBSS */
+ cdf_mem_copy(&(addbss_param->ssId.ssId),
+ mlm_start_req->ssId.ssId, mlm_start_req->ssId.length);
+ addbss_param->ssId.length = mlm_start_req->ssId.length;
+ addbss_param->bHiddenSSIDEn = mlm_start_req->ssidHidden;
+ lim_log(mac_ctx, LOGE, FL("TRYING TO HIDE SSID %d"),
+ addbss_param->bHiddenSSIDEn);
+ /* CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed. */
+ addbss_param->bProxyProbeRespEn = 0;
+ addbss_param->obssProtEnabled = mlm_start_req->obssProtEnabled;
+
+#if defined WLAN_FEATURE_VOWIFI
+ addbss_param->maxTxPower = session->maxTxPower;
+#endif
+ mlm_add_sta(mac_ctx, &addbss_param->staContext,
+ addbss_param->bssId, addbss_param->htCapable,
+ session);
+
+ addbss_param->status = CDF_STATUS_SUCCESS;
+ addbss_param->respReqd = 1;
+
+ /* Set a new state for MLME */
+ session->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+ session->limMlmState));
+
+ /* pass on the session persona to hal */
+ addbss_param->halPersona = session->pePersona;
+
+ addbss_param->bSpectrumMgtEnabled = session->spectrumMgtEnabled ||
+ lim_isconnected_on_dfs_channel(mlm_start_req->channelNumber);
+#if defined WLAN_FEATURE_VOWIFI_11R
+ addbss_param->extSetStaKeyParamValid = 0;
+#endif
+
+ addbss_param->dot11_mode = session->dot11mode;
+ addbss_param->nss = session->nss;
+ lim_log(mac_ctx, LOG2, FL("dot11_mode:%d nss value:%d"),
+ addbss_param->dot11_mode, addbss_param->nss);
+
+ msg_buf.type = WMA_ADD_BSS_REQ;
+ msg_buf.reserved = 0;
+ msg_buf.bodyptr = addbss_param;
+ msg_buf.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, session->peSessionId, msg_buf.type));
+
+ lim_log(mac_ctx, LOGW, FL("Sending WMA_ADD_BSS_REQ..."));
+ retcode = wma_post_ctrl_msg(mac_ctx, &msg_buf);
+ if (eSIR_SUCCESS != retcode) {
+ lim_log(mac_ctx, LOGE,
+ FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
+ retcode);
+ cdf_mem_free(addbss_param);
+ return eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+
+ return eSIR_SME_SUCCESS;
+}
+
+/**
+ * lim_process_mlm_start_req() - process MLM_START_REQ message
+ *
+ * @mac_ctx: global MAC context
+ * @msg_buf: Pointer to MLM message buffer
+ *
+ * This function is called to process MLM_START_REQ message
+ * from SME
+ * 1) MLME receives LIM_MLM_START_REQ from LIM
+ * 2) MLME sends WMA_ADD_BSS_REQ to HAL
+ * 3) MLME changes state to eLIM_MLM_WT_ADD_BSS_RSP_STATE
+ * MLME now waits for HAL to send WMA_ADD_BSS_RSP
+ *
+ * Return: None
+ */
+static void lim_process_mlm_start_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tLimMlmStartReq *mlm_start_req;
+ tLimMlmStartCnf mlm_start_cnf;
+ tpPESession session = NULL;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ mlm_start_req = (tLimMlmStartReq *) msg_buf;
+ session = pe_find_session_by_session_id(mac_ctx,
+ mlm_start_req->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ mlm_start_cnf.resultCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ if (session->limMlmState != eLIM_MLM_IDLE_STATE) {
+ /*
+ * Should not have received Start req in states other than idle.
+ * Return Start confirm with failure code.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("received unexpected MLM_START_REQ in state %X"),
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+ mlm_start_cnf.resultCode =
+ eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ goto end;
+ }
+
+ mlm_start_cnf.resultCode =
+ lim_mlm_add_bss(mac_ctx, mlm_start_req, session);
+
+end:
+ /* Update PE session Id */
+ mlm_start_cnf.sessionId = mlm_start_req->sessionId;
+
+ /* Free up buffer allocated for LimMlmScanReq */
+ cdf_mem_free(msg_buf);
+
+ /*
+ * Respond immediately to LIM, only if MLME has not been
+ * successfully able to send WMA_ADD_BSS_REQ to HAL.
+ * Else, LIM_MLM_START_CNF will be sent after receiving
+ * WMA_ADD_BSS_RSP from HAL
+ */
+ if (eSIR_SME_SUCCESS != mlm_start_cnf.resultCode)
+ lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
+ (uint32_t *) &mlm_start_cnf);
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+/**
+ * lim_process_mlm_oem_data_req() - process MLM OEM_DATA_REQ message
+ * @mac_ctx: global MAC context
+ * @msg_buf: MLM message buffer
+ *
+ * This function process MLM OEM_DATA_REQ message.
+ *
+ * Return: None
+ */
+static void lim_process_mlm_oem_data_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tLimMlmOemDataRsp *mlm_oem_data_rsp;
+
+ if (((mac_ctx->lim.gLimMlmState == eLIM_MLM_IDLE_STATE) ||
+ (mac_ctx->lim.gLimMlmState == eLIM_MLM_JOINED_STATE) ||
+ (mac_ctx->lim.gLimMlmState == eLIM_MLM_AUTHENTICATED_STATE) ||
+ (mac_ctx->lim.gLimMlmState == eLIM_MLM_BSS_STARTED_STATE) ||
+ (mac_ctx->lim.gLimMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))) {
+ /*
+ * Hold onto the oem data request criteria
+ * Free gpLimMlmOemDataReq to avoid memory leak due to
+ * second OEM data request
+ */
+ if (mac_ctx->lim.gpLimMlmOemDataReq) {
+ cdf_mem_free(mac_ctx->lim.gpLimMlmOemDataReq);
+ mac_ctx->lim.gpLimMlmOemDataReq = NULL;
+ }
+
+ mac_ctx->lim.gpLimMlmOemDataReq = (tLimMlmOemDataReq *) msg_buf;
+ mac_ctx->lim.gLimPrevMlmState = mac_ctx->lim.gLimMlmState;
+
+ lim_log(mac_ctx, LOG2, FL("Calling lim_send_hal_oem_data_req"));
+ lim_send_hal_oem_data_req(mac_ctx);
+ } else {
+ /* Should not have received oem data req in other states */
+ lim_log(mac_ctx, LOGW, FL
+ ("unexpected LIM_MLM_OEM_DATA_REQ in invalid state %X"),
+ mac_ctx->lim.gLimMlmState);
+ lim_print_mlm_state(mac_ctx, LOGW, mac_ctx->lim.gLimMlmState);
+
+ /* Free up buffer allocated */
+ cdf_mem_free(msg_buf);
+
+ /* Return Meas confirm with INVALID_PARAMETERS */
+ mlm_oem_data_rsp = cdf_mem_malloc(sizeof(tLimMlmOemDataRsp));
+ if (mlm_oem_data_rsp != NULL) {
+ lim_post_sme_message(mac_ctx, LIM_MLM_OEM_DATA_CNF,
+ (uint32_t *) mlm_oem_data_rsp);
+ cdf_mem_free(mlm_oem_data_rsp);
+ } else {
+ lim_log(mac_ctx, LOGP, FL
+ ("Could not allocate memory for mlm_oem_data_rsp"));
+ return;
+ }
+ }
+
+ return;
+}
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+/**
+ * lim_post_join_set_link_state_callback()- registered callback to perform post
+ * peer creation operations
+ *
+ * @mac: pointer to global mac structure
+ * @callback_arg: registered callback argument
+ * @status: peer creation status
+ *
+ * this is registered callback function during association to perform
+ * post peer creation operation based on the peer creation status
+ *
+ * Return: none
+ */
+void lim_post_join_set_link_state_callback(tpAniSirGlobal mac,
+ void *callback_arg, bool status)
+{
+ uint8_t chan_num, sec_chan_offset;
+ tpPESession session_entry = (tpPESession) callback_arg;
+ tLimMlmJoinCnf mlm_join_cnf;
+
+ lim_log(mac, LOG1, FL("Sessionid %d set link state(%d) cb status:%d"),
+ session_entry->peSessionId, session_entry->limMlmState,
+ status);
+
+ if (!status) {
+ lim_log(mac, LOGE,
+ FL("failed to find pe session for session id:%d"),
+ session_entry->peSessionId);
+ goto failure;
+ }
+
+ chan_num = session_entry->currentOperChannel;
+ sec_chan_offset = session_entry->htSecondaryChannelOffset;
+ /*
+ * store the channel switch session_entry in the lim
+ * global variable
+ */
+ session_entry->channelChangeReasonCode =
+ LIM_SWITCH_CHANNEL_JOIN;
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || \
+ defined(FEATURE_WLAN_LFR)
+ session_entry->pLimMlmReassocRetryReq = NULL;
+#endif
+ lim_log(mac, LOGE,
+ FL("[lim_process_mlm_join_req]: suspend link success(%d) "
+ "on sessionid: %d setting channel to: %d with ch_width :%d "
+ "and maxtxPower: %d"), status, session_entry->peSessionId,
+ session_entry->currentOperChannel,
+ session_entry->ch_width,
+ session_entry->maxTxPower);
+ lim_set_channel(mac, session_entry->currentOperChannel,
+ session_entry->ch_center_freq_seg0,
+ session_entry->ch_center_freq_seg1,
+ session_entry->ch_width,
+ session_entry->maxTxPower,
+ session_entry->peSessionId);
+ return;
+
+failure:
+ MTRACE(mac_trace(mac, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
+ session_entry->limMlmState));
+ session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+ mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlm_join_cnf.sessionId = session_entry->peSessionId;
+ mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ lim_post_sme_message(mac, LIM_MLM_JOIN_CNF, (uint32_t *) &mlm_join_cnf);
+}
+
+/**
+ * lim_process_mlm_post_join_suspend_link() - This function is called after the
+ * suspend link while joining off channel.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @status: status of suspend link.
+ * @ctx: passed while calling suspend link(session)
+ *
+ * This function does following:
+ * Check for suspend state.
+ * If success, proceed with setting link state to recieve the
+ * probe response/beacon from intended AP.
+ * Switch to the APs channel.
+ * On an error case, send the MLM_JOIN_CNF with error status.
+ *
+ * @Return None
+ */
+static void
+lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx,
+ CDF_STATUS status,
+ uint32_t *ctx)
+{
+ tLimMlmJoinCnf mlm_join_cnf;
+ tpPESession session = (tpPESession) ctx;
+ tSirLinkState lnk_state;
+
+ if (CDF_STATUS_SUCCESS != status) {
+ lim_log(mac_ctx, LOGE,
+ FL("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join"),
+ session->peSessionId);
+ }
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
+
+ /* assign appropriate sessionId to the timer object */
+ mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId =
+ session->peSessionId;
+
+ lnk_state = (LIM_IS_BT_AMP_STA_ROLE(session) ?
+ eSIR_LINK_BTAMP_PREASSOC_STATE : eSIR_LINK_PREASSOC_STATE);
+ lim_log(mac_ctx, LOG1, FL("[lim_process_mlm_join_req]: lnk_state:%d"),
+ lnk_state);
+
+ if (lim_set_link_state(mac_ctx, lnk_state,
+ session->pLimMlmJoinReq->bssDescription.bssId,
+ session->selfMacAddr,
+ lim_post_join_set_link_state_callback,
+ session) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("SessionId:%d lim_set_link_state to eSIR_LINK_PREASSOC_STATE Failed!!"),
+ session->peSessionId);
+ lim_print_mac_addr(mac_ctx,
+ session->pLimMlmJoinReq->bssDescription.bssId, LOGE);
+ mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ session->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session->peSessionId, session->limMlmState));
+ goto error;
+ }
+
+ return;
+error:
+ mlm_join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlm_join_cnf.sessionId = session->peSessionId;
+ mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+ (uint32_t *) &mlm_join_cnf);
+}
+
+/**
+ * lim_process_mlm_join_req() - process mlm join request.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: Pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_JOIN_REQ message
+ * from SME. It does following:
+ * 1) Initialize LIM, HAL, DPH
+ * 2) Configure the BSS for which the JOIN REQ was received
+ * a) Send WMA_ADD_BSS_REQ to HAL -
+ * This will identify the BSS that we are interested in
+ * --AND--
+ * Add a STA entry for the AP (in a STA context)
+ * b) Wait for WMA_ADD_BSS_RSP
+ * c) Send WMA_ADD_STA_REQ to HAL
+ * This will add the "local STA" entry to the STA table
+ * 3) Continue as before, i.e,
+ * a) Send a PROBE REQ
+ * b) Wait for PROBE RSP/BEACON containing the SSID that
+ * we are interested in
+ * c) Then start an AUTH seq
+ * d) Followed by the ASSOC seq
+ *
+ * @Return: None
+ */
+static void lim_process_mlm_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
+{
+ tLimMlmJoinCnf mlmjoin_cnf;
+ uint8_t sessionid;
+ tpPESession session;
+
+ sessionid = ((tpLimMlmJoinReq) msg)->sessionId;
+
+ session = pe_find_session_by_session_id(mac_ctx, sessionid);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE, FL("SessionId:%d does not exist"),
+ sessionid);
+ goto error;
+ }
+
+ if ((!LIM_IS_AP_ROLE(session) &&
+ !LIM_IS_BT_AMP_AP_ROLE(session)) &&
+ ((session->limMlmState == eLIM_MLM_IDLE_STATE) ||
+ (session->limMlmState == eLIM_MLM_JOINED_STATE)) &&
+ (SIR_MAC_GET_ESS
+ (((tpLimMlmJoinReq) msg)->bssDescription.capabilityInfo) !=
+ SIR_MAC_GET_IBSS(((tpLimMlmJoinReq) msg)->bssDescription.
+ capabilityInfo))) {
+ /* Hold onto Join request parameters */
+
+ session->pLimMlmJoinReq = (tpLimMlmJoinReq) msg;
+ if (is_lim_session_off_channel(mac_ctx, sessionid)) {
+ lim_log(mac_ctx, LOG1,
+ "SessionId:%d LimSession is on OffChannel",
+ sessionid);
+ /* suspend link */
+ lim_log(mac_ctx, LOG1,
+ FL("Suspend link, sessionid %d is off channel"),
+ sessionid);
+ if (lim_is_link_suspended(mac_ctx)) {
+ lim_log(mac_ctx, LOGE, FL(
+ "link is already suspended, session %d"
+ ), sessionid);
+ goto error;
+ }
+ lim_process_mlm_post_join_suspend_link(mac_ctx,
+ CDF_STATUS_SUCCESS, (uint32_t *)session);
+ } else {
+ lim_log(mac_ctx, LOG1, FL("No need to Suspend link"));
+ /*
+ * No need to Suspend link as LimSession is not
+ * off channel, calling
+ * lim_process_mlm_post_join_suspend_link with
+ * status as SUCCESS.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("SessionId:%d Join req on current chan"),
+ sessionid);
+ lim_process_mlm_post_join_suspend_link(mac_ctx,
+ CDF_STATUS_SUCCESS, (uint32_t *)session);
+ }
+ return;
+ } else {
+ /**
+ * Should not have received JOIN req in states other than
+ * Idle state or on AP.
+ * Return join confirm with invalid parameters code.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("Session:%d Unexpected Join req, role %d state %X"),
+ session->peSessionId, GET_LIM_SYSTEM_ROLE(session),
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+ }
+
+error:
+ cdf_mem_free(msg);
+ if (session != NULL)
+ session->pLimMlmJoinReq = NULL;
+ mlmjoin_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmjoin_cnf.sessionId = sessionid;
+ mlmjoin_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+ (uint32_t *)&mlmjoin_cnf);
+
+}
+
+/**
+ * lim_is_auth_req_expected() - check if auth request is expected
+ *
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ *
+ * This function is called by lim_process_mlm_auth_req to check
+ * if auth request is expected.
+ *
+ * Return: true if expected and false otherwise
+ */
+static bool lim_is_auth_req_expected(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ bool flag = false;
+
+ /*
+ * Expect Auth request only when:
+ * 1. STA joined/associated with a BSS or
+ * 2. STA is in IBSS mode
+ * and STA is going to authenticate with a unicast
+ * address and requested authentication algorithm is
+ * supported.
+ */
+
+ flag = ((((LIM_IS_STA_ROLE(session) ||
+ LIM_IS_BT_AMP_STA_ROLE(session)) &&
+ ((session->limMlmState == eLIM_MLM_JOINED_STATE) ||
+ (session->limMlmState ==
+ eLIM_MLM_LINK_ESTABLISHED_STATE))) ||
+ (LIM_IS_IBSS_ROLE(session) &&
+ (session->limMlmState ==
+ eLIM_MLM_BSS_STARTED_STATE))) &&
+ (!lim_is_group_addr(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr))
+ && lim_is_auth_algo_supported(mac_ctx,
+ mac_ctx->lim.gpLimMlmAuthReq->authType, session));
+
+ return flag;
+}
+
+/**
+ * lim_is_preauth_ctx_exisits() - check if preauth context exists
+ *
+ * @mac_ctx: global MAC context
+ * @session: PE session entry
+ * @preauth_node_ptr: pointer to preauth node pointer
+ *
+ * This function is called by lim_process_mlm_auth_req to check
+ * if preauth context already exists
+ *
+ * Return: true if exists and false otherwise
+ */
+static bool lim_is_preauth_ctx_exists(tpAniSirGlobal mac_ctx,
+ tpPESession session,
+ struct tLimPreAuthNode **preauth_node_ptr)
+{
+ bool fl = false;
+ struct tLimPreAuthNode *preauth_node;
+ tpDphHashNode stads;
+ tSirMacAddr curr_bssid;
+
+ preauth_node = *preauth_node_ptr;
+ sir_copy_mac_addr(curr_bssid, session->bssId);
+ stads = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session->dph.dphHashTable);
+ preauth_node = lim_search_pre_auth_list(mac_ctx,
+ mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
+
+ fl = (((LIM_IS_STA_ROLE(session) || LIM_IS_BT_AMP_STA_ROLE(session)) &&
+ (session->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ ((stads != NULL) &&
+ (mac_ctx->lim.gpLimMlmAuthReq->authType ==
+ stads->mlmStaContext.authType)) &&
+ (cdf_mem_compare(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+ curr_bssid, sizeof(tSirMacAddr)))) ||
+ ((preauth_node != NULL) &&
+ (preauth_node->authType ==
+ mac_ctx->lim.gpLimMlmAuthReq->authType)));
+
+ return fl;
+}
+
+/**
+ * lim_process_mlm_auth_req() - process lim auth request
+ *
+ * @mac_ctx: global MAC context
+ * @msg: MLM auth request message
+ *
+ * This function is called to process MLM_AUTH_REQ message from SME
+ *
+ * @Return: None
+ */
+static void lim_process_mlm_auth_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
+{
+ uint32_t num_preauth_ctx;
+ tSirMacAddr curr_bssid;
+ tSirMacAuthFrameBody auth_frame_body;
+ tLimMlmAuthCnf mlm_auth_cnf;
+ struct tLimPreAuthNode *preauth_node = NULL;
+ uint8_t session_id;
+ tpPESession session;
+
+ if (msg == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ mac_ctx->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) msg;
+ session_id = mac_ctx->lim.gpLimMlmAuthReq->sessionId;
+ session = pe_find_session_by_session_id(mac_ctx, session_id);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGP, FL("SessionId:%d does not exist"),
+ session_id);
+ return;
+ }
+
+ lim_log(mac_ctx, LOG1, FL("Process Auth Req sessionID %d Systemrole %d"
+ "mlmstate %d from: " MAC_ADDRESS_STR
+ " with authtype %d"), session_id,
+ GET_LIM_SYSTEM_ROLE(session), session->limMlmState,
+ MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr),
+ mac_ctx->lim.gpLimMlmAuthReq->authType);
+
+ sir_copy_mac_addr(curr_bssid, session->bssId);
+
+ if (!lim_is_auth_req_expected(mac_ctx, session)) {
+ /*
+ * Unexpected auth request.
+ * Return Auth confirm with Invalid parameters code.
+ */
+ mlm_auth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ /*
+ * This is a request for pre-authentication. Check if there exists
+ * context already for the requested peer OR
+ * if this request is for the AP we're currently associated with.
+ * If yes, return auth confirm immediately when
+ * requested auth type is same as the one used before.
+ */
+ if (lim_is_preauth_ctx_exists(mac_ctx, session, &preauth_node)) {
+ lim_log(mac_ctx, LOG2,
+ FL("Already have pre-auth context with peer: "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr));
+ mlm_auth_cnf.resultCode = (tSirResultCodes)
+ eSIR_MAC_SUCCESS_STATUS;
+ goto end;
+ } else {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_MAX_NUM_PRE_AUTH,
+ (uint32_t *) &num_preauth_ctx) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Could not retrieve NumPreAuthLimit from CFG"));
+
+ if (mac_ctx->lim.gLimNumPreAuthContexts == num_preauth_ctx) {
+ lim_log(mac_ctx, LOGW,
+ FL("Number of pre-auth reached max limit"));
+ /* Return Auth confirm with reject code */
+ mlm_auth_cnf.resultCode =
+ eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED;
+ goto end;
+ }
+ }
+
+ /* Delete pre-auth node if exists */
+ if (preauth_node)
+ lim_delete_pre_auth_node(mac_ctx,
+ mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr);
+
+ session->limPrevMlmState = session->limMlmState;
+ session->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+ session->limMlmState));
+
+ /* Prepare & send Authentication frame */
+ auth_frame_body.authAlgoNumber =
+ (uint8_t) mac_ctx->lim.gpLimMlmAuthReq->authType;
+ auth_frame_body.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1;
+ auth_frame_body.authStatusCode = 0;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_AUTH_START_EVENT, session,
+ eSIR_SUCCESS, auth_frame_body.authStatusCode);
+#endif
+
+ lim_send_auth_mgmt_frame(mac_ctx,
+ &auth_frame_body, mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+ LIM_NO_WEP_IN_FC, session);
+
+ /* assign appropriate session_id to the timer object */
+ mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId = session_id;
+
+ /* Activate Auth failure timer */
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+ session->peSessionId, eLIM_AUTH_FAIL_TIMER));
+ if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAuthFailureTimer)
+ != TX_SUCCESS) {
+ /* Could not start Auth failure timer. */
+ lim_log(mac_ctx, LOGP,
+ FL("could not start Auth failure timer"));
+ /* Cleanup as if auth timer expired */
+ lim_process_auth_failure_timeout(mac_ctx);
+ }
+ return;
+end:
+ cdf_mem_copy((uint8_t *) &mlm_auth_cnf.peerMacAddr,
+ (uint8_t *) &mac_ctx->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ mlm_auth_cnf.authType = mac_ctx->lim.gpLimMlmAuthReq->authType;
+ mlm_auth_cnf.sessionId = session_id;
+
+ cdf_mem_free(mac_ctx->lim.gpLimMlmAuthReq);
+ mac_ctx->lim.gpLimMlmAuthReq = NULL;
+ lim_log(mac_ctx, LOG1, "SessionId:%d LimPostSme LIM_MLM_AUTH_CNF ",
+ session_id);
+ lim_post_sme_message(mac_ctx, LIM_MLM_AUTH_CNF,
+ (uint32_t *) &mlm_auth_cnf);
+}
+
+/**
+ * lim_process_mlm_assoc_req() - This function is called to process
+ * MLM_ASSOC_REQ message from SME
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_ASSOC_REQ message from SME
+ *
+ * @Return None
+ */
+
+static void lim_process_mlm_assoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tSirMacAddr curr_bssId;
+ tLimMlmAssocReq *mlm_assoc_req;
+ tLimMlmAssocCnf mlm_assoc_cnf;
+ tpPESession session_entry;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ mlm_assoc_req = (tLimMlmAssocReq *) msg_buf;
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ mlm_assoc_req->sessionId);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGP,
+ FL("SessionId:%d Session Does not exist"),
+ mlm_assoc_req->sessionId);
+ cdf_mem_free(mlm_assoc_req);
+ return;
+ }
+
+ sir_copy_mac_addr(curr_bssId, session_entry->bssId);
+
+ if (!((!LIM_IS_AP_ROLE(session_entry) &&
+ !LIM_IS_BT_AMP_AP_ROLE(session_entry)) &&
+ (session_entry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE ||
+ session_entry->limMlmState == eLIM_MLM_JOINED_STATE) &&
+ (cdf_mem_compare(mlm_assoc_req->peerMacAddr,
+ curr_bssId, sizeof(tSirMacAddr))))) {
+ /*
+ * Received Association request either in invalid state
+ * or to a peer MAC entity whose address is different
+ * from one that STA is currently joined with or on AP.
+ * Return Assoc confirm with Invalid parameters code.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("received unexpected MLM_ASSOC_CNF in state %X for role=%d, MAC addr= "
+ MAC_ADDRESS_STR), session_entry->limMlmState,
+ GET_LIM_SYSTEM_ROLE(session_entry),
+ MAC_ADDR_ARRAY(mlm_assoc_req->peerMacAddr));
+ lim_print_mlm_state(mac_ctx, LOGW, session_entry->limMlmState);
+ mlm_assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ goto end;
+ }
+
+ /* map the session entry pointer to the AssocFailureTimer */
+ mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId =
+ mlm_assoc_req->sessionId;
+#ifdef WLAN_FEATURE_11W
+ /*
+ * Store current MLM state in case ASSOC response returns with
+ * TRY_AGAIN_LATER return code.
+ */
+ if (session_entry->limRmfEnabled) {
+ session_entry->pmfComebackTimerInfo.limPrevMlmState =
+ session_entry->limPrevMlmState;
+ session_entry->pmfComebackTimerInfo.limMlmState =
+ session_entry->limMlmState;
+ }
+#endif /* WLAN_FEATURE_11W */
+
+ session_entry->limPrevMlmState = session_entry->limMlmState;
+ session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId,
+ session_entry->limMlmState));
+ lim_log(mac_ctx, LOG1, FL("SessionId:%d Sending Assoc_Req Frame"),
+ session_entry->peSessionId);
+
+ /* Prepare and send Association request frame */
+ lim_send_assoc_req_mgmt_frame(mac_ctx, mlm_assoc_req, session_entry);
+
+ /*
+ * Set the link state to postAssoc, so HW can start receiving frames
+ * from AP.
+ */
+ if ((session_entry->bssType == eSIR_BTAMP_STA_MODE) ||
+ ((session_entry->bssType == eSIR_BTAMP_AP_MODE)
+ && LIM_IS_BT_AMP_STA_ROLE(session_entry))) {
+ if (lim_set_link_state(mac_ctx, eSIR_LINK_BTAMP_POSTASSOC_STATE,
+ curr_bssId, session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to set the LinkState"));
+ }
+ /* Start association failure timer */
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+ session_entry->peSessionId, eLIM_ASSOC_FAIL_TIMER));
+ if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimAssocFailureTimer)
+ != TX_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("SessionId:%d couldn't start Assoc failure timer"),
+ session_entry->peSessionId);
+ /* Cleanup as if assoc timer expired */
+ lim_process_assoc_failure_timeout(mac_ctx, LIM_ASSOC);
+ }
+
+ return;
+end:
+ /* Update PE session Id */
+ mlm_assoc_cnf.sessionId = mlm_assoc_req->sessionId;
+ /* Free up buffer allocated for assocReq */
+ cdf_mem_free(mlm_assoc_req);
+ lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+ (uint32_t *) &mlm_assoc_cnf);
+}
+
+/**
+ * lim_process_mlm_reassoc_req() - process mlm reassoc request.
+ *
+ * @mac_ctx: pointer to Global MAC structure
+ * @msg: pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_REASSOC_REQ message
+ * from SME
+ *
+ * Return: None
+ */
+static void lim_process_mlm_reassoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg)
+{
+ uint8_t channel, sec_ch_offset;
+ struct tLimPreAuthNode *auth_node;
+ tLimMlmReassocReq *reassoc_req;
+ tLimMlmReassocCnf reassoc_cnf;
+ tpPESession session;
+
+ if (msg == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ reassoc_req = (tLimMlmReassocReq *) msg;
+ session = pe_find_session_by_session_id(mac_ctx,
+ reassoc_req->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session Does not exist for given sessionId %d"),
+ reassoc_req->sessionId);
+ cdf_mem_free(reassoc_req);
+ return;
+ }
+
+ lim_log(mac_ctx, LOG1,
+ FL("Process ReAssoc Req on sessionID %d Systemrole %d mlmstate %d from: " MAC_ADDRESS_STR),
+ reassoc_req->sessionId, GET_LIM_SYSTEM_ROLE(session),
+ session->limMlmState, MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
+
+ if ((LIM_IS_AP_ROLE(session) ||
+ LIM_IS_BT_AMP_AP_ROLE(session)) ||
+ (session->limMlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+ /*
+ * Received Reassoc request in invalid state or
+ * in AP role.Return Reassoc confirm with Invalid
+ * parameters code.
+ */
+
+ lim_log(mac_ctx, LOGW,
+ FL("received unexpected MLM_REASSOC_CNF in state %X for role=%d, MAC addr= " MAC_ADDRESS_STR),
+ session->limMlmState, GET_LIM_SYSTEM_ROLE(session),
+ MAC_ADDR_ARRAY(reassoc_req->peerMacAddr));
+ lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
+ reassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ goto end;
+ }
+
+ if (session->pLimMlmReassocReq)
+ cdf_mem_free(session->pLimMlmReassocReq);
+
+ /*
+ * Hold Re-Assoc request as part of Session, knock-out mac_ctx
+ * Hold onto Reassoc request parameters
+ */
+ session->pLimMlmReassocReq = reassoc_req;
+
+ /* See if we have pre-auth context with new AP */
+ auth_node = lim_search_pre_auth_list(mac_ctx, session->limReAssocbssId);
+
+ if (!auth_node && (!cdf_mem_compare(reassoc_req->peerMacAddr,
+ session->bssId,
+ sizeof(tSirMacAddr)))) {
+ /*
+ * Either pre-auth context does not exist AND
+ * we are not reassociating with currently
+ * associated AP.
+ * Return Reassoc confirm with not authenticated
+ */
+ reassoc_cnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED;
+ reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+
+ goto end;
+ }
+ /* assign the sessionId to the timer object */
+ mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId =
+ reassoc_req->sessionId;
+ session->limPrevMlmState = session->limMlmState;
+ session->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId,
+ session->limMlmState));
+
+ /* Derive channel from BSS description and store it at CFG. */
+ channel = session->limReassocChannelId;
+ sec_ch_offset = session->reAssocHtSecondaryChannelOffset;
+
+ /* Apply previously set configuration at HW */
+ lim_apply_configuration(mac_ctx, session);
+
+ /* store the channel switch sessionEntry in the lim global var */
+ session->channelChangeReasonCode =
+ LIM_SWITCH_CHANNEL_REASSOC;
+
+ /* Switch channel to the new Operating channel for Reassoc */
+ lim_set_channel(mac_ctx, channel,
+ session->ch_center_freq_seg0,
+ session->ch_center_freq_seg1,
+ session->ch_width,
+ session->maxTxPower,
+ session->peSessionId);
+
+ return;
+end:
+ reassoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE sessio Id */
+ reassoc_cnf.sessionId = reassoc_req->sessionId;
+ /* Free up buffer allocated for reassocReq */
+ cdf_mem_free(reassoc_req);
+ session->pLimReAssocReq = NULL;
+ lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &reassoc_cnf);
+}
+
+/**
+ * lim_process_mlm_disassoc_req_ntf() - process disassoc request notification
+ *
+ * @mac_ctx: global MAC context
+ * @suspend_status: suspend status
+ * @msg: mlm message buffer
+ *
+ * This function is used to process MLM disassoc notification
+ *
+ * Return: None
+ */
+static void
+lim_process_mlm_disassoc_req_ntf(tpAniSirGlobal mac_ctx,
+ CDF_STATUS suspend_status, uint32_t *msg)
+{
+ uint16_t aid;
+ tSirMacAddr curr_bssid;
+ tpDphHashNode stads;
+ tLimMlmDisassocReq *mlm_disassocreq;
+ tLimMlmDisassocCnf mlm_disassoccnf;
+ tpPESession session;
+ extern bool send_disassoc_frame;
+ tLimMlmStates mlm_state;
+
+ if (CDF_STATUS_SUCCESS != suspend_status)
+ lim_log(mac_ctx, LOGE, FL("Suspend Status is not success %X"),
+ suspend_status);
+
+ mlm_disassocreq = (tLimMlmDisassocReq *) msg;
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mlm_disassocreq->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given sessionId %d"),
+ mlm_disassocreq->sessionId);
+ mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ lim_log(mac_ctx, LOG1,
+ FL("Process DisAssoc Req on sessionID %d Systemrole %d"
+ "mlmstate %d from: " MAC_ADDRESS_STR),
+ mlm_disassocreq->sessionId, GET_LIM_SYSTEM_ROLE(session),
+ session->limMlmState,
+ MAC_ADDR_ARRAY(mlm_disassocreq->peerMacAddr));
+
+ sir_copy_mac_addr(curr_bssid, session->bssId);
+
+ switch (GET_LIM_SYSTEM_ROLE(session)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ if (!cdf_mem_compare(mlm_disassocreq->peerMacAddr,
+ curr_bssid, sizeof(tSirMacAddr))) {
+ lim_log(mac_ctx, LOGW,
+ FL("received MLM_DISASSOC_REQ with invalid BSS id"));
+ lim_print_mac_addr(mac_ctx,
+ mlm_disassocreq->peerMacAddr, LOGW);
+
+ /* Prepare and Send LIM_MLM_DISASSOC_CNF */
+ mlm_disassoccnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ break;
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_AP_ROLE:
+ case eLIM_P2P_DEVICE_GO:
+ if (true ==
+ mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+ lim_log(mac_ctx, LOGE,
+ FL("CAC timer is running, drop disassoc from going out"));
+ mlm_disassoccnf.resultCode = eSIR_SME_SUCCESS;
+ goto end;
+ }
+ break;
+ default:
+ break;
+ } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */
+
+ /*
+ * Check if there exists a context for the peer entity
+ * to be disassociated with.
+ */
+ stads = dph_lookup_hash_entry(mac_ctx, mlm_disassocreq->peerMacAddr,
+ &aid, &session->dph.dphHashTable);
+ if (stads)
+ mlm_state = stads->mlmStaContext.mlmState;
+
+ if ((stads == NULL) ||
+ (stads &&
+ ((mlm_state != eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (mlm_state != eLIM_MLM_WT_ASSOC_CNF_STATE) &&
+ (mlm_state != eLIM_MLM_ASSOCIATED_STATE)))) {
+ /*
+ * Received LIM_MLM_DISASSOC_REQ for STA that does not
+ * have context or in some transit state.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid MLM_DISASSOC_REQ, Addr= " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mlm_disassocreq->peerMacAddr));
+ if (stads != NULL)
+ lim_log(mac_ctx, LOGE, FL("Sta MlmState : %d"),
+ stads->mlmStaContext.mlmState);
+
+ /* Prepare and Send LIM_MLM_DISASSOC_CNF */
+ mlm_disassoccnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ stads->mlmStaContext.disassocReason = (tSirMacReasonCodes)
+ mlm_disassocreq->reasonCode;
+ stads->mlmStaContext.cleanupTrigger = mlm_disassocreq->disassocTrigger;
+
+ /*
+ * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+ * This is to address the issue of race condition between
+ * disconnect request from the HDD and deauth from AP
+ */
+
+ stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ /* Send Disassociate frame to peer entity */
+ if (send_disassoc_frame && (mlm_disassocreq->reasonCode !=
+ eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
+ mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
+ mlm_disassocreq;
+ /*
+ * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+ * This is to address the issue of race condition between
+ * disconnect request from the HDD and deauth from AP
+ */
+ stads->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+
+ /*
+ * If the reason for disassociation is inactivity of STA, then
+ * dont wait for acknowledgement
+ */
+ if ((mlm_disassocreq->reasonCode ==
+ eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON) &&
+ LIM_IS_AP_ROLE(session)) {
+ lim_send_disassoc_mgmt_frame(mac_ctx,
+ mlm_disassocreq->reasonCode,
+ mlm_disassocreq->peerMacAddr, session, false);
+
+ /* Send Disassoc CNF and receive path cleanup */
+ lim_send_disassoc_cnf(mac_ctx);
+ } else {
+ lim_send_disassoc_mgmt_frame(mac_ctx,
+ mlm_disassocreq->reasonCode,
+ mlm_disassocreq->peerMacAddr, session, true);
+ /*
+ * Abort Tx so that data frames won't be sent to the AP
+ * after sending Disassoc.
+ */
+ if (LIM_IS_STA_ROLE(session))
+ wma_tx_abort(session->smeSessionId);
+ }
+ } else {
+ /* Disassoc frame is not sent OTA */
+ send_disassoc_frame = 1;
+ /* Receive path cleanup with dummy packet */
+ if (eSIR_SUCCESS !=
+ lim_cleanup_rx_path(mac_ctx, stads, session)) {
+ mlm_disassoccnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ /* Free up buffer allocated for mlmDisassocReq */
+ cdf_mem_free(mlm_disassocreq);
+ }
+
+ return;
+
+end:
+ cdf_mem_copy((uint8_t *) &mlm_disassoccnf.peerMacAddr,
+ (uint8_t *) mlm_disassocreq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlm_disassoccnf.aid = mlm_disassocreq->aid;
+ mlm_disassoccnf.disassocTrigger = mlm_disassocreq->disassocTrigger;
+
+ /* Update PE session ID */
+ mlm_disassoccnf.sessionId = mlm_disassocreq->sessionId;
+
+ /* Free up buffer allocated for mlmDisassocReq */
+ cdf_mem_free(mlm_disassocreq);
+
+ lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
+ (uint32_t *) &mlm_disassoccnf);
+}
+
+/**
+ * lim_check_disassoc_deauth_ack_pending() - check if deauth is pending
+ *
+ * @mac_ctx - global MAC context
+ * @sta_mac - station MAC
+ *
+ * This function checks if diassociation or deauthentication is pending for
+ * given station MAC address.
+ *
+ * Return: true if pending and false otherwise.
+ */
+bool lim_check_disassoc_deauth_ack_pending(tpAniSirGlobal mac_ctx,
+ uint8_t *sta_mac)
+{
+ tLimMlmDisassocReq *disassoc_req;
+ tLimMlmDeauthReq *deauth_req;
+
+ disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+ deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+ if ((disassoc_req && (cdf_mem_compare((uint8_t *) sta_mac,
+ (uint8_t *) &disassoc_req->peerMacAddr,
+ sizeof(tSirMacAddr)))) ||
+ (deauth_req && (cdf_mem_compare((uint8_t *) sta_mac,
+ (uint8_t *) &deauth_req->peerMacAddr,
+ sizeof(tSirMacAddr))))) {
+ PELOG1(lim_log(mac_ctx, LOG1,
+ FL("Disassoc/Deauth ack pending"));)
+ return true;
+ } else {
+ PELOG1(lim_log(mac_ctx, LOG1,
+ FL("Disassoc/Deauth Ack not pending"));)
+ return false;
+ }
+}
+
+/*
+ * lim_clean_up_disassoc_deauth_req() - cleans up pending disassoc or deauth req
+ *
+ * @mac_ctx: mac_ctx
+ * @sta_mac: sta mac address
+ * @clean_rx_path: flag to indicate whether to cleanup rx path or not
+ *
+ * This function cleans up pending disassoc or deauth req
+ *
+ * Return: void
+ */
+void lim_clean_up_disassoc_deauth_req(tpAniSirGlobal mac_ctx,
+ uint8_t *sta_mac, bool clean_rx_path)
+{
+ tLimMlmDisassocReq *mlm_disassoc_req;
+ tLimMlmDeauthReq *mlm_deauth_req;
+ mlm_disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+ if (mlm_disassoc_req &&
+ (cdf_mem_compare((uint8_t *) sta_mac,
+ (uint8_t *) &mlm_disassoc_req->peerMacAddr,
+ sizeof(tSirMacAddr)))) {
+ if (clean_rx_path) {
+ lim_process_disassoc_ack_timeout(mac_ctx);
+ } else {
+ if (tx_timer_running(
+ &mac_ctx->lim.limTimers.gLimDisassocAckTimer)) {
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_DISASSOC_ACK_TIMER);
+ }
+ cdf_mem_free(mlm_disassoc_req);
+ mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq =
+ NULL;
+ }
+ }
+
+ mlm_deauth_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+ if (mlm_deauth_req &&
+ (cdf_mem_compare((uint8_t *) sta_mac,
+ (uint8_t *) &mlm_deauth_req->peerMacAddr,
+ sizeof(tSirMacAddr)))) {
+ if (clean_rx_path) {
+ lim_process_deauth_ack_timeout(mac_ctx);
+ } else {
+ if (tx_timer_running(
+ &mac_ctx->lim.limTimers.gLimDeauthAckTimer)) {
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_DEAUTH_ACK_TIMER);
+ }
+ cdf_mem_free(mlm_deauth_req);
+ mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq =
+ NULL;
+ }
+ }
+}
+
+/*
+ * lim_process_disassoc_ack_timeout() - wrapper function around
+ * lim_send_disassoc_cnf
+ *
+ * @mac_ctx: mac_ctx
+ *
+ * wrapper function around lim_send_disassoc_cnf
+ *
+ * Return: void
+ */
+void lim_process_disassoc_ack_timeout(tpAniSirGlobal mac_ctx)
+{
+ lim_log(mac_ctx, LOG1, FL(""));
+ lim_send_disassoc_cnf(mac_ctx);
+}
+
+/**
+ * lim_process_mlm_disassoc_req() - This function is called to process
+ * MLM_DISASSOC_REQ message from SME
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_DISASSOC_REQ message from SME
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_disassoc_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tLimMlmDisassocReq *mlm_disassoc_req;
+ tpPESession session;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ mlm_disassoc_req = (tLimMlmDisassocReq *) msg_buf;
+ lim_log(mac_ctx, LOG1,
+ FL("Process disassoc req, sessionID %d from: "MAC_ADDRESS_STR),
+ mlm_disassoc_req->sessionId,
+ MAC_ADDR_ARRAY(mlm_disassoc_req->peerMacAddr));
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mlm_disassoc_req->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given sessionId %d"),
+ mlm_disassoc_req->sessionId);
+ return;
+ }
+
+ lim_process_mlm_disassoc_req_ntf(mac_ctx, CDF_STATUS_SUCCESS,
+ (uint32_t *) msg_buf);
+}
+
+/**
+ * lim_process_mlm_deauth_req_ntf() - This function is process mlm deauth req
+ * notification
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @suspend_status: suspend status
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * This function is process mlm deauth req notification
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_deauth_req_ntf(tpAniSirGlobal mac_ctx,
+ CDF_STATUS suspend_status, uint32_t *msg_buf)
+{
+ uint16_t aid;
+ tSirMacAddr curr_bssId;
+ tpDphHashNode sta_ds;
+ struct tLimPreAuthNode *auth_node;
+ tLimMlmDeauthReq *mlm_deauth_req;
+ tLimMlmDeauthCnf mlm_deauth_cnf;
+ tpPESession session;
+
+ if (CDF_STATUS_SUCCESS != suspend_status)
+ lim_log(mac_ctx, LOGE, FL("Suspend Status is not success %X"),
+ suspend_status);
+
+ mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
+ session = pe_find_session_by_session_id(mac_ctx,
+ mlm_deauth_req->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given sessionId %d"),
+ mlm_deauth_req->sessionId);
+ cdf_mem_free(mlm_deauth_req);
+ return;
+ }
+ lim_log(mac_ctx, LOG1, FL("Process Deauth Req on sessionID %d Systemrole %d"
+ "mlmstate %d from: " MAC_ADDRESS_STR),
+ mlm_deauth_req->sessionId,
+ GET_LIM_SYSTEM_ROLE(session),
+ session->limMlmState,
+ MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
+ sir_copy_mac_addr(curr_bssId, session->bssId);
+
+ switch (GET_LIM_SYSTEM_ROLE(session)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ switch (session->limMlmState) {
+ case eLIM_MLM_IDLE_STATE:
+ /*
+ * Attempting to Deauthenticate with a pre-authenticated
+ * peer. Deauthetiate with peer if there exists a
+ * pre-auth context below.
+ */
+ break;
+ case eLIM_MLM_AUTHENTICATED_STATE:
+ case eLIM_MLM_WT_ASSOC_RSP_STATE:
+ case eLIM_MLM_LINK_ESTABLISHED_STATE:
+ if (!cdf_mem_compare(mlm_deauth_req->peerMacAddr,
+ curr_bssId, sizeof(tSirMacAddr))) {
+ lim_log(mac_ctx, LOGE,
+ FL("received MLM_DEAUTH_REQ with invalid BSS id "
+ "Peer MAC: "MAC_ADDRESS_STR
+ " CFG BSSID Addr : "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(
+ mlm_deauth_req->peerMacAddr),
+ MAC_ADDR_ARRAY(curr_bssId));
+ /* Prepare and Send LIM_MLM_DEAUTH_CNF */
+ mlm_deauth_cnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ if ((session->limMlmState ==
+ eLIM_MLM_AUTHENTICATED_STATE) ||
+ (session->limMlmState ==
+ eLIM_MLM_WT_ASSOC_RSP_STATE)) {
+ /* Send deauth frame to peer entity */
+ lim_send_deauth_mgmt_frame(mac_ctx,
+ mlm_deauth_req->reasonCode,
+ mlm_deauth_req->peerMacAddr,
+ session, false);
+ /* Prepare and Send LIM_MLM_DEAUTH_CNF */
+ mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
+ session->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session->peSessionId,
+ session->limMlmState));
+ goto end;
+ }
+ break;
+ default:
+ lim_log(mac_ctx, LOGW,
+ FL("received MLM_DEAUTH_REQ with in state %d for peer "
+ MAC_ADDRESS_STR),
+ session->limMlmState,
+ MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
+ lim_print_mlm_state(mac_ctx, LOGW,
+ session->limMlmState);
+ /* Prepare and Send LIM_MLM_DEAUTH_CNF */
+ mlm_deauth_cnf.resultCode =
+ eSIR_SME_STA_NOT_AUTHENTICATED;
+
+ goto end;
+ }
+ break;
+ case eLIM_STA_IN_IBSS_ROLE:
+ lim_log(mac_ctx, LOGE, FL("received MLM_DEAUTH_REQ IBSS Mode"));
+ mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ case eLIM_AP_ROLE:
+ case eLIM_P2P_DEVICE_GO:
+ if (true ==
+ mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+ lim_log(mac_ctx, LOGE,
+ FL("CAC timer is running, drop disassoc from going out"));
+ mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
+ goto end;
+ }
+ break;
+
+ default:
+ break;
+ } /* end switch (GET_LIM_SYSTEM_ROLE(session)) */
+
+ /*
+ * Check if there exists a context for the peer entity
+ * to be deauthenticated with.
+ */
+ sta_ds = dph_lookup_hash_entry(mac_ctx, mlm_deauth_req->peerMacAddr,
+ &aid, &session->dph.dphHashTable);
+
+ if (sta_ds == NULL) {
+ /* Check if there exists pre-auth context for this STA */
+ auth_node = lim_search_pre_auth_list(mac_ctx,
+ mlm_deauth_req->peerMacAddr);
+ if (auth_node == NULL) {
+ /*
+ * Received DEAUTH REQ for a STA that is neither
+ * Associated nor Pre-authenticated. Log error,
+ * Prepare and Send LIM_MLM_DEAUTH_CNF
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("received MLM_DEAUTH_REQ in mlme state %d for STA that "
+ "does not have context, Addr="
+ MAC_ADDRESS_STR),
+ session->limMlmState,
+ MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
+ mlm_deauth_cnf.resultCode =
+ eSIR_SME_STA_NOT_AUTHENTICATED;
+ } else {
+ mlm_deauth_cnf.resultCode = eSIR_SME_SUCCESS;
+ /* Delete STA from pre-auth STA list */
+ lim_delete_pre_auth_node(mac_ctx,
+ mlm_deauth_req->peerMacAddr);
+ /* Send Deauthentication frame to peer entity */
+ lim_send_deauth_mgmt_frame(mac_ctx,
+ mlm_deauth_req->reasonCode,
+ mlm_deauth_req->peerMacAddr,
+ session, false);
+ }
+ goto end;
+ } else if ((sta_ds->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (sta_ds->mlmStaContext.mlmState !=
+ eLIM_MLM_WT_ASSOC_CNF_STATE)) {
+ /*
+ * received MLM_DEAUTH_REQ for STA that either has no context or
+ * in some transit state
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid MLM_DEAUTH_REQ, Addr="MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
+ /* Prepare and Send LIM_MLM_DEAUTH_CNF */
+ mlm_deauth_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ /* sta_ds->mlmStaContext.rxPurgeReq = 1; */
+ sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes)
+ mlm_deauth_req->reasonCode;
+ sta_ds->mlmStaContext.cleanupTrigger = mlm_deauth_req->deauthTrigger;
+ mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = mlm_deauth_req;
+ /*
+ * Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE
+ * This is to address the issue of race condition between
+ * disconnect request from the HDD and disassoc from
+ * inactivity timer. This will make sure that we will not
+ * process disassoc if deauth is in progress for the station
+ * and thus mlmStaContext.cleanupTrigger will not be overwritten.
+ */
+ sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
+ /* Send Deauthentication frame to peer entity */
+ lim_send_deauth_mgmt_frame(mac_ctx, mlm_deauth_req->reasonCode,
+ mlm_deauth_req->peerMacAddr, session, true);
+ return;
+end:
+ cdf_mem_copy((uint8_t *) &mlm_deauth_cnf.peerMacAddr,
+ (uint8_t *) mlm_deauth_req->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlm_deauth_cnf.deauthTrigger = mlm_deauth_req->deauthTrigger;
+ mlm_deauth_cnf.aid = mlm_deauth_req->aid;
+ mlm_deauth_cnf.sessionId = mlm_deauth_req->sessionId;
+
+ /* Free up buffer allocated for mlmDeauthReq */
+ cdf_mem_free(mlm_deauth_req);
+ lim_post_sme_message(mac_ctx,
+ LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlm_deauth_cnf);
+}
+
+/*
+ * lim_process_deauth_ack_timeout() - wrapper function around
+ * lim_send_deauth_cnf
+ *
+ * @mac_ctx: mac_ctx
+ *
+ * wrapper function around lim_send_deauth_cnf
+ *
+ * Return: void
+ */
+void lim_process_deauth_ack_timeout(tpAniSirGlobal mac_ctx)
+{
+ lim_log(mac_ctx, LOG1, FL(""));
+ lim_send_deauth_cnf(mac_ctx);
+}
+
+/*
+ * lim_process_mlm_deauth_req() - This function is called to process
+ * MLM_DEAUTH_REQ message from SME
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_DEAUTH_REQ message from SME
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_deauth_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tLimMlmDeauthReq *mlm_deauth_req;
+ tpPESession session;
+
+ if (msg_buf == NULL) {
+ PELOGE(lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+
+ mlm_deauth_req = (tLimMlmDeauthReq *) msg_buf;
+ lim_log(mac_ctx, LOG1,
+ FL("Process Deauth Req on sessionID %d from: "
+ MAC_ADDRESS_STR),
+ mlm_deauth_req->sessionId,
+ MAC_ADDR_ARRAY(mlm_deauth_req->peerMacAddr));
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mlm_deauth_req->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given sessionId %d"),
+ mlm_deauth_req->sessionId);
+ return;
+ }
+ lim_process_mlm_deauth_req_ntf(mac_ctx, CDF_STATUS_SUCCESS,
+ (uint32_t *) msg_buf);
+}
+
+/**
+ * lim_process_mlm_set_keys_req() - This function is called to process
+ * MLM_SETKEYS_REQ message from SME
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_SETKEYS_REQ message from SME
+ *
+ * @Return: None
+ */
+static void
+lim_process_mlm_set_keys_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ uint16_t aid;
+ uint16_t sta_idx = 0;
+ uint32_t default_key_id = 0;
+ tSirMacAddr curr_bssid;
+ tpDphHashNode sta_ds;
+ tLimMlmSetKeysReq *mlm_set_keys_req;
+ tLimMlmSetKeysCnf mlm_set_keys_cnf;
+ tpPESession session;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ mlm_set_keys_req = (tLimMlmSetKeysReq *) msg_buf;
+ /* Hold onto the SetKeys request parameters */
+ mac_ctx->lim.gpLimMlmSetKeysReq = (void *)mlm_set_keys_req;
+ session = pe_find_session_by_session_id(mac_ctx,
+ mlm_set_keys_req->sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given sessionId"));
+ return;
+ }
+
+ lim_log(mac_ctx, LOGW,
+ FL("Received MLM_SETKEYS_REQ with parameters:"
+ "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - "),
+ mlm_set_keys_req->aid, mlm_set_keys_req->edType,
+ mlm_set_keys_req->numKeys);
+ lim_print_mac_addr(mac_ctx, mlm_set_keys_req->peerMacAddr, LOGW);
+ sir_copy_mac_addr(curr_bssid, session->bssId);
+
+ switch (GET_LIM_SYSTEM_ROLE(session)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ /*
+ * In case of TDLS, peerMac address need not be BssId. Skip this
+ * check if TDLS is enabled.
+ */
+#ifndef FEATURE_WLAN_TDLS
+ if ((!lim_is_addr_bc(mlm_set_keys_req->peerMacAddr)) &&
+ (!cdf_mem_compare(mlm_set_keys_req->peerMacAddr,
+ curr_bssid, sizeof(tSirMacAddr)))) {
+ lim_log(mac_ctx, LOGW,
+ FL("Received MLM_SETKEYS_REQ with invalid BSSID"
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mlm_set_keys_req->peerMacAddr));
+ /*
+ * Prepare and Send LIM_MLM_SETKEYS_CNF with error code
+ */
+ mlm_set_keys_cnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+#endif
+ break;
+ case eLIM_STA_IN_IBSS_ROLE:
+ /*
+ * update the IBSS PE session encrption type based on the
+ * key type
+ */
+ session->encryptType = mlm_set_keys_req->edType;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Use the "unicast" parameter to determine if the "Group Keys"
+ * are being set.
+ * mlm_set_keys_req->key.unicast = 0 -> Multicast/broadcast
+ * mlm_set_keys_req->key.unicast - 1 -> Unicast keys are being set
+ */
+ if (lim_is_addr_bc(mlm_set_keys_req->peerMacAddr)) {
+ lim_log(mac_ctx, LOG1, FL("Trying to set Group Keys...%d "),
+ mlm_set_keys_req->sessionId);
+ /*
+ * When trying to set Group Keys for any security mode other
+ * than WEP, use the STA Index corresponding to the AP...
+ */
+ switch (mlm_set_keys_req->edType) {
+ case eSIR_ED_CCMP:
+#ifdef WLAN_FEATURE_11W
+ case eSIR_ED_AES_128_CMAC:
+#endif
+ sta_idx = session->staId;
+ break;
+ default:
+ break;
+ }
+ } else {
+ lim_log(mac_ctx, LOG1, FL("Trying to set Unicast Keys..."));
+ /*
+ * Check if there exists a context for the
+ * peer entity for which keys need to be set.
+ */
+ sta_ds = dph_lookup_hash_entry(mac_ctx,
+ mlm_set_keys_req->peerMacAddr, &aid,
+ &session->dph.dphHashTable);
+ if ((sta_ds == NULL) ||
+ ((sta_ds->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ !LIM_IS_AP_ROLE(session))) {
+ /*
+ * Received LIM_MLM_SETKEYS_REQ for STA that does not
+ * have context or in some transit state.
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("Invalid MLM_SETKEYS_REQ, Addr = "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(mlm_set_keys_req->peerMacAddr));
+ /* Prepare and Send LIM_MLM_SETKEYS_CNF */
+ mlm_set_keys_cnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ } else {
+ sta_idx = sta_ds->staIndex;
+ }
+ }
+
+ if ((mlm_set_keys_req->numKeys == 0)
+ && (mlm_set_keys_req->edType != eSIR_ED_NONE)) {
+ /*
+ * Broadcast/Multicast Keys (for WEP!!) are NOT sent
+ * via this interface!! This indicates to HAL that the WEP Keys
+ * need to be extracted from the CFG and applied to hardware
+ */
+ default_key_id = 0xff;
+ } else if (mlm_set_keys_req->key[0].keyId &&
+ ((mlm_set_keys_req->edType == eSIR_ED_WEP40) ||
+ (mlm_set_keys_req->edType == eSIR_ED_WEP104))) {
+ /*
+ * If the Key Id is non zero and encryption mode is WEP,
+ * the key index is coming from the upper layers so that key
+ * only need to be used as the default tx key, This is being
+ * used only in case of WEP mode in HAL
+ */
+ default_key_id = mlm_set_keys_req->key[0].keyId;
+ } else {
+ default_key_id = 0;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("Trying to set keys for STA Index [%d], using default_key_id [%d]"),
+ sta_idx, default_key_id);
+
+ if (lim_is_addr_bc(mlm_set_keys_req->peerMacAddr)) {
+ session->limPrevMlmState = session->limMlmState;
+ session->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session->peSessionId, session->limMlmState));
+ lim_log(mac_ctx, LOG1, FL("Trying to set Group Keys...%d "),
+ session->peSessionId);
+ /* Package WMA_SET_BSSKEY_REQ message parameters */
+ lim_send_set_bss_key_req(mac_ctx, mlm_set_keys_req, session);
+ return;
+ } else {
+ /*
+ * Package WMA_SET_STAKEY_REQ / WMA_SET_STA_BCASTKEY_REQ message
+ * parameters
+ */
+ lim_send_set_sta_key_req(mac_ctx, mlm_set_keys_req, sta_idx,
+ (uint8_t) default_key_id, session,
+ true);
+ return;
+ }
+end:
+ mlm_set_keys_cnf.sessionId = mlm_set_keys_req->sessionId;
+ lim_post_sme_set_keys_cnf(mac_ctx, mlm_set_keys_req, &mlm_set_keys_cnf);
+}
+
+/**
+ * lim_process_periodic_probe_req_timer() - This function is called to process
+ * periodic probe request to send during scan.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process periodic probe request to send during scan
+ *
+ * @Return None
+ */
+static void lim_process_periodic_probe_req_timer(tpAniSirGlobal mac_ctx)
+{
+ uint8_t channel_num;
+ uint8_t i = 0;
+ tLimMlmScanReq *mlm_scan_req;
+ tSirRetStatus status = eSIR_SUCCESS;
+ TX_TIMER *probe_req_timer =
+ &mac_ctx->lim.limTimers.gLimPeriodicProbeReqTimer;
+
+ if (cdf_mc_timer_get_current_state(&probe_req_timer->cdf_timer)
+ != CDF_TIMER_STATE_STOPPED) {
+ lim_log(mac_ctx, LOG1, FL("Invalid state of timer"));
+ return;
+ }
+
+ if (!((mac_ctx->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE)
+ && (probe_req_timer->sessionId != 0xff)
+ && (mac_ctx->lim.probeCounter < mac_ctx->lim.maxProbe))) {
+ lim_log(mac_ctx, LOG1,
+ FL("received unexpected Periodic scan timeout in state %X"),
+ mac_ctx->lim.gLimMlmState);
+ return;
+ }
+
+ mlm_scan_req = mac_ctx->lim.gpLimMlmScanReq;
+ lim_log(mac_ctx, LOG1, FL("Scanning : Periodic scanning"));
+ mac_ctx->lim.probeCounter++;
+ /* Periodic channel timer timed out to send probe request. */
+ channel_num = lim_get_current_scan_channel(mac_ctx);
+ do {
+ /*
+ * Prepare and send Probe Request frame for all the SSIDs
+ * present in the saved MLM
+ */
+ status = lim_send_probe_req_mgmt_frame(mac_ctx,
+ &mlm_scan_req->ssId[i], mlm_scan_req->bssId,
+ channel_num, mac_ctx->lim.gSelfMacAddr,
+ mlm_scan_req->dot11mode,
+ mlm_scan_req->uIEFieldLen,
+ (uint8_t *) (mlm_scan_req) +
+ mlm_scan_req->uIEFieldOffset);
+ if (status != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("send ProbeReq failed for SSID %s on channel: %d"),
+ mlm_scan_req->ssId[i].ssId, channel_num);
+ return;
+ }
+ i++;
+ } while (i < mlm_scan_req->numSsid);
+ /* Activate timer again */
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+ probe_req_timer->sessionId,
+ eLIM_PERIODIC_PROBE_REQ_TIMER));
+ if (tx_timer_activate(probe_req_timer) != TX_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("could not start periodic probe req timer"));
+ return;
+ }
+}
+
+/**
+ * lim_process_join_failure_timeout() - This function is called to process
+ * JoinFailureTimeout
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process JoinFailureTimeout
+ *
+ * @Return None
+ */
+static void lim_process_join_failure_timeout(tpAniSirGlobal mac_ctx)
+{
+ tLimMlmJoinCnf mlm_join_cnf;
+ uint32_t len;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ host_log_rssi_pkt_type *rssi_log = NULL;
+#endif
+ tpPESession session;
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mac_ctx->lim.limTimers.gLimJoinFailureTimer.sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
+ host_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C);
+ if (rssi_log)
+ rssi_log->rssi = session->rssi;
+ WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
+#endif
+
+ if (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
+ len = sizeof(tSirMacAddr);
+ /* Change timer for future activations */
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
+ /* Change Periodic probe req timer for future activation */
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+ /* Issue MLM join confirm with timeout reason code */
+ lim_log(mac_ctx, LOGE,
+ FL("In state eLIM_MLM_WT_JOIN_BEACON_STATE."));
+ lim_log(mac_ctx, LOGE,
+ FL("Join Failure Timeout occurred for session %d with BSS "
+ MAC_ADDRESS_STR),
+ session->peSessionId, MAC_ADDR_ARRAY(session->bssId));
+
+ mlm_join_cnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE;
+ mlm_join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ session->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session->peSessionId, session->limMlmState));
+ if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
+ session->bssId, session->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ ("Failed to set the LinkState"));
+ /* Update PE session Id */
+ mlm_join_cnf.sessionId = session->peSessionId;
+ /* Freeup buffer allocated to join request */
+ if (session->pLimMlmJoinReq) {
+ cdf_mem_free(session->pLimMlmJoinReq);
+ session->pLimMlmJoinReq = NULL;
+ }
+ lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
+ (uint32_t *) &mlm_join_cnf);
+ return;
+ } else {
+ lim_log(mac_ctx, LOGW,
+ FL("received unexpected JOIN failure timeout in state %X"),
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
+ }
+}
+
+/**
+ * lim_process_periodic_join_probe_req_timer() - This function is called to
+ * process periodic probe request send during joining process.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process periodic probe request send during
+ * joining process.
+ *
+ * @Return None
+ */
+static void lim_process_periodic_join_probe_req_timer(tpAniSirGlobal mac_ctx)
+{
+ tpPESession session;
+ tSirMacSSid ssid;
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given SessionId : %d"),
+ mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.
+ sessionId);
+ return;
+ }
+
+ if ((true ==
+ tx_timer_running(&mac_ctx->lim.limTimers.gLimJoinFailureTimer))
+ && (session->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) {
+ cdf_mem_copy(ssid.ssId, session->ssId.ssId,
+ session->ssId.length);
+ ssid.length = session->ssId.length;
+ lim_send_probe_req_mgmt_frame(mac_ctx, &ssid,
+ session->pLimMlmJoinReq->bssDescription.bssId,
+ session->currentOperChannel /*chanNum */,
+ session->selfMacAddr, session->dot11mode,
+ session->pLimJoinReq->addIEScan.length,
+ session->pLimJoinReq->addIEScan.addIEdata);
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+ /* Activate Join Periodic Probe Req timer */
+ if (tx_timer_activate(
+ &mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer) !=
+ TX_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("could not activate Periodic Join req failure timer"));
+ return;
+ }
+ }
+}
+
+/**
+ * lim_process_auth_failure_timeout() - This function is called to process Min
+ * Channel Timeout during channel scan.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process Min Channel Timeout during channel scan.
+ *
+ * @Return: None
+ */
+static void lim_process_auth_failure_timeout(tpAniSirGlobal mac_ctx)
+{
+ /* fetch the sessionEntry based on the sessionId */
+ tpPESession session;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ host_log_rssi_pkt_type *rssi_log = NULL;
+#endif
+
+ session = pe_find_session_by_session_id(mac_ctx,
+ mac_ctx->lim.limTimers.gLimAuthFailureTimer.sessionId);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ lim_log(mac_ctx, LOGE,
+ FL("received AUTH failure timeout in sessionid %d "
+ "limMlmstate %X limSmeState %X"),
+ session->peSessionId, session->limMlmState,
+ session->limSmeState);
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ WLAN_HOST_DIAG_LOG_ALLOC(rssi_log, host_log_rssi_pkt_type,
+ LOG_WLAN_RSSI_UPDATE_C);
+ if (rssi_log)
+ rssi_log->rssi = session->rssi;
+ WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
+#endif
+
+ switch (session->limMlmState) {
+ case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+ case eLIM_MLM_WT_AUTH_FRAME4_STATE:
+ /*
+ * Requesting STA did not receive next auth frame before Auth
+ * Failure timeout. Issue MLM auth confirm with timeout reason
+ * code. Restore default failure timeout
+ */
+ if (CDF_P2P_CLIENT_MODE == session->pePersona
+ && session->defaultAuthFailureTimeout)
+ cfg_set_int(mac_ctx,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ session->defaultAuthFailureTimeout);
+ lim_restore_from_auth_state(mac_ctx,
+ eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,
+ eSIR_MAC_UNSPEC_FAILURE_REASON, session);
+ break;
+ default:
+ /*
+ * Auth failure timer should not have timed out
+ * in states other than wt_auth_frame2/4
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("received unexpected AUTH failure timeout in state %X"),
+ session->limMlmState);
+ lim_print_mlm_state(mac_ctx, LOGE, session->limMlmState);
+ break;
+ }
+}
+
+/**
+ * lim_process_auth_rsp_timeout() - This function is called to process Min
+ * Channel Timeout during channel scan.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process Min Channel Timeout during channel scan.
+ *
+ * @Return: None
+ */
+static void
+lim_process_auth_rsp_timeout(tpAniSirGlobal mac_ctx, uint32_t auth_idx)
+{
+ struct tLimPreAuthNode *auth_node;
+ tpPESession session;
+ uint8_t session_id;
+
+ auth_node = lim_get_pre_auth_node_from_index(mac_ctx,
+ &mac_ctx->lim.gLimPreAuthTimerTable, auth_idx);
+ if (NULL == auth_node) {
+ lim_log(mac_ctx, LOGW, FL("Invalid auth node"));
+ return;
+ }
+
+ session = pe_find_session_by_bssid(mac_ctx, auth_node->peerMacAddr,
+ &session_id);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGW,
+ FL("session does not exist for given BSSID "));
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) {
+ if (auth_node->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) {
+ lim_log(mac_ctx, LOGE,
+ FL("received AUTH rsp timeout in unexpected "
+ "state for MAC address: " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(auth_node->peerMacAddr));
+ } else {
+ auth_node->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE;
+ auth_node->fTimerStarted = 0;
+ lim_log(mac_ctx, LOG1,
+ FL("AUTH rsp timedout for MAC address "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(auth_node->peerMacAddr));
+ /* Change timer to reactivate it in future */
+ lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
+ eLIM_AUTH_RSP_TIMER, auth_node->authNodeIdx);
+ lim_delete_pre_auth_node(mac_ctx,
+ auth_node->peerMacAddr);
+ }
+ }
+}
+
+/**
+ * lim_process_assoc_failure_timeout() - This function is called to process Min
+ * Channel Timeout during channel scan.
+ *
+ * @mac_ctx Pointer to Global MAC structure
+ *
+ * This function is called to process Min Channel Timeout during channel scan.
+ *
+ * @Return: None
+ */
+static void
+lim_process_assoc_failure_timeout(tpAniSirGlobal mac_ctx, uint32_t msg_type)
+{
+
+ tLimMlmAssocCnf mlm_assoc_cnf;
+ tpPESession session;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ host_log_rssi_pkt_type *rssi_log = NULL;
+#endif
+ /*
+ * to fetch the lim/mlm state based on the session_id, use the
+ * below sessionEntry
+ */
+ uint8_t session_id;
+
+ if (msg_type == LIM_ASSOC)
+ session_id =
+ mac_ctx->lim.limTimers.gLimAssocFailureTimer.sessionId;
+ else
+ session_id =
+ mac_ctx->lim.limTimers.gLimReassocFailureTimer.sessionId;
+
+ session = pe_find_session_by_session_id(mac_ctx, session_id);
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ WLAN_HOST_DIAG_LOG_ALLOC(rssi_log,
+ host_log_rssi_pkt_type,
+ LOG_WLAN_RSSI_UPDATE_C);
+ if (rssi_log)
+ rssi_log->rssi = session->rssi;
+ WLAN_HOST_DIAG_LOG_REPORT(rssi_log);
+#endif
+
+ lim_log(mac_ctx, LOG1,
+ FL("Re/Association Response not received before timeout "));
+
+ if ((LIM_IS_AP_ROLE(session) || LIM_IS_BT_AMP_AP_ROLE(session)) ||
+ ((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
+ (session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) &&
+ (session->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
+ /*
+ * Re/Assoc failure timer should not have timedout on AP
+ * or in a state other than wt_re/assoc_response.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("received unexpected REASSOC failure timeout in state %X for role %d"),
+ session->limMlmState,
+ GET_LIM_SYSTEM_ROLE(session));
+ lim_print_mlm_state(mac_ctx, LOGW, session->limMlmState);
+ return;
+ }
+
+ if ((msg_type == LIM_ASSOC) || ((msg_type == LIM_REASSOC)
+ && (session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) {
+ lim_log(mac_ctx, LOGE,
+ FL("(Re)Assoc Failure Timeout occurred."));
+ session->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session->peSessionId, session->limMlmState));
+ /* Change timer for future activations */
+ lim_deactivate_and_change_timer(mac_ctx, eLIM_ASSOC_FAIL_TIMER);
+ /*
+ * Free up buffer allocated for JoinReq held by
+ * MLM state machine
+ */
+ if (session->pLimMlmJoinReq) {
+ cdf_mem_free(session->pLimMlmJoinReq);
+ session->pLimMlmJoinReq = NULL;
+ }
+ /* To remove the preauth node in case of fail to associate */
+ if (lim_search_pre_auth_list(mac_ctx, session->bssId)) {
+ lim_log(mac_ctx, LOG1,
+ FL(" delete pre auth node for "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(session->bssId));
+ lim_delete_pre_auth_node(mac_ctx,
+ session->bssId);
+ }
+
+ mlm_assoc_cnf.resultCode = eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE;
+ mlm_assoc_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE session Id */
+ mlm_assoc_cnf.sessionId = session->peSessionId;
+ if (msg_type == LIM_ASSOC) {
+ lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+ (uint32_t *) &mlm_assoc_cnf);
+ } else {
+ /*
+ * Will come here only in case of 11r, Ese FT
+ * when reassoc rsp is not received and we
+ * receive a reassoc - timesout
+ */
+ mlm_assoc_cnf.resultCode =
+ eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE;
+ lim_post_sme_message(mac_ctx, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlm_assoc_cnf);
+ }
+ } else {
+ /*
+ * Restore pre-reassoc req state.
+ * Set BSSID to currently associated AP address.
+ */
+ session->limMlmState = session->limPrevMlmState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session->peSessionId, session->limMlmState));
+ lim_restore_pre_reassoc_state(mac_ctx,
+ eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
+ }
+}
+
+/**
+ * lim_complete_mlm_scan() - This function is called to send MLM_SCAN_CNF
+ * message to SME state machine.
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ret_code: Result code to be sent
+ *
+ * This function is called to send MLM_SCAN_CNF message to SME state machine.
+ *
+ * @Return: None
+ */
+
+void lim_complete_mlm_scan(tpAniSirGlobal mac_ctx, tSirResultCodes ret_code)
+{
+ tLimMlmScanCnf mlm_scan_cnf;
+
+ /* Restore previous MLM state */
+ mac_ctx->lim.gLimMlmState = mac_ctx->lim.gLimPrevMlmState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, NO_SESSION,
+ mac_ctx->lim.gLimMlmState));
+ lim_restore_pre_scan_state(mac_ctx);
+ /* Free up mac_ctx->lim.gLimMlmScanReq */
+ if (NULL != mac_ctx->lim.gpLimMlmScanReq) {
+ cdf_mem_free(mac_ctx->lim.gpLimMlmScanReq);
+ mac_ctx->lim.gpLimMlmScanReq = NULL;
+ }
+
+ mlm_scan_cnf.resultCode = ret_code;
+ lim_post_sme_message(mac_ctx, LIM_MLM_SCAN_CNF,
+ (uint32_t *) &mlm_scan_cnf);
+}
+
+/**
+ * lim_set_channel() - set channel api for lim
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @channel: power save state
+ * @ch_center_freq_seg0: center freq seq 0
+ * @ch_center_freq_seg1: center freq seq 1
+ * @ch_width: channel width
+ * @max_tx_power: max tx power
+ * @pe_session_id: pe session id
+ *
+ * set channel api for lim
+ *
+ * @Return: None
+ */
+void lim_set_channel(tpAniSirGlobal mac_ctx, uint8_t channel,
+ uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width, tPowerdBm max_tx_power,
+ uint8_t pe_session_id)
+{
+#if !defined WLAN_FEATURE_VOWIFI
+ uint32_t localPwrConstraint;
+#endif
+ tpPESession pe_session;
+ pe_session = pe_find_session_by_session_id(mac_ctx, pe_session_id);
+
+ if (NULL == pe_session) {
+ lim_log(mac_ctx, LOGP, FL("Invalid PE session = %d"),
+ pe_session_id);
+ return;
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0,
+ ch_center_freq_seg1, ch_width,
+ max_tx_power, pe_session_id, false);
+#else
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ &localPwrConstraint) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("couldn't read CFG_LOCAL_POWER_CONSTRAINT"));
+ return;
+ }
+ /* Send WMA_CHNL_SWITCH_IND to HAL */
+ lim_send_switch_chnl_params(mac_ctx, channel, ch_center_freq_seg0,
+ ch_center_freq_seg1, ch_width,
+ (tPowerdBm) localPwrConstraint,
+ pe_session_id, false);
+#endif
+}
diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
new file mode 100644
index 0000000..4450acd
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -0,0 +1,4200 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_timer_utils.h"
+#include "lim_send_messages.h"
+#include "lim_admit_control.h"
+#include "lim_send_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft.h"
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "lim_session_utils.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+#include "wma_types.h"
+#include "cds_utils.h"
+#include "lim_types.h"
+
+#define MAX_SUPPORTED_PEERS_WEP 16
+
+static void lim_handle_sme_join_result(tpAniSirGlobal, tSirResultCodes, uint16_t,
+ tpPESession);
+static void lim_handle_sme_reaasoc_result(tpAniSirGlobal, tSirResultCodes, uint16_t,
+ tpPESession);
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+void lim_process_mlm_oem_data_req_cnf(tpAniSirGlobal, uint32_t *);
+#endif
+void lim_process_mlm_join_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_auth_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_start_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_assoc_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_assoc_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_reassoc_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_reassoc_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_set_keys_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_disassoc_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_disassoc_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_deauth_ind(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_deauth_cnf(tpAniSirGlobal, uint32_t *);
+void lim_process_mlm_purge_sta_ind(tpAniSirGlobal, uint32_t *);
+static void lim_handle_del_bss_in_re_assoc_context(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tpPESession psessionEntry);
+void lim_get_session_info(tpAniSirGlobal pMac, uint8_t *, uint8_t *, uint16_t *);
+static void
+lim_process_btamp_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+/**
+ * lim_process_mlm_rsp_messages()
+ *
+ ***FUNCTION:
+ * This function is called to processes various MLM response (CNF/IND
+ * messages from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void
+lim_process_mlm_rsp_messages(tpAniSirGlobal pMac, uint32_t msgType,
+ uint32_t *pMsgBuf)
+{
+
+ if (pMsgBuf == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+ MTRACE(mac_trace(pMac, TRACE_CODE_TX_LIM_MSG, 0, msgType));
+ switch (msgType) {
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case LIM_MLM_OEM_DATA_CNF:
+ lim_process_mlm_oem_data_req_cnf(pMac, pMsgBuf);
+ pMsgBuf = NULL;
+ break;
+#endif
+
+ case LIM_MLM_AUTH_CNF:
+ lim_process_mlm_auth_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_ASSOC_CNF:
+ lim_process_mlm_assoc_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_START_CNF:
+ lim_process_mlm_start_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_JOIN_CNF:
+ lim_process_mlm_join_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_ASSOC_IND:
+ lim_process_mlm_assoc_ind(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_REASSOC_CNF:
+ lim_process_mlm_reassoc_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DISASSOC_CNF:
+ lim_process_mlm_disassoc_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DISASSOC_IND:
+ lim_process_mlm_disassoc_ind(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_PURGE_STA_IND:
+ lim_process_mlm_purge_sta_ind(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DEAUTH_CNF:
+ lim_process_mlm_deauth_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_DEAUTH_IND:
+ lim_process_mlm_deauth_ind(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_SETKEYS_CNF:
+ lim_process_mlm_set_keys_cnf(pMac, pMsgBuf);
+ break;
+ case LIM_MLM_TSPEC_CNF:
+ break;
+ default:
+ break;
+ } /* switch (msgType) */
+ return;
+} /*** end lim_process_mlm_rsp_messages() ***/
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+/**
+ * lim_process_mlm_oem_data_req_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes LIM_MLM_OEM_DATA_REQ_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+
+void lim_process_mlm_oem_data_req_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tLimMlmOemDataRsp *measRsp;
+
+ tSirResultCodes resultCode = eSIR_SME_SUCCESS;
+
+ measRsp = (tLimMlmOemDataRsp *) (pMsgBuf);
+
+ /* Now send the meas confirm message to the sme */
+ lim_send_sme_oem_data_rsp(pMac, (uint32_t *) measRsp, resultCode);
+
+ /* Dont free the memory here. It will be freed up by the callee */
+
+ return;
+}
+#endif
+
+/**
+ * lim_process_mlm_start_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_START_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_start_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpPESession psessionEntry = NULL;
+ tLimMlmStartCnf *pLimMlmStartCnf;
+ uint8_t smesessionId;
+ uint16_t smetransactionId;
+ uint8_t channelId;
+
+ if (pMsgBuf == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+ pLimMlmStartCnf = (tLimMlmStartCnf *) pMsgBuf;
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pLimMlmStartCnf->sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL(
+ "Session does Not exist with given sessionId "));)
+ return;
+ }
+ smesessionId = psessionEntry->smeSessionId;
+ smetransactionId = psessionEntry->transactionId;
+
+ if (psessionEntry->limSmeState != eLIM_SME_WT_START_BSS_STATE) {
+ /*
+ * Should not have received Start confirm from MLM
+ * in other states. Log error.
+ */
+ PELOGE(lim_log(pMac, LOGE, FL
+ ("received unexpected MLM_START_CNF in state %X"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+ if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS) {
+
+ /*
+ * Update global SME state so that Beacon Generation
+ * module starts writing Beacon frames into TFP's
+ * Beacon file register.
+ */
+ psessionEntry->limSmeState = eLIM_SME_NORMAL_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+ if (psessionEntry->bssType == eSIR_BTAMP_STA_MODE) {
+ lim_log(pMac, LOG1,
+ FL("*** Started BSS in BT_AMP STA SIDE***"));
+ } else if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
+ lim_log(pMac, LOG1,
+ FL("*** Started BSS in BT_AMP AP SIDE***"));
+ } else if (psessionEntry->bssType == eSIR_INFRA_AP_MODE) {
+ lim_log(pMac, LOG1,
+ FL("*** Started BSS in INFRA AP SIDE***"));
+ } else
+ PELOG1(lim_log(pMac, LOG1, FL("*** Started BSS ***"));)
+ } else {
+ /* Start BSS is a failure */
+ pe_delete_session(pMac, psessionEntry);
+ psessionEntry = NULL;
+ PELOGE(lim_log(pMac, LOGE, FL("Start BSS Failed "));)
+ }
+ /* Send response to Host */
+ lim_send_sme_start_bss_rsp(pMac, eWNI_SME_START_BSS_RSP,
+ ((tLimMlmStartCnf *)pMsgBuf)->resultCode,
+ psessionEntry, smesessionId, smetransactionId);
+ if ((psessionEntry != NULL) &&
+ (((tLimMlmStartCnf *) pMsgBuf)->resultCode ==
+ eSIR_SME_SUCCESS)) {
+ channelId = psessionEntry->pLimStartBssReq->channelId;
+
+ /* We should start beacon transmission only if the channel
+ * on which we are operating is non-DFS until the channel
+ * availability check is done. The PE will receive an explicit
+ * request from upper layers to start the beacon transmission
+ */
+
+ if (LIM_IS_IBSS_ROLE(psessionEntry) ||
+ (LIM_IS_AP_ROLE(psessionEntry) &&
+ (cds_get_channel_state(channelId) !=
+ CHANNEL_STATE_DFS))) {
+ /* Configure beacon and send beacons to HAL */
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("Start Beacon with ssid %s Ch %d"),
+ psessionEntry->ssId.ssId,
+ psessionEntry->currentOperChannel);
+ lim_send_beacon_ind(pMac, psessionEntry);
+ }
+ }
+}
+
+/*** end lim_process_mlm_start_cnf() ***/
+
+/**
+ * lim_process_mlm_join_cnf() - Processes join confirmation
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This Function handles the join confirmation message
+ * LIM_MLM_JOIN_CNF.
+ *
+ * Return: None
+ */
+void lim_process_mlm_join_cnf(tpAniSirGlobal mac_ctx,
+ uint32_t *msg)
+{
+ tSirResultCodes result_code;
+ tLimMlmJoinCnf *join_cnf;
+ tpPESession session_entry;
+
+ join_cnf = (tLimMlmJoinCnf *) msg;
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ join_cnf->sessionId);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE, FL("SessionId:%d does not exist"),
+ join_cnf->sessionId);
+ return;
+ }
+
+ if (session_entry->limSmeState != eLIM_SME_WT_JOIN_STATE) {
+ lim_log(mac_ctx, LOGE,
+ FL("received unexpected MLM_JOIN_CNF in state %X"),
+ session_entry->limSmeState);
+ return;
+ }
+
+ result_code = ((tLimMlmJoinCnf *) msg)->resultCode;
+ /* Process Join confirm from MLM */
+ if (result_code == eSIR_SME_SUCCESS) {
+ lim_log(mac_ctx, LOG1, FL("***SessionId:%d Joined ESS ***"),
+ join_cnf->sessionId);
+ /* Setup hardware upfront */
+ if (lim_sta_send_add_bss_pre_assoc(mac_ctx, false,
+ session_entry) == eSIR_SUCCESS)
+ return;
+ else
+ result_code = eSIR_SME_REFUSED;
+ }
+
+ /* Join failure */
+ session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ /* Send Join response to Host */
+ lim_handle_sme_join_result(mac_ctx, result_code,
+ ((tLimMlmJoinCnf *) msg)->protStatusCode, session_entry);
+ return;
+}
+
+/**
+ * lim_send_mlm_assoc_req() - Association request will be processed
+ * mac_ctx: Pointer to Global MAC structure
+ * session_entry: Pointer to session etnry
+ *
+ * This function is sends ASSOC request MLM message to MLM State machine.
+ * ASSOC request packet would be by picking parameters from psessionEntry
+ * automatically based on the current state of MLM state machine.
+ * ASSUMPTIONS:
+ * this function is called in middle of connection state machine and is
+ * expected to be called after auth cnf has been received or after ASSOC rsp
+ * with TRY_AGAIN_LATER was received and required time has elapsed after that.
+ *
+ * Return: None
+ */
+
+void lim_send_mlm_assoc_req(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry)
+{
+ tLimMlmAssocReq *assoc_req;
+ uint32_t val;
+ uint16_t caps;
+ uint32_t tele_bcn = 0;
+ tpSirMacCapabilityInfo cap_info;
+
+ /* Successful MAC based authentication. Trigger Association with BSS */
+ lim_log(mac_ctx, LOG1, FL("SessionId:%d Authenticated with BSS"),
+ session_entry->peSessionId);
+
+ if (NULL == session_entry->pLimJoinReq) {
+ lim_log(mac_ctx, LOGE, FL("Join Request is NULL."));
+ /* No need to Assert. JOIN timeout will handle this error */
+ return;
+ }
+
+ assoc_req = cdf_mem_malloc(sizeof(tLimMlmAssocReq));
+ if (NULL == assoc_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("call to AllocateMemory failed for mlmAssocReq"));
+ return;
+ }
+ val = sizeof(tSirMacAddr);
+ sir_copy_mac_addr(assoc_req->peerMacAddr, session_entry->bssId);
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ (uint32_t *) &assoc_req->assocFailureTimeout)
+ != eSIR_SUCCESS) {
+ /* Could not get AssocFailureTimeout value from CFG.*/
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve AssocFailureTimeout value"));
+ }
+
+ if (cfg_get_capability_info(mac_ctx, &caps, session_entry)
+ != eSIR_SUCCESS)
+ /* Could not get Capabilities value from CFG.*/
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve Capabilities value"));
+
+ /* Clear spectrum management bit if AP doesn't support it */
+ if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+ LIM_SPECTRUM_MANAGEMENT_BIT_MASK))
+ /*
+ * AP doesn't support spectrum management
+ * clear spectrum management bit
+ */
+ caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK);
+
+ /* Clear rrm bit if AP doesn't support it */
+ if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo
+ & LIM_RRM_BIT_MASK))
+ caps &= (~LIM_RRM_BIT_MASK);
+
+ /* Clear short preamble bit if AP does not support it */
+ if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+ (LIM_SHORT_PREAMBLE_BIT_MASK))) {
+ caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK);
+ lim_log(mac_ctx, LOG1,
+ FL("Clearing short preamble:no AP support"));
+ }
+
+ /* Clear immediate block ack bit if AP does not support it */
+ if (!(session_entry->pLimJoinReq->bssDescription.capabilityInfo &
+ (LIM_IMMEDIATE_BLOCK_ACK_MASK))) {
+ caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK);
+ lim_log(mac_ctx, LOG1,
+ FL("Clearing Immed Blk Ack:no AP support"));
+ }
+
+ assoc_req->capabilityInfo = caps;
+ cap_info = ((tpSirMacCapabilityInfo) &assoc_req->capabilityInfo);
+ lim_log(mac_ctx, LOG3, FL("Capabilities to be used in AssocReq=0x%X,"
+ "privacy bit=%x shortSlotTime %x"), caps,
+ cap_info->privacy,
+ cap_info->shortSlotTime);
+
+ /*
+ * If telescopic beaconing is enabled, set listen interval to
+ * WNI_CFG_TELE_BCN_MAX_LI
+ */
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_WAKEUP_EN, &tele_bcn)
+ != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));
+
+ val = WNI_CFG_LISTEN_INTERVAL_STADEF;
+ if (tele_bcn) {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
+ eSIR_SUCCESS)
+ /*
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve ListenInterval"));
+ } else {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_LISTEN_INTERVAL,
+ &val) != eSIR_SUCCESS)
+ /*
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve ListenInterval"));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_REQ_EVENT,
+ session_entry, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ assoc_req->listenInterval = (uint16_t) val;
+ /* Update PE session ID */
+ assoc_req->sessionId = session_entry->peSessionId;
+ session_entry->limPrevSmeState = session_entry->limSmeState;
+ session_entry->limSmeState = eLIM_SME_WT_ASSOC_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId, session_entry->limSmeState));
+ lim_post_mlm_message(mac_ctx, LIM_MLM_ASSOC_REQ,
+ (uint32_t *) assoc_req);
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_pmf_comeback_timer_callback() -PMF callback handler
+ * @context: Timer context
+ *
+ * This function is called to processes the PMF comeback
+ * callback
+ *
+ * Return: None
+ */
+void lim_pmf_comeback_timer_callback(void *context)
+{
+ tComebackTimerInfo *info = (tComebackTimerInfo *) context;
+ tpAniSirGlobal mac_ctx = info->pMac;
+ tpPESession psessionEntry = &mac_ctx->lim.gpSession[info->sessionID];
+
+ lim_log(mac_ctx, LOGE,
+ FL("comeback later timer expired. sending MLM ASSOC req"));
+ /* set MLM state such that ASSOC REQ packet will be sent out */
+ psessionEntry->limPrevMlmState = info->limPrevMlmState;
+ psessionEntry->limMlmState = info->limMlmState;
+ lim_send_mlm_assoc_req(mac_ctx, psessionEntry);
+}
+#endif /* WLAN_FEATURE_11W */
+
+/**
+ * lim_process_mlm_auth_cnf()-Process Auth confirmation
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This function is called to processes MLM_AUTH_CNF
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+void lim_process_mlm_auth_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg)
+{
+ tAniAuthType auth_type, auth_mode;
+ tLimMlmAuthReq *auth_req;
+ tLimMlmAuthCnf *auth_cnf;
+ tpPESession session_entry;
+
+ if (msg == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+ auth_cnf = (tLimMlmAuthCnf *) msg;
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ auth_cnf->sessionId);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE, FL("SessionId:%d session doesn't exist"),
+ auth_cnf->sessionId);
+ return;
+ }
+
+ if ((session_entry->limSmeState != eLIM_SME_WT_AUTH_STATE &&
+ session_entry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE) ||
+ LIM_IS_AP_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ /**
+ * Should not have received AUTH confirm
+ * from MLM in other states or on AP.
+ * Log error
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("SessionId:%d received MLM_AUTH_CNF in state %X"),
+ session_entry->peSessionId, session_entry->limSmeState);
+ return;
+ }
+
+ if (((tLimMlmAuthCnf *) msg)->resultCode == eSIR_SME_SUCCESS) {
+ if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) {
+ lim_send_mlm_assoc_req(mac_ctx, session_entry);
+ } else {
+ /*
+ * Successful Pre-authentication. Send
+ * Pre-auth response to host
+ */
+ session_entry->limSmeState =
+ session_entry->limPrevSmeState;
+ MTRACE(mac_trace
+ (mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ }
+ /* Return for success case */
+ return;
+ }
+ /*
+ * Failure case handle:
+ * Process AUTH confirm from MLM
+ */
+ if (session_entry->limSmeState == eLIM_SME_WT_AUTH_STATE) {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_AUTHENTICATION_TYPE,
+ (uint32_t *) &auth_type) != eSIR_SUCCESS) {
+ /*
+ * Could not get AuthType value from CFG.
+ * Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("Fail to retrieve AuthType value"));
+ }
+ } else {
+ auth_type = mac_ctx->lim.gLimPreAuthType;
+ }
+
+ if ((auth_type == eSIR_AUTO_SWITCH) &&
+ (((tLimMlmAuthCnf *) msg)->authType == eSIR_OPEN_SYSTEM)
+ && (eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS ==
+ ((tLimMlmAuthCnf *) msg)->protStatusCode)) {
+ /*
+ * When Open authentication fails with reason
+ * code "13" and authType set to 'auto switch',
+ * Try with Shared Authentication
+ */
+ auth_mode = eSIR_SHARED_KEY;
+ /* Trigger MAC based Authentication */
+ auth_req = cdf_mem_malloc(sizeof(tLimMlmAuthReq));
+ if (NULL == auth_req) {
+ /* Log error */
+ lim_log(mac_ctx, LOGP,
+ FL("mlmAuthReq :Memory alloc failed "));
+ return;
+ }
+ cdf_mem_set((uint8_t *) auth_req,
+ sizeof(tLimMlmAuthReq), 0);
+ if (session_entry->limSmeState ==
+ eLIM_SME_WT_AUTH_STATE) {
+ sir_copy_mac_addr(auth_req->peerMacAddr,
+ session_entry->bssId);
+ } else {
+ cdf_mem_copy((uint8_t *)&auth_req->peerMacAddr,
+ (uint8_t *)&mac_ctx->lim.gLimPreAuthPeerAddr,
+ sizeof(tSirMacAddr));
+ }
+ auth_req->authType = auth_mode;
+ /* Update PE session Id */
+ auth_req->sessionId = auth_cnf->sessionId;
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ (uint32_t *) &auth_req->authFailureTimeout)
+ != eSIR_SUCCESS) {
+ /*
+ * Could not get AuthFailureTimeout value from CFG.
+ * Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("Fail:retrieve AuthFailureTimeout "));
+ }
+ lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
+ (uint32_t *) auth_req);
+ return;
+ } else {
+ /* MAC based authentication failure */
+ if (session_entry->limSmeState ==
+ eLIM_SME_WT_AUTH_STATE) {
+ lim_log(mac_ctx, LOGE,
+ FL("Auth Failure occurred."));
+ session_entry->limSmeState =
+ eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ session_entry->limMlmState =
+ eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId,
+ session_entry->limMlmState));
+ /*
+ * Need to send Join response with
+ * auth failure to Host.
+ */
+ lim_handle_sme_join_result(mac_ctx,
+ ((tLimMlmAuthCnf *)msg)->resultCode,
+ ((tLimMlmAuthCnf *)msg)->protStatusCode,
+ session_entry);
+ } else {
+ /*
+ * Pre-authentication failure.
+ * Send Pre-auth failure response to host
+ */
+ session_entry->limSmeState =
+ session_entry->limPrevSmeState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ }
+ }
+}
+
+/**
+ * lim_process_mlm_assoc_cnf() - Process association confirmation
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This function is called to processes MLM_ASSOC_CNF
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+void lim_process_mlm_assoc_cnf(tpAniSirGlobal mac_ctx,
+ uint32_t *msg)
+{
+ tpPESession session_entry;
+ tLimMlmAssocCnf *assoc_cnf;
+
+ if (msg == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+ assoc_cnf = (tLimMlmAssocCnf *) msg;
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ assoc_cnf->sessionId);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("SessionId:%d Session does not exist"),
+ assoc_cnf->sessionId);
+ return;
+ }
+ if (session_entry->limSmeState != eLIM_SME_WT_ASSOC_STATE ||
+ LIM_IS_AP_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ /*
+ * Should not have received Assocication confirm
+ * from MLM in other states OR on AP.
+ * Log error
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("SessionId:%d Received MLM_ASSOC_CNF in state %X"),
+ session_entry->peSessionId, session_entry->limSmeState);
+ return;
+ }
+ if (((tLimMlmAssocCnf *) msg)->resultCode != eSIR_SME_SUCCESS) {
+ /* Association failure */
+ lim_log(mac_ctx, LOG1, FL("SessionId:%d Association failure"),
+ session_entry->peSessionId);
+ session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId, mac_ctx->lim.gLimSmeState));
+ /*
+ * Need to send Join response with
+ * Association failure to Host.
+ */
+ lim_handle_sme_join_result(mac_ctx,
+ ((tLimMlmAssocCnf *) msg)->resultCode,
+ ((tLimMlmAssocCnf *) msg)->protStatusCode,
+ session_entry);
+ } else {
+ /* Successful Association */
+ lim_log(mac_ctx, LOG1, FL("SessionId:%d Associated with BSS"),
+ session_entry->peSessionId);
+ session_entry->limSmeState = eLIM_SME_LINK_EST_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ /**
+ * Need to send Join response with
+ * Association success to Host.
+ */
+ lim_handle_sme_join_result(mac_ctx,
+ ((tLimMlmAssocCnf *) msg)->resultCode,
+ ((tLimMlmAssocCnf *) msg)->protStatusCode,
+ session_entry);
+ }
+}
+
+/**
+ * lim_process_mlm_reassoc_cnf() - process mlm reassoc cnf msg
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the MLM message buffer
+ *
+ * This function is called to process MLM_REASSOC_CNF message from MLM State
+ * machine.
+ *
+ * @Return: void
+ */
+void lim_process_mlm_reassoc_cnf(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tpPESession session;
+ tLimMlmReassocCnf *lim_mlm_reassoc_cnf;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+ lim_mlm_reassoc_cnf = (tLimMlmReassocCnf *) msg_buf;
+ session = pe_find_session_by_session_id(mac_ctx,
+ lim_mlm_reassoc_cnf->sessionId);
+ if (session == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session Does not exist for given session Id"));
+ return;
+ }
+ if ((session->limSmeState != eLIM_SME_WT_REASSOC_STATE) ||
+ LIM_IS_AP_ROLE(session) || LIM_IS_BT_AMP_AP_ROLE(session)) {
+ /*
+ * Should not have received Reassocication confirm
+ * from MLM in other states OR on AP.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("Rcv unexpected MLM_REASSOC_CNF in role %d, sme state 0x%X"),
+ GET_LIM_SYSTEM_ROLE(session), session->limSmeState);
+ return;
+ }
+ if (session->pLimReAssocReq) {
+ cdf_mem_free(session->pLimReAssocReq);
+ session->pLimReAssocReq = NULL;
+ }
+
+ /*
+ * Upon Reassoc success or failure, freeup the cached preauth request,
+ * to ensure that channel switch is now allowed following any change in
+ * HT params.
+ */
+ if (session->ftPEContext.pFTPreAuthReq) {
+ lim_log(mac_ctx, LOG1, FL("Freeing pFTPreAuthReq= %p"),
+ session->ftPEContext.pFTPreAuthReq);
+ if (session->ftPEContext.pFTPreAuthReq->pbssDescription) {
+ cdf_mem_free(
+ session->ftPEContext.pFTPreAuthReq->pbssDescription);
+ session->ftPEContext.pFTPreAuthReq->pbssDescription =
+ NULL;
+ }
+ cdf_mem_free(session->ftPEContext.pFTPreAuthReq);
+ session->ftPEContext.pFTPreAuthReq = NULL;
+ session->ftPEContext.ftPreAuthSession = false;
+ }
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (session->bRoamSynchInProgress) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ FL("LFR3:Re-set the LIM Ctxt Roam Synch In Progress"));
+ session->bRoamSynchInProgress = false;
+ }
+#endif
+
+ lim_log(mac_ctx, LOG1, FL("Rcv MLM_REASSOC_CNF with result code %d"),
+ lim_mlm_reassoc_cnf->resultCode);
+ if (lim_mlm_reassoc_cnf->resultCode == eSIR_SME_SUCCESS) {
+ /* Successful Reassociation */
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ FL("*** Reassociated with new BSS ***"));
+
+ session->limSmeState = eLIM_SME_LINK_EST_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session->peSessionId, session->limSmeState));
+
+ /* Need to send Reassoc rsp with Reassoc success to Host. */
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
+ lim_mlm_reassoc_cnf->resultCode,
+ lim_mlm_reassoc_cnf->protStatusCode,
+ session, session->smeSessionId,
+ session->transactionId);
+ } else if (lim_mlm_reassoc_cnf->resultCode
+ == eSIR_SME_REASSOC_REFUSED) {
+ /*
+ * Reassociation failure With the New AP but we still have the
+ * link with the Older AP
+ */
+ session->limSmeState = eLIM_SME_LINK_EST_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session->peSessionId, session->limSmeState));
+
+ /* Need to send Reassoc rsp with Assoc failure to Host. */
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
+ lim_mlm_reassoc_cnf->resultCode,
+ lim_mlm_reassoc_cnf->protStatusCode,
+ session, session->smeSessionId,
+ session->transactionId);
+ } else {
+ /* Reassociation failure */
+ session->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session->peSessionId, session->limSmeState));
+ /* Need to send Reassoc rsp with Assoc failure to Host. */
+ lim_handle_sme_reaasoc_result(mac_ctx,
+ lim_mlm_reassoc_cnf->resultCode,
+ lim_mlm_reassoc_cnf->protStatusCode,
+ session);
+ }
+}
+
+/**
+ * lim_fill_assoc_ind_params() - Initialize association indication
+ * mac_ctx: Pointer to Global MAC structure
+ * assoc_ind: PE association indication structure
+ * sme_assoc_ind: SME association indication
+ * session_entry: PE session entry
+ *
+ * This function is called to initialzie the association
+ * indication strucutre to process association indication.
+ *
+ * Return: None
+ */
+
+void
+lim_fill_assoc_ind_params(tpAniSirGlobal mac_ctx,
+ tpLimMlmAssocInd assoc_ind, tSirSmeAssocInd *sme_assoc_ind,
+ tpPESession session_entry)
+{
+ sme_assoc_ind->length = sizeof(tSirSmeAssocInd);
+ sme_assoc_ind->sessionId = session_entry->smeSessionId;
+
+ /* Required for indicating the frames to upper layer */
+ sme_assoc_ind->assocReqLength = assoc_ind->assocReqLength;
+ sme_assoc_ind->assocReqPtr = assoc_ind->assocReqPtr;
+
+ sme_assoc_ind->beaconPtr = session_entry->beacon;
+ sme_assoc_ind->beaconLength = session_entry->bcnLen;
+
+ /* Fill in peerMacAddr */
+ cdf_mem_copy(sme_assoc_ind->peerMacAddr, assoc_ind->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ /* Fill in aid */
+ sme_assoc_ind->aid = assoc_ind->aid;
+ /* Fill in bssId */
+ cdf_mem_copy(sme_assoc_ind->bssId, session_entry->bssId,
+ sizeof(tSirMacAddr));
+ /* Fill in authType */
+ sme_assoc_ind->authType = assoc_ind->authType;
+ /* Fill in ssId */
+ cdf_mem_copy((uint8_t *) &sme_assoc_ind->ssId,
+ (uint8_t *) &(assoc_ind->ssId), assoc_ind->ssId.length + 1);
+ sme_assoc_ind->rsnIE.length = assoc_ind->rsnIE.length;
+ cdf_mem_copy((uint8_t *) &sme_assoc_ind->rsnIE.rsnIEdata,
+ (uint8_t *) &(assoc_ind->rsnIE.rsnIEdata),
+ assoc_ind->rsnIE.length);
+
+#ifdef FEATURE_WLAN_WAPI
+ sme_assoc_ind->wapiIE.length = assoc_ind->wapiIE.length;
+ cdf_mem_copy((uint8_t *) &sme_assoc_ind->wapiIE.wapiIEdata,
+ (uint8_t *) &(assoc_ind->wapiIE.wapiIEdata),
+ assoc_ind->wapiIE.length);
+#endif
+ sme_assoc_ind->addIE.length = assoc_ind->addIE.length;
+ cdf_mem_copy((uint8_t *) &sme_assoc_ind->addIE.addIEdata,
+ (uint8_t *) &(assoc_ind->addIE.addIEdata),
+ assoc_ind->addIE.length);
+
+ /* Copy the new TITAN capabilities */
+ sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator;
+ if (assoc_ind->spectrumMgtIndicator == eSIR_TRUE) {
+ sme_assoc_ind->powerCap.minTxPower =
+ assoc_ind->powerCap.minTxPower;
+ sme_assoc_ind->powerCap.maxTxPower =
+ assoc_ind->powerCap.maxTxPower;
+ sme_assoc_ind->supportedChannels.numChnl =
+ assoc_ind->supportedChannels.numChnl;
+ cdf_mem_copy((uint8_t *) &sme_assoc_ind->supportedChannels.
+ channelList,
+ (uint8_t *) &(assoc_ind->supportedChannels.channelList),
+ assoc_ind->supportedChannels.numChnl);
+ }
+ cdf_mem_copy(&sme_assoc_ind->chan_info, &assoc_ind->chan_info,
+ sizeof(tSirSmeChanInfo));
+ /* Fill in WmmInfo */
+ sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent;
+}
+
+/**
+ * lim_process_mlm_assoc_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_ASSOC_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_assoc_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ uint32_t len;
+ tSirMsgQ msgQ;
+ tSirSmeAssocInd *pSirSmeAssocInd;
+ tpDphHashNode pStaDs = 0;
+ tpPESession psessionEntry;
+ if (pMsgBuf == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ ((tpLimMlmAssocInd) pMsgBuf)->
+ sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session Does not exist for given sessionId"));
+ return;
+ }
+ /* / Inform Host of STA association */
+ len = sizeof(tSirSmeAssocInd);
+ pSirSmeAssocInd = cdf_mem_malloc(len);
+ if (NULL == pSirSmeAssocInd) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_ASSOC_IND"));
+ return;
+ }
+
+ pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND;
+ lim_fill_assoc_ind_params(pMac, (tpLimMlmAssocInd) pMsgBuf, pSirSmeAssocInd,
+ psessionEntry);
+ msgQ.type = eWNI_SME_ASSOC_IND;
+ msgQ.bodyptr = pSirSmeAssocInd;
+ msgQ.bodyval = 0;
+ pStaDs = dph_get_hash_entry(pMac,
+ ((tpLimMlmAssocInd) pMsgBuf)->aid,
+ &psessionEntry->dph.dphHashTable);
+ if (!pStaDs) { /* good time to panic... */
+ lim_log(pMac, LOGE,
+ FL
+ ("MLM AssocInd: Station context no longer valid (aid %d)"),
+ ((tpLimMlmAssocInd) pMsgBuf)->aid);
+ cdf_mem_free(pSirSmeAssocInd);
+
+ return;
+ }
+ pSirSmeAssocInd->staId = pStaDs->staIndex;
+ pSirSmeAssocInd->reassocReq = pStaDs->mlmStaContext.subType;
+ pSirSmeAssocInd->timingMeasCap = pStaDs->timingMeasCap;
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_ASSOC_IND_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT);
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND"));
+ )
+ /*
+ ** turn on a timer to detect the loss of ASSOC CNF
+ **/
+ lim_activate_cnf_timer(pMac,
+ (uint16_t) ((tpLimMlmAssocInd) pMsgBuf)->aid,
+ psessionEntry);
+
+} /*** end lim_process_mlm_assoc_ind() ***/
+
+/**
+ * lim_process_mlm_disassoc_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_DISASSOC_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_disassoc_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tLimMlmDisassocInd *pMlmDisassocInd;
+ tpPESession psessionEntry;
+ pMlmDisassocInd = (tLimMlmDisassocInd *) pMsgBuf;
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMlmDisassocInd->sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+ break;
+ default: /* eLIM_AP_ROLE //eLIM_BT_AMP_AP_ROLE */
+ PELOG1(lim_log(pMac, LOG1,
+ FL("*** Peer staId=%d Disassociated ***"),
+ pMlmDisassocInd->aid);
+ )
+ /* Send SME_DISASOC_IND after Polaris cleanup */
+ /* (after receiving LIM_MLM_PURGE_STA_IND) */
+ break;
+ } /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
+} /*** end lim_process_mlm_disassoc_ind() ***/
+
+/**
+ * lim_process_mlm_disassoc_cnf() - Processes disassociation
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: A pointer to the MLM message buffer
+ *
+ * This function is called to processes MLM_DISASSOC_CNF
+ * message from MLM State machine.
+ *
+ * Return: None
+ */
+void lim_process_mlm_disassoc_cnf(tpAniSirGlobal mac_ctx,
+ uint32_t *msg)
+{
+ tSirResultCodes result_code;
+ tLimMlmDisassocCnf *disassoc_cnf;
+ tpPESession session_entry;
+ disassoc_cnf = (tLimMlmDisassocCnf *) msg;
+
+ session_entry =
+ pe_find_session_by_session_id(mac_ctx, disassoc_cnf->sessionId);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session Does not exist for given session Id"));
+ return;
+ }
+ result_code = (tSirResultCodes)(disassoc_cnf->disassocTrigger ==
+ eLIM_LINK_MONITORING_DISASSOC) ?
+ eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
+ disassoc_cnf->resultCode;
+ if (LIM_IS_STA_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_STA_ROLE(session_entry)) {
+ /* Disassociate Confirm from MLM */
+ if ((session_entry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
+ && (session_entry->limSmeState !=
+ eLIM_SME_WT_DEAUTH_STATE)) {
+ /*
+ * Should not have received
+ * Disassocate confirm
+ * from MLM in other states.Log error
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("received MLM_DISASSOC_CNF in state %X"),
+ session_entry->limSmeState);
+ return;
+ }
+ if (mac_ctx->lim.gLimRspReqd)
+ mac_ctx->lim.gLimRspReqd = false;
+ if (disassoc_cnf->disassocTrigger ==
+ eLIM_PROMISCUOUS_MODE_DISASSOC) {
+ if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
+ session_entry->limSmeState =
+ session_entry->limPrevSmeState;
+ else
+ session_entry->limSmeState =
+ eLIM_SME_OFFLINE_STATE;
+ MTRACE(mac_trace
+ (mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ } else {
+ if (disassoc_cnf->resultCode != eSIR_SME_SUCCESS)
+ session_entry->limSmeState =
+ session_entry->limPrevSmeState;
+ else
+ session_entry->limSmeState =
+ eLIM_SME_IDLE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ lim_send_sme_disassoc_ntf(mac_ctx,
+ disassoc_cnf->peerMacAddr, result_code,
+ disassoc_cnf->disassocTrigger,
+ disassoc_cnf->aid, session_entry->smeSessionId,
+ session_entry->transactionId, session_entry);
+ }
+ } else if (LIM_IS_AP_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ lim_send_sme_disassoc_ntf(mac_ctx, disassoc_cnf->peerMacAddr,
+ result_code, disassoc_cnf->disassocTrigger,
+ disassoc_cnf->aid, session_entry->smeSessionId,
+ session_entry->transactionId, session_entry);
+ }
+}
+
+/**
+ * lim_process_mlm_deauth_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_DEAUTH_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_deauth_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tLimMlmDeauthInd *pMlmDeauthInd;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+ pMlmDeauthInd = (tLimMlmDeauthInd *) pMsgBuf;
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pMlmDeauthInd->peerMacAddr, &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("session does not exist for Addr:" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pMlmDeauthInd->peerMacAddr));
+ return;
+ }
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+
+ default: /* eLIM_AP_ROLE */
+ {
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("*** Received Deauthentication from staId=%d ***"),
+ pMlmDeauthInd->aid);
+ )
+ }
+ /* Send SME_DEAUTH_IND after Polaris cleanup */
+ /* (after receiving LIM_MLM_PURGE_STA_IND) */
+ break;
+ } /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
+} /*** end lim_process_mlm_deauth_ind() ***/
+
+/**
+ * lim_process_mlm_deauth_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_DEAUTH_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_deauth_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ uint16_t aid;
+ tSirResultCodes resultCode;
+ tLimMlmDeauthCnf *pMlmDeauthCnf;
+ tpPESession psessionEntry;
+
+ if (pMsgBuf == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+ pMlmDeauthCnf = (tLimMlmDeauthCnf *) pMsgBuf;
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMlmDeauthCnf->sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("session does not exist for given session Id "));
+ )
+ return;
+ }
+
+ resultCode = (tSirResultCodes)
+ (pMlmDeauthCnf->deauthTrigger ==
+ eLIM_LINK_MONITORING_DEAUTH) ?
+ eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE :
+ pMlmDeauthCnf->resultCode;
+ aid = LIM_IS_AP_ROLE(psessionEntry) ? pMlmDeauthCnf->aid : 1;
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ /* Deauth Confirm from MLM */
+ if (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) {
+ /**
+ * Should not have received Deauth confirm
+ * from MLM in other states.
+ * Log error
+ */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received unexpected MLM_DEAUTH_CNF in state %X"),
+ psessionEntry->limSmeState);)
+ return;
+ }
+ if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) {
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ PELOG1(lim_log(pMac, LOG1,
+ FL("*** Deauthenticated with BSS ***"));)
+ } else
+ psessionEntry->limSmeState =
+ psessionEntry->limPrevSmeState;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+
+ if (pMac->lim.gLimRspReqd)
+ pMac->lim.gLimRspReqd = false;
+ }
+ /* On STA or on BASIC AP, send SME_DEAUTH_RSP to host */
+ lim_send_sme_deauth_ntf(pMac, pMlmDeauthCnf->peerMacAddr,
+ resultCode,
+ pMlmDeauthCnf->deauthTrigger,
+ aid, psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+} /*** end lim_process_mlm_deauth_cnf() ***/
+
+/**
+ * lim_process_mlm_purge_sta_ind()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_PURGE_STA_IND
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_purge_sta_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirResultCodes resultCode;
+ tpLimMlmPurgeStaInd pMlmPurgeStaInd;
+ tpPESession psessionEntry;
+ if (pMsgBuf == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+ pMlmPurgeStaInd = (tpLimMlmPurgeStaInd) pMsgBuf;
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMlmPurgeStaInd->sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("session does not exist for given bssId"));
+ )
+ return;
+ }
+ /* Purge STA indication from MLM */
+ resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode;
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+ case eLIM_STA_IN_IBSS_ROLE:
+ break;
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ default: /* eLIM_AP_ROLE */
+ if (LIM_IS_STA_ROLE(psessionEntry) &&
+ (psessionEntry->limSmeState !=
+ eLIM_SME_WT_DISASSOC_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) {
+ /**
+ * Should not have received
+ * Purge STA indication
+ * from MLM in other states.
+ * Log error
+ */
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("received unexpected MLM_PURGE_STA_IND in state %X"),
+ psessionEntry->limSmeState);
+ )
+ break;
+ }
+ PELOG1(lim_log(pMac, LOG1,
+ FL("*** Cleanup completed for staId=%d ***"),
+ pMlmPurgeStaInd->aid);
+ )
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+
+ }
+ if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) {
+ lim_send_sme_deauth_ntf(pMac,
+ pMlmPurgeStaInd->peerMacAddr,
+ resultCode,
+ pMlmPurgeStaInd->purgeTrigger,
+ pMlmPurgeStaInd->aid,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+ } else
+ lim_send_sme_disassoc_ntf(pMac,
+ pMlmPurgeStaInd->peerMacAddr,
+ resultCode,
+ pMlmPurgeStaInd->purgeTrigger,
+ pMlmPurgeStaInd->aid,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId,
+ psessionEntry);
+ } /* end switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) */
+} /*** end lim_process_mlm_purge_sta_ind() ***/
+
+/**
+ * lim_process_mlm_set_keys_cnf()
+ *
+ ***FUNCTION:
+ * This function is called to processes MLM_SETKEYS_CNF
+ * message from MLM State machine.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_set_keys_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ /* Prepare and send SME_SETCONTEXT_RSP message */
+ tLimMlmSetKeysCnf *pMlmSetKeysCnf;
+ tpPESession psessionEntry;
+ uint16_t aid;
+ tpDphHashNode sta_ds;
+
+ if (pMsgBuf == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));)
+ return;
+ }
+ pMlmSetKeysCnf = (tLimMlmSetKeysCnf *) pMsgBuf;
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMlmSetKeysCnf->sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("session does not exist for given sessionId "));
+ )
+ return;
+ }
+ psessionEntry->is_key_installed = 0;
+ lim_log(pMac, LOG1,
+ FL("Received MLM_SETKEYS_CNF with resultCode = %d"),
+ pMlmSetKeysCnf->resultCode);
+ /* if the status is success keys are installed in the
+ * Firmware so we can set the protection bit
+ */
+ if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) {
+ psessionEntry->is_key_installed = 1;
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ sta_ds = dph_lookup_hash_entry(pMac,
+ pMlmSetKeysCnf->peerMacAddr,
+ &aid, &psessionEntry->dph.dphHashTable);
+ if (sta_ds != NULL)
+ sta_ds->is_key_installed = 1;
+ }
+ }
+ lim_send_sme_set_context_rsp(pMac,
+ pMlmSetKeysCnf->peerMacAddr,
+ 1,
+ (tSirResultCodes) pMlmSetKeysCnf->resultCode,
+ psessionEntry, psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+} /*** end lim_process_mlm_set_keys_cnf() ***/
+
+/**
+ * lim_handle_sme_join_result() - Handles sme join result
+ * @mac_ctx: Pointer to Global MAC structure
+ * @result_code: Failure code to be sent
+ * @prot_status_code : Protocol status code
+ * @session_entry: PE session handle
+ *
+ * This function is called to process join/auth/assoc failures
+ * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or
+ * MLM_ASSOC_CNF with a success code in case of STA role and
+ * MLM_JOIN_CNF with success in case of STA in IBSS role.
+ *
+ * Return: None
+ */
+static void
+lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
+ tSirResultCodes result_code, uint16_t prot_status_code,
+ tpPESession session_entry)
+{
+ tpDphHashNode sta_ds = NULL;
+ uint8_t sme_session_id;
+ uint16_t sme_trans_id;
+
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE, FL("psessionEntry is NULL "));
+ return;
+ }
+ sme_session_id = session_entry->smeSessionId;
+ sme_trans_id = session_entry->transactionId;
+ /*
+ * When associations is failed , delete the session created
+ * and pass NULL to limsendsmeJoinReassocRsp()
+ */
+ if (result_code != eSIR_SME_SUCCESS) {
+ sta_ds =
+ dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds != NULL) {
+ sta_ds->mlmStaContext.disassocReason =
+ eSIR_MAC_UNSPEC_FAILURE_REASON;
+ sta_ds->mlmStaContext.cleanupTrigger =
+ eLIM_JOIN_FAILURE;
+ sta_ds->mlmStaContext.resultCode = result_code;
+ sta_ds->mlmStaContext.protStatusCode = prot_status_code;
+ /*
+ * FIX_ME: at the end of lim_cleanup_rx_path,
+ * make sure PE is sending eWNI_SME_JOIN_RSP
+ * to SME
+ */
+ lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
+ cdf_mem_free(session_entry->pLimJoinReq);
+ session_entry->pLimJoinReq = NULL;
+ return;
+ }
+ }
+
+ cdf_mem_free(session_entry->pLimJoinReq);
+ session_entry->pLimJoinReq = NULL;
+ /* Delete teh session if JOIN failure occurred. */
+ if (result_code != eSIR_SME_SUCCESS) {
+ if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
+ session_entry->bssId,
+ session_entry->selfMacAddr, NULL, NULL)
+ != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to set the DownState."));
+ if (lim_set_link_state
+ (mac_ctx, eSIR_LINK_IDLE_STATE,
+ session_entry->bssId,
+ session_entry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to set the LinkState."));
+ pe_delete_session(mac_ctx, session_entry);
+ session_entry = NULL;
+ }
+
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, result_code,
+ prot_status_code, session_entry, sme_session_id, sme_trans_id);
+}
+
+/**
+ * lim_handle_sme_reaasoc_result()
+ *
+ ***FUNCTION:
+ * This function is called to process reassoc failures
+ * upon receiving REASSOC_CNF with a failure code or
+ * MLM_REASSOC_CNF with a success code in case of STA role
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param resultCode Failure code to be sent
+ *
+ *
+ * @return None
+ */
+static void
+lim_handle_sme_reaasoc_result(tpAniSirGlobal pMac, tSirResultCodes resultCode,
+ uint16_t protStatusCode, tpPESession psessionEntry)
+{
+ tpDphHashNode pStaDs = NULL;
+ uint8_t smesessionId;
+ uint16_t smetransactionId;
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("psessionEntry is NULL "));)
+ return;
+ }
+ smesessionId = psessionEntry->smeSessionId;
+ smetransactionId = psessionEntry->transactionId;
+ /* When associations is failed , delete the session created and pass NULL to limsendsmeJoinReassocRsp() */
+ if (resultCode != eSIR_SME_SUCCESS) {
+ pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL) {
+ pStaDs->mlmStaContext.disassocReason =
+ eSIR_MAC_UNSPEC_FAILURE_REASON;
+ pStaDs->mlmStaContext.cleanupTrigger =
+ eLIM_JOIN_FAILURE;
+ pStaDs->mlmStaContext.resultCode = resultCode;
+ pStaDs->mlmStaContext.protStatusCode = protStatusCode;
+ lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
+ return;
+ }
+ }
+ /* Delete teh session if REASSOC failure occurred. */
+ if (resultCode != eSIR_SME_SUCCESS) {
+ if (NULL != psessionEntry) {
+ pe_delete_session(pMac, psessionEntry);
+ psessionEntry = NULL;
+ }
+ }
+ lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP, resultCode,
+ protStatusCode, psessionEntry, smesessionId,
+ smetransactionId);
+} /*** end limHandleSmeReassocResult() ***/
+
+/**
+ * lim_process_mlm_add_sta_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process a WMA_ADD_STA_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+void lim_process_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ /* we need to process the deferred message since the initiating req. there might be nested request. */
+ /* in the case of nested request the new request initiated from the response will take care of resetting */
+ /* the deffered flag. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ if (LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_AP_ROLE(psessionEntry)) {
+ lim_process_ap_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+ lim_process_sta_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
+}
+
+/**
+ * lim_process_sta_mlm_add_sta_rsp () - Process add sta response
+ * @mac_ctx: Pointer to mac context
+ * @msg: tpSirMsgQan Message structure
+ * @session_entry: PE session entry
+ *
+ * Process ADD STA response sent from WMA and posts results
+ * to SME.
+ *
+ * Return: Null
+ */
+
+void lim_process_sta_mlm_add_sta_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg, tpPESession session_entry)
+{
+ tLimMlmAssocCnf mlm_assoc_cnf;
+ tpDphHashNode sta_ds;
+ uint32_t msg_type = LIM_MLM_ASSOC_CNF;
+ tpAddStaParams add_sta_params = (tpAddStaParams) msg->bodyptr;
+ tpPESession ft_session = NULL;
+ uint8_t ft_session_id;
+
+ if (NULL == add_sta_params) {
+ lim_log(mac_ctx, LOGE, FL("Encountered NULL Pointer"));
+ return;
+ }
+
+ if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
+ msg_type = LIM_MLM_REASSOC_CNF;
+
+ if (true == session_entry->fDeauthReceived) {
+ lim_log(mac_ctx, LOGE,
+ FL("Received Deauth frame in ADD_STA_RESP state"));
+ if (CDF_STATUS_SUCCESS == add_sta_params->status) {
+ lim_log(mac_ctx, LOGE,
+ FL("ADD_STA success, send update result code with eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA staIdx: %d limMlmState: %d"),
+ add_sta_params->staIdx,
+ session_entry->limMlmState);
+
+ if (session_entry->limSmeState ==
+ eLIM_SME_WT_REASSOC_STATE)
+ msg_type = LIM_MLM_REASSOC_CNF;
+ /*
+ * We are sending result code
+ * eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA which
+ * will trigger proper cleanup (DEL_STA/DEL_BSS both
+ * required) in either assoc cnf or reassoc cnf handler.
+ */
+ mlm_assoc_cnf.resultCode =
+ eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA;
+ session_entry->staId = add_sta_params->staIdx;
+ goto end;
+ }
+ }
+
+ if (CDF_STATUS_SUCCESS == add_sta_params->status) {
+ if (eLIM_MLM_WT_ADD_STA_RSP_STATE !=
+ session_entry->limMlmState) {
+ lim_log(mac_ctx, LOGE,
+ FL("Received WMA_ADD_STA_RSP in state %X"),
+ session_entry->limMlmState);
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) {
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ /* check if we have keys(PTK)to install in case of 11r */
+ tpftPEContext ft_ctx = &session_entry->ftPEContext;
+ ft_session = pe_find_session_by_bssid(mac_ctx,
+ session_entry->limReAssocbssId, &ft_session_id);
+ if (ft_session != NULL &&
+ ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid
+ == true) {
+ tpLimMlmSetKeysReq pMlmStaKeys =
+ &ft_ctx->PreAuthKeyInfo.extSetStaKeyParam;
+ lim_send_set_sta_key_req(mac_ctx, pMlmStaKeys,
+ 0, 0, ft_session, false);
+ ft_ctx->PreAuthKeyInfo.extSetStaKeyParamValid =
+ false;
+ }
+#endif
+ }
+ /*
+ * Update the DPH Hash Entry for this STA
+ * with proper state info
+ */
+ sta_ds =
+ dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (NULL != sta_ds)
+ sta_ds->mlmStaContext.mlmState =
+ eLIM_MLM_LINK_ESTABLISHED_STATE;
+ else
+ lim_log(mac_ctx, LOGW,
+ FL("Fail to get DPH Hash Entry for AID - %d"),
+ DPH_STA_HASH_INDEX_PEER);
+ session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId,
+ session_entry->limMlmState));
+ /*
+ * Storing the self StaIndex(Generated by HAL) in
+ * session context, instead of storing it in DPH Hash
+ * entry for Self STA.
+ * DPH entry for the self STA stores the sta index for
+ * the BSS entry to which the STA is associated
+ */
+ session_entry->staId = add_sta_params->staIdx;
+
+#ifdef WLAN_DEBUG
+ mac_ctx->lim.gLimNumLinkEsts++;
+#endif
+#ifdef FEATURE_WLAN_TDLS
+ /* initialize TDLS peer related data */
+ lim_init_tdls_data(mac_ctx, session_entry);
+#endif
+ /*
+ * Return Assoc confirm to SME with success
+ * FIXME - Need the correct ASSOC RSP code to
+ * be passed in here
+ */
+ mlm_assoc_cnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS;
+ } else {
+ lim_log(mac_ctx, LOGE, FL("ADD_STA failed!"));
+ if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE)
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
+ else
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+end:
+ if (NULL != msg->bodyptr) {
+ cdf_mem_free(add_sta_params);
+ msg->bodyptr = NULL;
+ }
+ /* Updating PE session Id */
+ mlm_assoc_cnf.sessionId = session_entry->peSessionId;
+ lim_post_sme_message(mac_ctx, msg_type, (uint32_t *) &mlm_assoc_cnf);
+ if (true == session_entry->fDeauthReceived)
+ session_entry->fDeauthReceived = false;
+ return;
+}
+
+void lim_process_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ /* we need to process the deferred message since the initiating req. there might be nested request. */
+ /* in the case of nested request the new request initiated from the response will take care of resetting */
+ /* the deffered flag. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pMac->sys.gSysFrameCount[SIR_MAC_MGMT_FRAME][SIR_MAC_MGMT_DEAUTH] = 0;
+
+ if ((LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry) ||
+ LIM_IS_AP_ROLE(psessionEntry)) &&
+ (psessionEntry->statypeForBss == STA_ENTRY_SELF)) {
+ lim_process_bt_amp_ap_mlm_del_bss_rsp(pMac, limMsgQ, psessionEntry);
+ return;
+ }
+ lim_process_sta_mlm_del_bss_rsp(pMac, limMsgQ, psessionEntry);
+
+#ifdef WLAN_FEATURE_11W
+ if (psessionEntry->limRmfEnabled) {
+ if (eSIR_SUCCESS !=
+ lim_send_exclude_unencrypt_ind(pMac, true, psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Could not send down Exclude Unencrypted Indication!"));
+ }
+ }
+#endif
+}
+
+void lim_process_sta_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+
+ if (NULL == pDelBssParams) {
+ lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
+ goto end;
+ }
+ if (CDF_STATUS_SUCCESS == pDelBssParams->status) {
+ PELOGW(lim_log(pMac, LOGW,
+ FL("STA received the DEL_BSS_RSP for BSSID: %X."),
+ pDelBssParams->bssIdx);
+ )
+ if (lim_set_link_state
+ (pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Failure in setting link state to IDLE"));
+ )
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (pStaDs == NULL) {
+ lim_log(pMac, LOGE, FL("DPH Entry for STA 1 missing."));
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (eLIM_MLM_WT_DEL_BSS_RSP_STATE !=
+ pStaDs->mlmStaContext.mlmState) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("Received unexpected WMA_DEL_BSS_RSP in state %X"),
+ pStaDs->mlmStaContext.mlmState);
+ )
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ PELOG1(lim_log
+ (pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId);
+ lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
+ )
+ } else {
+ lim_log(pMac, LOGE, FL("DEL BSS failed!"));
+ statusCode = eSIR_SME_STOP_BSS_FAILURE;
+ }
+end:
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pDelBssParams);
+ limMsgQ->bodyptr = NULL;
+ }
+ if (pStaDs == NULL)
+ return;
+ if ((LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
+ (psessionEntry->limSmeState !=
+ eLIM_SME_WT_DISASSOC_STATE &&
+ psessionEntry->limSmeState !=
+ eLIM_SME_WT_DEAUTH_STATE) &&
+ pStaDs->mlmStaContext.cleanupTrigger !=
+ eLIM_JOIN_FAILURE) {
+ /** The Case where the DelBss is invoked from
+ * context of other than normal DisAssoc / Deauth OR
+ * as part of Join Failure.
+ */
+ lim_handle_del_bss_in_re_assoc_context(pMac, pStaDs, psessionEntry);
+ return;
+ }
+ lim_prepare_and_send_del_sta_cnf(pMac, pStaDs, statusCode, psessionEntry);
+ return;
+}
+
+void lim_process_bt_amp_ap_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tSirResultCodes rc = eSIR_SME_SUCCESS;
+ tSirRetStatus status;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr;
+ tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE, FL("Session entry passed is NULL"));
+ if (pDelBss != NULL) {
+ cdf_mem_free(pDelBss);
+ limMsgQ->bodyptr = NULL;
+ }
+ return;
+ }
+
+ if (pDelBss == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("BSS: DEL_BSS_RSP with no body!"));)
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
+ pMac->lim.gLimMlmState));
+
+ if (eLIM_MLM_WT_DEL_BSS_RSP_STATE != psessionEntry->limMlmState) {
+ lim_log(pMac, LOGE,
+ FL("Received unexpected WMA_DEL_BSS_RSP in state %X"),
+ psessionEntry->limMlmState);
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (pDelBss->status != CDF_STATUS_SUCCESS) {
+ lim_log(pMac, LOGE, FL("BSS: DEL_BSS_RSP error (%x) Bss %d "),
+ pDelBss->status, pDelBss->bssIdx);
+ rc = eSIR_SME_STOP_BSS_FAILURE;
+ goto end;
+ }
+ status = lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
+ psessionEntry->selfMacAddr, NULL, NULL);
+ if (status != eSIR_SUCCESS) {
+ rc = eSIR_SME_REFUSED;
+ goto end;
+ }
+ /** Softmac may send all the buffered packets right after resuming the transmission hence
+ * to occupy the medium during non channel occupancy period. So resume the transmission after
+ * HAL gives back the response.
+ */
+ dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
+ lim_delete_pre_auth_list(pMac);
+ /* Initialize number of associated stations during cleanup */
+ psessionEntry->gLimNumOfCurrentSTAs = 0;
+end:
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+ pe_delete_session(pMac, psessionEntry);
+
+ if (pDelBss != NULL) {
+ cdf_mem_free(pDelBss);
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+/**
+ * lim_process_mlm_del_sta_rsp() - Process DEL STA response
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process a WMA_DEL_STA_RSP from
+ * WMA Upon receipt of this message from FW.
+ *
+ * Return: None
+ */
+void lim_process_mlm_del_sta_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg)
+{
+ /*
+ * we need to process the deferred message since the
+ * initiating req. there might be nested request
+ * in the case of nested request the new request
+ * initiated from the response will take care of resetting
+ * the deffered flag.
+ */
+ tpPESession session_entry;
+ tpDeleteStaParams del_sta_params;
+ del_sta_params = (tpDeleteStaParams) msg->bodyptr;
+ if (NULL == del_sta_params) {
+ lim_log(mac_ctx, LOGE,
+ FL("null pointer del_sta_params msg"));
+ return;
+ }
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ del_sta_params->sessionId);
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGP,
+ FL("Session Doesn't exist"));
+ cdf_mem_free(del_sta_params);
+ msg->bodyptr = NULL;
+ return;
+ }
+
+ if (LIM_IS_BT_AMP_AP_ROLE(session_entry) ||
+ LIM_IS_AP_ROLE(session_entry)) {
+ lim_process_bt_amp_ap_mlm_del_sta_rsp(mac_ctx, msg,
+ session_entry);
+ return;
+ }
+ lim_process_sta_mlm_del_sta_rsp(mac_ctx, msg, session_entry);
+}
+
+void lim_process_bt_amp_ap_mlm_del_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs;
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+ if (limMsgQ->bodyptr == NULL) {
+ lim_log(pMac, LOGE, FL("limMsgQ->bodyptry NULL"));
+ return;
+ }
+
+ pStaDs =
+ dph_get_hash_entry(pMac, pDelStaParams->assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ lim_log(pMac, LOGE,
+ FL("DPH Entry for STA %X missing."),
+ pDelStaParams->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ cdf_mem_free(pDelStaParams);
+ limMsgQ->bodyptr = NULL;
+
+ return;
+ }
+ lim_log(pMac, LOG1, FL("Received del Sta Rsp in StaD MlmState : %d"),
+ pStaDs->mlmStaContext.mlmState);
+ if (CDF_STATUS_SUCCESS == pDelStaParams->status) {
+ lim_log(pMac, LOGW,
+ FL("AP received the DEL_STA_RSP for assocID: %X."),
+ pDelStaParams->assocId);
+
+ if ((eLIM_MLM_WT_DEL_STA_RSP_STATE !=
+ pStaDs->mlmStaContext.mlmState)
+ && (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
+ pStaDs->mlmStaContext.mlmState)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Received unexpected WMA_DEL_STA_RSP in state %s for staId %d assocId %d "),
+ lim_mlm_state_str(pStaDs->mlmStaContext.mlmState),
+ pStaDs->staIndex, pStaDs->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+
+ lim_log(pMac, LOG1,
+ FL("Deleted STA AssocID %d staId %d MAC "),
+ pStaDs->assocId, pStaDs->staIndex);
+ lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
+ if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE ==
+ pStaDs->mlmStaContext.mlmState) {
+ cdf_mem_free(pDelStaParams);
+ limMsgQ->bodyptr = NULL;
+ if (lim_add_sta(pMac, pStaDs, false, psessionEntry) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not Add STA with assocId=%d"),
+ pStaDs->assocId);
+ )
+ /* delete the TS if it has already been added. */
+ /* send the response with error status. */
+ if (pStaDs->qos.addtsPresent) {
+ tpLimTspecInfo pTspecInfo;
+ if (eSIR_SUCCESS ==
+ lim_tspec_find_by_assoc_id(pMac,
+ pStaDs->assocId,
+ &pStaDs->qos.addts.tspec,
+ &pMac->lim.tspecInfo[0],
+ &pTspecInfo)) {
+ lim_admit_control_delete_ts(pMac,
+ pStaDs->
+ assocId,
+ &pStaDs->
+ qos.
+ addts.
+ tspec.
+ tsinfo,
+ NULL,
+ &pTspecInfo->
+ idx);
+ }
+ }
+ lim_reject_association(pMac,
+ pStaDs->staAddr,
+ pStaDs->mlmStaContext.
+ subType, true,
+ pStaDs->mlmStaContext.
+ authType, pStaDs->assocId,
+ true,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ }
+ return;
+ }
+ } else {
+ lim_log(pMac, LOGW, FL("DEL STA failed!"));
+ statusCode = eSIR_SME_REFUSED;
+ }
+end:
+ cdf_mem_free(pDelStaParams);
+ limMsgQ->bodyptr = NULL;
+ if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
+ pStaDs->mlmStaContext.mlmState) {
+ lim_prepare_and_send_del_sta_cnf(pMac, pStaDs, statusCode,
+ psessionEntry);
+ }
+ return;
+}
+
+void lim_process_sta_mlm_del_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tSirResultCodes statusCode = eSIR_SME_SUCCESS;
+ tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = NULL;
+ if (NULL == pDelStaParams) {
+ lim_log(pMac, LOGE, FL("Encountered NULL Pointer"));
+ goto end;
+ }
+ if (CDF_STATUS_SUCCESS == pDelStaParams->status) {
+ pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ /* TODO: any response to be sent out here ? */
+ lim_log(pMac, LOGE, FL("DPH Entry for STA %X missing."),
+ pDelStaParams->assocId);
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ if (eLIM_MLM_WT_DEL_STA_RSP_STATE != psessionEntry->limMlmState) {
+ /* TODO: any response to be sent out here ? */
+ lim_log(pMac, LOGE,
+ FL
+ ("Received unexpected WMA_DELETE_STA_RSP in state %s"),
+ lim_mlm_state_str(psessionEntry->limMlmState));
+ statusCode = eSIR_SME_REFUSED;
+ goto end;
+ }
+ PELOG1(lim_log
+ (pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId);
+ lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
+ )
+ lim_log(pMac, LOGW,
+ FL("DEL_STA_RSP received for assocID: %X"),
+ pDelStaParams->assocId);
+ /* we must complete all cleanup related to delSta before calling limDelBSS. */
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pDelStaParams);
+ limMsgQ->bodyptr = NULL;
+ }
+ statusCode =
+ (tSirResultCodes) lim_del_bss(pMac, pStaDs, 0, psessionEntry);
+ return;
+ } else {
+ lim_log(pMac, LOGE, FL("DEL_STA failed for sta Id %d"),
+ pDelStaParams->staIdx);
+ statusCode = eSIR_SME_REFUSED;
+ }
+end:
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pDelStaParams);
+ limMsgQ->bodyptr = NULL;
+ }
+ return;
+}
+
+void lim_process_ap_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
+ tpDphHashNode pStaDs = NULL;
+
+ if (NULL == pAddStaParams) {
+ lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
+ goto end;
+ }
+
+ pStaDs =
+ dph_get_hash_entry(pMac, pAddStaParams->assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ /* TODO: any response to be sent out here ? */
+ lim_log(pMac, LOGE, FL("DPH Entry for STA %X missing."),
+ pAddStaParams->assocId);
+ goto end;
+ }
+ /* */
+ /* TODO & FIXME_GEN4 */
+ /* Need to inspect tSirMsgQ.reserved for a valid Dialog token! */
+ /* */
+ /* TODO: any check for pMac->lim.gLimMlmState ? */
+ if (eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) {
+ /* TODO: any response to be sent out here ? */
+ lim_log(pMac, LOGE,
+ FL("Received unexpected WMA_ADD_STA_RSP in state %X"),
+ pStaDs->mlmStaContext.mlmState);
+ goto end;
+ }
+ if (CDF_STATUS_SUCCESS != pAddStaParams->status) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Error! rcvd delSta rsp from HAL with status %d"),
+ pAddStaParams->status);
+ )
+ lim_reject_association(pMac, pStaDs->staAddr,
+ pStaDs->mlmStaContext.subType,
+ true, pStaDs->mlmStaContext.authType,
+ pStaDs->assocId, true,
+ (tSirResultCodes)
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ psessionEntry);
+ goto end;
+ }
+ pStaDs->bssId = pAddStaParams->bssIdx;
+ pStaDs->staIndex = pAddStaParams->staIdx;
+ /* if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state */
+ pStaDs->valid = 1;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE;
+ lim_log(pMac, LOG1,
+ FL("AddStaRsp Success.STA AssocID %d staId %d MAC "),
+ pStaDs->assocId, pStaDs->staIndex);
+ lim_print_mac_addr(pMac, pStaDs->staAddr, LOG1);
+
+ /* For BTAMP-AP, the flow sequence shall be:
+ * 1) PE sends eWNI_SME_ASSOC_IND to SME
+ * 2) PE receives eWNI_SME_ASSOC_CNF from SME
+ * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA
+ */
+ lim_send_mlm_assoc_ind(pMac, pStaDs, psessionEntry);
+ /* fall though to reclaim the original Add STA Response message */
+end:
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pAddStaParams);
+ limMsgQ->bodyptr = NULL;
+ }
+ return;
+}
+
+/**
+ * lim_process_ap_mlm_add_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WMA_ADD_BSS_REQ
+ * > Init other remaining LIM variables
+ * > Init the AID pool, for that BSSID
+ * > Init the Pre-AUTH list, for that BSSID
+ * > Create LIM timers, specific to that BSSID
+ * > Init DPH related parameters that are specific to that BSSID
+ * > TODO - When do we do the actual change channel?
+ *
+ ***LOGIC:
+ * SME sends eWNI_SME_START_BSS_REQ to LIM
+ * LIM sends LIM_MLM_START_REQ to MLME
+ * MLME sends WMA_ADD_BSS_REQ to HAL
+ * HAL responds with WMA_ADD_BSS_RSP to MLME
+ * MLME responds with LIM_MLM_START_CNF to LIM
+ * LIM responds with eWNI_SME_START_BSS_RSP to SME
+ *
+ ***ASSUMPTIONS:
+ * tSirMsgQ.body is allocated by MLME during lim_process_mlm_start_req
+ * tSirMsgQ.body will now be freed by this routine
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+static void lim_process_ap_mlm_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tpPESession psessionEntry;
+ uint8_t isWepEnabled = false;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ if (NULL == pAddBssParams) {
+ lim_log(pMac, LOGE, FL("Encountered NULL Pointer"));
+ goto end;
+ }
+ /* TBD: free the memory before returning, do it for all places where lookup fails. */
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pAddBssParams->sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("session does not exist for given sessionId"));
+ )
+ if (NULL != pAddBssParams) {
+ cdf_mem_free(pAddBssParams);
+ limMsgQ->bodyptr = NULL;
+ }
+ return;
+ }
+ /* Update PE session Id */
+ mlmStartCnf.sessionId = pAddBssParams->sessionId;
+ if (CDF_STATUS_SUCCESS == pAddBssParams->status) {
+ PELOG2(lim_log
+ (pMac, LOG2,
+ FL("WMA_ADD_BSS_RSP returned with CDF_STATUS_SUCCESS"));
+ )
+ if (lim_set_link_state
+ (pMac, eSIR_LINK_AP_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS)
+ goto end;
+ /* Set MLME state */
+ psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+ psessionEntry->chainMask = pAddBssParams->chainMask;
+ psessionEntry->smpsMode = pAddBssParams->smpsMode;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+ if (eSIR_IBSS_MODE == pAddBssParams->bssType) {
+ /** IBSS is 'active' when we receive
+ * Beacon frames from other STAs that are part of same IBSS.
+ * Mark internal state as inactive until then.
+ */
+ psessionEntry->limIbssActive = false;
+ psessionEntry->statypeForBss = STA_ENTRY_PEER; /* to know session created for self/peer */
+ limResetHBPktCount(psessionEntry);
+ }
+ psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+
+ if (eSIR_INFRA_AP_MODE == pAddBssParams->bssType)
+ psessionEntry->limSystemRole = eLIM_AP_ROLE;
+ else
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+ sch_edca_profile_update(pMac, psessionEntry);
+ lim_init_pre_auth_list(pMac);
+ /* Check the SAP security configuration.If configured to
+ * WEP then max clients supported is 16
+ */
+ if (psessionEntry->privacy) {
+ if ((psessionEntry->gStartBssRSNIe.present)
+ || (psessionEntry->gStartBssWPAIe.present))
+ lim_log(pMac, LOG1,
+ FL("WPA/WPA2 SAP configuration\n"));
+ else {
+ if (pMac->lim.gLimAssocStaLimit >
+ MAX_SUPPORTED_PEERS_WEP) {
+ lim_log(pMac, LOG1,
+ FL("WEP SAP Configuration\n"));
+ pMac->lim.gLimAssocStaLimit =
+ MAX_SUPPORTED_PEERS_WEP;
+ isWepEnabled = true;
+ }
+ }
+ }
+ lim_init_peer_idxpool(pMac, psessionEntry);
+
+ /* Start OLBC timer */
+ if (tx_timer_activate
+ (&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) !=
+ TX_SUCCESS) {
+ lim_log(pMac, LOGE, FL("tx_timer_activate failed"));
+ }
+
+ /* Apply previously set configuration at HW */
+ lim_apply_configuration(pMac, psessionEntry);
+
+ /* In lim_apply_configuration gLimAssocStaLimit is assigned from cfg.
+ * So update the value to 16 in case SoftAP is configured in WEP.
+ */
+ if ((pMac->lim.gLimAssocStaLimit > MAX_SUPPORTED_PEERS_WEP)
+ && (isWepEnabled))
+ pMac->lim.gLimAssocStaLimit = MAX_SUPPORTED_PEERS_WEP;
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+ mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+ } else {
+ lim_log(pMac, LOGE, FL("WMA_ADD_BSS_REQ failed with status %d"),
+ pAddBssParams->status);
+ mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ lim_post_sme_message(pMac, LIM_MLM_START_CNF, (uint32_t *) &mlmStartCnf);
+end:
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pAddBssParams);
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+/**
+ * lim_process_ibss_mlm_add_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WMA_ADD_BSS_REQ
+ * > Init other remaining LIM variables
+ * > Init the AID pool, for that BSSID
+ * > Init the Pre-AUTH list, for that BSSID
+ * > Create LIM timers, specific to that BSSID
+ * > Init DPH related parameters that are specific to that BSSID
+ * > TODO - When do we do the actual change channel?
+ *
+ ***LOGIC:
+ * SME sends eWNI_SME_START_BSS_REQ to LIM
+ * LIM sends LIM_MLM_START_REQ to MLME
+ * MLME sends WMA_ADD_BSS_REQ to HAL
+ * HAL responds with WMA_ADD_BSS_RSP to MLME
+ * MLME responds with LIM_MLM_START_CNF to LIM
+ * LIM responds with eWNI_SME_START_BSS_RSP to SME
+ *
+ ***ASSUMPTIONS:
+ * tSirMsgQ.body is allocated by MLME during lim_process_mlm_start_req
+ * tSirMsgQ.body will now be freed by this routine
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param tSirMsgQ The MsgQ header, which contains the response buffer
+ *
+ * @return None
+ */
+static void
+lim_process_ibss_mlm_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+
+ if (NULL == pAddBssParams) {
+ lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
+ goto end;
+ }
+ if (CDF_STATUS_SUCCESS == pAddBssParams->status) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("WMA_ADD_BSS_RSP returned with CDF_STATUS_SUCCESS"));
+ )
+ if (lim_set_link_state
+ (pMac, eSIR_LINK_IBSS_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS)
+ goto end;
+ /* Set MLME state */
+ psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+ /** IBSS is 'active' when we receive
+ * Beacon frames from other STAs that are part of same IBSS.
+ * Mark internal state as inactive until then.
+ */
+ psessionEntry->limIbssActive = false;
+ limResetHBPktCount(psessionEntry);
+ psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+ psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+ psessionEntry->statypeForBss = STA_ENTRY_SELF;
+ sch_edca_profile_update(pMac, psessionEntry);
+ if (0 == psessionEntry->freePeerIdxHead)
+ lim_init_peer_idxpool(pMac, psessionEntry);
+
+ /* Apply previously set configuration at HW */
+ lim_apply_configuration(pMac, psessionEntry);
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+ mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+ /* If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM */
+ if (true == pMac->lim.gLimIbssCoalescingHappened) {
+ lim_ibss_add_bss_rsp_when_coalescing(pMac, limMsgQ->bodyptr,
+ psessionEntry);
+ goto end;
+ }
+ } else {
+ lim_log(pMac, LOGE, FL("WMA_ADD_BSS_REQ failed with status %d"),
+ pAddBssParams->status);
+ mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ /* Send this message to SME, when ADD_BSS is initiated by SME */
+ /* If ADD_BSS is done as part of coalescing, this won't happen. */
+ /* Update PE session Id */
+ mlmStartCnf.sessionId = psessionEntry->peSessionId;
+ lim_post_sme_message(pMac, LIM_MLM_START_CNF, (uint32_t *) &mlmStartCnf);
+end:
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pAddBssParams);
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+/**
+ * csr_neighbor_roam_handoff_req_hdlr - Processes handoff request
+ * @mac_ctx: Pointer to mac context
+ * @msg: message sent to HDD
+ * @session_entry: PE session handle
+ *
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL if the state is pre assoc.
+ *
+ * Return: Null
+ */
+static void
+lim_process_sta_add_bss_rsp_pre_assoc(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg, tpPESession session_entry)
+{
+ tpAddBssParams pAddBssParams = (tpAddBssParams) msg->bodyptr;
+ tAniAuthType cfgAuthType, authMode;
+ tLimMlmAuthReq *pMlmAuthReq;
+ tpDphHashNode pStaDs = NULL;
+
+ if (NULL == pAddBssParams) {
+ lim_log(mac_ctx, LOGE, FL("Invalid body pointer in message"));
+ goto joinFailure;
+ }
+ if (CDF_STATUS_SUCCESS == pAddBssParams->status) {
+ pStaDs = dph_add_hash_entry(mac_ctx,
+ pAddBssParams->staContext.staMac,
+ DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ /* Could not add hash table entry */
+ lim_log(mac_ctx, LOGE,
+ FL("could not add hash entry at DPH for "));
+ lim_print_mac_addr(mac_ctx,
+ pAddBssParams->staContext.staMac, LOGE);
+ goto joinFailure;
+ }
+ session_entry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+ /* Success, handle below */
+ pStaDs->bssId = pAddBssParams->bssIdx;
+ /* STA Index(genr by HAL) for the BSS entry is stored here */
+ pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+ /* Trigger Authentication with AP */
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_AUTHENTICATION_TYPE,
+ (uint32_t *) &cfgAuthType) != eSIR_SUCCESS) {
+ /*
+ * Could not get AuthType from CFG.
+ * Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve AuthType"));
+ }
+ /* Try Open Authentication first */
+ if (cfgAuthType == eSIR_AUTO_SWITCH)
+ authMode = eSIR_OPEN_SYSTEM;
+ else
+ authMode = cfgAuthType;
+
+ /* Trigger MAC based Authentication */
+ pMlmAuthReq = cdf_mem_malloc(sizeof(tLimMlmAuthReq));
+ if (NULL == pMlmAuthReq) {
+ lim_log(mac_ctx, LOGP,
+ FL("Allocate Memory failed for mlmAuthReq"));
+ return;
+ }
+ sir_copy_mac_addr(pMlmAuthReq->peerMacAddr,
+ session_entry->bssId);
+
+ pMlmAuthReq->authType = authMode;
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ (uint32_t *) &pMlmAuthReq->authFailureTimeout)
+ != eSIR_SUCCESS) {
+ /*
+ * Could not get AuthFailureTimeout
+ * value from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("Fail: retrieve AuthFailureTimeout value"));
+ }
+ session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
+ pMlmAuthReq->sessionId = session_entry->peSessionId;
+ session_entry->limPrevSmeState = session_entry->limSmeState;
+ session_entry->limSmeState = eLIM_SME_WT_AUTH_STATE;
+ /* remember staId in case of assoc timeout/failure handling */
+ session_entry->staId = pAddBssParams->staContext.staIdx;
+
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ lim_log(mac_ctx, LOG1,
+ FL("SessionId:%d lim_post_mlm_message "
+ "LIM_MLM_AUTH_REQ with limSmeState:%d"),
+ session_entry->peSessionId, session_entry->limSmeState);
+ lim_post_mlm_message(mac_ctx, LIM_MLM_AUTH_REQ,
+ (uint32_t *) pMlmAuthReq);
+ return;
+ }
+
+joinFailure:
+ {
+ session_entry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+
+ /* Send Join response to Host */
+ lim_handle_sme_join_result(mac_ctx, eSIR_SME_REFUSED,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS, session_entry);
+ }
+
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/*------------------------------------------------------------------------------------------
+ *
+ * Function to handle WMA_ADD_BSS_RSP, in FT reassoc state.
+ * Function to Send ReAssociation Request.
+ *
+ *
+ ***------------------------------------------------------------------------------------------
+ */
+static inline void
+lim_process_sta_mlm_add_bss_rsp_ft(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
+ tpDphHashNode pStaDs = NULL;
+ tpAddStaParams pAddStaParams = NULL;
+ uint32_t listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+ uint32_t selfStaDot11Mode = 0;
+
+ /* Sanity Checks */
+
+ if (pAddBssParams == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Invalid parameters"));)
+ goto end;
+ }
+ if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE !=
+ psessionEntry->limMlmState) {
+ goto end;
+ }
+
+ pStaDs = dph_add_hash_entry(pMac, pAddBssParams->bssId,
+ DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ /* Could not add hash table entry */
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not add hash entry at DPH for "));
+ )
+ lim_print_mac_addr(pMac, pAddBssParams->staContext.staMac,
+ LOGE);
+ goto end;
+ }
+ /* Prepare and send Reassociation request frame */
+ /* start reassoc timer. */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (psessionEntry->bRoamSynchInProgress != true) {
+#endif
+ pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
+ psessionEntry->peSessionId;
+ /* / Start reassociation failure timer */
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE,
+ psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
+ if (tx_timer_activate
+ (&pMac->lim.limTimers.gLimReassocFailureTimer)
+ != TX_SUCCESS) {
+ /* / Could not start reassoc failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not start Reassociation failure timer"));
+ /* Return Reassoc confirm with */
+ /* Resources Unavailable */
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ goto end;
+ }
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ pMac->lim.pSessionEntry = psessionEntry;
+ if (NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) {
+ /* Take a copy of reassoc request for retrying */
+ pMac->lim.pSessionEntry->pLimMlmReassocRetryReq =
+ cdf_mem_malloc(sizeof(tLimMlmReassocReq));
+ if (NULL ==
+ pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)
+ goto end;
+ cdf_mem_set(pMac->lim.pSessionEntry->
+ pLimMlmReassocRetryReq,
+ sizeof(tLimMlmReassocReq), 0);
+ cdf_mem_copy(pMac->lim.pSessionEntry->
+ pLimMlmReassocRetryReq,
+ psessionEntry->pLimMlmReassocReq,
+ sizeof(tLimMlmReassocReq));
+ }
+ pMac->lim.reAssocRetryAttempt = 0;
+#endif
+ lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac,
+ psessionEntry->
+ pLimMlmReassocReq,
+ psessionEntry);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+} else {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:Do not activate timer and dont send the reassoc req");
+}
+#endif
+ psessionEntry->limPrevMlmState = psessionEntry->limMlmState;
+ psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ eLIM_MLM_WT_FT_REASSOC_RSP_STATE));
+ PELOGE(lim_log
+ (pMac, LOG1, FL("Set the mlm state to %d session=%d"),
+ psessionEntry->limMlmState, psessionEntry->peSessionId);
+ )
+
+ psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+
+ /* Success, handle below */
+ pStaDs->bssId = pAddBssParams->bssIdx;
+ /* STA Index(genr by HAL) for the BSS entry is stored here */
+ pStaDs->staIndex = pAddBssParams->staContext.staIdx;
+ pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig;
+ pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig;
+
+#if defined WLAN_FEATURE_VOWIFI
+ rrm_cache_mgmt_tx_power(pMac, pAddBssParams->txMgmtPower, psessionEntry);
+#endif
+
+ pAddStaParams = cdf_mem_malloc(sizeof(tAddStaParams));
+ if (NULL == pAddStaParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during ADD_STA"));
+ goto end;
+ }
+ cdf_mem_set((uint8_t *) pAddStaParams, sizeof(tAddStaParams), 0);
+
+ /* / Add STA context at MAC HW (BMU, RHP & TFP) */
+ cdf_mem_copy((uint8_t *) pAddStaParams->staMac,
+ (uint8_t *) psessionEntry->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) pAddStaParams->bssId,
+ psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ pAddStaParams->staType = STA_ENTRY_SELF;
+ pAddStaParams->status = CDF_STATUS_SUCCESS;
+ pAddStaParams->respReqd = 1;
+
+ /* Update PE session ID */
+ pAddStaParams->sessionId = psessionEntry->peSessionId;
+ pAddStaParams->smesessionId = psessionEntry->smeSessionId;
+
+ /* This will indicate HAL to "allocate" a new STA index */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (psessionEntry->bRoamSynchInProgress != true)
+#endif
+ pAddStaParams->staIdx = STA_INVALID_IDX;
+ pAddStaParams->updateSta = false;
+
+ pAddStaParams->shortPreambleSupported =
+ (uint8_t) psessionEntry->beaconParams.fShortPreamble;
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_peer_rate_set(pMac, &pAddStaParams->supportedRates, NULL,
+ false, psessionEntry, NULL);
+#else
+ lim_populate_peer_rate_set(pMac, &pAddStaParams->supportedRates, NULL,
+ false, psessionEntry);
+#endif
+
+ if (psessionEntry->htCapability) {
+ pAddStaParams->htCapable = psessionEntry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ pAddStaParams->vhtCapable = psessionEntry->vhtCapability;
+ pAddStaParams->ch_width = psessionEntry->ch_width;
+#endif
+
+ pAddStaParams->greenFieldCapable =
+ lim_get_ht_capability(pMac, eHT_GREENFIELD,
+ psessionEntry);
+ pAddStaParams->mimoPS =
+ lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
+ psessionEntry);
+ pAddStaParams->rifsMode =
+ lim_get_ht_capability(pMac, eHT_RIFS_MODE, psessionEntry);
+ pAddStaParams->lsigTxopProtection =
+ lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
+ psessionEntry);
+ pAddStaParams->maxAmpduDensity =
+ lim_get_ht_capability(pMac, eHT_MPDU_DENSITY, psessionEntry);
+ pAddStaParams->maxAmpduSize =
+ lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
+ psessionEntry);
+ pAddStaParams->maxAmsduSize =
+ lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
+ psessionEntry);
+ pAddStaParams->fDsssCckMode40Mhz =
+ lim_get_ht_capability(pMac, eHT_DSSS_CCK_MODE_40MHZ,
+ psessionEntry);
+ pAddStaParams->fShortGI20Mhz =
+ lim_get_ht_capability(pMac, eHT_SHORT_GI_20MHZ, psessionEntry);
+ pAddStaParams->fShortGI40Mhz =
+ lim_get_ht_capability(pMac, eHT_SHORT_GI_40MHZ, psessionEntry);
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
+ pAddStaParams->listenInterval = (uint16_t) listenInterval;
+
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
+ pAddStaParams->supportedRates.opRateMode =
+ lim_get_sta_rate_mode((uint8_t) selfStaDot11Mode);
+ pAddStaParams->encryptType = psessionEntry->encryptType;
+ pAddStaParams->maxTxPower = psessionEntry->maxTxPower;
+
+ /* Lets save this for when we receive the Reassoc Rsp */
+ psessionEntry->ftPEContext.pAddStaReq = pAddStaParams;
+
+ if (pAddBssParams != NULL) {
+ cdf_mem_free(pAddBssParams);
+ pAddBssParams = NULL;
+ limMsgQ->bodyptr = NULL;
+ }
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (psessionEntry->bRoamSynchInProgress) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:Prepare and save pAddStaReq in pMac for post-assoc-rsp");
+ lim_process_assoc_rsp_frame(pMac, pMac->roam.pReassocResp,
+ LIM_REASSOC, psessionEntry);
+ }
+#endif
+ return;
+
+end:
+ /* Free up buffer allocated for reassocReq */
+ if (psessionEntry != NULL)
+ if (psessionEntry->pLimMlmReassocReq != NULL) {
+ cdf_mem_free(psessionEntry->pLimMlmReassocReq);
+ psessionEntry->pLimMlmReassocReq = NULL;
+ }
+
+ if (pAddBssParams != NULL) {
+ cdf_mem_free(pAddBssParams);
+ pAddBssParams = NULL;
+ limMsgQ->bodyptr = NULL;
+ }
+
+ mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE session Id */
+ if (psessionEntry != NULL)
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+ else
+ mlmReassocCnf.sessionId = 0;
+
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+}
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+/**
+ * lim_process_sta_mlm_add_bss_rsp() - Process ADD BSS response
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * > Validates the result of WMA_ADD_BSS_REQ
+ * > Now, send an ADD_STA to HAL and ADD the "local" STA itself
+ *
+ * MLME had sent WMA_ADD_BSS_REQ to HAL
+ * HAL responded with WMA_ADD_BSS_RSP to MLME
+ * MLME now sends WMA_ADD_STA_REQ to HAL
+ * ASSUMPTIONS:
+ * tSirMsgQ.body is allocated by MLME during lim_process_mlm_join_req
+ * tSirMsgQ.body will now be freed by this routine
+ *
+ * Return: None
+ */
+static void
+lim_process_sta_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg, tpPESession session_entry)
+{
+ tpAddBssParams add_bss_params = (tpAddBssParams) msg->bodyptr;
+ tLimMlmAssocCnf mlm_assoc_cnf;
+ uint32_t msg_type = LIM_MLM_ASSOC_CNF;
+ uint32_t sub_type = LIM_ASSOC;
+ tpDphHashNode sta_ds = NULL;
+ uint16_t sta_idx = STA_INVALID_IDX;
+ uint8_t update_sta = false;
+ mlm_assoc_cnf.resultCode = eSIR_SME_SUCCESS;
+
+ if (eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE ==
+ session_entry->limMlmState) {
+ lim_log(mac_ctx, LOG1,
+ "SessionId:%d lim_process_sta_add_bss_rsp_pre_assoc",
+ session_entry->peSessionId);
+ lim_process_sta_add_bss_rsp_pre_assoc(mac_ctx, msg,
+ session_entry);
+ goto end;
+ }
+ if (eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == session_entry->limMlmState
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ || (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
+ session_entry->limMlmState)
+#endif
+ ) {
+ msg_type = LIM_MLM_REASSOC_CNF;
+ sub_type = LIM_REASSOC;
+ /*
+ * If Reassoc is happening for the same BSS, then
+ * use the existing StaId and indicate to HAL to update
+ * the existing STA entry.
+ * If Reassoc is happening for the new BSS, then
+ * old BSS and STA entry would have been already deleted
+ * before PE tries to add BSS for the new BSS, so set the
+ * updateSta to false and pass INVALID STA Index.
+ */
+ if (sir_compare_mac_addr(session_entry->bssId,
+ session_entry->limReAssocbssId)) {
+ sta_idx = session_entry->staId;
+ update_sta = true;
+ }
+ }
+
+ if (add_bss_params == 0)
+ goto end;
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ if (session_entry->bRoamSynchInProgress)
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "LFR3:lim_process_sta_mlm_add_bss_rsp");
+#endif
+
+ if (CDF_STATUS_SUCCESS == add_bss_params->status) {
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
+ session_entry->limMlmState) {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("Mlm=%d %d"),
+ session_entry->limMlmState,
+ eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+#endif
+ lim_process_sta_mlm_add_bss_rsp_ft(mac_ctx, msg,
+ session_entry);
+ goto end;
+ }
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+ /* Set MLME state */
+ session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId,
+ session_entry->limMlmState));
+ /* to know the session started for self or for peer */
+ session_entry->statypeForBss = STA_ENTRY_PEER;
+ /* Now, send WMA_ADD_STA_REQ */
+ lim_log(mac_ctx, LOGW,
+ FL("SessionId:%d On STA: ADD_BSS was successful"),
+ session_entry->peSessionId);
+ sta_ds =
+ dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session:%d Fail to add Self Entry for STA"),
+ session_entry->peSessionId);
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_REFUSED;
+ } else {
+ session_entry->bssIdx =
+ (uint8_t) add_bss_params->bssIdx;
+ /* Success, handle below */
+ sta_ds->bssId = add_bss_params->bssIdx;
+ /*
+ * STA Index(genr by HAL) for the BSS
+ * entry is stored here
+ */
+ sta_ds->staIndex = add_bss_params->staContext.staIdx;
+ sta_ds->ucUcastSig =
+ add_bss_params->staContext.ucUcastSig;
+ sta_ds->ucBcastSig =
+ add_bss_params->staContext.ucBcastSig;
+ /* Downgrade the EDCA parameters if needed */
+ lim_set_active_edca_params(mac_ctx,
+ session_entry->gLimEdcaParams, session_entry);
+ lim_send_edca_params(mac_ctx,
+ session_entry->gLimEdcaParamsActive,
+ sta_ds->bssId);
+#if defined WLAN_FEATURE_VOWIFI
+ rrm_cache_mgmt_tx_power(mac_ctx,
+ add_bss_params->txMgmtPower, session_entry);
+#endif
+ if (lim_add_sta_self(mac_ctx, sta_idx, update_sta,
+ session_entry) != eSIR_SUCCESS) {
+ /* Add STA context at HW */
+ lim_log(mac_ctx, LOGE,
+ FL("Session:%d could not Add Self"
+ "Entry for the station"),
+ session_entry->peSessionId);
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+ }
+ } else {
+ lim_log(mac_ctx, LOGP, FL("SessionId:%d ADD_BSS failed!"),
+ session_entry->peSessionId);
+ /* Return Assoc confirm to SME with failure */
+ if (eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE ==
+ session_entry->limMlmState)
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE;
+ else
+ mlm_assoc_cnf.resultCode =
+ (tSirResultCodes) eSIR_SME_REFUSED;
+ }
+
+ if (mlm_assoc_cnf.resultCode != eSIR_SME_SUCCESS) {
+ session_entry->limMlmState = eLIM_MLM_IDLE_STATE;
+ if (lim_set_link_state(mac_ctx, eSIR_LINK_IDLE_STATE,
+ session_entry->bssId,
+ session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE, FL("Failed to set the LinkState"));
+ /* Update PE session Id */
+ mlm_assoc_cnf.sessionId = session_entry->peSessionId;
+ lim_post_sme_message(mac_ctx, msg_type,
+ (uint32_t *) &mlm_assoc_cnf);
+ }
+end:
+ if (0 != msg->bodyptr) {
+ cdf_mem_free(add_bss_params);
+ msg->bodyptr = NULL;
+ }
+}
+
+/**
+ * lim_process_mlm_add_bss_rsp() - Processes ADD BSS Response
+ *
+ * @mac_ctx - Pointer to Global MAC structure
+ * @msg - The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process a WMA_ADD_BSS_RSP from HAL.
+ * Upon receipt of this message from HAL, MLME -
+ * Determines the "state" in which this message was received
+ * Forwards it to the appropriate callback
+ *
+ *LOGIC:
+ * WMA_ADD_BSS_RSP can be received by MLME while the LIM is
+ * in the following two states:
+ * 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE
+ * 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE
+ * Based on these two states, this API will determine where to
+ * route the message to
+ *
+ * Return None
+ */
+void lim_process_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg)
+{
+ tLimMlmStartCnf mlm_start_cnf;
+ tpPESession session_entry;
+ tpAddBssParams add_bss_param = (tpAddBssParams) (msg->bodyptr);
+ tSirBssType bss_type;
+
+ if (NULL == add_bss_param) {
+ lim_log(mac_ctx, LOGE, FL("Encountered NULL Pointer"));
+ return;
+ }
+
+ /*
+ * we need to process the deferred message since the
+ * initiating req.there might be nested request.
+ * in the case of nested request the new request initiated
+ * from the response will take care of resetting the deffered
+ * flag.
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+ /* Validate SME/LIM/MLME state */
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ add_bss_param->sessionId);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE, FL("SessionId:%d Session Doesn't exist"),
+ add_bss_param->sessionId);
+ if (NULL != add_bss_param) {
+ cdf_mem_free(add_bss_param);
+ msg->bodyptr = NULL;
+ }
+ return;
+ }
+
+ session_entry->nss = add_bss_param->nss;
+ bss_type = session_entry->bssType;
+ /* update PE session Id */
+ mlm_start_cnf.sessionId = session_entry->peSessionId;
+ if (eSIR_IBSS_MODE == bss_type) {
+ lim_process_ibss_mlm_add_bss_rsp(mac_ctx, msg, session_entry);
+ } else {
+ if (eLIM_SME_WT_START_BSS_STATE == session_entry->limSmeState) {
+ if (eLIM_MLM_WT_ADD_BSS_RSP_STATE !=
+ session_entry->limMlmState) {
+ /* Mesg received from HAL in Invalid state! */
+ lim_log(mac_ctx, LOGE,
+ FL("SessionId:%d Received "
+ " WMA_ADD_BSS_RSP in state %X"),
+ session_entry->peSessionId,
+ session_entry->limMlmState);
+ mlm_start_cnf.resultCode =
+ eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ if (0 != msg->bodyptr) {
+ cdf_mem_free(add_bss_param);
+ msg->bodyptr = NULL;
+ }
+ lim_post_sme_message(mac_ctx, LIM_MLM_START_CNF,
+ (uint32_t *) &mlm_start_cnf);
+ } else if ((bss_type == eSIR_BTAMP_AP_MODE) ||
+ (bss_type == eSIR_BTAMP_STA_MODE)) {
+ lim_process_btamp_add_bss_rsp(mac_ctx, msg,
+ session_entry);
+ } else
+ lim_process_ap_mlm_add_bss_rsp(mac_ctx, msg);
+ } else {
+ /* Called while processing assoc response */
+ lim_process_sta_mlm_add_bss_rsp(mac_ctx, msg,
+ session_entry);
+ }
+ }
+
+#ifdef WLAN_FEATURE_11W
+ if (session_entry->limRmfEnabled) {
+ if (eSIR_SUCCESS !=
+ lim_send_exclude_unencrypt_ind(mac_ctx, false,
+ session_entry)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to send Exclude Unencrypted Ind."));
+ }
+ }
+#endif
+}
+
+/**
+ * lim_process_mlm_set_sta_key_rsp() - Process STA key response
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg: The MsgQ header, which contains the response buffer
+ *
+ * This function is called to process the following two
+ * messages from HAL:
+ * 1) WMA_SET_BSSKEY_RSP
+ * 2) WMA_SET_STAKEY_RSP
+ * 3) WMA_SET_STA_BCASTKEY_RSP
+ * Upon receipt of this message from HAL,
+ * MLME -
+ * > Determines the "state" in which this message was received
+ * > Forwards it to the appropriate callback
+ * LOGIC:
+ * WMA_SET_BSSKEY_RSP/WMA_SET_STAKEY_RSP can be
+ * received by MLME while in the following state:
+ * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR--
+ * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR--
+ * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE
+ * Based on this state, this API will determine where to
+ * route the message to
+ * Assumption:
+ * ONLY the MLME state is being taken into account for now.
+ * This is because, it appears that the handling of the
+ * SETKEYS REQ is handled symmetrically on both the AP & STA
+ *
+ * Return: None
+ */
+void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg)
+{
+ uint8_t resp_reqd = 1;
+ tLimMlmSetKeysCnf mlm_set_key_cnf;
+ uint8_t session_id = 0;
+ tpPESession session_entry;
+
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+ cdf_mem_set((void *)&mlm_set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
+ if (NULL == msg->bodyptr) {
+ PELOGE(lim_log(mac_ctx, LOGE, FL("msg bodyptr is NULL"));)
+ return;
+ }
+ session_id = ((tpSetStaKeyParams) msg->bodyptr)->sessionId;
+ session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
+ if (session_entry == NULL) {
+ PELOGE(lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given session_id"));)
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ return;
+ }
+ if (eLIM_MLM_WT_SET_STA_KEY_STATE != session_entry->limMlmState) {
+ /* Mesg received from HAL in Invalid state! */
+ lim_log(mac_ctx, LOGE,
+ FL("Received unexpected [Mesg Id - %d] in state %X"),
+ msg->type, session_entry->limMlmState);
+ /* There's not much that MLME can do at this stage... */
+ resp_reqd = 0;
+ } else {
+ mlm_set_key_cnf.resultCode =
+ (uint16_t)(((tpSetStaKeyParams) msg->bodyptr)->status);
+ }
+
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ /* Restore MLME state */
+ session_entry->limMlmState = session_entry->limPrevMlmState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId, session_entry->limMlmState));
+ if (resp_reqd) {
+ tpLimMlmSetKeysReq lpLimMlmSetKeysReq =
+ (tpLimMlmSetKeysReq) mac_ctx->lim.gpLimMlmSetKeysReq;
+ /* Prepare and Send LIM_MLM_SETKEYS_CNF */
+ if (NULL != lpLimMlmSetKeysReq) {
+ cdf_mem_copy((uint8_t *) &mlm_set_key_cnf.peerMacAddr,
+ (uint8_t *) lpLimMlmSetKeysReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ /*
+ * Free the buffer cached for the global
+ * mac_ctx->lim.gpLimMlmSetKeysReq
+ */
+ cdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
+ mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+ }
+ mlm_set_key_cnf.sessionId = session_id;
+ lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
+ (uint32_t *) &mlm_set_key_cnf);
+ }
+}
+
+/**
+ * lim_process_mlm_set_bss_key_rsp() - handles BSS key
+ *
+ * @mac_ctx: A pointer to Global MAC structure
+ * @msg: Message from SME
+ *
+ * This function processes BSS key response and updates
+ * PE status accordingly.
+ *
+ * Return: NULL
+ */
+void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ msg)
+{
+ tLimMlmSetKeysCnf set_key_cnf;
+ uint16_t result_status;
+ uint8_t session_id = 0;
+ tpPESession session_entry;
+ tpLimMlmSetKeysReq set_key_req;
+
+ SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
+ cdf_mem_set((void *)&set_key_cnf, sizeof(tLimMlmSetKeysCnf), 0);
+ if (NULL == msg->bodyptr) {
+ PELOGE(lim_log(mac_ctx, LOGE, FL("msg bodyptr is null"));)
+ return;
+ }
+ session_id = ((tpSetBssKeyParams) msg->bodyptr)->sessionId;
+ session_entry = pe_find_session_by_session_id(mac_ctx, session_id);
+ if (session_entry == NULL) {
+ PELOGE(lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given sessionId [%d]"),
+ session_id);)
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ return;
+ }
+ if (eLIM_MLM_WT_SET_BSS_KEY_STATE == session_entry->limMlmState)
+ result_status =
+ (uint16_t)(((tpSetBssKeyParams)msg->bodyptr)->status);
+ else
+ /*
+ * BCAST key also uses tpSetStaKeyParams.
+ * Done this way for readabilty.
+ */
+ result_status =
+ (uint16_t)(((tpSetStaKeyParams)msg->bodyptr)->status);
+
+ /* Validate MLME state */
+ if (eLIM_MLM_WT_SET_BSS_KEY_STATE != session_entry->limMlmState &&
+ eLIM_MLM_WT_SET_STA_BCASTKEY_STATE !=
+ session_entry->limMlmState) {
+ /* Msg received from HAL in Invalid state! */
+ lim_log(mac_ctx, LOGE,
+ FL("Received unexpected [Mesg Id - %d] in state %X"),
+ msg->type, session_entry->limMlmState);
+ } else {
+ set_key_cnf.resultCode = result_status;
+ }
+
+ cdf_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
+ /* Restore MLME state */
+ session_entry->limMlmState = session_entry->limPrevMlmState;
+
+ MTRACE(mac_trace
+ (mac_ctx, TRACE_CODE_MLM_STATE, session_entry->peSessionId,
+ session_entry->limMlmState));
+ set_key_req =
+ (tpLimMlmSetKeysReq) mac_ctx->lim.gpLimMlmSetKeysReq;
+ set_key_cnf.sessionId = session_id;
+
+ /* Prepare and Send LIM_MLM_SETKEYS_CNF */
+ if (NULL != set_key_req) {
+ cdf_mem_copy((uint8_t *) &set_key_cnf.peerMacAddr,
+ (uint8_t *) set_key_req->peerMacAddr,
+ sizeof(tSirMacAddr));
+ /*
+ * Free the buffer cached for the
+ * global mac_ctx->lim.gpLimMlmSetKeysReq
+ */
+ cdf_mem_free(mac_ctx->lim.gpLimMlmSetKeysReq);
+ mac_ctx->lim.gpLimMlmSetKeysReq = NULL;
+ }
+ lim_post_sme_message(mac_ctx, LIM_MLM_SETKEYS_CNF,
+ (uint32_t *) &set_key_cnf);
+}
+
+/**
+ * lim_process_switch_channel_re_assoc_req()
+ *
+ ***FUNCTION:
+ * This function is called to send the reassoc req mgmt frame after the
+ * switchChannelRsp message is received from HAL.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure.
+ * @param psessionEntry - session related information.
+ * @param status - channel switch success/failure.
+ *
+ * @return None
+ */
+static void lim_process_switch_channel_re_assoc_req(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ CDF_STATUS status)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+ tLimMlmReassocReq *pMlmReassocReq;
+ pMlmReassocReq =
+ (tLimMlmReassocReq *) (psessionEntry->pLimMlmReassocReq);
+ if (pMlmReassocReq == NULL) {
+ lim_log(pMac, LOGP,
+ FL
+ ("pLimMlmReassocReq does not exist for given switchChanSession"));
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+ if (status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("Change channel failed!!"));)
+ mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL;
+ goto end;
+ }
+ /* / Start reassociation failure timer */
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
+ eLIM_REASSOC_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+ != TX_SUCCESS) {
+ /* / Could not start reassoc failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("could not start Reassociation failure timer"));
+ /* Return Reassoc confirm with */
+ /* Resources Unavailable */
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ /* / Prepare and send Reassociation request frame */
+ lim_send_reassoc_req_mgmt_frame(pMac, pMlmReassocReq, psessionEntry);
+ return;
+end:
+ /* Free up buffer allocated for reassocReq */
+ if (pMlmReassocReq != NULL) {
+ /* Update PE session Id */
+ mlmReassocCnf.sessionId = pMlmReassocReq->sessionId;
+ cdf_mem_free(pMlmReassocReq);
+ psessionEntry->pLimMlmReassocReq = NULL;
+ } else {
+ mlmReassocCnf.sessionId = 0;
+ }
+
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE sessio Id */
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+}
+
+
+/**
+ * lim_process_switch_channel_join_req() -Initiates probe request
+ *
+ * @mac_ctx - A pointer to Global MAC structure
+ * @sessionEntry - session related information.
+ * @status - channel switch success/failure
+ *
+ * This function is called to send the probe req mgmt frame
+ * after the switchChannelRsp message is received from HAL.
+ *
+ * Return None
+ */
+static void lim_process_switch_channel_join_req(
+ tpAniSirGlobal mac_ctx, tpPESession session_entry,
+ CDF_STATUS status)
+{
+ tSirMacSSid ssId;
+ tLimMlmJoinCnf join_cnf;
+ if (status != CDF_STATUS_SUCCESS) {
+ PELOGE(lim_log(mac_ctx, LOGE, FL("Change channel failed!!"));)
+ goto error;
+ }
+
+ if ((NULL == session_entry) || (NULL == session_entry->pLimMlmJoinReq)
+ || (NULL == session_entry->pLimJoinReq)) {
+ PELOGE(lim_log(mac_ctx, LOGE, FL("invalid pointer!!"));)
+ goto error;
+ }
+
+ /*
+ * eSIR_BTAMP_AP_MODE stroed as bss type in session
+ * Table when join req is received, is to be veified
+ */
+ if (session_entry->bssType == eSIR_BTAMP_AP_MODE) {
+ if (lim_set_link_state
+ (mac_ctx, eSIR_LINK_BTAMP_PREASSOC_STATE,
+ session_entry->bssId, session_entry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (mac_ctx, LOGE,
+ FL("Sessionid: %d Set link state "
+ "failed!! BSSID:" MAC_ADDRESS_STR),
+ session_entry->peSessionId,
+ MAC_ADDR_ARRAY(session_entry->bssId));)
+ goto error;
+ }
+ }
+
+ session_entry->limPrevMlmState = session_entry->limMlmState;
+ session_entry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE;
+ lim_log(mac_ctx, LOG1,
+ FL("Sessionid %d prev lim state %d new lim state %d "
+ "systemrole = %d"), session_entry->peSessionId,
+ session_entry->limPrevMlmState,
+ session_entry->limMlmState, GET_LIM_SYSTEM_ROLE(session_entry));
+
+ /* Apply previously set configuration at HW */
+ lim_apply_configuration(mac_ctx, session_entry);
+
+ /*
+ * If sendDeauthBeforeCon is enabled, Send Deauth first to AP if last
+ * disconnection was caused by HB failure.
+ */
+ if(mac_ctx->roam.configParam.sendDeauthBeforeCon) {
+ int apCount;
+
+ for(apCount = 0; apCount < 2; apCount++) {
+
+ if (cdf_mem_compare(session_entry->pLimMlmJoinReq->bssDescription.bssId,
+ mac_ctx->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) {
+
+ lim_log(mac_ctx, LOGE, FL("Index %d Sessionid: %d Send deauth on "
+ "channel %d to BSSID: "MAC_ADDRESS_STR ), apCount,
+ session_entry->peSessionId, session_entry->currentOperChannel,
+ MAC_ADDR_ARRAY(session_entry->pLimMlmJoinReq->bssDescription.
+ bssId));
+
+ lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON,
+ session_entry->pLimMlmJoinReq->bssDescription.bssId,
+ session_entry, false );
+
+ cdf_mem_zero(mac_ctx->lim.gLimHeartBeatApMac[apCount],
+ sizeof(tSirMacAddr));
+ break;
+ }
+ }
+ }
+
+ /* Wait for Beacon to announce join success */
+ cdf_mem_copy(ssId.ssId,
+ session_entry->ssId.ssId, session_entry->ssId.length);
+ ssId.length = session_entry->ssId.length;
+
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+
+ /* assign appropriate sessionId to the timer object */
+ mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId =
+ session_entry->peSessionId;
+ lim_log(mac_ctx, LOG1,
+ FL("Sessionid: %d Send Probe req on channel %d ssid:%.*s "
+ "BSSID: " MAC_ADDRESS_STR), session_entry->peSessionId,
+ session_entry->currentOperChannel, ssId.length, ssId.ssId,
+ MAC_ADDR_ARRAY(
+ session_entry->pLimMlmJoinReq->bssDescription.bssId));
+
+ /*
+ * We need to wait for probe response, so start join
+ * timeout timer.This timer will be deactivated once
+ * we receive probe response.
+ */
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE,
+ session_entry->peSessionId, eLIM_JOIN_FAIL_TIMER));
+ if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimJoinFailureTimer) !=
+ TX_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("couldn't activate Join failure timer"));
+ session_entry->limMlmState = session_entry->limPrevMlmState;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
+ session_entry->peSessionId,
+ mac_ctx->lim.gLimMlmState));
+ session_entry->pLimMlmJoinReq = NULL;
+ goto error;
+ }
+ /* include additional IE if there is */
+ lim_send_probe_req_mgmt_frame(mac_ctx, &ssId,
+ session_entry->pLimMlmJoinReq->bssDescription.bssId,
+ session_entry->currentOperChannel, session_entry->selfMacAddr,
+ session_entry->dot11mode,
+ session_entry->pLimJoinReq->addIEScan.length,
+ session_entry->pLimJoinReq->addIEScan.addIEdata);
+
+ if (session_entry->pePersona == CDF_P2P_CLIENT_MODE) {
+ /* Activate Join Periodic Probe Req timer */
+ if (tx_timer_activate
+ (&mac_ctx->lim.limTimers.gLimPeriodicJoinProbeReqTimer)
+ != TX_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("Periodic JoinReq timer activate failed"));
+ goto error;
+ }
+ }
+ return;
+error:
+ if (NULL != session_entry) {
+ if (session_entry->pLimMlmJoinReq) {
+ cdf_mem_free(session_entry->pLimMlmJoinReq);
+ session_entry->pLimMlmJoinReq = NULL;
+ }
+ if (session_entry->pLimJoinReq) {
+ cdf_mem_free(session_entry->pLimJoinReq);
+ session_entry->pLimJoinReq = NULL;
+ }
+ join_cnf.sessionId = session_entry->peSessionId;
+ } else {
+ join_cnf.sessionId = 0;
+ }
+ join_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ join_cnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF, (uint32_t *)&join_cnf);
+}
+
+/**
+ * lim_process_switch_channel_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to process switchChannelRsp message from HAL.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param body - message body.
+ *
+ * @return None
+ */
+void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *body)
+{
+ tpSwitchChannelParams pChnlParams = NULL;
+ CDF_STATUS status;
+ uint16_t channelChangeReasonCode;
+ uint8_t peSessionId;
+ tpPESession psessionEntry;
+ /* we need to process the deferred message since the initiating req. there might be nested request. */
+ /* in the case of nested request the new request initiated from the response will take care of resetting */
+ /* the deffered flag. */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ pChnlParams = (tpSwitchChannelParams) body;
+ status = pChnlParams->status;
+ peSessionId = pChnlParams->peSessionId;
+
+ psessionEntry = pe_find_session_by_session_id(pMac, peSessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("session does not exist for given sessionId"));
+ return;
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ /* HAL fills in the tx power used for mgmt frames in this field. */
+ /* Store this value to use in TPC report IE. */
+ rrm_cache_mgmt_tx_power(pMac, pChnlParams->txMgmtPower, psessionEntry);
+#endif
+ channelChangeReasonCode = psessionEntry->channelChangeReasonCode;
+ /* initialize it back to invalid id */
+ psessionEntry->chainMask = pChnlParams->chainMask;
+ psessionEntry->nss = pChnlParams->nss;
+ psessionEntry->smpsMode = pChnlParams->smpsMode;
+ psessionEntry->channelChangeReasonCode = 0xBAD;
+ lim_log(pMac, LOG1, FL("channelChangeReasonCode %d"),
+ channelChangeReasonCode);
+ switch (channelChangeReasonCode) {
+ case LIM_SWITCH_CHANNEL_REASSOC:
+ lim_process_switch_channel_re_assoc_req(pMac, psessionEntry, status);
+ break;
+ case LIM_SWITCH_CHANNEL_JOIN:
+ lim_process_switch_channel_join_req(pMac, psessionEntry, status);
+ break;
+
+ case LIM_SWITCH_CHANNEL_OPERATION:
+ /*
+ * The above code should also use the callback.
+ * mechanism below, there is scope for cleanup here.
+ * THat way all this response handler does is call the call back
+ * We can get rid of the reason code here.
+ */
+ if (pMac->lim.gpchangeChannelCallback) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ "Channel changed hence invoke registered call back");
+ )
+ pMac->lim.gpchangeChannelCallback(pMac, status,
+ pMac->lim.
+ gpchangeChannelData,
+ psessionEntry);
+ }
+ break;
+ case LIM_SWITCH_CHANNEL_SAP_DFS:
+ {
+ /* Note: This event code specific to SAP mode
+ * When SAP session issues channel change as performing
+ * DFS, we will come here. Other sessions, for e.g. P2P
+ * will have to define their own event code and channel
+ * switch handler. This is required since the SME may
+ * require completely different information for P2P unlike
+ * SAP.
+ */
+ lim_send_sme_ap_channel_switch_resp(pMac, psessionEntry,
+ pChnlParams);
+ }
+ break;
+ default:
+ break;
+ }
+ cdf_mem_free(body);
+}
+
+/**
+ * @function : lim_handle_del_bss_in_re_assoc_context
+ * @brief : While Processing the ReAssociation Response Frame in STA,
+ * a. immediately after receiving the Reassoc Response the RxCleanUp is
+ * being issued and the end of DelBSS the new BSS is being added.
+ *
+ * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context
+ * change, We need to update CSR with ReAssocCNF Response with the
+ * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS
+ * context only
+ *
+ * @param : pMac - tpAniSirGlobal
+ * pStaDs - Station Descriptor
+ *
+ * @return : none
+ */
+static void
+lim_handle_del_bss_in_re_assoc_context(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+ /*
+ * Skipped the DeleteDPH Hash Entry as we need it for the new BSS
+ * Set the MlmState to IDLE
+ */
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ /* Update PE session Id */
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+ switch (psessionEntry->limSmeState) {
+ case eLIM_SME_WT_REASSOC_STATE:
+ {
+ tpSirAssocRsp assocRsp;
+ tpDphHashNode pStaDs;
+ tSirRetStatus retStatus = eSIR_SUCCESS;
+ tpSchBeaconStruct beacon_struct;
+ beacon_struct = cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == beacon_struct) {
+ lim_log(pMac, LOGE, FL("beaconStruct alloc failed"));
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ lim_delete_dph_hash_entry(pMac, psessionEntry->bssId,
+ DPH_STA_HASH_INDEX_PEER, psessionEntry);
+ goto error;
+ }
+ /* Delete the older STA Table entry */
+ lim_delete_dph_hash_entry(pMac, psessionEntry->bssId,
+ DPH_STA_HASH_INDEX_PEER, psessionEntry);
+ /*
+ * Add an entry for AP to hash table
+ * maintained by DPH module
+ */
+ pStaDs = dph_add_hash_entry(pMac,
+ psessionEntry->limReAssocbssId,
+ DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ /* Could not add hash table entry */
+ lim_log(pMac, LOGE,
+ FL("could not add hash entry at DPH for "));
+ lim_print_mac_addr(pMac,
+ psessionEntry->limReAssocbssId, LOGE);
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS;
+ goto error;
+ }
+ /*
+ * While Processing the ReAssoc Response Frame the ReAssocRsp Frame
+ * is being stored to be used here for sending ADDBSS
+ */
+ assocRsp =
+ (tpSirAssocRsp) psessionEntry->limAssocResponseData;
+ lim_update_assoc_sta_datas(pMac, pStaDs, assocRsp,
+ psessionEntry);
+ lim_update_re_assoc_globals(pMac, assocRsp, psessionEntry);
+ lim_extract_ap_capabilities(pMac,
+ (uint8_t *) psessionEntry->pLimReAssocReq->bssDescription.ieFields,
+ lim_get_ielen_from_bss_description(
+ &psessionEntry->pLimReAssocReq->bssDescription),
+ beacon_struct);
+ if (pMac->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_sta_protection_on_assoc(pMac,
+ beacon_struct,
+ psessionEntry);
+ if (beacon_struct->erpPresent) {
+ if (beacon_struct->erpIEInfo.barkerPreambleMode)
+ psessionEntry->beaconParams.fShortPreamble = 0;
+ else
+ psessionEntry->beaconParams.fShortPreamble = 1;
+ }
+ /*
+ * updateBss flag is false, as in this case, PE is first
+ * deleting the existing BSS and then adding a new one
+ */
+ if (eSIR_SUCCESS !=
+ lim_sta_send_add_bss(pMac, assocRsp, beacon_struct,
+ &psessionEntry->pLimReAssocReq->bssDescription,
+ false, psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL("Posting ADDBSS in the ReAssocCtx has Failed "));
+ retStatus = eSIR_FAILURE;
+ }
+ if (retStatus != eSIR_SUCCESS) {
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ cdf_mem_free(assocRsp);
+ pMac->lim.gLimAssocResponseData = NULL;
+ cdf_mem_free(beacon_struct);
+ goto error;
+ }
+ cdf_mem_free(assocRsp);
+ cdf_mem_free(beacon_struct);
+ psessionEntry->limAssocResponseData = NULL;
+ }
+ break;
+ case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE:
+ {
+ /** Case wherein the DisAssoc / Deauth
+ * being sent as response to ReAssoc Req*/
+ /** Send the Reason code as the same received in Disassoc / Deauth Frame*/
+ mlmReassocCnf.resultCode =
+ pStaDs->mlmStaContext.disassocReason;
+ mlmReassocCnf.protStatusCode =
+ pStaDs->mlmStaContext.cleanupTrigger;
+ /** Set the SME State back to WT_Reassoc State*/
+ psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
+ pStaDs->assocId, psessionEntry);
+ if (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ psessionEntry->limMlmState =
+ eLIM_MLM_IDLE_STATE;
+ }
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+ }
+ break;
+ default:
+ lim_log(pMac, LOGE,
+ FL("DelBss is being invoked in the wrong system Role /unhandled SME State"));
+
+ mlmReassocCnf.resultCode = eSIR_SME_REFUSED;
+ mlmReassocCnf.protStatusCode =
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto error;
+ }
+ return;
+error:
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+}
+
+/* Added For BT -AMP Support */
+static void
+lim_process_btamp_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry)
+{
+ tLimMlmStartCnf mlmStartCnf;
+ tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr;
+
+ if (NULL == pAddBssParams) {
+ lim_log(pMac, LOGE, FL("Invalid body pointer in message"));
+ goto end;
+ }
+ if (CDF_STATUS_SUCCESS == pAddBssParams->status) {
+ lim_log(pMac, LOG2,
+ FL("WMA_ADD_BSS_RSP returned with CDF_STATUS_SUCCESS"));
+ if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
+ if (lim_set_link_state
+ (pMac, eSIR_LINK_BTAMP_AP_STATE,
+ psessionEntry->bssId, psessionEntry->selfMacAddr,
+ NULL, NULL) != eSIR_SUCCESS)
+ goto end;
+ } else if (psessionEntry->bssType == eSIR_BTAMP_STA_MODE) {
+ if (lim_set_link_state
+ (pMac, eSIR_LINK_SCAN_STATE, psessionEntry->bssId,
+ psessionEntry->selfMacAddr, NULL,
+ NULL) != eSIR_SUCCESS)
+ goto end;
+ }
+ /* Set MLME state */
+ psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE;
+ psessionEntry->statypeForBss = STA_ENTRY_SELF; /* to know session started for peer or for self */
+ psessionEntry->bssIdx = (uint8_t) pAddBssParams->bssIdx;
+ sch_edca_profile_update(pMac, psessionEntry);
+ lim_init_peer_idxpool(pMac, psessionEntry);
+
+ /* Apply previously set configuration at HW */
+ lim_apply_configuration(pMac, psessionEntry);
+ psessionEntry->staId = pAddBssParams->staContext.staIdx;
+ mlmStartCnf.resultCode = eSIR_SME_SUCCESS;
+ } else {
+ lim_log(pMac, LOGE, FL("WMA_ADD_BSS_REQ failed with status %d"),
+ pAddBssParams->status);
+ mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ }
+ mlmStartCnf.sessionId = psessionEntry->peSessionId;
+ lim_post_sme_message(pMac, LIM_MLM_START_CNF, (uint32_t *) &mlmStartCnf);
+end:
+ if (0 != limMsgQ->bodyptr) {
+ cdf_mem_free(pAddBssParams);
+ limMsgQ->bodyptr = NULL;
+ }
+}
+
+/**
+ * @function : lim_handle_add_bss_in_re_assoc_context
+ * @brief : While Processing the ReAssociation Response Frame in STA,
+ * a. immediately after receiving the Reassoc Response the RxCleanUp is
+ * being issued and the end of DelBSS the new BSS is being added.
+ *
+ * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context
+ * change, We need to update CSR with ReAssocCNF Response with the
+ * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS
+ * context only
+ *
+ * @param : pMac - tpAniSirGlobal
+ * pStaDs - Station Descriptor
+ *
+ * @return : none
+ */
+void
+lim_handle_add_bss_in_re_assoc_context(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf;
+ /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/
+ /** Set the MlmState to IDLE*/
+ psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+ switch (psessionEntry->limSmeState) {
+ case eLIM_SME_WT_REASSOC_STATE: {
+ tpSirAssocRsp assocRsp;
+ tpDphHashNode pStaDs;
+ tSirRetStatus retStatus = eSIR_SUCCESS;
+ tSchBeaconStruct *pBeaconStruct;
+ pBeaconStruct =
+ cdf_mem_malloc(sizeof(tSchBeaconStruct));
+ if (NULL == pBeaconStruct) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to allocate memory in lim_handle_add_bss_in_re_assoc_context"));
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto Error;
+ }
+ /* Get the AP entry from DPH hash table */
+ pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("Fail to get STA PEER entry from hash"));
+ )
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS;
+ cdf_mem_free(pBeaconStruct);
+ goto Error;
+ }
+ /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame
+ * is being stored to be used here for sending ADDBSS
+ */
+ assocRsp =
+ (tpSirAssocRsp) psessionEntry->limAssocResponseData;
+ lim_update_assoc_sta_datas(pMac, pStaDs, assocRsp,
+ psessionEntry);
+ lim_update_re_assoc_globals(pMac, assocRsp, psessionEntry);
+ lim_extract_ap_capabilities(pMac,
+ (uint8_t *) psessionEntry->
+ pLimReAssocReq->bssDescription.
+ ieFields,
+ lim_get_ielen_from_bss_description
+ (&psessionEntry->
+ pLimReAssocReq->
+ bssDescription),
+ pBeaconStruct);
+ if (pMac->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_sta_protection_on_assoc(pMac,
+ pBeaconStruct,
+ psessionEntry);
+
+ if (pBeaconStruct->erpPresent) {
+ if (pBeaconStruct->erpIEInfo.barkerPreambleMode)
+ psessionEntry->beaconParams.
+ fShortPreamble = 0;
+ else
+ psessionEntry->beaconParams.
+ fShortPreamble = 1;
+ }
+
+ psessionEntry->isNonRoamReassoc = 1;
+ if (eSIR_SUCCESS !=
+ lim_sta_send_add_bss(pMac, assocRsp, pBeaconStruct,
+ &psessionEntry->pLimReAssocReq->
+ bssDescription, true,
+ psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Posting ADDBSS in the ReAssocContext has Failed "));
+ retStatus = eSIR_FAILURE;
+ }
+ if (retStatus != eSIR_SUCCESS) {
+ mlmReassocCnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode =
+ eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ cdf_mem_free(assocRsp);
+ pMac->lim.gLimAssocResponseData = NULL;
+ cdf_mem_free(pBeaconStruct);
+ goto Error;
+ }
+ cdf_mem_free(assocRsp);
+ psessionEntry->limAssocResponseData = NULL;
+ cdf_mem_free(pBeaconStruct);
+ }
+ break;
+ case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: {
+ /* Case wherein the DisAssoc / Deauth
+ * being sent as response to ReAssoc Req
+ * Send the Reason code as the same received
+ * in Disassoc / Deauth Frame
+ */
+ mlmReassocCnf.resultCode =
+ pStaDs->mlmStaContext.disassocReason;
+ mlmReassocCnf.protStatusCode =
+ pStaDs->mlmStaContext.cleanupTrigger;
+ /** Set the SME State back to WT_Reassoc State*/
+ psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
+ pStaDs->assocId, psessionEntry);
+ if (LIM_IS_STA_ROLE(psessionEntry)) {
+ psessionEntry->limMlmState =
+ eLIM_MLM_IDLE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+ }
+
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+ }
+ break;
+ default:
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("DelBss is being invoked in the wrong system Role /unhandled SME State"));
+ )
+ mlmReassocCnf.resultCode = eSIR_SME_REFUSED;
+ mlmReassocCnf.protStatusCode =
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto Error;
+ }
+ return;
+Error:
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+}
+
+void lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tBeaconGenParams *pBeaconGenParams = NULL;
+ tSirMsgQ limMsg;
+ /** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("Error:Unable to get the PESessionEntry"));
+ )
+ return;
+ }
+ pBeaconGenParams = cdf_mem_malloc(sizeof(*pBeaconGenParams));
+ if (NULL == pBeaconGenParams) {
+ PELOGE(lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during sending beaconPreMessage"));
+ )
+ return;
+ }
+ cdf_mem_set(pBeaconGenParams, sizeof(*pBeaconGenParams), 0);
+ cdf_mem_copy((void *)pBeaconGenParams->bssId,
+ (void *)psessionEntry->bssId, CDF_MAC_ADDR_SIZE);
+ limMsg.bodyptr = pBeaconGenParams;
+ sch_process_pre_beacon_ind(pMac, &limMsg);
+ return;
+}
+
+#ifdef FEATURE_WLAN_SCAN_PNO
+/**
+ * lim_send_sme_scan_cache_updated_ind()
+ *
+ ***FUNCTION:
+ * This function is used to post WMA_SME_SCAN_CACHE_UPDATED message to WMA.
+ * This message is the indication to WMA that all scan cache results
+ * are updated from LIM to SME. Mainly used only in PNO offload case.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * This function should be called after posting scan cache results to SME.
+ *
+ ***NOTE:
+ * NA
+ *
+ * @return None
+ */
+void lim_send_sme_scan_cache_updated_ind(uint8_t sessionId)
+{
+ cds_msg_t msg;
+
+ msg.type = WMA_SME_SCAN_CACHE_UPDATED;
+ msg.reserved = 0;
+ msg.bodyptr = NULL;
+ msg.bodyval = sessionId;
+
+ if (!CDF_IS_STATUS_SUCCESS
+ (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)))
+ CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR,
+ "%s: Not able to post WMA_SME_SCAN_CACHE_UPDATED message to WMA",
+ __func__);
+}
+#endif
+
+void lim_send_scan_offload_complete(tpAniSirGlobal pMac,
+ tSirScanOffloadEvent *pScanEvent)
+{
+
+ pMac->lim.gLimRspReqd = false;
+ lim_send_sme_scan_rsp(pMac, pScanEvent->reasonCode,
+ pScanEvent->sessionId, 0, pScanEvent->scanId);
+#ifdef FEATURE_WLAN_SCAN_PNO
+ lim_send_sme_scan_cache_updated_ind(pScanEvent->sessionId);
+#endif
+}
+
+void lim_process_rx_scan_event(tpAniSirGlobal pMac, void *buf)
+{
+ tSirScanOffloadEvent *pScanEvent = (tSirScanOffloadEvent *) buf;
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ "scan_id = %u", pScanEvent->scanId);
+ switch (pScanEvent->event) {
+ case SCAN_EVENT_STARTED:
+ break;
+ case SCAN_EVENT_START_FAILED:
+ case SCAN_EVENT_COMPLETED:
+ if (P2P_SCAN_TYPE_LISTEN == pScanEvent->p2pScanType) {
+ lim_send_sme_roc_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
+ CDF_STATUS_SUCCESS,
+ pScanEvent->sessionId,
+ pScanEvent->scanId);
+ cdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
+ pMac->lim.gpLimRemainOnChanReq = NULL;
+ /*
+ * If remain on channel timer expired and action frame
+ * is pending then indicate confirmation with status
+ * failure.
+ */
+ if (pMac->lim.mgmtFrameSessionId != 0xff) {
+ lim_send_sme_rsp(pMac,
+ eWNI_SME_ACTION_FRAME_SEND_CNF,
+ eSIR_SME_SEND_ACTION_FAIL,
+ pMac->lim.mgmtFrameSessionId, 0);
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ }
+ } else {
+ lim_send_scan_offload_complete(pMac, pScanEvent);
+ }
+ break;
+ case SCAN_EVENT_FOREIGN_CHANNEL:
+ if (P2P_SCAN_TYPE_LISTEN == pScanEvent->p2pScanType) {
+ /*Send Ready on channel indication to SME */
+ if (pMac->lim.gpLimRemainOnChanReq) {
+ lim_send_sme_roc_rsp(pMac,
+ eWNI_SME_REMAIN_ON_CHN_RDY_IND,
+ CDF_STATUS_SUCCESS,
+ pScanEvent->sessionId,
+ pScanEvent->scanId);
+ } else {
+ lim_log(pMac, LOGE,
+ FL("gpLimRemainOnChanReq is NULL"));
+ }
+ }
+ break;
+ case SCAN_EVENT_BSS_CHANNEL:
+ case SCAN_EVENT_DEQUEUED:
+ case SCAN_EVENT_PREEMPTED:
+ default:
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ "Received unhandled scan event %u",
+ pScanEvent->event);
+ }
+ cdf_mem_free(buf);
+}
diff --git a/core/mac/src/pe/lim/lim_process_probe_req_frame.c b/core/mac/src/pe/lim/lim_process_probe_req_frame.c
new file mode 100644
index 0000000..ccc8712
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_probe_req_frame.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_process_probe_req_frame.cc contains the code
+ * for processing Probe Request Frame.
+ * Author: Chandra Modumudi
+ * Date: 02/28/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_ser_des_utils.h"
+#include "parser_api.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+
+void
+
+lim_send_sme_probe_req_ind(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ uint8_t *pProbeReqIE,
+ uint32_t ProbeReqIELen, tpPESession psessionEntry);
+
+/**
+ * lim_get_wpspbc_sessions() - to get wps pbs sessions
+ * @mac_ctx: Pointer to Global MAC structure
+ * @addr: A pointer to probe request source MAC addresss
+ * @uuid_e: A pointer to UUIDE element of WPS IE in WPS PBC probe request
+ * @session: A pointer to station PE session
+ *
+ * This function is called to query the WPS PBC overlap. This function
+ * check WPS PBC probe request link list for PBC overlap
+ *
+ * @return None
+ */
+
+void lim_get_wpspbc_sessions(tpAniSirGlobal mac_ctx, uint8_t *addr,
+ uint8_t *uuid_e, eWPSPBCOverlap *overlap,
+ tpPESession session)
+{
+ int count = 0;
+ tSirWPSPBCSession *pbc;
+ uint32_t cur_time;
+
+ cur_time = (uint32_t) (cdf_mc_timer_get_system_ticks() /
+ CDF_TICKS_PER_SECOND);
+ cdf_mem_set((uint8_t *) addr, sizeof(tSirMacAddr), 0);
+ cdf_mem_set((uint8_t *) uuid_e, SIR_WPS_UUID_LEN, 0);
+ for (pbc = session->pAPWPSPBCSession; pbc; pbc = pbc->next) {
+ if (cur_time > pbc->timestamp + SIR_WPS_PBC_WALK_TIME)
+ break;
+ count++;
+ if (count > 1)
+ break;
+ cdf_mem_copy((uint8_t *) addr, (uint8_t *) pbc->addr,
+ sizeof(tSirMacAddr));
+ cdf_mem_copy((uint8_t *) uuid_e, (uint8_t *) pbc->uuid_e,
+ SIR_WPS_UUID_LEN);
+ }
+ if (count > 1)
+ /* Overlap */
+ *overlap = eSAP_WPSPBC_OVERLAP_IN120S;
+ else if (count == 0)
+ /* no WPS probe request in 120 second */
+ *overlap = eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S;
+ else
+ /* One WPS probe request in 120 second */
+ *overlap = eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S;
+
+ lim_log(mac_ctx, LOGE, FL("overlap = %d"), *overlap);
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOGE, addr,
+ sizeof(tSirMacAddr));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOGE, uuid_e,
+ SIR_WPS_UUID_LEN);
+ return;
+}
+
+/**
+ * lim_remove_timeout_pb_csessions
+ *
+ ***FUNCTION:
+ * This function is called to remove the WPS PBC probe request entires from specific entry to end.
+ *
+ ***LOGIC:
+ *
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pbc The beginning entry in WPS PBC probe request link list
+ *
+ * @return None
+ */
+static void lim_remove_timeout_pb_csessions(tpAniSirGlobal pMac,
+ tSirWPSPBCSession *pbc)
+{
+ tSirWPSPBCSession *prev;
+
+ while (pbc) {
+ prev = pbc;
+ pbc = pbc->next;
+
+ PELOG4(lim_log(pMac, LOG4, FL("WPS PBC sessions remove"));)
+ PELOG4(sir_dump_buf
+ (pMac, SIR_LIM_MODULE_ID, LOG4, prev->addr,
+ sizeof(tSirMacAddr));
+ )
+ PELOG4(sir_dump_buf
+ (pMac, SIR_LIM_MODULE_ID, LOG4, prev->uuid_e,
+ SIR_WPS_UUID_LEN);
+ )
+
+ cdf_mem_free(prev);
+ }
+}
+
+void lim_remove_pbc_sessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,
+ tpPESession psessionEntry)
+{
+ tSirWPSPBCSession *pbc, *prev = NULL;
+ prev = pbc = psessionEntry->pAPWPSPBCSession;
+
+ while (pbc) {
+ if (cdf_mem_compare((uint8_t *) pbc->addr,
+ (uint8_t *) pRemoveMac,
+ sizeof(tSirMacAddr))) {
+ prev->next = pbc->next;
+ if (pbc == psessionEntry->pAPWPSPBCSession)
+ psessionEntry->pAPWPSPBCSession = pbc->next;
+ cdf_mem_free(pbc);
+ return;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+
+}
+
+/**
+ * lim_update_pbc_session_entry
+ *
+ ***FUNCTION:
+ * This function is called when probe request with WPS PBC IE is received
+ *
+ ***LOGIC:
+ * This function add the WPS PBC probe request in the WPS PBC probe request link list
+ * The link list is in decreased time order of probe request that is received.
+ * The entry that is more than 120 second is removed.
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param addr A pointer to probe request source MAC addresss
+ * @param uuid_e A pointer to UUIDE element of WPS IE
+ * @param psessionEntry A pointer to station PE session
+ *
+ * @return None
+ */
+
+static void lim_update_pbc_session_entry(tpAniSirGlobal pMac,
+ uint8_t *addr, uint8_t *uuid_e,
+ tpPESession psessionEntry)
+{
+ tSirWPSPBCSession *pbc, *prev = NULL;
+
+ uint32_t curTime;
+
+ curTime =
+ (uint32_t) (cdf_mc_timer_get_system_ticks() /
+ CDF_TICKS_PER_SECOND);
+
+ PELOG4(lim_log
+ (pMac, LOG4, FL("Receive WPS probe reques curTime=%d"), curTime);
+ )
+ PELOG4(sir_dump_buf
+ (pMac, SIR_LIM_MODULE_ID, LOG4, addr, sizeof(tSirMacAddr));
+ )
+ PELOG4(sir_dump_buf
+ (pMac, SIR_LIM_MODULE_ID, LOG4, uuid_e, SIR_WPS_UUID_LEN);
+ )
+
+ pbc = psessionEntry->pAPWPSPBCSession;
+
+ while (pbc) {
+ if (cdf_mem_compare
+ ((uint8_t *) pbc->addr, (uint8_t *) addr,
+ sizeof(tSirMacAddr))
+ && cdf_mem_compare((uint8_t *) pbc->uuid_e,
+ (uint8_t *) uuid_e, SIR_WPS_UUID_LEN)) {
+ if (prev)
+ prev->next = pbc->next;
+ else
+ psessionEntry->pAPWPSPBCSession = pbc->next;
+ break;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+
+ if (!pbc) {
+ pbc = cdf_mem_malloc(sizeof(tSirWPSPBCSession));
+ if (NULL == pbc) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("memory allocate failed!"));
+ )
+ return;
+ }
+ cdf_mem_copy((uint8_t *) pbc->addr, (uint8_t *) addr,
+ sizeof(tSirMacAddr));
+
+ if (uuid_e)
+ cdf_mem_copy((uint8_t *) pbc->uuid_e,
+ (uint8_t *) uuid_e, SIR_WPS_UUID_LEN);
+ }
+
+ pbc->next = psessionEntry->pAPWPSPBCSession;
+ psessionEntry->pAPWPSPBCSession = pbc;
+ pbc->timestamp = curTime;
+
+ /* remove entries that have timed out */
+ prev = pbc;
+ pbc = pbc->next;
+
+ while (pbc) {
+ if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) {
+ prev->next = NULL;
+ lim_remove_timeout_pb_csessions(pMac, pbc);
+ break;
+ }
+ prev = pbc;
+ pbc = pbc->next;
+ }
+}
+
+/**
+ * lim_wpspbc_close
+ *
+ ***FUNCTION:
+ * This function is called when BSS is closed
+ *
+ ***LOGIC:
+ * This function remove all the WPS PBC entries
+ *
+ ***ASSUMPTIONS:
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param psessionEntry A pointer to station PE session
+ *
+ * @return None
+ */
+
+void lim_wpspbc_close(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ lim_remove_timeout_pb_csessions(pMac, psessionEntry->pAPWPSPBCSession);
+
+}
+
+/**
+ * lim_check11b_rates
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_probe_req_frame() upon
+ * Probe Request frame reception.
+ *
+ ***LOGIC:
+ * This function check 11b rates in supportedRates and extendedRates rates
+ *
+ ***NOTE:
+ *
+ * @param rate
+ *
+ * @return BOOLEAN
+ */
+
+bool lim_check11b_rates(uint8_t rate)
+{
+ if ((0x02 == (rate))
+ || (0x04 == (rate))
+ || (0x0b == (rate))
+ || (0x16 == (rate))
+ ) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * lim_process_probe_req_frame: to process probe req frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_pkt_info: A pointer to Buffer descriptor + associated PDUs
+ * @session: a ponter to session entry
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Request frame reception. This function processes received
+ * Probe Request frame and responds with Probe Response.
+ * Only AP or STA in IBSS mode that sent last Beacon will respond to
+ * Probe Request.
+ * ASSUMPTIONS:
+ * 1. AP or STA in IBSS mode that sent last Beacon will always respond
+ * to Probe Request received with broadcast SSID.
+ * NOTE:
+ * 1. Dunno what to do with Rates received in Probe Request frame
+ * 2. Frames with out-of-order fields/IEs are dropped.
+ *
+ *
+ * Return: none
+ */
+
+void
+lim_process_probe_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+ tpPESession session)
+{
+ uint8_t *body_ptr;
+ tpSirMacMgmtHdr mac_hdr;
+ uint32_t frame_len;
+ tSirProbeReq probe_req;
+ tAniSSID ssid;
+
+ /* Don't send probe responses if disabled */
+ if (mac_ctx->lim.gLimProbeRespDisableFlag)
+ return;
+
+ /*
+ * Don't send probe response if P2P go is scanning till scan
+ * come to idle state.
+ */
+ if ((session->pePersona == CDF_P2P_GO_MODE) &&
+ ((mac_ctx->lim.gpLimRemainOnChanReq) ||
+ (mac_ctx->lim.gLimHalScanState != eLIM_HAL_IDLE_SCAN_STATE))) {
+ lim_log(mac_ctx, LOG3,
+ FL("GO is scanning, don't send probersp on diff chnl"));
+ return;
+ }
+ mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ if (LIM_IS_AP_ROLE(session) ||
+ LIM_IS_BT_AMP_AP_ROLE(session) ||
+ LIM_IS_BT_AMP_STA_ROLE(session) ||
+ (LIM_IS_IBSS_ROLE(session) &&
+ (WMA_GET_RX_BEACON_SENT(rx_pkt_info)))) {
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+ lim_log(mac_ctx, LOG3,
+ FL("Received Probe Request %d bytes from "),
+ frame_len);
+ lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOG3);
+ /* Get pointer to Probe Request frame body */
+ body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+
+ /* Parse Probe Request frame */
+ if (sir_convert_probe_req_frame2_struct(mac_ctx, body_ptr,
+ frame_len, &probe_req) == eSIR_FAILURE) {
+ lim_log(mac_ctx, LOGE,
+ FL("Parse error ProbeReq, length=%d, SA is: "
+ MAC_ADDRESS_STR), frame_len,
+ MAC_ADDR_ARRAY(mac_hdr->sa));
+ mac_ctx->sys.probeError++;
+ return;
+ }
+ if (session->pePersona == CDF_P2P_GO_MODE) {
+ uint8_t i = 0, rate_11b = 0, other_rates = 0;
+ /* Check 11b rates in supported rates */
+ for (i = 0; i < probe_req.supportedRates.numRates;
+ i++) {
+ if (lim_check11b_rates(
+ probe_req.supportedRates.rate[i] &
+ 0x7f))
+ rate_11b++;
+ else
+ other_rates++;
+ }
+
+ /* Check 11b rates in extended rates */
+ for (i = 0; i < probe_req.extendedRates.numRates; i++) {
+ if (lim_check11b_rates(
+ probe_req.extendedRates.rate[i] & 0x7f))
+ rate_11b++;
+ else
+ other_rates++;
+ }
+
+ if ((rate_11b > 0) && (other_rates == 0)) {
+ lim_log(mac_ctx, LOG3,
+ FL("Received a probe req frame with only 11b rates, SA is: "));
+ lim_print_mac_addr(mac_ctx,
+ mac_hdr->sa, LOG3);
+ return;
+ }
+ }
+ if (LIM_IS_AP_ROLE(session) &&
+ ((session->APWPSIEs.SirWPSProbeRspIE.FieldPresent
+ & SIR_WPS_PROBRSP_VER_PRESENT)
+ && (probe_req.wscIePresent == 1)
+ && (probe_req.probeReqWscIeInfo.DevicePasswordID.id ==
+ WSC_PASSWD_ID_PUSH_BUTTON)
+ && (probe_req.probeReqWscIeInfo.UUID_E.present == 1))) {
+ if (session->fwdWPSPBCProbeReq) {
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID,
+ LOG4, mac_hdr->sa, sizeof(tSirMacAddr));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID,
+ LOG4, body_ptr, frame_len);
+ lim_send_sme_probe_req_ind(mac_ctx, mac_hdr->sa,
+ body_ptr, frame_len, session);
+ } else {
+ lim_update_pbc_session_entry(mac_ctx,
+ mac_hdr->sa,
+ probe_req.probeReqWscIeInfo.UUID_E.uuid,
+ session);
+ }
+ }
+ ssid.length = session->ssId.length;
+ /* Copy the SSID from sessio entry to local variable */
+ cdf_mem_copy(ssid.ssId, session->ssId.ssId,
+ session->ssId.length);
+
+ /*
+ * Compare received SSID with current SSID. If they match,
+ * reply with Probe Response
+ */
+ if (probe_req.ssId.length) {
+ if (!ssid.length)
+ goto multipleSSIDcheck;
+
+ if (cdf_mem_compare((uint8_t *) &ssid,
+ (uint8_t *) &(probe_req.ssId),
+ (uint8_t) (ssid.length + 1))) {
+ lim_send_probe_rsp_mgmt_frame(mac_ctx,
+ mac_hdr->sa, &ssid,
+ DPH_USE_MGMT_STAID,
+ DPH_NON_KEEPALIVE_FRAME,
+ session,
+ probe_req.p2pIePresent);
+ return;
+ } else if (session->pePersona ==
+ CDF_P2P_GO_MODE) {
+ uint8_t direct_ssid[7] = "DIRECT-";
+ uint8_t direct_ssid_len = 7;
+ if (cdf_mem_compare((uint8_t *) &direct_ssid,
+ (uint8_t *) &(probe_req.ssId.ssId),
+ (uint8_t) (direct_ssid_len))) {
+ lim_send_probe_rsp_mgmt_frame(mac_ctx,
+ mac_hdr->sa,
+ &ssid,
+ DPH_USE_MGMT_STAID,
+ DPH_NON_KEEPALIVE_FRAME,
+ session,
+ probe_req.p2pIePresent);
+ return;
+ }
+ } else {
+ lim_log(mac_ctx, LOG3,
+ FL("Ignore ProbeReq frm with unmatch SSID received from "));
+ lim_print_mac_addr(mac_ctx, mac_hdr->sa,
+ LOG3);
+ mac_ctx->sys.probeBadSsid++;
+ }
+ } else {
+ /*
+ * Broadcast SSID in the Probe Request.
+ * Reply with SSID we're configured with.
+ * Turn off the SSID length to 0 if hidden SSID feature
+ * is present
+ */
+ if (session->ssidHidden)
+ /*
+ * We are returning from here as probe request
+ * contains the broadcast SSID. So no need to
+ * send the probe resp
+ */
+ return;
+ lim_send_probe_rsp_mgmt_frame(mac_ctx, mac_hdr->sa,
+ &ssid,
+ DPH_USE_MGMT_STAID,
+ DPH_NON_KEEPALIVE_FRAME,
+ session,
+ probe_req.p2pIePresent);
+ return;
+ }
+multipleSSIDcheck:
+ lim_log(mac_ctx, LOG3,
+ FL("Ignore ProbeReq frm with unmatch SSID rcved from"));
+ lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOG3);
+ mac_ctx->sys.probeBadSsid++;
+ } else {
+ /* Ignore received Probe Request frame */
+ lim_log(mac_ctx, LOG3,
+ FL("Ignoring Probe Request frame received from "));
+ lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOG3);
+ mac_ctx->sys.probeIgnore++;
+ }
+ return;
+}
+
+/**
+ * lim_indicate_probe_req_to_hdd
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_probe_req_frame_multiple_bss() upon
+ * Probe Request frame reception.
+ *
+ ***LOGIC:
+ * This function processes received Probe Request frame and Pass
+ * Probe Request Frame to HDD.
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pBd A pointer to Buffer descriptor + associated PDUs
+ * @param psessionEntry A pointer to PE session
+ *
+ * @return None
+ */
+
+static void
+lim_indicate_probe_req_to_hdd(tpAniSirGlobal pMac, uint8_t *pBd,
+ tpPESession psessionEntry)
+{
+ tpSirMacMgmtHdr pHdr;
+ uint32_t frameLen;
+
+ lim_log(pMac, LOG1, "Received a probe request frame");
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pBd);
+ frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
+
+ /* send the probe req to SME. */
+ lim_send_sme_mgmt_frame_ind(pMac, pHdr->fc.subType,
+ (uint8_t *) pHdr,
+ (frameLen + sizeof(tSirMacMgmtHdr)),
+ psessionEntry->smeSessionId, WMA_GET_RX_CH(pBd),
+ psessionEntry, 0);
+} /*** end lim_indicate_probe_req_to_hdd() ***/
+
+/**
+ * lim_process_probe_req_frame_multiple_bss() - to process probe req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @buf_descr: A pointer to Buffer descriptor + associated PDUs
+ * @session: A pointer to PE session
+ *
+ * This function is called by limProcessMessageQueue() upon
+ * Probe Request frame reception. This function call
+ * lim_indicate_probe_req_to_hdd function to indicate
+ * Probe Request frame to HDD. It also call lim_process_probe_req_frame
+ * function which process received Probe Request frame and responds
+ * with Probe Response.
+ *
+ * @return None
+ */
+void
+lim_process_probe_req_frame_multiple_bss(tpAniSirGlobal mac_ctx,
+ uint8_t *buf_descr, tpPESession session)
+{
+ uint8_t i;
+
+ if (session != NULL) {
+ if (LIM_IS_AP_ROLE(session)) {
+ lim_indicate_probe_req_to_hdd(mac_ctx,
+ buf_descr, session);
+ }
+ lim_process_probe_req_frame(mac_ctx, buf_descr, session);
+ return;
+ }
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ session = pe_find_session_by_session_id(mac_ctx, i);
+ if (session == NULL)
+ continue;
+ if (LIM_IS_AP_ROLE(session))
+ lim_indicate_probe_req_to_hdd(mac_ctx,
+ buf_descr, session);
+ if (LIM_IS_AP_ROLE(session) ||
+ LIM_IS_IBSS_ROLE(session) ||
+ LIM_IS_BT_AMP_AP_ROLE(session) ||
+ LIM_IS_BT_AMP_STA_ROLE(session))
+ lim_process_probe_req_frame(mac_ctx,
+ buf_descr, session);
+ }
+}
+
+/**
+ * lim_send_sme_probe_req_ind()
+ *
+ ***FUNCTION:
+ * This function is to send
+ * eWNI_SME_WPS_PBC_PROBE_REQ_IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_WPS_PBC_PROBE_REQ_IND
+ * to host.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr that the probe request
+ * is generated.
+ * @param pProbeReqIE pointer to RAW probe request IE
+ * @param ProbeReqIELen The length of probe request IE.
+ * @param psessionEntry A pointer to PE session
+ *
+ * @return None
+ */
+void
+lim_send_sme_probe_req_ind(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ uint8_t *pProbeReqIE,
+ uint32_t ProbeReqIELen, tpPESession psessionEntry)
+{
+ tSirSmeProbeReqInd *pSirSmeProbeReqInd;
+ tSirMsgQ msgQ;
+
+ pSirSmeProbeReqInd = cdf_mem_malloc(sizeof(tSirSmeProbeReqInd));
+ if (NULL == pSirSmeProbeReqInd) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_PROBE_REQ_IND"));
+ return;
+ }
+
+ msgQ.type = eWNI_SME_WPS_PBC_PROBE_REQ_IND;
+ msgQ.bodyval = 0;
+ msgQ.bodyptr = pSirSmeProbeReqInd;
+
+ pSirSmeProbeReqInd->messageType = eWNI_SME_WPS_PBC_PROBE_REQ_IND;
+ pSirSmeProbeReqInd->length = sizeof(tSirSmeProbeReq);
+ pSirSmeProbeReqInd->sessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_copy(pSirSmeProbeReqInd->bssId, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ cdf_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.peerMacAddr,
+ peerMacAddr, sizeof(tSirMacAddr));
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIELen =
+ (uint16_t) ProbeReqIELen;
+ cdf_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIE, pProbeReqIE,
+ ProbeReqIELen);
+
+ if (lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("couldnt send the probe req to hdd"));
+ )
+ }
+
+} /*** end lim_send_sme_probe_req_ind() ***/
diff --git a/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
new file mode 100644
index 0000000..d3df1d3
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_process_probe_rsp_frame.cc contains the code
+ * for processing Probe Response Frame.
+ * Author: Chandra Modumudi
+ * Date: 03/01/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_messages.h"
+
+#include "parser_api.h"
+
+tSirRetStatus lim_validate_ie_information_in_probe_rsp_frame(uint8_t *pRxPacketInfo)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ if (WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) <
+ (SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN)) {
+ status = eSIR_FAILURE;
+ }
+
+ return status;
+}
+
+/**
+ * lim_process_probe_rsp_frame() - processes received Probe Response frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_Packet_info: A pointer to Buffer descriptor + associated PDUs
+ * @session_entry: Handle to the session.
+ *
+ * This function processes received Probe Response frame.
+ * Frames with out-of-order IEs are dropped.
+ * In case of IBSS, join 'success' makes MLM state machine
+ * transition into 'BSS started' state. This may have to change
+ * depending on supporting what kinda Authentication in IBSS.
+ *
+ * Return: None
+ */
+void
+lim_process_probe_rsp_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_Packet_info,
+ tpPESession session_entry)
+{
+ uint8_t *body;
+ uint32_t frame_len = 0;
+ tSirMacAddr current_bssid;
+ tpSirMacMgmtHdr header;
+ tSirProbeRespBeacon *probe_rsp;
+ uint8_t qos_enabled = false;
+ uint8_t wme_enabled = false;
+
+ if (!session_entry) {
+ lim_log(mac_ctx, LOGE, FL("session_entry is NULL"));
+ return;
+ }
+ lim_log(mac_ctx, LOG1, "SessionId:%d ProbeRsp Frame is received",
+ session_entry->peSessionId);
+
+ probe_rsp = cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+ if (NULL == probe_rsp) {
+ lim_log(mac_ctx, LOGE,
+ FL
+ ("Unable to allocate memory "));
+ return;
+ }
+
+ probe_rsp->ssId.length = 0;
+ probe_rsp->wpa.length = 0;
+
+ header = WMA_GET_RX_MAC_HEADER(rx_Packet_info);
+
+ lim_log(mac_ctx, LOG2,
+ FL("Rx Probe Response with length = %d from "MAC_ADDRESS_STR),
+ WMA_GET_RX_MPDU_LEN(rx_Packet_info),
+ MAC_ADDR_ARRAY(header->sa));
+
+ /* Validate IE information before processing Probe Response Frame */
+ if (lim_validate_ie_information_in_probe_rsp_frame(rx_Packet_info) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOG1,
+ FL("Parse error ProbeResponse, length=%d"), frame_len);
+ cdf_mem_free(probe_rsp);
+ return;
+ }
+
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_Packet_info);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("Probe Resp Frame Received: BSSID "
+ MAC_ADDRESS_STR " (RSSI %d)"),
+ MAC_ADDR_ARRAY(header->bssId),
+ (uint) abs((int8_t)WMA_GET_RX_RSSI_DB(rx_Packet_info)));
+ /* Get pointer to Probe Response frame body */
+ body = WMA_GET_RX_MPDU_DATA(rx_Packet_info);
+ /* Enforce Mandatory IEs */
+ if ((sir_convert_probe_frame2_struct(mac_ctx,
+ body, frame_len, probe_rsp) == eSIR_FAILURE) ||
+ !probe_rsp->ssidPresent) {
+ lim_log(mac_ctx, LOG1,
+ FL("Parse error ProbeResponse, length=%d"), frame_len);
+ cdf_mem_free(probe_rsp);
+ return;
+ }
+ lim_check_and_add_bss_description(mac_ctx, probe_rsp,
+ rx_Packet_info, false, true);
+ /* To Support BT-AMP */
+ if ((mac_ctx->lim.gLimMlmState ==
+ eLIM_MLM_WT_PROBE_RESP_STATE) ||
+ (mac_ctx->lim.gLimMlmState ==
+ eLIM_MLM_PASSIVE_SCAN_STATE)) {
+ lim_check_and_add_bss_description(mac_ctx, probe_rsp,
+ rx_Packet_info, ((mac_ctx->lim.
+ gLimHalScanState == eLIM_HAL_SCANNING_STATE)
+ ? true : false), true);
+ } else if (session_entry->limMlmState ==
+ eLIM_MLM_WT_JOIN_BEACON_STATE) {
+ /*
+ * Either Beacon/probe response is required.
+ * Hence store it in same buffer.
+ */
+ if (session_entry->beacon != NULL) {
+ cdf_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+ }
+ session_entry->bcnLen =
+ WMA_GET_RX_PAYLOAD_LEN(rx_Packet_info);
+ session_entry->beacon =
+ cdf_mem_malloc(session_entry->bcnLen);
+ if (NULL == session_entry->beacon) {
+ lim_log(mac_ctx, LOGE,
+ FL("No Memory to store beacon"));
+ } else {
+ /*
+ * Store the Beacon/ProbeRsp.
+ * This is sent to csr/hdd in join cnf response.
+ */
+ cdf_mem_copy(session_entry->beacon,
+ WMA_GET_RX_MPDU_DATA
+ (rx_Packet_info),
+ session_entry->bcnLen);
+ }
+ /* STA in WT_JOIN_BEACON_STATE */
+ lim_check_and_announce_join_success(mac_ctx, probe_rsp,
+ header,
+ session_entry);
+ } else if (session_entry->limMlmState ==
+ eLIM_MLM_LINK_ESTABLISHED_STATE) {
+ tpDphHashNode sta_ds = NULL;
+ /*
+ * Check if this Probe Response is for
+ * our Probe Request sent upon reaching
+ * heart beat threshold
+ */
+ sir_copy_mac_addr(current_bssid, session_entry->bssId);
+ if (!cdf_mem_compare(current_bssid, header->bssId,
+ sizeof(tSirMacAddr))) {
+ cdf_mem_free(probe_rsp);
+ return;
+ }
+ if (!LIM_IS_CONNECTION_ACTIVE(session_entry)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Recved Probe Resp from AP,AP-alive"));
+ if (probe_rsp->HTInfo.present)
+ lim_received_hb_handler(mac_ctx,
+ probe_rsp->HTInfo.primaryChannel,
+ session_entry);
+ else
+ lim_received_hb_handler(mac_ctx,
+ (uint8_t)probe_rsp->channelNumber,
+ session_entry);
+ }
+ if (LIM_IS_STA_ROLE(session_entry)) {
+ if (probe_rsp->channelSwitchPresent) {
+ lim_update_channel_switch(mac_ctx,
+ probe_rsp,
+ session_entry);
+ } else if (session_entry->gLimSpecMgmt.dot11hChanSwState
+ == eLIM_11H_CHANSW_RUNNING) {
+ lim_cancel_dot11h_channel_switch(
+ mac_ctx, session_entry);
+ }
+ }
+ /*
+ * Now Process EDCA Parameters, if EDCAParamSet
+ * count is different.
+ * -- While processing beacons in link established
+ * state if it is determined that
+ * QoS Info IE has a different count for EDCA Params,
+ * and EDCA IE is not present in beacon,
+ * then probe req is sent out to get the EDCA params.
+ */
+ sta_ds = dph_get_hash_entry(mac_ctx,
+ DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ limGetQosMode(session_entry, &qos_enabled);
+ limGetWmeMode(session_entry, &wme_enabled);
+ lim_log(mac_ctx, LOG2,
+ FL("wmeEdcaPresent: %d wme_enabled: %d"),
+ probe_rsp->wmeEdcaPresent, wme_enabled);
+ lim_log(mac_ctx, LOG2,
+ FL("edcaPresent: %d, qos_enabled: %d"),
+ probe_rsp->edcaPresent, qos_enabled);
+ lim_log(mac_ctx, LOG2,
+ FL("edcaParams.qosInfo.count: %d"),
+ probe_rsp->edcaParams.qosInfo.count);
+ lim_log(mac_ctx, LOG2,
+ FL("schObject.gLimEdcaParamSetCount: %d"),
+ session_entry->gLimEdcaParamSetCount);
+ if (((probe_rsp->wmeEdcaPresent && wme_enabled) ||
+ (probe_rsp->edcaPresent && qos_enabled)) &&
+ (probe_rsp->edcaParams.qosInfo.count !=
+ session_entry->gLimEdcaParamSetCount)) {
+ if (sch_beacon_edca_process(mac_ctx,
+ &probe_rsp->edcaParams,
+ session_entry) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("EDCA param process error"));
+ } else if (sta_ds != NULL) {
+ /*
+ * If needed, downgrade the
+ * EDCA parameters
+ */
+ lim_set_active_edca_params(mac_ctx,
+ session_entry->
+ gLimEdcaParams,
+ session_entry);
+ lim_send_edca_params(mac_ctx,
+ session_entry->
+ gLimEdcaParamsActive,
+ sta_ds->bssId);
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("SelfEntry missing in Hash"));
+ }
+ }
+ if (session_entry->fWaitForProbeRsp == true) {
+ lim_log(mac_ctx, LOGW,
+ FL("Check probe resp for caps change"));
+ lim_detect_change_in_ap_capabilities(
+ mac_ctx, probe_rsp, session_entry);
+ }
+ } else {
+ if (LIM_IS_IBSS_ROLE(session_entry) &&
+ (session_entry->limMlmState ==
+ eLIM_MLM_BSS_STARTED_STATE))
+ lim_handle_ibss_coalescing(mac_ctx, probe_rsp,
+ rx_Packet_info, session_entry);
+ }
+ cdf_mem_free(probe_rsp);
+
+ /* Ignore Probe Response frame in all other states */
+ return;
+}
+
+/**
+ * lim_process_probe_rsp_frame_no_session() - process Probe Response frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @rx_packet_info: A pointer to Buffer descriptor + associated PDUs
+ *
+ * This function processes received Probe Response frame with no session.
+ *
+ * Return: None
+ */
+void
+lim_process_probe_rsp_frame_no_session(tpAniSirGlobal mac_ctx,
+ uint8_t *rx_packet_info)
+{
+ uint8_t *body;
+ uint32_t frame_len = 0;
+ tpSirMacMgmtHdr header;
+ tSirProbeRespBeacon *probe_rsp;
+
+ probe_rsp = cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+ if (NULL == probe_rsp) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to allocate memory"));
+ return;
+ }
+
+ probe_rsp->ssId.length = 0;
+ probe_rsp->wpa.length = 0;
+
+ header = WMA_GET_RX_MAC_HEADER(rx_packet_info);
+
+ lim_log(mac_ctx, LOG2,
+ FL("Received Probe Response frame with length=%d from "),
+ WMA_GET_RX_MPDU_LEN(rx_packet_info));
+ lim_print_mac_addr(mac_ctx, header->sa, LOG2);
+
+ /* Validate IE information before processing Probe Response Frame */
+ if (lim_validate_ie_information_in_probe_rsp_frame(rx_packet_info) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOG1,
+ FL("Parse error ProbeResponse, length=%d"), frame_len);
+ cdf_mem_free(probe_rsp);
+ return;
+ }
+
+ frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_packet_info);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("Probe Resp Frame Received: BSSID "
+ MAC_ADDRESS_STR " (RSSI %d)"),
+ MAC_ADDR_ARRAY(header->bssId),
+ (uint) abs((int8_t)WMA_GET_RX_RSSI_DB(rx_packet_info)));
+ /*
+ * Get pointer to Probe Response frame body
+ */
+ body = WMA_GET_RX_MPDU_DATA(rx_packet_info);
+ if (sir_convert_probe_frame2_struct(mac_ctx, body, frame_len,
+ probe_rsp) == eSIR_FAILURE) {
+ lim_log(mac_ctx, LOG1,
+ FL("Parse error ProbeResponse, length=%d\n"),
+ frame_len);
+ cdf_mem_free(probe_rsp);
+ return;
+ }
+ lim_log(mac_ctx, LOG2, FL("Save this probe rsp in LFR cache"));
+ lim_check_and_add_bss_description(mac_ctx, probe_rsp,
+ rx_packet_info, false, true);
+ cdf_mem_free(probe_rsp);
+ return;
+}
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
new file mode 100644
index 0000000..0db6d07
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -0,0 +1,5690 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_process_sme_req_messages.cc contains the code
+ * for processing SME request messages.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cds_api.h"
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_sme_req_utils.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_admit_control.h"
+#include "dph_hash_table.h"
+#include "lim_send_messages.h"
+#include "lim_api.h"
+#include "wmm_apsd.h"
+#include "sir_mac_prot_def.h"
+
+#include "sap_api.h"
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+#include <lim_ft.h>
+#endif
+
+/*
+ * This overhead is time for sending NOA start to host in case of GO/sending
+ * NULL data & receiving ACK in case of P2P Client and starting actual scanning
+ * with init scan req/rsp plus in case of concurrency, taking care of sending
+ * null data and receiving ACK to/from AP/Also SetChannel with calibration
+ * is taking around 7ms .
+ */
+#define SCAN_MESSAGING_OVERHEAD 20 /* in msecs */
+#define JOIN_NOA_DURATION 2000 /* in msecs */
+#define OEM_DATA_NOA_DURATION 60 /* in msecs */
+#define DEFAULT_PASSIVE_MAX_CHANNEL_TIME 110 /* in msecs */
+
+#define CONV_MS_TO_US 1024 /* conversion factor from ms to us */
+
+/* SME REQ processing function templates */
+static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal, uint32_t *);
+static bool __lim_process_sme_start_bss_req(tpAniSirGlobal, tpSirMsgQ pMsg);
+static void __lim_process_sme_scan_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_join_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_reassoc_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_disassoc_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_deauth_req(tpAniSirGlobal, uint32_t *);
+static void __lim_process_sme_set_context_req(tpAniSirGlobal, uint32_t *);
+static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal, tpSirMsgQ pMsg);
+static void lim_process_sme_channel_change_request(tpAniSirGlobal pMac,
+ uint32_t *pMsg);
+static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg);
+static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal pMac, uint32_t *pMsg);
+static void lim_process_nss_update_request(tpAniSirGlobal pMac, uint32_t *pMsg);
+static void lim_process_set_ie_req(tpAniSirGlobal pMac, uint32_t *pMsg);
+
+static void lim_start_bss_update_add_ie_buffer(tpAniSirGlobal pMac,
+ uint8_t **pDstData_buff,
+ uint16_t *pDstDataLen,
+ uint8_t *pSrcData_buff,
+ uint16_t srcDataLen);
+
+static void lim_update_add_ie_buffer(tpAniSirGlobal pMac,
+ uint8_t **pDstData_buff,
+ uint16_t *pDstDataLen,
+ uint8_t *pSrcData_buff, uint16_t srcDataLen);
+
+static void lim_process_modify_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
+
+static void lim_process_update_add_ies(tpAniSirGlobal pMac, uint32_t *pMsg);
+
+extern void pe_register_wma_handle(tpAniSirGlobal pMac);
+
+/**
+ * lim_process_set_hw_mode() - Send set HW mode command to WMA
+ * @mac: Globacl MAC pointer
+ * @msg: Message containing the hw mode index
+ *
+ * Send the set HW mode command to WMA
+ *
+ * Return: CDF_STATUS_SUCCESS if message posting is successful
+ */
+static CDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
+{
+ CDF_STATUS status = CDF_STATUS_SUCCESS;
+ cds_msg_t cds_message;
+ struct sir_hw_mode *req_msg;
+ uint32_t len;
+ struct s_sir_set_hw_mode *buf;
+ tSirMsgQ resp_msg;
+ struct sir_set_hw_mode_resp *param;
+
+ buf = (struct s_sir_set_hw_mode *) msg;
+ if (!buf) {
+ lim_log(mac, LOGE, FL("Set HW mode param is NULL"));
+ /* To free the active command list */
+ goto fail;
+ }
+
+ len = sizeof(*req_msg);
+
+ req_msg = cdf_mem_malloc(len);
+ if (!req_msg) {
+ lim_log(mac, LOGE, FL("cdf_mem_malloc failed"));
+ /* Free the active command list
+ * Probably the malloc is going to fail there as well?!
+ */
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ cdf_mem_zero(req_msg, len);
+
+ req_msg->hw_mode_index = buf->set_hw.hw_mode_index;
+ /* Other parameters are not needed for WMA */
+
+ cds_message.bodyptr = req_msg;
+ cds_message.type = SIR_HAL_SOC_SET_HW_MODE;
+
+ lim_log(mac, LOG1, FL("Posting SIR_HAL_SOC_SET_HW_MOD to WMA"));
+ status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
+ lim_log(mac, LOGE,
+ FL("vos_mq_post_message failed!(err=%d)"),
+ status);
+ cdf_mem_free(req_msg);
+ goto fail;
+ }
+ return status;
+fail:
+ param = cdf_mem_malloc(sizeof(*param));
+ if (!param) {
+ lim_log(mac, LOGE, FL("HW mode resp failed"));
+ return CDF_STATUS_E_FAILURE;
+ }
+ param->status = SET_HW_MODE_STATUS_ECANCELED;
+ param->cfgd_hw_mode_index = 0;
+ param->num_vdev_mac_entries = 0;
+ resp_msg.type = eWNI_SME_SET_HW_MODE_RESP;
+ resp_msg.bodyptr = param;
+ resp_msg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_process_set_dual_mac_cfg_req() - Set dual mac config command to WMA
+ * @mac: Global MAC pointer
+ * @msg: Message containing the dual mac config parameter
+ *
+ * Send the set dual mac config command to WMA
+ *
+ * Return: CDF_STATUS_SUCCESS if message posting is successful
+ */
+static CDF_STATUS lim_process_set_dual_mac_cfg_req(tpAniSirGlobal mac,
+ uint32_t *msg)
+{
+ CDF_STATUS status = CDF_STATUS_SUCCESS;
+ cds_msg_t cds_message;
+ struct sir_dual_mac_config *req_msg;
+ uint32_t len;
+ struct sir_set_dual_mac_cfg *buf;
+ tSirMsgQ resp_msg;
+ struct sir_dual_mac_config_resp *param;
+
+ buf = (struct sir_set_dual_mac_cfg *) msg;
+ if (!buf) {
+ lim_log(mac, LOGE, FL("Set Dual mac config is NULL"));
+ /* To free the active command list */
+ goto fail;
+ }
+
+ len = sizeof(*req_msg);
+
+ req_msg = cdf_mem_malloc(len);
+ if (!req_msg) {
+ lim_log(mac, LOGE, FL("vos_mem_malloc failed"));
+ /* Free the active command list
+ * Probably the malloc is going to fail there as well?!
+ */
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ cdf_mem_zero(req_msg, len);
+
+ req_msg->scan_config = buf->set_dual_mac.scan_config;
+ req_msg->fw_mode_config = buf->set_dual_mac.fw_mode_config;
+ /* Other parameters are not needed for WMA */
+
+ cds_message.bodyptr = req_msg;
+ cds_message.type = SIR_HAL_SOC_DUAL_MAC_CFG_REQ;
+
+ lim_log(mac, LOG1,
+ FL("Post SIR_HAL_SOC_DUAL_MAC_CFG_REQ to WMA: %x %x"),
+ req_msg->scan_config, req_msg->fw_mode_config);
+ status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
+ lim_log(mac, LOGE,
+ FL("vos_mq_post_message failed!(err=%d)"),
+ status);
+ cdf_mem_free(req_msg);
+ goto fail;
+ }
+ return status;
+fail:
+ param = cdf_mem_malloc(sizeof(*param));
+ if (!param) {
+ lim_log(mac, LOGE, FL("Dual mac config resp failed"));
+ return CDF_STATUS_E_FAILURE;
+ }
+ param->status = SET_HW_MODE_STATUS_ECANCELED;
+ resp_msg.type = eWNI_SME_SET_DUAL_MAC_CFG_RESP;
+ resp_msg.bodyptr = param;
+ resp_msg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(mac, &resp_msg, ePROT);
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * __lim_fresh_scan_reqd() - determine if a fresh scan request must be issued.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @return_fresh_results: Trigger fresh scan.
+ *
+ * PE will do fresh scan, if all of the active sessions are in
+ * good state (Link Est or BSS Started). If one of the sessions
+ * is not in one of the above states, then PE does not do fresh
+ * scan. If no session exists (scanning very first time),
+ * then PE will always do fresh scan if SME asks it to do that.
+ *
+ * Return: true for fresh scan results, false if in invalid state.
+ */
+static uint8_t
+__lim_fresh_scan_reqd(tpAniSirGlobal mac_ctx, uint8_t return_fresh_results)
+{
+ uint8_t valid_state = true;
+ int i;
+
+ lim_log(mac_ctx, LOG1, FL("gLimSmeState: %d, returnFreshResults 0x%x"),
+ mac_ctx->lim.gLimSmeState, return_fresh_results);
+
+ if (mac_ctx->lim.gLimSmeState != eLIM_SME_IDLE_STATE) {
+ lim_log(mac_ctx, LOG1, FL("return FALSE"));
+ return false;
+ }
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ lim_log(mac_ctx, LOG1,
+ FL("session %d, bsstype %d, limSystemRole %d, limSmeState %d"),
+ i, mac_ctx->lim.gpSession[i].bssType,
+ mac_ctx->lim.gpSession[i].limSystemRole,
+ mac_ctx->lim.gpSession[i].limSmeState);
+ if (mac_ctx->lim.gpSession[i].valid == true) {
+ if (!((((mac_ctx->lim.gpSession[i].bssType ==
+ eSIR_INFRASTRUCTURE_MODE) ||
+ (mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_BT_AMP_STA_ROLE)) &&
+ (mac_ctx->lim.gpSession[i].limSmeState ==
+ eLIM_SME_LINK_EST_STATE)) ||
+ (((mac_ctx->lim.gpSession[i].bssType ==
+ eSIR_IBSS_MODE) ||
+ (mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_BT_AMP_AP_ROLE) ||
+ (mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_BT_AMP_STA_ROLE)) &&
+ (mac_ctx->lim.gpSession[i].limSmeState ==
+ eLIM_SME_NORMAL_STATE)) ||
+ ((((mac_ctx->lim.gpSession[i].bssType ==
+ eSIR_INFRA_AP_MODE) &&
+ (mac_ctx->lim.gpSession[i].pePersona ==
+ CDF_P2P_GO_MODE)) ||
+ (mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_AP_ROLE)) &&
+ (mac_ctx->lim.gpSession[i].limSmeState ==
+ eLIM_SME_NORMAL_STATE)))) {
+ valid_state = false;
+ break;
+ }
+ }
+ }
+
+ lim_log(mac_ctx, LOG1, FL("valid_state: %d"), valid_state);
+
+ if ((valid_state) &&
+ (return_fresh_results & SIR_BG_SCAN_RETURN_FRESH_RESULTS))
+ return true;
+ else
+ return false;
+}
+
+/**
+ * __lim_is_sme_assoc_cnf_valid()
+ *
+ ***FUNCTION:
+ * This function is called by __lim_process_sme_assoc_cnf_new() upon
+ * receiving SME_ASSOC_CNF.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMeasReq Pointer to Received ASSOC_CNF message
+ * @return true When received SME_ASSOC_CNF is formatted
+ * correctly
+ * false otherwise
+ */
+
+static inline uint8_t __lim_is_sme_assoc_cnf_valid(tpSirSmeAssocCnf pAssocCnf)
+{
+ if (lim_is_group_addr(pAssocCnf->peerMacAddr))
+ return false;
+ else
+ return true;
+} /*** end __lim_is_sme_assoc_cnf_valid() ***/
+
+/**
+ * __lim_get_sme_join_req_size_for_alloc()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ * number being scanned.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pBssDescr
+ * @return Total IE length
+ */
+
+static uint16_t __lim_get_sme_join_req_size_for_alloc(uint8_t *pBuf)
+{
+ uint16_t len = 0;
+
+ if (!pBuf)
+ return len;
+
+ pBuf += sizeof(uint16_t);
+ len = lim_get_u16(pBuf);
+ return len + sizeof(uint16_t);
+}
+
+/**
+ * __lim_is_defered_msg_for_learn() - message handling in SME learn state
+ * @pMac: Global MAC context
+ * @pMsg: Pointer to message posted from SME to LIM.
+ *
+ * Has role only if 11h is enabled. Not used on STA side.
+ * Defers the message if SME is in learn state and brings
+ * the LIM back to normal mode.
+ *
+ * Return: true - If defered false - Otherwise
+ */
+
+static bool __lim_is_defered_msg_for_learn(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (lim_is_system_in_scan_state(pMac)) {
+ if (lim_defer_msg(pMac, pMsg) != TX_SUCCESS) {
+ lim_log(pMac, LOGE, FL("Could not defer Msg = %d"),
+ pMsg->type);
+ return false;
+ }
+ lim_log(pMac, LOG1,
+ FL("Defer the message, in learn mode type = %d"),
+ pMsg->type);
+ return true;
+ }
+ return false;
+}
+
+/**
+ * __lim_is_defered_msg_for_radar() - Defers the message if radar is detected
+ * @mac_ctx: Pointer to Global MAC structure
+ * @message: Pointer to message posted from SME to LIM.
+ *
+ * Has role only if 11h is enabled. Not used on STA side.
+ * Defers the message if radar is detected.
+ *
+ * Return: true, if defered otherwise return false.
+ */
+static bool
+__lim_is_defered_msg_for_radar(tpAniSirGlobal mac_ctx, tpSirMsgQ message)
+{
+ /*
+ * fRadarDetCurOperChan will be set only if we
+ * detect radar in current operating channel and
+ * System Role == AP ROLE
+ *
+ * TODO: Need to take care radar detection.
+ *
+ * if (LIM_IS_RADAR_DETECTED(mac_ctx))
+ */
+ if (0) {
+ if (lim_defer_msg(mac_ctx, message) != TX_SUCCESS) {
+ lim_log(mac_ctx, LOGE, FL("Could not defer Msg = %d"),
+ message->type);
+ return false;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("Defer the message, in learn mode type = %d"),
+ message->type);
+ return true;
+ }
+ return false;
+}
+
+/**
+ * __lim_process_sme_sys_ready_ind () - Process ready indication from WMA
+ * @pMac: Global MAC context
+ * @pMsgBuf: Message from WMA
+ *
+ * handles the notification from HDD. PE just forwards this message to HAL.
+ *
+ * Return: true-Posting to HAL failed, so PE will consume the buffer.
+ * false-Posting to HAL successful, so HAL will consume the buffer.
+ */
+
+static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirMsgQ msg;
+ tSirSmeReadyReq *ready_req = (tSirSmeReadyReq *) pMsgBuf;
+
+ msg.type = WMA_SYS_READY_IND;
+ msg.reserved = 0;
+ msg.bodyptr = pMsgBuf;
+ msg.bodyval = 0;
+
+ if (ANI_DRIVER_TYPE(pMac) != eDRIVER_TYPE_MFG) {
+ pe_register_wma_handle(pMac);
+ pMac->lim.add_bssdescr_callback = ready_req->add_bssdescr_cb;
+ }
+ PELOGW(lim_log(pMac, LOGW, FL("sending WMA_SYS_READY_IND msg to HAL"));)
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
+
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+ lim_log(pMac, LOGP, FL("wma_post_ctrl_msg failed"));
+ return true;
+ }
+ return false;
+}
+
+#ifdef WLAN_FEATURE_11AC
+
+uint32_t lim_get_center_channel(tpAniSirGlobal pMac, uint8_t primarychanNum,
+ ePhyChanBondState secondaryChanOffset,
+ uint8_t chanWidth)
+{
+ if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
+ switch (secondaryChanOffset) {
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+ return primarychanNum;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+ return primarychanNum + 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+ return primarychanNum - 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+ return primarychanNum + 6;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+ return primarychanNum + 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+ return primarychanNum - 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+ return primarychanNum - 6;
+ default:
+ return eSIR_CFG_INVALID_ID;
+ }
+ } else if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
+ switch (secondaryChanOffset) {
+ case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+ return primarychanNum + 2;
+ case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+ return primarychanNum - 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+ return primarychanNum;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+ return primarychanNum + 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+ return primarychanNum - 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+ return primarychanNum + 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+ return primarychanNum - 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+ return primarychanNum + 2;
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+ return primarychanNum - 2;
+ default:
+ return eSIR_CFG_INVALID_ID;
+ }
+ }
+ return primarychanNum;
+}
+
+#endif
+
+/**
+ *lim_configure_ap_start_bss_session() - Configure the AP Start BSS in session.
+ *@mac_ctx: Pointer to Global MAC structure
+ *@session: A pointer to session entry
+ *@sme_start_bss_req: Start BSS Request from upper layers.
+ *
+ * This function is used to configure the start bss parameters
+ * in to the session.
+ *
+ * Return: None.
+ */
+static void
+lim_configure_ap_start_bss_session(tpAniSirGlobal mac_ctx, tpPESession session,
+ tpSirSmeStartBssReq sme_start_bss_req)
+{
+ session->limSystemRole = eLIM_AP_ROLE;
+ session->privacy = sme_start_bss_req->privacy;
+ session->fwdWPSPBCProbeReq = sme_start_bss_req->fwdWPSPBCProbeReq;
+ session->authType = sme_start_bss_req->authType;
+ /* Store the DTIM period */
+ session->dtimPeriod = (uint8_t) sme_start_bss_req->dtimPeriod;
+ /* Enable/disable UAPSD */
+ session->apUapsdEnable = sme_start_bss_req->apUapsdEnable;
+ if (session->pePersona == CDF_P2P_GO_MODE) {
+ session->proxyProbeRspEn = 0;
+ } else {
+ /*
+ * To detect PBC overlap in SAP WPS mode,
+ * Host handles Probe Requests.
+ */
+ if (SAP_WPS_DISABLED == sme_start_bss_req->wps_state)
+ session->proxyProbeRspEn = 1;
+ else
+ session->proxyProbeRspEn = 0;
+ }
+ session->ssidHidden = sme_start_bss_req->ssidHidden;
+ session->wps_state = sme_start_bss_req->wps_state;
+ session->sap_dot11mc = sme_start_bss_req->sap_dot11mc;
+ lim_get_short_slot_from_phy_mode(mac_ctx, session, session->gLimPhyMode,
+ &session->shortSlotTimeSupported);
+ session->isCoalesingInIBSSAllowed =
+ sme_start_bss_req->isCoalesingInIBSSAllowed;
+
+}
+
+/**
+ * __lim_handle_sme_start_bss_request() - process SME_START_BSS_REQ message
+ *@mac_ctx: Pointer to Global MAC structure
+ *@msg_buf: A pointer to the SME message buffer
+ *
+ * This function is called to process SME_START_BSS_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+static void
+__lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ uint16_t size;
+ uint32_t val = 0;
+ tSirRetStatus ret_status;
+ tSirMacChanNum channel_number;
+ tLimMlmStartReq *mlm_start_req = NULL;
+ tpSirSmeStartBssReq sme_start_bss_req = NULL;
+ tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+ /* Flag Used in case of IBSS to Auto generate BSSID. */
+ uint32_t auto_gen_bssid = false;
+ uint8_t session_id;
+ tpPESession session = NULL;
+ uint8_t sme_session_id = 0;
+ uint16_t sme_transaction_id = 0;
+ uint32_t chanwidth;
+ tSirRetStatus cfg_get_wmi_dfs_master_param = eSIR_SUCCESS;
+
+/* FEATURE_WLAN_DIAG_SUPPORT */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ /*
+ * Since the session is not created yet, sending NULL.
+ * The response should have the correct state.
+ */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+ NULL, 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_log(mac_ctx, LOG1, FL("Received START_BSS_REQ"));
+
+ /*
+ * Global Sme state and mlm states are not defined yet,
+ * for BT-AMP Suppoprt . TO BE DONE
+ */
+ if ((mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) ||
+ (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE)) {
+ size = sizeof(tSirSmeStartBssReq);
+
+ sme_start_bss_req = cdf_mem_malloc(size);
+ if (NULL == sme_start_bss_req) {
+ lim_log(mac_ctx, LOGE,
+ FL("Allocate Memory fail for LimStartBssReq"));
+ /* Send failure response to host */
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+ cdf_mem_set((void *)sme_start_bss_req, size, 0);
+ cdf_mem_copy(sme_start_bss_req, msg_buf,
+ sizeof(tSirSmeStartBssReq));
+ if (!lim_is_sme_start_bss_req_valid(mac_ctx,
+ sme_start_bss_req)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Received invalid eWNI_SME_START_BSS_REQ"));
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto free;
+ }
+
+ /*
+ * This is the place where PE is going to create a session.
+ * If session is not existed, then create a new session
+ */
+ session = pe_find_session_by_bssid(mac_ctx,
+ sme_start_bss_req->bssId, &session_id);
+ if (session != NULL) {
+ lim_log(mac_ctx, LOGW,
+ FL("Session Already exists for given BSSID"));
+ ret_code = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ session = NULL;
+ goto free;
+ } else {
+ session = pe_create_session(mac_ctx,
+ sme_start_bss_req->bssId,
+ &session_id, mac_ctx->lim.maxStation,
+ sme_start_bss_req->bssType);
+ if (session == NULL) {
+ lim_log(mac_ctx, LOGW,
+ FL("Session Can not be created "));
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto free;
+ }
+ }
+
+ /* Probe resp add ie */
+ lim_start_bss_update_add_ie_buffer(mac_ctx,
+ &session->addIeParams.probeRespData_buff,
+ &session->addIeParams.probeRespDataLen,
+ sme_start_bss_req->addIeParams.probeRespData_buff,
+ sme_start_bss_req->addIeParams.probeRespDataLen);
+
+ /* Probe Beacon add ie */
+ lim_start_bss_update_add_ie_buffer(mac_ctx,
+ &session->addIeParams.probeRespBCNData_buff,
+ &session->addIeParams.probeRespBCNDataLen,
+ sme_start_bss_req->addIeParams.probeRespBCNData_buff,
+ sme_start_bss_req->addIeParams.probeRespBCNDataLen);
+
+ /* Assoc resp IE */
+ lim_start_bss_update_add_ie_buffer(mac_ctx,
+ &session->addIeParams.assocRespData_buff,
+ &session->addIeParams.assocRespDataLen,
+ sme_start_bss_req->addIeParams.assocRespData_buff,
+ sme_start_bss_req->addIeParams.assocRespDataLen);
+
+ /* Store the session related params in newly created session */
+ session->pLimStartBssReq = sme_start_bss_req;
+
+ /* Store PE session_id in session Table */
+ session->peSessionId = session_id;
+
+ /* Store SME session Id in sessionTable */
+ session->smeSessionId = sme_start_bss_req->sessionId;
+
+ session->transactionId = sme_start_bss_req->transactionId;
+
+ cdf_mem_copy(&(session->htConfig),
+ &(sme_start_bss_req->htConfig),
+ sizeof(session->htConfig));
+
+ sir_copy_mac_addr(session->selfMacAddr,
+ sme_start_bss_req->selfMacAddr);
+
+ /* Copy SSID to session table */
+ cdf_mem_copy((uint8_t *) &session->ssId,
+ (uint8_t *) &sme_start_bss_req->ssId,
+ (sme_start_bss_req->ssId.length + 1));
+
+ session->bssType = sme_start_bss_req->bssType;
+
+ session->nwType = sme_start_bss_req->nwType;
+
+ session->beaconParams.beaconInterval =
+ sme_start_bss_req->beaconInterval;
+
+ /* Store the channel number in session Table */
+ session->currentOperChannel =
+ sme_start_bss_req->channelId;
+
+ /* Store Persona */
+ session->pePersona = sme_start_bss_req->bssPersona;
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("PE PERSONA=%d"), session->pePersona);
+
+ /* Update the phymode */
+ session->gLimPhyMode = sme_start_bss_req->nwType;
+
+ session->maxTxPower =
+ cfg_get_regulatory_max_transmit_power(mac_ctx,
+ session->currentOperChannel);
+ /* Store the dot 11 mode in to the session Table */
+ session->dot11mode = sme_start_bss_req->dot11mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ session->cc_switch_mode =
+ sme_start_bss_req->cc_switch_mode;
+#endif
+ session->htCapability =
+ IS_DOT11_MODE_HT(session->dot11mode);
+ session->vhtCapability =
+ IS_DOT11_MODE_VHT(session->dot11mode);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("*****session->vhtCapability = %d"),
+ session->vhtCapability);
+ session->txLdpcIniFeatureEnabled =
+ sme_start_bss_req->txLdpcIniFeatureEnabled;
+
+ if (mac_ctx->roam.configParam.enable2x2)
+ session->nss = 2;
+ else
+ session->nss = 1;
+#ifdef WLAN_FEATURE_11W
+ session->limRmfEnabled =
+ sme_start_bss_req->pmfCapable ? 1 : 0;
+ lim_log(mac_ctx, LOG1, FL("Session RMF enabled: %d"),
+ session->limRmfEnabled);
+#endif
+
+ cdf_mem_copy((void *)&session->rateSet,
+ (void *)&sme_start_bss_req->operationalRateSet,
+ sizeof(tSirMacRateSet));
+ cdf_mem_copy((void *)&session->extRateSet,
+ (void *)&sme_start_bss_req->extendedRateSet,
+ sizeof(tSirMacRateSet));
+
+ switch (sme_start_bss_req->bssType) {
+ case eSIR_INFRA_AP_MODE:
+ lim_configure_ap_start_bss_session(mac_ctx, session,
+ sme_start_bss_req);
+ break;
+ case eSIR_IBSS_MODE:
+ session->limSystemRole = eLIM_STA_IN_IBSS_ROLE;
+ lim_get_short_slot_from_phy_mode(mac_ctx, session,
+ session->gLimPhyMode,
+ &session->shortSlotTimeSupported);
+
+ /*
+ * initialize to "OPEN".
+ * will be updated upon key installation
+ */
+ session->encryptType = eSIR_ED_NONE;
+
+ break;
+
+ case eSIR_BTAMP_AP_MODE:
+ session->limSystemRole = eLIM_BT_AMP_AP_ROLE;
+ break;
+
+ case eSIR_BTAMP_STA_MODE:
+ session->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ break;
+
+ /*
+ * There is one more mode called auto mode.
+ * which is used no where
+ */
+
+ /* FORBUILD -TEMPFIX.. HOW TO use AUTO MODE????? */
+
+ default:
+ /* not used anywhere...used in scan function */
+ break;
+ }
+
+ /*
+ * BT-AMP: Allocate memory for the array of
+ * parsed (Re)Assoc request structure
+ */
+ if ((sme_start_bss_req->bssType == eSIR_BTAMP_AP_MODE) ||
+ (sme_start_bss_req->bssType == eSIR_INFRA_AP_MODE)) {
+ session->parsedAssocReq =
+ cdf_mem_malloc(session->dph.dphHashTable.
+ size * sizeof(tpSirAssocReq));
+ if (NULL == session->parsedAssocReq) {
+ lim_log(mac_ctx, LOGW,
+ FL("AllocateMemory() failed"));
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto free;
+ }
+ cdf_mem_set(session->parsedAssocReq,
+ (session->dph.dphHashTable.size *
+ sizeof(tpSirAssocReq)), 0);
+ }
+
+ if (!sme_start_bss_req->channelId) {
+ lim_log(mac_ctx, LOGE,
+ FL("Received invalid eWNI_SME_START_BSS_REQ"));
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto free;
+ }
+ channel_number = sme_start_bss_req->channelId;
+#ifdef QCA_HT_2040_COEX
+ if (sme_start_bss_req->obssEnabled)
+ session->htSupportedChannelWidthSet =
+ session->htCapability;
+ else
+#endif
+ session->htSupportedChannelWidthSet =
+ (sme_start_bss_req->sec_ch_offset) ? 1 : 0;
+ session->htSecondaryChannelOffset =
+ sme_start_bss_req->sec_ch_offset;
+ session->htRecommendedTxWidthSet =
+ (session->htSecondaryChannelOffset) ? 1 : 0;
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("cbMode %u"), sme_start_bss_req->cbMode);
+ if (session->vhtCapability || session->htCapability) {
+ chanwidth = sme_start_bss_req->vht_channel_width;
+ lim_log(mac_ctx, LOG1, FL("vht_channel_width %u"),
+ sme_start_bss_req->vht_channel_width);
+ if (channel_number <= RF_CHAN_14 &&
+ chanwidth != eHT_CHANNEL_WIDTH_20MHZ) {
+ chanwidth = CH_WIDTH_20MHZ;
+ session->htSupportedChannelWidthSet = 0;
+ lim_log(mac_ctx, LOG1,
+ FL("Set chanwidth to 20Mhz, chan %d"),
+ channel_number);
+ }
+ session->ch_width = chanwidth;
+ if (session->htSupportedChannelWidthSet) {
+ session->ch_center_freq_seg0 =
+ sme_start_bss_req->center_freq_seg0;
+ session->ch_center_freq_seg1 =
+ sme_start_bss_req->center_freq_seg1;
+ } else {
+ session->ch_center_freq_seg0 = 0;
+ session->ch_center_freq_seg1 = 0;
+ }
+ }
+
+ if (session->vhtCapability &&
+ (CH_WIDTH_160MHZ > session->ch_width)) {
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_VHT_SU_BEAMFORMER_CAP, &val) !=
+ eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE, FL(
+ "cfg get vht su bformer failed"));
+
+ session->enable_su_tx_bformer = val;
+ } else {
+ session->nss = 1;
+ }
+ lim_log(mac_ctx, LOG1, FL("vht su tx bformer %d"), val);
+
+ /* Delete pre-auth list if any */
+ lim_delete_pre_auth_list(mac_ctx);
+
+ /*
+ * keep the RSN/WPA IE information in PE Session Entry
+ * later will be using this to check when received (Re)Assoc req
+ */
+ lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(mac_ctx,
+ &sme_start_bss_req->rsnIE, session);
+
+ if (LIM_IS_AP_ROLE(session) || LIM_IS_IBSS_ROLE(session)) {
+ session->gLimProtectionControl =
+ sme_start_bss_req->protEnabled;
+ /*
+ * each byte will have the following info
+ * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
+ * reserved reserved RIFS Lsig n-GF ht20 11g 11b
+ */
+ cdf_mem_copy((void *)&session->cfgProtection,
+ (void *)&sme_start_bss_req->ht_capab,
+ sizeof(uint16_t));
+ /* Initialize WPS PBC session link list */
+ session->pAPWPSPBCSession = NULL;
+ }
+ /* Prepare and Issue LIM_MLM_START_REQ to MLM */
+ mlm_start_req = cdf_mem_malloc(sizeof(tLimMlmStartReq));
+ if (NULL == mlm_start_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("Allocate Memory failed for mlmStartReq"));
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto free;
+ }
+
+ cdf_mem_set((void *)mlm_start_req, sizeof(tLimMlmStartReq), 0);
+
+ /* Copy SSID to the MLM start structure */
+ cdf_mem_copy((uint8_t *) &mlm_start_req->ssId,
+ (uint8_t *) &sme_start_bss_req->ssId,
+ sme_start_bss_req->ssId.length + 1);
+ mlm_start_req->ssidHidden = sme_start_bss_req->ssidHidden;
+ mlm_start_req->obssProtEnabled =
+ sme_start_bss_req->obssProtEnabled;
+
+ mlm_start_req->bssType = session->bssType;
+
+ /* Fill PE session Id from the session Table */
+ mlm_start_req->sessionId = session->peSessionId;
+
+ if ((mlm_start_req->bssType == eSIR_BTAMP_STA_MODE) ||
+ (mlm_start_req->bssType == eSIR_BTAMP_AP_MODE) ||
+ (mlm_start_req->bssType == eSIR_INFRA_AP_MODE)) {
+ /*
+ * Copy the BSSId from sessionTable to
+ * mlmStartReq struct
+ */
+ sir_copy_mac_addr(mlm_start_req->bssId, session->bssId);
+ } else {
+ /* ibss mode */
+ mac_ctx->lim.gLimIbssCoalescingHappened = false;
+
+ ret_status = wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_IBSS_AUTO_BSSID,
+ &auto_gen_bssid);
+ if (ret_status != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("Get Auto Gen BSSID fail,Status=%d"),
+ ret_status);
+ ret_code = eSIR_LOGP_EXCEPTION;
+ goto free;
+ }
+
+ if (!auto_gen_bssid) {
+ /*
+ * We're not auto generating BSSID.
+ * Instead, get it from session entry
+ */
+ sir_copy_mac_addr(mlm_start_req->bssId,
+ session->bssId);
+ /*
+ * Start IBSS group BSSID
+ * Auto Generating BSSID.
+ */
+ auto_gen_bssid = ((mlm_start_req->bssId[0] &
+ 0x01) ? true : false);
+ }
+
+ if (auto_gen_bssid) {
+ /*
+ * if BSSID is not any uc id.
+ * then use locally generated BSSID.
+ * Autogenerate the BSSID
+ */
+ lim_get_random_bssid(mac_ctx,
+ mlm_start_req->bssId);
+ mlm_start_req->bssId[0] = 0x02;
+
+ /*
+ * Copy randomly generated BSSID
+ * to the session Table
+ */
+ sir_copy_mac_addr(session->bssId,
+ mlm_start_req->bssId);
+ }
+ }
+ /* store the channel num in mlmstart req structure */
+ mlm_start_req->channelNumber = session->currentOperChannel;
+ mlm_start_req->cbMode = sme_start_bss_req->cbMode;
+ mlm_start_req->beaconPeriod =
+ session->beaconParams.beaconInterval;
+
+ if (LIM_IS_AP_ROLE(session)) {
+ mlm_start_req->dtimPeriod = session->dtimPeriod;
+ mlm_start_req->wps_state = session->wps_state;
+
+ } else {
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_DTIM_PERIOD, &val) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve DTIM Period"));
+ mlm_start_req->dtimPeriod = (uint8_t) val;
+ }
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_CFP_PERIOD, &val) !=
+ eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve Beacon interval"));
+ mlm_start_req->cfParamSet.cfpPeriod = (uint8_t) val;
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_CFP_MAX_DURATION, &val) !=
+ eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve CFPMaxDuration"));
+ mlm_start_req->cfParamSet.cfpMaxDuration = (uint16_t) val;
+
+ /*
+ * this may not be needed anymore now,
+ * as rateSet is now included in the
+ * session entry and MLM has session context.
+ */
+ cdf_mem_copy((void *)&mlm_start_req->rateSet,
+ (void *)&session->rateSet,
+ sizeof(tSirMacRateSet));
+
+ /* Now populate the 11n related parameters */
+ mlm_start_req->nwType = session->nwType;
+ mlm_start_req->htCapable = session->htCapability;
+
+ mlm_start_req->htOperMode = mac_ctx->lim.gHTOperMode;
+ /* Unused */
+ mlm_start_req->dualCTSProtection =
+ mac_ctx->lim.gHTDualCTSProtection;
+ mlm_start_req->txChannelWidthSet =
+ session->htRecommendedTxWidthSet;
+
+ session->limRFBand = lim_get_rf_band(channel_number);
+
+ /* Initialize 11h Enable Flag */
+ session->lim11hEnable = 0;
+ if ((mlm_start_req->bssType != eSIR_IBSS_MODE) &&
+ (SIR_BAND_5_GHZ == session->limRFBand)) {
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Fail to get WNI_CFG_11H_ENABLED "));
+ else
+ session->lim11hEnable = val;
+
+ if (session->lim11hEnable &&
+ (eSIR_INFRA_AP_MODE ==
+ mlm_start_req->bssType)) {
+ cfg_get_wmi_dfs_master_param =
+ wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_DFS_MASTER_ENABLED,
+ &val);
+ session->lim11hEnable = val;
+ }
+ if (cfg_get_wmi_dfs_master_param != eSIR_SUCCESS)
+ /* Failed get CFG WNI_CFG_DFS_MASTER_ENABLED */
+ lim_log(mac_ctx, LOGE,
+ FL("Get Fail, CFG DFS ENABLE"));
+ }
+
+ if (!session->lim11hEnable) {
+ if (cfg_set_int(mac_ctx,
+ WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) !=
+ eSIR_SUCCESS)
+ /*
+ * Failed to set the CFG param
+ * WNI_CFG_LOCAL_POWER_CONSTRAINT
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("Set LOCAL_POWER_CONSTRAINT failed"));
+ }
+
+ session->limPrevSmeState = session->limSmeState;
+ session->limSmeState = eLIM_SME_WT_START_BSS_STATE;
+ MTRACE(mac_trace
+ (mac_ctx, TRACE_CODE_SME_STATE,
+ session->peSessionId,
+ session->limSmeState));
+
+ lim_post_mlm_message(mac_ctx, LIM_MLM_START_REQ,
+ (uint32_t *) mlm_start_req);
+ return;
+ } else {
+
+ lim_log(mac_ctx, LOGE,
+ FL("Received unexpected START_BSS_REQ, in state %X"),
+ mac_ctx->lim.gLimSmeState);
+ ret_code = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED;
+ goto end;
+ } /* if (mac_ctx->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) */
+
+free:
+ if ((session != NULL) &&
+ (session->pLimStartBssReq == sme_start_bss_req)) {
+ session->pLimStartBssReq = NULL;
+ }
+ cdf_mem_free(sme_start_bss_req);
+ cdf_mem_free(mlm_start_req);
+
+end:
+ if (sme_start_bss_req != NULL) {
+ sme_session_id = sme_start_bss_req->sessionId;
+ sme_transaction_id = sme_start_bss_req->transactionId;
+ }
+ if (NULL != session) {
+ pe_delete_session(mac_ctx, session);
+ session = NULL;
+ }
+ lim_send_sme_start_bss_rsp(mac_ctx, eWNI_SME_START_BSS_RSP, ret_code,
+ session, sme_session_id, sme_transaction_id);
+}
+
+/**
+ * __lim_process_sme_start_bss_req() - Call handler to start BSS
+ *
+ * @pMac: Global MAC context
+ * @pMsg: Message pointer
+ *
+ * Wrapper for the function __lim_handle_sme_start_bss_request
+ * This message will be defered until softmac come out of
+ * scan mode or if we have detected radar on the current
+ * operating channel.
+ *
+ * return true - If we consumed the buffer
+ * false - If have defered the message.
+ */
+static bool __lim_process_sme_start_bss_req(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (__lim_is_defered_msg_for_learn(pMac, pMsg) ||
+ __lim_is_defered_msg_for_radar(pMac, pMsg)) {
+ /**
+ * If message defered, buffer is not consumed yet.
+ * So return false
+ */
+ return false;
+ }
+
+ __lim_handle_sme_start_bss_request(pMac, (uint32_t *) pMsg->bodyptr);
+ return true;
+}
+
+/**
+ * lim_get_random_bssid()
+ *
+ * FUNCTION:This function is called to process generate the random number for bssid
+ * This function is called to process SME_SCAN_REQ message
+ * from HDD or upper layer application.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ * 1. geneartes the unique random number for bssid in ibss
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *data Pointer to bssid buffer
+ * @return None
+ */
+void lim_get_random_bssid(tpAniSirGlobal pMac, uint8_t *data)
+{
+ uint32_t random[2];
+ random[0] = tx_time_get();
+ random[0] |= (random[0] << 15);
+ random[1] = random[0] >> 1;
+ cdf_mem_copy(data, (uint8_t *) random, sizeof(tSirMacAddr));
+}
+
+static CDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
+ tpSirSmeScanReq pScanReq)
+{
+ tSirScanOffloadReq *pScanOffloadReq;
+ uint8_t *p;
+ uint8_t *ht_cap_ie;
+ tSirMsgQ msg;
+ uint16_t i, len;
+ uint16_t ht_cap_len = 0, addn_ie_len = 0;
+#ifdef WLAN_FEATURE_11AC
+ uint8_t *vht_cap_ie;
+ uint16_t vht_cap_len = 0;
+#endif /* WLAN_FEATURE_11AC */
+ tSirRetStatus status, rc = eSIR_SUCCESS;
+ tDot11fIEExtCap extracted_extcap = {0};
+ bool extcap_present = true;
+
+ if (pScanReq->uIEFieldLen) {
+ status = lim_strip_extcap_update_struct(pMac,
+ (uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
+ &pScanReq->uIEFieldLen, &extracted_extcap);
+
+ if (eSIR_SUCCESS != status) {
+ extcap_present = false;
+ lim_log(pMac, LOG1,
+ FL("Unable to Strip ExtCap IE from Scan Req"));
+ }
+
+ if (extcap_present) {
+ lim_log(pMac, LOG1,
+ FL("Extcap was part of SCAN IE - Updating FW"));
+ lim_send_ext_cap_ie(pMac, pScanReq->sessionId,
+ &extracted_extcap, true);
+ }
+ } else {
+ lim_log(pMac, LOG1,
+ FL("No IEs in the scan request from supplicant"));
+ }
+
+ /**
+ * The tSirScanOffloadReq will reserve the space for first channel,
+ * so allocate the memory for (numChannels - 1) and uIEFieldLen
+ */
+ len = sizeof(tSirScanOffloadReq) +
+ (pScanReq->channelList.numChannels - 1) + pScanReq->uIEFieldLen;
+
+ if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
+ lim_log(pMac, LOG1,
+ FL("Adding HT Caps IE since dot11mode=%d"),
+ pScanReq->dot11mode);
+ /* 2 bytes for EID and Length */
+ ht_cap_len = 2 + sizeof(tHtCaps);
+ len += ht_cap_len;
+ addn_ie_len += ht_cap_len;
+ }
+
+#ifdef WLAN_FEATURE_11AC
+ if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
+ lim_log(pMac, LOG1,
+ FL("Adding VHT Caps IE since dot11mode=%d"),
+ pScanReq->dot11mode);
+ /* 2 bytes for EID and Length */
+ vht_cap_len = 2 + sizeof(tSirMacVHTCapabilityInfo) +
+ sizeof(tSirVhtMcsInfo);
+ len += vht_cap_len;
+ addn_ie_len += vht_cap_len;
+ }
+#endif /* WLAN_FEATURE_11AC */
+
+ pScanOffloadReq = cdf_mem_malloc(len);
+ if (NULL == pScanOffloadReq) {
+ lim_log(pMac, LOGE,
+ FL("AllocateMemory failed for pScanOffloadReq"));
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ cdf_mem_set((uint8_t *) pScanOffloadReq, len, 0);
+
+ msg.type = WMA_START_SCAN_OFFLOAD_REQ;
+ msg.bodyptr = pScanOffloadReq;
+ msg.bodyval = 0;
+
+ cdf_mem_copy((uint8_t *) pScanOffloadReq->bssId,
+ (uint8_t *) pScanReq->bssId, sizeof(tSirMacAddr));
+
+ if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) {
+ lim_log(pMac, LOGE,
+ FL("Invalid value (%d) for numSsid"),
+ SIR_SCAN_MAX_NUM_SSID);
+ cdf_mem_free(pScanOffloadReq);
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ pScanOffloadReq->numSsid = pScanReq->numSsid;
+ for (i = 0; i < pScanOffloadReq->numSsid; i++) {
+ pScanOffloadReq->ssId[i].length = pScanReq->ssId[i].length;
+ cdf_mem_copy((uint8_t *) pScanOffloadReq->ssId[i].ssId,
+ (uint8_t *) pScanReq->ssId[i].ssId,
+ pScanOffloadReq->ssId[i].length);
+ }
+
+ pScanOffloadReq->hiddenSsid = pScanReq->hiddenSsid;
+ cdf_mem_copy((uint8_t *) pScanOffloadReq->selfMacAddr,
+ (uint8_t *) pScanReq->selfMacAddr, sizeof(tSirMacAddr));
+ pScanOffloadReq->bssType = pScanReq->bssType;
+ pScanOffloadReq->dot11mode = pScanReq->dot11mode;
+ pScanOffloadReq->scanType = pScanReq->scanType;
+ pScanOffloadReq->minChannelTime = pScanReq->minChannelTime;
+ pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime;
+ pScanOffloadReq->restTime = pScanReq->restTime;
+
+ /* for normal scan, the value for p2pScanType should be 0
+ always */
+ if (pScanReq->p2pSearch)
+ pScanOffloadReq->p2pScanType = P2P_SCAN_TYPE_SEARCH;
+
+ pScanOffloadReq->sessionId = pScanReq->sessionId;
+ pScanOffloadReq->scan_id = pScanReq->scan_id;
+
+ if (pScanOffloadReq->sessionId >= pMac->lim.maxBssId)
+ lim_log(pMac, LOGE, FL("Invalid pe sessionID : %d"),
+ pScanOffloadReq->sessionId);
+
+ pScanOffloadReq->channelList.numChannels =
+ pScanReq->channelList.numChannels;
+ p = &(pScanOffloadReq->channelList.channelNumber[0]);
+ for (i = 0; i < pScanOffloadReq->channelList.numChannels; i++)
+ p[i] = pScanReq->channelList.channelNumber[i];
+
+ pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen;
+ pScanOffloadReq->uIEFieldOffset = len - addn_ie_len -
+ pScanOffloadReq->uIEFieldLen;
+ cdf_mem_copy((uint8_t *) pScanOffloadReq +
+ pScanOffloadReq->uIEFieldOffset,
+ (uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
+ pScanReq->uIEFieldLen);
+
+ /* Copy HT Capability info if dot11mode is HT */
+ if (IS_DOT11_MODE_HT(pScanReq->dot11mode)) {
+ /* Populate EID and Length field here */
+ ht_cap_ie = (uint8_t *) pScanOffloadReq +
+ pScanOffloadReq->uIEFieldOffset +
+ pScanOffloadReq->uIEFieldLen;
+ cdf_mem_set(ht_cap_ie, ht_cap_len, 0);
+ *ht_cap_ie = SIR_MAC_HT_CAPABILITIES_EID;
+ *(ht_cap_ie + 1) = ht_cap_len - 2;
+ lim_set_ht_caps(pMac, NULL, ht_cap_ie, ht_cap_len);
+ pScanOffloadReq->uIEFieldLen += ht_cap_len;
+ }
+
+#ifdef WLAN_FEATURE_11AC
+ /* Copy VHT Capability info if dot11mode is VHT Capable */
+ if (IS_DOT11_MODE_VHT(pScanReq->dot11mode)) {
+ /* Populate EID and Length field here */
+ vht_cap_ie = (uint8_t *) pScanOffloadReq +
+ pScanOffloadReq->uIEFieldOffset +
+ pScanOffloadReq->uIEFieldLen;
+ cdf_mem_set(vht_cap_ie, vht_cap_len, 0);
+ *vht_cap_ie = SIR_MAC_VHT_CAPABILITIES_EID;
+ *(vht_cap_ie + 1) = vht_cap_len - 2;
+ lim_set_vht_caps(pMac, NULL, vht_cap_ie, vht_cap_len);
+ pScanOffloadReq->uIEFieldLen += vht_cap_len;
+ }
+#endif /* WLAN_FEATURE_11AC */
+
+ rc = wma_post_ctrl_msg(pMac, &msg);
+ if (rc != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure"));
+ cdf_mem_free(pScanOffloadReq);
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ lim_log(pMac, LOG1, FL("Processed Offload Scan Request Successfully"));
+
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * __lim_process_sme_scan_req() - Process the SME Scan Request
+ * @mac_ctx: Global MAC Context
+ * @msg_buf: Buffer which contains the request and pertinent parameters
+ *
+ * This function is called to process SME_SCAN_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void __lim_process_sme_scan_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tpSirSmeScanReq scan_req;
+ uint8_t valid_req = 0;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SCAN_REQ_EVENT, NULL,
+ eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+
+ scan_req = (tpSirSmeScanReq) msg_buf;
+ lim_log(mac_ctx, LOG1,
+ FL("SME SCAN REQ id %d numChan %d min %d max %d IELen %d first %d fresh %d unique %d type %d rsp %d"),
+ scan_req->scan_id, scan_req->channelList.numChannels,
+ scan_req->minChannelTime, scan_req->maxChannelTime,
+ scan_req->uIEFieldLen, scan_req->returnAfterFirstMatch,
+ scan_req->returnFreshResults, scan_req->returnUniqueResults,
+ scan_req->scanType, mac_ctx->lim.gLimRspReqd ? 1 : 0);
+ /*
+ * Since scan req always requires a response, we will overwrite response
+ * required here. This is added esp to take care of the condition where
+ * in p2p go case, we hold the scan req and insert single NOA. We send
+ * the held scan request to FW later on getting start NOA ind from FW so
+ * we lose state of the gLimRspReqd flag for the scan req if any other
+ * request comes by then. e.g. While unit testing, we found when insert
+ * single NOA is done, we see a get stats request which turns the flag
+ * gLimRspReqd to false; now when we actually start the saved scan req
+ * for init scan after getting NOA started, the gLimRspReqd being a
+ * global flag is showing false instead of true value for this saved
+ * scan req. Since all scan reqs coming to lim require a response,
+ * there is no harm in setting the global flag gLimRspReqd to true here.
+ */
+ mac_ctx->lim.gLimRspReqd = true;
+
+ /*
+ * copy the Self MAC address from SmeReq to the globalplace,
+ * used for sending probe req
+ */
+ sir_copy_mac_addr(mac_ctx->lim.gSelfMacAddr, scan_req->selfMacAddr);
+ valid_req = lim_is_sme_scan_req_valid(mac_ctx, scan_req);
+
+ if (!valid_req || mac_ctx->lim.scan_disabled) {
+ lim_log(mac_ctx, LOGE,
+ FL("Scan disabled %d, Valid Scan Req %d"),
+ mac_ctx->lim.scan_disabled, valid_req);
+
+ if (mac_ctx->lim.gLimRspReqd) {
+ mac_ctx->lim.gLimRspReqd = false;
+
+ lim_send_sme_scan_rsp(mac_ctx,
+ eSIR_SME_INVALID_PARAMETERS,
+ scan_req->sessionId,
+ scan_req->transactionId,
+ scan_req->scan_id);
+ }
+ return;
+ }
+
+ /*
+ * If scan request is received in idle, joinFailed
+ * states or in link established state (in STA role)
+ * or in normal state (in STA-in-IBSS/AP role) with
+ * 'return fresh scan results' request from HDD or
+ * it is periodic background scanning request,
+ * trigger fresh scan request to MLM
+ */
+ if (__lim_fresh_scan_reqd(mac_ctx, scan_req->returnFreshResults)) {
+
+ mac_ctx->lim.gLim24Band11dScanDone = 0;
+ mac_ctx->lim.gLim50Band11dScanDone = 0;
+ mac_ctx->lim.gLimReturnAfterFirstMatch =
+ scan_req->returnAfterFirstMatch;
+ mac_ctx->lim.gLimReturnUniqueResults =
+ ((scan_req->returnUniqueResults) > 0 ? true : false);
+
+ if (CDF_STATUS_SUCCESS !=
+ lim_send_hal_start_scan_offload_req(mac_ctx,
+ scan_req)) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Couldn't send Offload scan request"));
+ lim_send_sme_scan_rsp(mac_ctx,
+ eSIR_SME_INVALID_PARAMETERS,
+ scan_req->sessionId,
+ scan_req->transactionId,
+ scan_req->scan_id);
+ return;
+ }
+ }
+ else {
+ /* In all other cases return 'cached' scan results */
+ if (mac_ctx->lim.gLimRspReqd) {
+ mac_ctx->lim.gLimRspReqd = false;
+ lim_send_sme_scan_rsp(mac_ctx, eSIR_SME_SUCCESS,
+ scan_req->sessionId,
+ scan_req->transactionId, scan_req->scan_id);
+ }
+ }
+}
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+static void __lim_process_sme_oem_data_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpSirOemDataReq pOemDataReq;
+ tLimMlmOemDataReq *pMlmOemDataReq;
+
+ pOemDataReq = (tpSirOemDataReq) pMsgBuf;
+
+ /* post the lim mlm message now */
+ pMlmOemDataReq = cdf_mem_malloc(sizeof(tLimMlmOemDataReq));
+ if (NULL == pMlmOemDataReq) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for mlmOemDataReq"));
+ return;
+ }
+ /* Initialize this buffer */
+ cdf_mem_set(pMlmOemDataReq, (sizeof(tLimMlmOemDataReq)), 0);
+
+ cdf_mem_copy(pMlmOemDataReq->selfMacAddr, pOemDataReq->selfMacAddr,
+ sizeof(tSirMacAddr));
+ cdf_mem_copy(pMlmOemDataReq->oemDataReq, pOemDataReq->oemDataReq,
+ OEM_DATA_REQ_SIZE);
+
+ /* Issue LIM_MLM_OEM_DATA_REQ to MLM */
+ lim_post_mlm_message(pMac, LIM_MLM_OEM_DATA_REQ,
+ (uint32_t *) pMlmOemDataReq);
+
+ return;
+
+} /*** end __lim_process_sme_oem_data_req() ***/
+
+#endif /* FEATURE_OEM_DATA_SUPPORT */
+
+/**
+ * __lim_process_clear_dfs_channel_list()
+ *
+ ***FUNCTION:
+ ***Clear DFS channel list when country is changed/aquired.
+ .*This message is sent from SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+static void __lim_process_clear_dfs_channel_list(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ cdf_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0);
+}
+
+/**
+ * __lim_process_sme_join_req() - process SME_JOIN_REQ message
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: A pointer to the SME message buffer
+ *
+ * This function is called to process SME_JOIN_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+static void
+__lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tpSirSmeJoinReq sme_join_req = NULL;
+ tLimMlmJoinReq *mlm_join_req;
+ tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+ uint32_t val = 0;
+ uint16_t n_size;
+ uint8_t session_id;
+ tpPESession session = NULL;
+ uint8_t sme_session_id;
+ uint16_t sme_transaction_id;
+ tPowerdBm local_power_constraint = 0, reg_max = 0;
+ uint16_t ie_len;
+ uint8_t *vendor_ie;
+ tSirBssDescription bss_desc;
+
+/* FEATURE_WLAN_DIAG_SUPPORT */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ /*
+ * Not sending any session, since it is not created yet.
+ * The response whould have correct state.
+ */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_log(mac_ctx, LOG1, FL("Received SME_JOIN_REQ"));
+#ifdef WLAN_FEATURE_VOWIFI
+ /*
+ * Need to read the CFG here itself as this is
+ * used in limExtractAPCapability() below.
+ * This CFG is actually read in rrm_update_config()
+ * which is called later. Because this is not
+ * read, RRM related path before calling rrm_update_config()
+ * is not getting executed causing issues
+ * like not honoring power constraint on 1st association
+ * after driver loading.
+ */
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_RRM_ENABLED, &val) !=
+ eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP, FL("cfg get rrm enabled failed"));
+ mac_ctx->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0;
+ val = 0;
+#endif /* WLAN_FEATURE_VOWIFI */
+
+ /*
+ * Expect Join request in idle state.
+ * Reassociate request is expected in link established state.
+ */
+
+ /* Global SME and LIM states are not defined yet for BT-AMP Support */
+ if (mac_ctx->lim.gLimSmeState == eLIM_SME_IDLE_STATE) {
+ n_size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)
+ msg_buf);
+
+ sme_join_req = cdf_mem_malloc(n_size);
+ if (NULL == sme_join_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("AllocateMemory failed for sme_join_req"));
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ return;
+ }
+ (void)cdf_mem_set((void *)sme_join_req, n_size, 0);
+ (void)cdf_mem_copy((void *)sme_join_req, (void *)msg_buf,
+ n_size);
+
+ if (!lim_is_sme_join_req_valid(mac_ctx, sme_join_req)) {
+ /* Received invalid eWNI_SME_JOIN_REQ */
+ /* Log the event */
+ lim_log(mac_ctx, LOGW,
+ FL("SessionId:%d JOIN REQ with invalid data"),
+ sme_join_req->sessionId);
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ bss_desc = sme_join_req->bssDescription;
+ /* check for the existence of start BSS session */
+
+ session = pe_find_session_by_bssid(mac_ctx, bss_desc.bssId,
+ &session_id);
+
+ if (session != NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session(%d) Already exists for BSSID: "
+ MAC_ADDRESS_STR " in limSmeState = %X"),
+ session_id,
+ MAC_ADDR_ARRAY(bss_desc.bssId),
+ session->limSmeState);
+
+ if (session->limSmeState == eLIM_SME_LINK_EST_STATE &&
+ session->smeSessionId == sme_join_req->sessionId) {
+ /*
+ * Received eWNI_SME_JOIN_REQ for same
+ * BSS as currently associated.
+ * Log the event and send success
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("SessionId: %d"), session_id);
+ lim_log(mac_ctx, LOGW,
+ FL("JOIN_REQ for current joined BSS"));
+ /* Send Join success response to host */
+ ret_code = eSIR_SME_ALREADY_JOINED_A_BSS;
+ session = NULL;
+ goto end;
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("JOIN_REQ not for current joined BSS"));
+ ret_code = eSIR_SME_REFUSED;
+ session = NULL;
+ goto end;
+ }
+ } else {
+ /*
+ * Session Entry does not exist for given BSSId
+ * Try to Create a new session
+ */
+ session = pe_create_session(mac_ctx, bss_desc.bssId,
+ &session_id, mac_ctx->lim.maxStation,
+ eSIR_INFRASTRUCTURE_MODE);
+ if (session == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session Can not be created "));
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ } else
+ lim_log(mac_ctx, LOG1,
+ FL("SessionId:%d New session created"),
+ session_id);
+ }
+ session->isAmsduSupportInAMPDU =
+ sme_join_req->isAmsduSupportInAMPDU;
+
+ /*
+ * Store Session related parameters
+ * Store PE session Id in session Table
+ */
+ session->peSessionId = session_id;
+
+ /* store the smejoin req handle in session table */
+ session->pLimJoinReq = sme_join_req;
+
+ /* Store SME session Id in sessionTable */
+ session->smeSessionId = sme_join_req->sessionId;
+
+ /* Store SME transaction Id in session Table */
+ session->transactionId = sme_join_req->transactionId;
+
+ /* Store beaconInterval */
+ session->beaconParams.beaconInterval =
+ bss_desc.beaconInterval;
+
+ cdf_mem_copy(&(session->htConfig), &(sme_join_req->htConfig),
+ sizeof(session->htConfig));
+
+ /* Copying of bssId is already done, while creating session */
+ sir_copy_mac_addr(session->selfMacAddr,
+ sme_join_req->selfMacAddr);
+ session->bssType = sme_join_req->bsstype;
+
+ session->statypeForBss = STA_ENTRY_PEER;
+ session->limWmeEnabled = sme_join_req->isWMEenabled;
+ session->limQosEnabled = sme_join_req->isQosEnabled;
+
+ /* Store vendor specfic IE for CISCO AP */
+ ie_len = (bss_desc.length + sizeof(bss_desc.length) -
+ GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+ vendor_ie = cfg_get_vendor_ie_ptr_from_oui(mac_ctx,
+ SIR_MAC_CISCO_OUI, SIR_MAC_CISCO_OUI_SIZE,
+ ((uint8_t *)&bss_desc.ieFields), ie_len);
+
+ if (NULL != vendor_ie) {
+ lim_log(mac_ctx, LOGE,
+ FL("DUT is trying to connect to Cisco AP"));
+ session->isCiscoVendorAP = true;
+ } else {
+ session->isCiscoVendorAP = false;
+ }
+
+ /* Copy the dot 11 mode in to the session table */
+
+ session->dot11mode = sme_join_req->dot11mode;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ session->cc_switch_mode = sme_join_req->cc_switch_mode;
+#endif
+ session->nwType = bss_desc.nwType;
+ session->enableAmpduPs = sme_join_req->enableAmpduPs;
+ session->enableHtSmps = sme_join_req->enableHtSmps;
+ session->htSmpsvalue = sme_join_req->htSmps;
+
+ /*Store Persona */
+ session->pePersona = sme_join_req->staPersona;
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("PE PERSONA=%d cbMode %u"),
+ session->pePersona, sme_join_req->cbMode);
+ if (mac_ctx->roam.configParam.enable2x2)
+ session->nss = 2;
+ else
+ session->nss = 1;
+#ifdef WLAN_FEATURE_11AC
+ session->vhtCapability =
+ IS_DOT11_MODE_VHT(session->dot11mode);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
+ "***__lim_process_sme_join_req: vhtCapability=%d****",
+ session->vhtCapability);
+ if (session->vhtCapability) {
+ if (session->pePersona == CDF_STA_MODE) {
+ session->txBFIniFeatureEnabled =
+ sme_join_req->txBFIniFeatureEnabled;
+ } else {
+ session->txBFIniFeatureEnabled = 0;
+ }
+ session->txMuBformee = sme_join_req->txMuBformee;
+ session->enableVhtpAid =
+ sme_join_req->enableVhtpAid;
+ session->enableVhtGid =
+ sme_join_req->enableVhtGid;
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
+ FL("***txBFIniFeatureEnabled=%d***"),
+ session->txBFIniFeatureEnabled);
+ if (wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_VHT_SU_BEAMFORMER_CAP, &val) !=
+ eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE, FL(
+ "cfg get vht su bformer failed"));
+
+ session->enable_su_tx_bformer = val;
+ lim_log(mac_ctx, LOGE, FL("vht su tx bformer %d"), val);
+ }
+ if (session->vhtCapability && session->txBFIniFeatureEnabled) {
+ if (cfg_set_int(mac_ctx, WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
+ session->txBFIniFeatureEnabled) !=
+ eSIR_SUCCESS) {
+ /*
+ * Set failed for
+ * CFG_VHT_SU_BEAMFORMEE_CAP
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("Failed CFG_VHT_SU_BEAMFORMEE_CAP"));
+ ret_code = eSIR_LOGP_EXCEPTION;
+ goto end;
+ }
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
+ "%s: txBFCsnValue=%d", __func__,
+ sme_join_req->txBFCsnValue);
+ if (cfg_set_int(mac_ctx,
+ WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
+ sme_join_req->txBFCsnValue) != eSIR_SUCCESS) {
+ /*
+ * Set Failed for CFG
+ * CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED
+ */
+ lim_log(mac_ctx, LOGP, FL("Set Fail CFG"));
+ ret_code = eSIR_LOGP_EXCEPTION;
+ goto end;
+ }
+ }
+#endif
+
+ /*Phy mode */
+ session->gLimPhyMode = bss_desc.nwType;
+ handle_ht_capabilityand_ht_info(mac_ctx, session);
+ /* Copy The channel Id to the session Table */
+ session->currentOperChannel = bss_desc.channelId;
+ /* cbMode is already merged value of peer and self -
+ * done by csr in csr_get_cb_mode_from_ies */
+ session->htSupportedChannelWidthSet =
+ (sme_join_req->cbMode) ? 1 : 0;
+ session->htRecommendedTxWidthSet =
+ session->htSupportedChannelWidthSet;
+ session->htSecondaryChannelOffset = sme_join_req->cbMode;
+
+ if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == sme_join_req->cbMode) {
+ session->ch_center_freq_seg0 =
+ session->currentOperChannel - 2;
+ session->ch_width = CH_WIDTH_40MHZ;
+ } else if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
+ sme_join_req->cbMode) {
+ session->ch_center_freq_seg0 =
+ session->currentOperChannel + 2;
+ session->ch_width = CH_WIDTH_40MHZ;
+ } else {
+ session->ch_center_freq_seg0 = 0;
+ session->ch_width = CH_WIDTH_20MHZ;
+ }
+
+ /* Record if management frames need to be protected */
+#ifdef WLAN_FEATURE_11W
+ if (eSIR_ED_AES_128_CMAC == sme_join_req->MgmtEncryptionType) {
+ CDF_STATUS cdf_status;
+ session->limRmfEnabled = 1;
+ session->pmfComebackTimerInfo.pMac = mac_ctx;
+ session->pmfComebackTimerInfo.sessionID =
+ session_id;
+ cdf_status = cdf_mc_timer_init(
+ &session->pmfComebackTimer,
+ CDF_TIMER_TYPE_SW,
+ lim_pmf_comeback_timer_callback,
+ (void *)&session->pmfComebackTimerInfo);
+ if (CDF_STATUS_SUCCESS != cdf_status) {
+ lim_log(mac_ctx, LOGP,
+ FL("cannot init pmf comeback timer."));
+ ret_code = eSIR_LOGP_EXCEPTION;
+ goto end;
+ }
+ } else {
+ session->limRmfEnabled = 0;
+ }
+#endif
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ session->rssi = bss_desc.rssi;
+#endif
+
+ /* Copy the SSID from smejoinreq to session entry */
+ session->ssId.length = sme_join_req->ssId.length;
+ cdf_mem_copy(session->ssId.ssId, sme_join_req->ssId.ssId,
+ session->ssId.length);
+
+ /*
+ * Determin 11r or ESE connection based on input from SME
+ * which inturn is dependent on the profile the user wants
+ * to connect to, So input is coming from supplicant
+ */
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ session->is11Rconnection = sme_join_req->is11Rconnection;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ session->isESEconnection = sme_join_req->isESEconnection;
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ session->isFastTransitionEnabled =
+ sme_join_req->isFastTransitionEnabled;
+#endif
+
+#ifdef FEATURE_WLAN_LFR
+ session->isFastRoamIniFeatureEnabled =
+ sme_join_req->isFastRoamIniFeatureEnabled;
+#endif
+ session->txLdpcIniFeatureEnabled =
+ sme_join_req->txLdpcIniFeatureEnabled;
+
+ if (session->bssType == eSIR_INFRASTRUCTURE_MODE) {
+ session->limSystemRole = eLIM_STA_ROLE;
+ } else if (session->bssType == eSIR_BTAMP_AP_MODE) {
+ session->limSystemRole = eLIM_BT_AMP_STA_ROLE;
+ } else {
+ /*
+ * Throw an error and return and make
+ * sure to delete the session.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("recvd JOIN_REQ with invalid bss type %d"),
+ session->bssType);
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ if (sme_join_req->addIEScan.length)
+ cdf_mem_copy(&session->pLimJoinReq->addIEScan,
+ &sme_join_req->addIEScan, sizeof(tSirAddie));
+
+ if (sme_join_req->addIEAssoc.length)
+ cdf_mem_copy(&session->pLimJoinReq->addIEAssoc,
+ &sme_join_req->addIEAssoc, sizeof(tSirAddie));
+
+ val = sizeof(tLimMlmJoinReq) +
+ session->pLimJoinReq->bssDescription.length + 2;
+ mlm_join_req = cdf_mem_malloc(val);
+ if (NULL == mlm_join_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("AllocateMemory failed for mlmJoinReq"));
+ return;
+ }
+ (void)cdf_mem_set((void *)mlm_join_req, val, 0);
+
+ /* PE SessionId is stored as a part of JoinReq */
+ mlm_join_req->sessionId = session->peSessionId;
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+ (uint32_t *) &mlm_join_req->joinFailureTimeout) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("couldn't retrieve JoinFailureTimer value"
+ " setting to default value"));
+ mlm_join_req->joinFailureTimeout =
+ WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF;
+ }
+
+ /* copy operational rate from session */
+ cdf_mem_copy((void *)&session->rateSet,
+ (void *)&sme_join_req->operationalRateSet,
+ sizeof(tSirMacRateSet));
+ cdf_mem_copy((void *)&session->extRateSet,
+ (void *)&sme_join_req->extendedRateSet,
+ sizeof(tSirMacRateSet));
+ /*
+ * this may not be needed anymore now, as rateSet is now
+ * included in the session entry and MLM has session context.
+ */
+ cdf_mem_copy((void *)&mlm_join_req->operationalRateSet,
+ (void *)&session->rateSet,
+ sizeof(tSirMacRateSet));
+
+ session->encryptType = sme_join_req->UCEncryptionType;
+
+ mlm_join_req->bssDescription.length =
+ session->pLimJoinReq->bssDescription.length;
+
+ cdf_mem_copy((uint8_t *) &mlm_join_req->bssDescription.bssId,
+ (uint8_t *)
+ &session->pLimJoinReq->bssDescription.bssId,
+ session->pLimJoinReq->bssDescription.length + 2);
+
+ session->limCurrentBssCaps =
+ session->pLimJoinReq->bssDescription.capabilityInfo;
+
+ reg_max = cfg_get_regulatory_max_transmit_power(mac_ctx,
+ session->currentOperChannel);
+ local_power_constraint = reg_max;
+
+ lim_extract_ap_capability(mac_ctx,
+ (uint8_t *)
+ session->pLimJoinReq->bssDescription.ieFields,
+ lim_get_ielen_from_bss_description(
+ &session->pLimJoinReq->bssDescription),
+ &session->limCurrentBssQosCaps,
+ &session->limCurrentBssPropCap,
+ &session->gLimCurrentBssUapsd,
+ &local_power_constraint, session);
+
+#ifdef FEATURE_WLAN_ESE
+ session->maxTxPower = lim_get_max_tx_power(reg_max,
+ local_power_constraint,
+ mac_ctx->roam.configParam.nTxPowerCap);
+#else
+ session->maxTxPower =
+ CDF_MIN(reg_max, (local_power_constraint));
+#endif
+#if defined WLAN_VOWIFI_DEBUG
+ lim_log(mac_ctx, LOGE,
+ "Regulatory max = %d, local power constraint = %d"
+ reg_max, local_power_constraint);
+ lim_log(mac_ctx, LOGE, FL(" max tx = %d"),
+ session->maxTxPower);
+#endif
+
+ if (session->gLimCurrentBssUapsd) {
+ session->gUapsdPerAcBitmask =
+ session->pLimJoinReq->uapsdPerAcBitmask;
+ lim_log(mac_ctx, LOG1,
+ FL("UAPSD flag for all AC - 0x%2x"),
+ session->gUapsdPerAcBitmask);
+
+ /* resetting the dynamic uapsd mask */
+ session->gUapsdPerAcDeliveryEnableMask = 0;
+ session->gUapsdPerAcTriggerEnableMask = 0;
+ }
+
+ session->limRFBand =
+ lim_get_rf_band(session->currentOperChannel);
+
+ /* Initialize 11h Enable Flag */
+ if (SIR_BAND_5_GHZ == session->limRFBand) {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED,
+ &val) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("Fail to get WNI_CFG_11H_ENABLED "));
+ session->lim11hEnable =
+ WNI_CFG_11H_ENABLED_STADEF;
+ } else {
+ session->lim11hEnable = val;
+ }
+ } else {
+ session->lim11hEnable = 0;
+ }
+
+ /*
+ * To care of the scenario when STA transitions from
+ * IBSS to Infrastructure mode.
+ */
+ mac_ctx->lim.gLimIbssCoalescingHappened = false;
+
+ session->limPrevSmeState = session->limSmeState;
+ session->limSmeState = eLIM_SME_WT_JOIN_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session->peSessionId,
+ session->limSmeState));
+
+ lim_log(mac_ctx, LOG1,
+ FL("SME JoinReq:Sessionid %d SSID len %d SSID : %s Channel %d, BSSID " MAC_ADDRESS_STR),
+ mlm_join_req->sessionId, session->ssId.length,
+ session->ssId.ssId, session->currentOperChannel,
+ MAC_ADDR_ARRAY(session->bssId));
+
+ /* Indicate whether spectrum management is enabled */
+ session->spectrumMgtEnabled =
+ sme_join_req->spectrumMgtIndicator;
+
+ /* Enable the spectrum management if this is a DFS channel */
+ if (session->country_info_present &&
+ lim_isconnected_on_dfs_channel(
+ session->currentOperChannel))
+ session->spectrumMgtEnabled = true;
+
+ session->isOSENConnection = sme_join_req->isOSENConnection;
+
+ lim_log(mac_ctx, LOG1,
+ FL("SessionId:%d MLM_JOIN_REQ is posted to MLM SM"),
+ mlm_join_req->sessionId);
+ /* Issue LIM_MLM_JOIN_REQ to MLM */
+ lim_post_mlm_message(mac_ctx, LIM_MLM_JOIN_REQ,
+ (uint32_t *) mlm_join_req);
+ return;
+
+ } else {
+ /* Received eWNI_SME_JOIN_REQ un expected state */
+ lim_log(mac_ctx, LOGE,
+ FL("received unexpected SME_JOIN_REQ in state %X"),
+ mac_ctx->lim.gLimSmeState);
+ lim_print_sme_state(mac_ctx, LOGE, mac_ctx->lim.gLimSmeState);
+ ret_code = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ session = NULL;
+ goto end;
+ }
+
+end:
+ sme_session_id = sme_join_req->sessionId;
+ sme_transaction_id = sme_join_req->transactionId;
+
+ if (sme_join_req) {
+ cdf_mem_free(sme_join_req);
+ sme_join_req = NULL;
+ if (NULL != session)
+ session->pLimJoinReq = NULL;
+ }
+ if (ret_code != eSIR_SME_SUCCESS) {
+ if (NULL != session) {
+ pe_delete_session(mac_ctx, session);
+ session = NULL;
+ }
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("Send failure status on sessionid: %d with ret_code = %d"),
+ sme_session_id, ret_code);
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, ret_code,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS, session, sme_session_id,
+ sme_transaction_id);
+}
+
+#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI
+uint8_t lim_get_max_tx_power(tPowerdBm regMax, tPowerdBm apTxPower,
+ uint8_t iniTxPower)
+{
+ uint8_t maxTxPower = 0;
+ uint8_t txPower = CDF_MIN(regMax, (apTxPower));
+ txPower = CDF_MIN(txPower, iniTxPower);
+ if ((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP))
+ maxTxPower = txPower;
+ else if (txPower < MIN_TX_PWR_CAP)
+ maxTxPower = MIN_TX_PWR_CAP;
+ else
+ maxTxPower = MAX_TX_PWR_CAP;
+
+ return maxTxPower;
+}
+#endif
+
+/**
+ * __lim_process_sme_reassoc_req() - process reassoc req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_REASSOC_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ uint16_t caps;
+ uint32_t val;
+ tpSirSmeJoinReq reassoc_req = NULL;
+ tLimMlmReassocReq *mlm_reassoc_req;
+ tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+ tpPESession session_entry = NULL;
+ uint8_t session_id;
+ uint8_t sme_session_id;
+ uint16_t transaction_id;
+ tPowerdBm local_pwr_constraint = 0, reg_max = 0;
+ uint32_t tele_bcn_en = 0;
+ uint16_t size;
+
+ lim_log(mac_ctx, LOG3, FL("Received REASSOC_REQ"));
+
+ size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)msg_buf);
+ reassoc_req = cdf_mem_malloc(size);
+ if (NULL == reassoc_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("call to AllocateMemory failed for reassoc_req"));
+
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+ (void)cdf_mem_set((void *)reassoc_req, size, 0);
+ (void)cdf_mem_copy((void *)reassoc_req, (void *)msg_buf, size);
+
+ if (!lim_is_sme_join_req_valid(mac_ctx,
+ (tpSirSmeJoinReq)reassoc_req)) {
+ /*
+ * Received invalid eWNI_SME_REASSOC_REQ
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("received SME_REASSOC_REQ with invalid data"));
+
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ reassoc_req->bssDescription.bssId,
+ &session_id);
+ if (session_entry == NULL) {
+ lim_print_mac_addr(mac_ctx, reassoc_req->bssDescription.bssId,
+ LOGE);
+ lim_log(mac_ctx, LOGE,
+ FL("Session does not exist for given bssId"));
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+ session_entry, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ /* mac_ctx->lim.gpLimReassocReq = reassoc_req;//TO SUPPORT BT-AMP */
+
+ /* Store the reassoc handle in the session Table */
+ session_entry->pLimReAssocReq = reassoc_req;
+
+ session_entry->dot11mode = reassoc_req->dot11mode;
+ session_entry->vhtCapability =
+ IS_DOT11_MODE_VHT(reassoc_req->dot11mode);
+ /*
+ * Reassociate request is expected
+ * in link established state only.
+ */
+
+ if (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE) {
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || \
+ defined(FEATURE_WLAN_LFR)
+ if (session_entry->limSmeState == eLIM_SME_WT_REASSOC_STATE) {
+ /*
+ * May be from 11r FT pre-auth. So lets check it
+ * before we bail out
+ */
+ lim_log(mac_ctx, LOG1, FL(
+ "Session in reassoc state is %d"),
+ session_entry->peSessionId);
+
+ /* Make sure its our preauth bssid */
+ if (!cdf_mem_compare(reassoc_req->bssDescription.bssId,
+ session_entry->limReAssocbssId,
+ 6)) {
+ lim_print_mac_addr(mac_ctx,
+ reassoc_req->bssDescription.
+ bssId, LOGE);
+ lim_log(mac_ctx, LOGP,
+ FL("Unknown bssId in reassoc state"));
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ lim_process_mlm_ft_reassoc_req(mac_ctx, msg_buf,
+ session_entry);
+ return;
+ }
+#endif
+ /*
+ * Should not have received eWNI_SME_REASSOC_REQ
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("received unexpected SME_REASSOC_REQ in state %X"),
+ session_entry->limSmeState);
+ lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState);
+
+ ret_code = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ goto end;
+ }
+
+ cdf_mem_copy(session_entry->limReAssocbssId,
+ session_entry->pLimReAssocReq->bssDescription.bssId,
+ sizeof(tSirMacAddr));
+
+ session_entry->limReassocChannelId =
+ session_entry->pLimReAssocReq->bssDescription.channelId;
+
+ session_entry->reAssocHtSupportedChannelWidthSet =
+ (session_entry->pLimReAssocReq->cbMode) ? 1 : 0;
+ session_entry->reAssocHtRecommendedTxWidthSet =
+ session_entry->reAssocHtSupportedChannelWidthSet;
+ session_entry->reAssocHtSecondaryChannelOffset =
+ session_entry->pLimReAssocReq->cbMode;
+
+ session_entry->limReassocBssCaps =
+ session_entry->pLimReAssocReq->bssDescription.capabilityInfo;
+ reg_max = cfg_get_regulatory_max_transmit_power(mac_ctx,
+ session_entry->currentOperChannel);
+ local_pwr_constraint = reg_max;
+
+ lim_extract_ap_capability(mac_ctx,
+ (uint8_t *)session_entry->pLimReAssocReq->bssDescription.ieFields,
+ lim_get_ielen_from_bss_description(
+ &session_entry->pLimReAssocReq->bssDescription),
+ &session_entry->limReassocBssQosCaps,
+ &session_entry->limReassocBssPropCap,
+ &session_entry->gLimCurrentBssUapsd,
+ &local_pwr_constraint, session_entry);
+ session_entry->maxTxPower = CDF_MIN(reg_max, (local_pwr_constraint));
+#if defined WLAN_VOWIFI_DEBUG
+ lim_log(mac_ctx, LOGE,
+ "Regulatory max = %d, local pwr constraint = %d, max tx = %d",
+ reg_max, local_pwr_constraint,
+ session_entry->maxTxPower);
+#endif
+ /* Copy the SSID from session entry to local variable */
+ session_entry->limReassocSSID.length = reassoc_req->ssId.length;
+ cdf_mem_copy(session_entry->limReassocSSID.ssId,
+ reassoc_req->ssId.ssId,
+ session_entry->limReassocSSID.length);
+ if (session_entry->gLimCurrentBssUapsd) {
+ session_entry->gUapsdPerAcBitmask =
+ session_entry->pLimReAssocReq->uapsdPerAcBitmask;
+ lim_log(mac_ctx, LOG1,
+ FL("UAPSD flag for all AC - 0x%2x"),
+ session_entry->gUapsdPerAcBitmask);
+ }
+
+ mlm_reassoc_req = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
+ if (NULL == mlm_reassoc_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("call to AllocateMemory failed for mlmReassocReq"));
+
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ }
+
+ cdf_mem_copy(mlm_reassoc_req->peerMacAddr,
+ session_entry->limReAssocbssId, sizeof(tSirMacAddr));
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ (uint32_t *)&mlm_reassoc_req->reassocFailureTimeout) !=
+ eSIR_SUCCESS) {
+ /*
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve ReassocFailureTimeout value"));
+ }
+
+ if (cfg_get_capability_info(mac_ctx, &caps, session_entry) !=
+ eSIR_SUCCESS) {
+ /*
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP, FL(
+ "could not retrieve Capabilities value"));
+ }
+ mlm_reassoc_req->capabilityInfo = caps;
+
+ /* Update PE session_id */
+ mlm_reassoc_req->sessionId = session_id;
+
+ /*
+ * If telescopic beaconing is enabled, set listen interval to
+ * WNI_CFG_TELE_BCN_MAX_LI
+ */
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_WAKEUP_EN,
+ &tele_bcn_en) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN"));
+
+ val = WNI_CFG_LISTEN_INTERVAL_STADEF;
+
+ if (tele_bcn_en) {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_TELE_BCN_MAX_LI, &val) !=
+ eSIR_SUCCESS)
+ /*
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve ListenInterval"));
+ } else {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_LISTEN_INTERVAL, &val) !=
+ eSIR_SUCCESS)
+ /*
+ * Could not get ListenInterval value
+ * from CFG. Log error.
+ */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve ListenInterval"));
+ }
+
+ mlm_reassoc_req->listenInterval = (uint16_t) val;
+
+ /* Indicate whether spectrum management is enabled */
+ session_entry->spectrumMgtEnabled = reassoc_req->spectrumMgtIndicator;
+
+ /* Enable the spectrum management if this is a DFS channel */
+ if (session_entry->country_info_present &&
+ lim_isconnected_on_dfs_channel(
+ session_entry->currentOperChannel))
+ session_entry->spectrumMgtEnabled = true;
+
+ session_entry->limPrevSmeState = session_entry->limSmeState;
+ session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE;
+
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+
+ lim_post_mlm_message(mac_ctx,
+ LIM_MLM_REASSOC_REQ, (uint32_t *)mlm_reassoc_req);
+ return;
+end:
+ if (reassoc_req) {
+ cdf_mem_free(reassoc_req);
+ if (session_entry)
+ session_entry->pLimReAssocReq = NULL;
+ }
+
+ if (session_entry) {
+ /*
+ * error occurred after we determined the session so extract
+ * session and transaction info from there
+ */
+ sme_session_id = session_entry->smeSessionId;
+ transaction_id = session_entry->transactionId;
+ } else
+ /*
+ * error occurred before or during the time we determined
+ * the session so extract the session and transaction info
+ * from the message
+ */
+ lim_get_session_info(mac_ctx, (uint8_t *) msg_buf,
+ &sme_session_id, &transaction_id);
+
+ /*
+ * Send Reassoc failure response to host
+ * (note session_entry may be NULL, but that's OK)
+ */
+ lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_REASSOC_RSP,
+ ret_code, eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ session_entry, sme_session_id,
+ transaction_id);
+}
+
+bool send_disassoc_frame = 1;
+/**
+ * __lim_process_sme_disassoc_req()
+ *
+ ***FUNCTION:
+ * This function is called to process SME_DISASSOC_REQ message
+ * from HDD or upper layer application.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+
+static void __lim_process_sme_disassoc_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ uint16_t disassocTrigger, reasonCode;
+ tLimMlmDisassocReq *pMlmDisassocReq;
+ tSirResultCodes retCode = eSIR_SME_SUCCESS;
+ tSirSmeDisassocReq smeDisassocReq;
+ tpPESession psessionEntry = NULL;
+ uint8_t sessionId;
+ uint8_t smesessionId;
+ uint16_t smetransactionId;
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ cdf_mem_copy(&smeDisassocReq, pMsgBuf, sizeof(tSirSmeDisassocReq));
+ smesessionId = smeDisassocReq.sessionId;
+ smetransactionId = smeDisassocReq.transactionId;
+ if (!lim_is_sme_disassoc_req_valid(pMac,
+ &smeDisassocReq,
+ psessionEntry)) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL("received invalid SME_DISASSOC_REQ message"));)
+ if (pMac->lim.gLimRspReqd) {
+ pMac->lim.gLimRspReqd = false;
+
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+
+ return;
+ }
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ smeDisassocReq.bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("session does not exist for given bssId "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(smeDisassocReq.bssId));
+ retCode = eSIR_SME_INVALID_PARAMETERS;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+ lim_log(pMac, LOG1,
+ FL("received DISASSOC_REQ message on sessionid %d Systemrole %d Reason: %u SmeState: %d from: "
+ MAC_ADDRESS_STR), smesessionId,
+ GET_LIM_SYSTEM_ROLE(psessionEntry), smeDisassocReq.reasonCode,
+ pMac->lim.gLimSmeState,
+ MAC_ADDR_ARRAY(smeDisassocReq.peerMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry,
+ 0, smeDisassocReq.reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ /* Update SME session Id and SME transaction ID */
+
+ psessionEntry->smeSessionId = smesessionId;
+ psessionEntry->transactionId = smetransactionId;
+
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ switch (psessionEntry->limSmeState) {
+ case eLIM_SME_ASSOCIATED_STATE:
+ case eLIM_SME_LINK_EST_STATE:
+ psessionEntry->limPrevSmeState =
+ psessionEntry->limSmeState;
+ psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+#ifdef FEATURE_WLAN_TDLS
+ /* Delete all TDLS peers connected before leaving BSS */
+ lim_delete_tdls_peers(pMac, psessionEntry);
+#endif
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+ lim_log(pMac, LOG1,
+ FL("Rcvd SME_DISASSOC_REQ while in limSmeState: %d "),
+ psessionEntry->limSmeState);
+ break;
+
+ case eLIM_SME_WT_DEAUTH_STATE:
+ /* PE shall still process the DISASSOC_REQ and proceed with
+ * link tear down even if it had already sent a DEAUTH_IND to
+ * to SME. pMac->lim.gLimPrevSmeState shall remain the same as
+ * its been set when PE entered WT_DEAUTH_STATE.
+ */
+ psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+ lim_log(pMac, LOG1,
+ FL("Rcvd SME_DISASSOC_REQ while in SME_WT_DEAUTH_STATE. "));
+ break;
+
+ case eLIM_SME_WT_DISASSOC_STATE:
+ /* PE Recieved a Disassoc frame. Normally it gets DISASSOC_CNF but it
+ * received DISASSOC_REQ. Which means host is also trying to disconnect.
+ * PE can continue processing DISASSOC_REQ and send the response instead
+ * of failing the request. SME will anyway ignore DEAUTH_IND that was sent
+ * for disassoc frame.
+ *
+ * It will send a disassoc, which is ok. However, we can use the global flag
+ * sendDisassoc to not send disassoc frame.
+ */
+ lim_log(pMac, LOG1,
+ FL("Rcvd SME_DISASSOC_REQ while in SME_WT_DISASSOC_STATE. "));
+ break;
+
+ case eLIM_SME_JOIN_FAILURE_STATE: {
+ /* Already in Disconnected State, return success */
+ lim_log(pMac, LOG1,
+ FL("Rcvd SME_DISASSOC_REQ while in eLIM_SME_JOIN_FAILURE_STATE. "));
+ if (pMac->lim.gLimRspReqd) {
+ retCode = eSIR_SME_SUCCESS;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+ }
+ break;
+ default:
+ /**
+ * STA is not currently associated.
+ * Log error and send response to host
+ */
+ lim_log(pMac, LOGE,
+ FL("received unexpected SME_DISASSOC_REQ in state %X"),
+ psessionEntry->limSmeState);
+ lim_print_sme_state(pMac, LOGE,
+ psessionEntry->limSmeState);
+
+ if (pMac->lim.gLimRspReqd) {
+ if (psessionEntry->limSmeState !=
+ eLIM_SME_WT_ASSOC_STATE)
+ pMac->lim.gLimRspReqd = false;
+
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ }
+
+ return;
+ }
+
+ break;
+
+ case eLIM_AP_ROLE:
+ case eLIM_BT_AMP_AP_ROLE:
+ /* Fall through */
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ default:
+ /* eLIM_UNKNOWN_ROLE */
+ lim_log(pMac, LOGE,
+ FL("received unexpected SME_DISASSOC_REQ for role %d"),
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+ retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE;
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ goto sendDisassoc;
+ } /* end switch (pMac->lim.gLimSystemRole) */
+
+ if (smeDisassocReq.reasonCode == eLIM_LINK_MONITORING_DISASSOC) {
+ /* / Disassociation is triggered by Link Monitoring */
+ lim_log(pMac, LOG1,
+ FL("Sending Disasscoc with reason Link Monitoring"));
+ disassocTrigger = eLIM_LINK_MONITORING_DISASSOC;
+ reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON;
+ } else {
+ disassocTrigger = eLIM_HOST_DISASSOC;
+ reasonCode = smeDisassocReq.reasonCode;
+ }
+
+ if (smeDisassocReq.doNotSendOverTheAir) {
+ lim_log(pMac, LOG1, FL("do not send dissoc over the air"));
+ send_disassoc_frame = 0;
+ }
+ /* Trigger Disassociation frame to peer MAC entity */
+ lim_log(pMac, LOG1, FL("Sending Disasscoc with disassoc Trigger"
+ " : %d, reasonCode : %d"),
+ disassocTrigger, reasonCode);
+
+ pMlmDisassocReq = cdf_mem_malloc(sizeof(tLimMlmDisassocReq));
+ if (NULL == pMlmDisassocReq) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("call to AllocateMemory failed for mlmDisassocReq"));
+
+ return;
+ }
+
+ cdf_mem_copy((uint8_t *) &pMlmDisassocReq->peerMacAddr,
+ (uint8_t *) &smeDisassocReq.peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ pMlmDisassocReq->reasonCode = reasonCode;
+ pMlmDisassocReq->disassocTrigger = disassocTrigger;
+
+ /* Update PE session ID */
+ pMlmDisassocReq->sessionId = sessionId;
+
+ lim_post_mlm_message(pMac,
+ LIM_MLM_DISASSOC_REQ, (uint32_t *) pMlmDisassocReq);
+ return;
+
+sendDisassoc:
+ if (psessionEntry)
+ lim_send_sme_disassoc_ntf(pMac, smeDisassocReq.peerMacAddr,
+ retCode,
+ disassocTrigger,
+ 1, smesessionId, smetransactionId,
+ psessionEntry);
+ else
+ lim_send_sme_disassoc_ntf(pMac, smeDisassocReq.peerMacAddr,
+ retCode,
+ disassocTrigger,
+ 1, smesessionId, smetransactionId, NULL);
+
+} /*** end __lim_process_sme_disassoc_req() ***/
+
+/** -----------------------------------------------------------------
+ \brief __lim_process_sme_disassoc_cnf() - Process SME_DISASSOC_CNF
+
+ This function is called to process SME_DISASSOC_CNF message
+ from HDD or upper layer application.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+static void __lim_process_sme_disassoc_cnf(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirSmeDisassocCnf smeDisassocCnf;
+ uint16_t aid;
+ tpDphHashNode pStaDs;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+
+ PELOG1(lim_log(pMac, LOG1, FL("received DISASSOC_CNF message"));)
+
+ cdf_mem_copy(&smeDisassocCnf, pMsgBuf,
+ sizeof(struct sSirSmeDisassocCnf));
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ smeDisassocCnf.bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("session does not exist for given bssId"));
+ return;
+ }
+
+ if (!lim_is_sme_disassoc_cnf_valid(pMac, &smeDisassocCnf, psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL("received invalid SME_DISASSOC_CNF message"));
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF)
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+ psessionEntry,
+ (uint16_t) smeDisassocCnf.statusCode, 0);
+ else if (smeDisassocCnf.messageType == eWNI_SME_DEAUTH_CNF)
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+ psessionEntry,
+ (uint16_t) smeDisassocCnf.statusCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE: /* To test reconn */
+ if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)
+ && (psessionEntry->limSmeState !=
+ eLIM_SME_WT_DEAUTH_STATE)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("received unexp SME_DISASSOC_CNF in state %X"),
+ psessionEntry->limSmeState);
+ lim_print_sme_state(pMac, LOGE,
+ psessionEntry->limSmeState);
+ return;
+ }
+ break;
+
+ case eLIM_AP_ROLE:
+ /* Fall through */
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ default: /* eLIM_UNKNOWN_ROLE */
+ lim_log(pMac, LOGE,
+ FL("received unexpected SME_DISASSOC_CNF role %d"),
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+
+ return;
+ }
+
+ if ((psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) ||
+ (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) ||
+ LIM_IS_AP_ROLE(psessionEntry)) {
+ pStaDs = dph_lookup_hash_entry(pMac,
+ smeDisassocCnf.peerMacAddr, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ lim_log(pMac, LOGE,
+ FL("DISASSOC_CNF for a STA with no context, addr= "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr));
+ return;
+ }
+#if defined WLAN_FEATURE_VOWIFI_11R
+ /* Delete FT session if there exists one */
+ lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
+#endif
+ lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
+
+ lim_clean_up_disassoc_deauth_req(pMac,
+ (char *)&smeDisassocCnf.peerMacAddr,
+ 0);
+ }
+
+ return;
+}
+
+/**
+ * __lim_process_sme_deauth_req() - process sme deauth req
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_DEAUTH_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void __lim_process_sme_deauth_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ uint16_t deauth_trigger, reason_code;
+ tLimMlmDeauthReq *mlm_deauth_req;
+ tSirSmeDeauthReq sme_deauth_req;
+ tSirResultCodes ret_code = eSIR_SME_SUCCESS;
+ tpPESession session_entry;
+ uint8_t session_id; /* PE sessionId */
+ uint8_t sme_session_id;
+ uint16_t sme_transaction_id;
+
+ lim_log(mac_ctx, LOG1, FL("received DEAUTH_REQ message"));
+
+ cdf_mem_copy(&sme_deauth_req, msg_buf, sizeof(tSirSmeDeauthReq));
+ sme_session_id = sme_deauth_req.sessionId;
+ sme_transaction_id = sme_deauth_req.transactionId;
+
+ /*
+ * We need to get a session first but we don't even know
+ * if the message is correct.
+ */
+ session_entry = pe_find_session_by_bssid(mac_ctx, sme_deauth_req.bssId,
+ &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given bssId"));
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ deauth_trigger = eLIM_HOST_DEAUTH;
+ goto send_deauth;
+ }
+
+ if (!lim_is_sme_deauth_req_valid(mac_ctx, &sme_deauth_req,
+ session_entry)) {
+ lim_log(mac_ctx, LOGE,
+ FL("received invalid SME_DEAUTH_REQ message"));
+ mac_ctx->lim.gLimRspReqd = false;
+
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ deauth_trigger = eLIM_HOST_DEAUTH;
+ goto send_deauth;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("received DEAUTH_REQ sessionid %d Systemrole %d reasoncode %u limSmestate %d from "
+ MAC_ADDRESS_STR), sme_session_id,
+ GET_LIM_SYSTEM_ROLE(session_entry), sme_deauth_req.reasonCode,
+ session_entry->limSmeState,
+ MAC_ADDR_ARRAY(sme_deauth_req.peerMacAddr));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+ session_entry, 0, sme_deauth_req.reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ /* Update SME session ID and Transaction ID */
+ session_entry->smeSessionId = sme_session_id;
+ session_entry->transactionId = sme_transaction_id;
+
+ switch (GET_LIM_SYSTEM_ROLE(session_entry)) {
+ case eLIM_STA_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+
+ switch (session_entry->limSmeState) {
+ case eLIM_SME_ASSOCIATED_STATE:
+ case eLIM_SME_LINK_EST_STATE:
+ case eLIM_SME_WT_ASSOC_STATE:
+ case eLIM_SME_JOIN_FAILURE_STATE:
+ case eLIM_SME_IDLE_STATE:
+ session_entry->limPrevSmeState =
+ session_entry->limSmeState;
+ session_entry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE,
+ session_entry->peSessionId,
+ session_entry->limSmeState));
+ /* Send Deauthentication request to MLM below */
+ break;
+ case eLIM_SME_WT_DEAUTH_STATE:
+ case eLIM_SME_WT_DISASSOC_STATE:
+ /*
+ * PE Recieved a Deauth/Disassoc frame. Normally it get
+ * DEAUTH_CNF/DISASSOC_CNF but it received DEAUTH_REQ.
+ * Which means host is also trying to disconnect.
+ * PE can continue processing DEAUTH_REQ and send
+ * the response instead of failing the request.
+ * SME will anyway ignore DEAUTH_IND/DISASSOC_IND that
+ * was sent for deauth/disassoc frame.
+ */
+ session_entry->limSmeState = eLIM_SME_WT_DEAUTH_STATE;
+ lim_log(mac_ctx, LOG1, FL(
+ "Rcvd SME_DEAUTH_REQ while in SME_WT_DEAUTH_STATE"));
+ break;
+ default:
+ /*
+ * STA is not in a state to deauthenticate with
+ * peer. Log error and send response to host.
+ */
+ lim_log(mac_ctx, LOGE, FL(
+ "received unexp SME_DEAUTH_REQ in state %X"),
+ session_entry->limSmeState);
+ lim_print_sme_state(mac_ctx, LOGE,
+ session_entry->limSmeState);
+
+ if (mac_ctx->lim.gLimRspReqd) {
+ mac_ctx->lim.gLimRspReqd = false;
+
+ ret_code = eSIR_SME_STA_NOT_AUTHENTICATED;
+ deauth_trigger = eLIM_HOST_DEAUTH;
+
+ /*
+ * here we received deauth request from AP so sme state
+ * is eLIM_SME_WT_DEAUTH_STATE.if we have ISSUED
+ * delSta then mlm state should be
+ * eLIM_MLM_WT_DEL_STA_RSP_STATE and ifwe got delBSS
+ * rsp then mlm state should be eLIM_MLM_IDLE_STATE
+ * so the below condition captures the state where
+ * delSta not done and firmware still in
+ * connected state.
+ */
+ if (session_entry->limSmeState ==
+ eLIM_SME_WT_DEAUTH_STATE &&
+ session_entry->limMlmState !=
+ eLIM_MLM_IDLE_STATE &&
+ session_entry->limMlmState !=
+ eLIM_MLM_WT_DEL_STA_RSP_STATE)
+ ret_code = eSIR_SME_DEAUTH_STATUS;
+ goto send_deauth;
+ }
+ return;
+ }
+ break;
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ lim_log(mac_ctx, LOGE, FL("Deauth not allowed in IBSS"));
+ if (mac_ctx->lim.gLimRspReqd) {
+ mac_ctx->lim.gLimRspReqd = false;
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ deauth_trigger = eLIM_HOST_DEAUTH;
+ goto send_deauth;
+ }
+ return;
+ case eLIM_AP_ROLE:
+ break;
+ default:
+ lim_log(mac_ctx, LOGE,
+ FL("received unexpected SME_DEAUTH_REQ for role %X"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ if (mac_ctx->lim.gLimRspReqd) {
+ mac_ctx->lim.gLimRspReqd = false;
+ ret_code = eSIR_SME_INVALID_PARAMETERS;
+ deauth_trigger = eLIM_HOST_DEAUTH;
+ goto send_deauth;
+ }
+ return;
+ } /* end switch (mac_ctx->lim.gLimSystemRole) */
+
+ if (sme_deauth_req.reasonCode == eLIM_LINK_MONITORING_DEAUTH) {
+ /* Deauthentication is triggered by Link Monitoring */
+ lim_log(mac_ctx, LOG1, FL("** Lost link with AP **"));
+ deauth_trigger = eLIM_LINK_MONITORING_DEAUTH;
+ reason_code = eSIR_MAC_UNSPEC_FAILURE_REASON;
+ } else {
+ deauth_trigger = eLIM_HOST_DEAUTH;
+ reason_code = sme_deauth_req.reasonCode;
+ }
+
+ /* Trigger Deauthentication frame to peer MAC entity */
+ mlm_deauth_req = cdf_mem_malloc(sizeof(tLimMlmDeauthReq));
+ if (NULL == mlm_deauth_req) {
+ lim_log(mac_ctx, LOGP,
+ FL("call to AllocateMemory failed for mlmDeauthReq"));
+ if (mac_ctx->lim.gLimRspReqd) {
+ mac_ctx->lim.gLimRspReqd = false;
+ ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+ deauth_trigger = eLIM_HOST_DEAUTH;
+ goto send_deauth;
+ }
+ return;
+ }
+
+ cdf_mem_copy((uint8_t *) &mlm_deauth_req->peerMacAddr,
+ (uint8_t *) &sme_deauth_req.peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ mlm_deauth_req->reasonCode = reason_code;
+ mlm_deauth_req->deauthTrigger = deauth_trigger;
+
+ /* Update PE session Id */
+ mlm_deauth_req->sessionId = session_id;
+
+ lim_post_mlm_message(mac_ctx, LIM_MLM_DEAUTH_REQ,
+ (uint32_t *)mlm_deauth_req);
+ return;
+
+send_deauth:
+ lim_send_sme_deauth_ntf(mac_ctx, sme_deauth_req.peerMacAddr, ret_code,
+ deauth_trigger, 1, sme_session_id, sme_transaction_id);
+}
+
+/**
+ * __lim_process_sme_set_context_req()
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_SETCONTEXT_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+static void
+__lim_process_sme_set_context_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ tpSirSmeSetContextReq set_context_req;
+ tLimMlmSetKeysReq *mlm_set_key_req;
+ tpPESession session_entry;
+ uint8_t session_id; /* PE sessionID */
+ uint8_t sme_session_id;
+ uint16_t sme_transaction_id;
+
+ lim_log(mac_ctx, LOG1, FL("received SETCONTEXT_REQ message"));
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ set_context_req = cdf_mem_malloc(sizeof(struct sSirSmeSetContextReq));
+ if (NULL == set_context_req) {
+ lim_log(mac_ctx, LOGP, FL(
+ "call to AllocateMemory failed for set_context_req"));
+ return;
+ }
+ cdf_mem_copy(set_context_req, msg_buf,
+ sizeof(struct sSirSmeSetContextReq));
+ sme_session_id = set_context_req->sessionId;
+ sme_transaction_id = set_context_req->transactionId;
+
+ if ((!lim_is_sme_set_context_req_valid(mac_ctx, set_context_req))) {
+ lim_log(mac_ctx, LOGW,
+ FL("received invalid SME_SETCONTEXT_REQ message"));
+ goto end;
+ }
+
+ if (set_context_req->keyMaterial.numKeys >
+ SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+ lim_log(mac_ctx, LOGE, FL(
+ "numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS"),
+ set_context_req->keyMaterial.numKeys);
+ lim_send_sme_set_context_rsp(mac_ctx,
+ set_context_req->peerMacAddr, 1,
+ eSIR_SME_INVALID_PARAMETERS, NULL,
+ sme_session_id, sme_transaction_id);
+ goto end;
+ }
+
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ set_context_req->bssId, &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGW,
+ FL("Session does not exist for given BSSID"));
+ lim_send_sme_set_context_rsp(mac_ctx,
+ set_context_req->peerMacAddr, 1,
+ eSIR_SME_INVALID_PARAMETERS, NULL,
+ sme_session_id, sme_transaction_id);
+ goto end;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+ session_entry, 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ if (((LIM_IS_STA_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_STA_ROLE(session_entry)) &&
+ (session_entry->limSmeState == eLIM_SME_LINK_EST_STATE)) ||
+ ((LIM_IS_IBSS_ROLE(session_entry) ||
+ LIM_IS_AP_ROLE(session_entry) ||
+ LIM_IS_BT_AMP_AP_ROLE(session_entry)) &&
+ (session_entry->limSmeState == eLIM_SME_NORMAL_STATE))) {
+ /* Trigger MLM_SETKEYS_REQ */
+ mlm_set_key_req = cdf_mem_malloc(sizeof(tLimMlmSetKeysReq));
+ if (NULL == mlm_set_key_req) {
+ lim_log(mac_ctx, LOGP, FL(
+ "mem alloc failed for mlmSetKeysReq"));
+ goto end;
+ }
+ mlm_set_key_req->edType = set_context_req->keyMaterial.edType;
+ mlm_set_key_req->numKeys =
+ set_context_req->keyMaterial.numKeys;
+ if (mlm_set_key_req->numKeys >
+ SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+ lim_log(mac_ctx, LOGP, FL(
+ "no.of keys exceeded max num of default keys limit"));
+ goto end;
+ }
+ cdf_mem_copy((uint8_t *) &mlm_set_key_req->peerMacAddr,
+ (uint8_t *) &set_context_req->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) &mlm_set_key_req->key,
+ (uint8_t *) &set_context_req->keyMaterial.key,
+ sizeof(tSirKeys) *
+ (mlm_set_key_req->numKeys ? mlm_set_key_req->
+ numKeys : 1));
+
+ mlm_set_key_req->sessionId = session_id;
+ mlm_set_key_req->smesessionId = sme_session_id;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL(
+ "received SETCONTEXT_REQ message sessionId=%d"),
+ mlm_set_key_req->sessionId);
+#endif
+
+ if (((set_context_req->keyMaterial.edType == eSIR_ED_WEP40) ||
+ (set_context_req->keyMaterial.edType == eSIR_ED_WEP104)) &&
+ LIM_IS_AP_ROLE(session_entry)) {
+ if (set_context_req->keyMaterial.key[0].keyLength) {
+ uint8_t key_id;
+ key_id =
+ set_context_req->keyMaterial.key[0].keyId;
+ cdf_mem_copy((uint8_t *)
+ &session_entry->WEPKeyMaterial[key_id],
+ (uint8_t *) &set_context_req->keyMaterial,
+ sizeof(tSirKeyMaterial));
+ } else {
+ uint32_t i;
+ for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+ i++) {
+ cdf_mem_copy((uint8_t *)
+ &mlm_set_key_req->key[i],
+ (uint8_t *)session_entry->WEPKeyMaterial[i].key,
+ sizeof(tSirKeys));
+ }
+ }
+ }
+ lim_post_mlm_message(mac_ctx, LIM_MLM_SETKEYS_REQ,
+ (uint32_t *) mlm_set_key_req);
+ } else {
+ lim_log(mac_ctx, LOGE, FL(
+ "rcvd unexpected SME_SETCONTEXT_REQ for role %d, state=%X"),
+ GET_LIM_SYSTEM_ROLE(session_entry),
+ session_entry->limSmeState);
+ lim_print_sme_state(mac_ctx, LOGE, session_entry->limSmeState);
+
+ lim_send_sme_set_context_rsp(mac_ctx,
+ set_context_req->peerMacAddr, 1,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,
+ session_entry, sme_session_id,
+ sme_transaction_id);
+ }
+end:
+ cdf_mem_free(set_context_req);
+ return;
+}
+
+/**
+ * lim_process_sme_get_assoc_sta_info() - process sme assoc sta req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_GET_ASSOC_STAS_REQ message
+ * from HDD or upper layer application.
+ *
+ * Return: None
+ */
+
+void lim_process_sme_get_assoc_sta_info(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tSirSmeGetAssocSTAsReq get_assoc_stas_req;
+ tpDphHashNode sta_ds = NULL;
+ tpPESession session_entry = NULL;
+ tSap_Event sap_event;
+ tpWLAN_SAPEventCB sap_event_cb = NULL;
+ tpSap_AssocMacAddr assoc_sta_tmp = NULL;
+ uint8_t session_id = CSR_SESSION_ID_INVALID;
+ uint8_t assoc_id = 0;
+ uint8_t sta_cnt = 0;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ cdf_mem_copy(&get_assoc_stas_req, msg_buf,
+ sizeof(struct sSirSmeGetAssocSTAsReq));
+ /*
+ * Get Associated stations from PE.
+ * Find PE session Entry
+ */
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ get_assoc_stas_req.bssId,
+ &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given bssId"));
+ goto lim_assoc_sta_end;
+ }
+
+ if (!LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Received unexpected message in state %X, in role %X"),
+ session_entry->limSmeState,
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ goto lim_assoc_sta_end;
+ }
+ /* Retrieve values obtained in the request message */
+ sap_event_cb = (tpWLAN_SAPEventCB)get_assoc_stas_req.pSapEventCallback;
+ assoc_sta_tmp = (tpSap_AssocMacAddr)get_assoc_stas_req.pAssocStasArray;
+
+ if (NULL == assoc_sta_tmp)
+ goto lim_assoc_sta_end;
+ for (assoc_id = 0; assoc_id < session_entry->dph.dphHashTable.size;
+ assoc_id++) {
+ sta_ds = dph_get_hash_entry(mac_ctx, assoc_id,
+ &session_entry->dph.dphHashTable);
+ if (NULL == sta_ds)
+ continue;
+ if (sta_ds->valid) {
+ cdf_mem_copy((uint8_t *) &assoc_sta_tmp->staMac,
+ (uint8_t *) &sta_ds->staAddr,
+ CDF_MAC_ADDR_SIZE);
+ assoc_sta_tmp->assocId = (uint8_t) sta_ds->assocId;
+ assoc_sta_tmp->staId = (uint8_t) sta_ds->staIndex;
+
+ cdf_mem_copy((uint8_t *)&assoc_sta_tmp->supportedRates,
+ (uint8_t *)&sta_ds->supportedRates,
+ sizeof(tSirSupportedRates));
+ assoc_sta_tmp->ShortGI40Mhz = sta_ds->htShortGI40Mhz;
+ assoc_sta_tmp->ShortGI20Mhz = sta_ds->htShortGI20Mhz;
+ assoc_sta_tmp->Support40Mhz =
+ sta_ds->htDsssCckRate40MHzSupport;
+
+ lim_log(mac_ctx, LOG1, FL("dph Station Number = %d"),
+ sta_cnt + 1);
+ lim_log(mac_ctx, LOG1, FL("MAC = " MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(sta_ds->staAddr));
+ lim_log(mac_ctx, LOG1, FL("Association Id = %d"),
+ sta_ds->assocId);
+ lim_log(mac_ctx, LOG1, FL("Station Index = %d"),
+ sta_ds->staIndex);
+ assoc_sta_tmp++;
+ sta_cnt++;
+ }
+ }
+lim_assoc_sta_end:
+ /*
+ * Call hdd callback with sap event to send the list of
+ * associated stations from PE
+ */
+ if (sap_event_cb != NULL) {
+ sap_event.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT;
+ sap_event.sapevt.sapAssocStaListEvent.module =
+ CDF_MODULE_ID_PE;
+ sap_event.sapevt.sapAssocStaListEvent.noOfAssocSta = sta_cnt;
+ sap_event.sapevt.sapAssocStaListEvent.pAssocStas =
+ (tpSap_AssocMacAddr)get_assoc_stas_req.pAssocStasArray;
+ sap_event_cb(&sap_event, get_assoc_stas_req.pUsrContext);
+ }
+}
+
+/**
+ * lim_process_sme_get_wpspbc_sessions - process sme get wpspbc req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to WPS PBC overlap query message
+ *
+ * This function parses get WPS PBC overlap information
+ * message and call callback to pass WPS PBC overlap
+ * information back to hdd.
+ *
+ * Return: None
+ */
+void lim_process_sme_get_wpspbc_sessions(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tSirSmeGetWPSPBCSessionsReq get_wps_pbc_sessions_req;
+ tpPESession session_entry = NULL;
+ tSap_Event sap_event;
+ tpWLAN_SAPEventCB sap_event_cb = NULL;
+ uint8_t session_id = CSR_SESSION_ID_INVALID;
+ tSirMacAddr zero_mac = { 0, 0, 0, 0, 0, 0 };
+ tSap_GetWPSPBCSessionEvent *sap_get_wpspbc_event;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ sap_get_wpspbc_event = &sap_event.sapevt.sapGetWPSPBCSessionEvent;
+ sap_get_wpspbc_event->status = CDF_STATUS_E_FAULT;
+
+ cdf_mem_copy(&get_wps_pbc_sessions_req, msg_buf,
+ sizeof(struct sSirSmeGetWPSPBCSessionsReq));
+ /*
+ * Get Associated stations from PE
+ * Find PE session Entry
+ */
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ get_wps_pbc_sessions_req.bssId, &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given bssId"));
+ goto lim_get_wpspbc_sessions_end;
+ }
+
+ if (!LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Received unexpected message in role %X"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ goto lim_get_wpspbc_sessions_end;
+ }
+ /*
+ * Call hdd callback with sap event to send the
+ * WPS PBC overlap information
+ */
+ sap_event.sapHddEventCode = eSAP_GET_WPSPBC_SESSION_EVENT;
+ sap_get_wpspbc_event->module = CDF_MODULE_ID_PE;
+
+ if (cdf_mem_compare(zero_mac, get_wps_pbc_sessions_req.pRemoveMac,
+ sizeof(tSirMacAddr))) {
+ lim_get_wpspbc_sessions(mac_ctx,
+ sap_get_wpspbc_event->addr.bytes,
+ sap_get_wpspbc_event->UUID_E,
+ &sap_get_wpspbc_event->wpsPBCOverlap,
+ session_entry);
+ } else {
+ lim_remove_pbc_sessions(mac_ctx,
+ get_wps_pbc_sessions_req.pRemoveMac,
+ session_entry);
+ /* don't have to inform the HDD/Host */
+ return;
+ }
+
+ lim_log(mac_ctx, LOGE, FL("wpsPBCOverlap %d"),
+ sap_get_wpspbc_event->wpsPBCOverlap);
+ lim_print_mac_addr(mac_ctx,
+ sap_get_wpspbc_event->addr.bytes, LOG4);
+
+ sap_get_wpspbc_event->status = CDF_STATUS_SUCCESS;
+
+lim_get_wpspbc_sessions_end:
+ sap_event_cb =
+ (tpWLAN_SAPEventCB)get_wps_pbc_sessions_req.pSapEventCallback;
+ if (NULL != sap_event_cb)
+ sap_event_cb(&sap_event, get_wps_pbc_sessions_req.pUsrContext);
+}
+
+/**
+ * __lim_counter_measures()
+ *
+ * FUNCTION:
+ * This function is called to "implement" MIC counter measure
+ * and is *temporary* only
+ *
+ * LOGIC: on AP, disassoc all STA associated thru TKIP,
+ * we don't do the proper STA disassoc sequence since the
+ * BSS will be stoped anyway
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+static void __lim_counter_measures(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirMacAddr mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
+ lim_send_disassoc_mgmt_frame(pMac, eSIR_MAC_MIC_FAILURE_REASON,
+ mac, psessionEntry, false);
+};
+
+void lim_process_tkip_counter_measures(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirSmeTkipCntrMeasReq tkipCntrMeasReq;
+ tpPESession psessionEntry;
+ uint8_t sessionId; /* PE sessionId */
+
+ cdf_mem_copy(&tkipCntrMeasReq, pMsgBuf,
+ sizeof(struct sSirSmeTkipCntrMeasReq));
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ tkipCntrMeasReq.bssId,
+ &sessionId);
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE,
+ FL("session does not exist for given BSSID "));
+ return;
+ }
+
+ if (tkipCntrMeasReq.bEnable)
+ __lim_counter_measures(pMac, psessionEntry);
+
+ psessionEntry->bTkipCntrMeasActive = tkipCntrMeasReq.bEnable;
+}
+
+static void
+__lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirSmeStopBssReq stopBssReq;
+ tSirRetStatus status;
+ tLimSmeStates prevState;
+ tpPESession psessionEntry;
+ uint8_t smesessionId;
+ uint8_t sessionId;
+ uint16_t smetransactionId;
+ uint8_t i = 0;
+ tpDphHashNode pStaDs = NULL;
+
+ cdf_mem_copy(&stopBssReq, pMsgBuf, sizeof(tSirSmeStopBssReq));
+ smesessionId = stopBssReq.sessionId;
+ smetransactionId = stopBssReq.transactionId;
+
+ if (!lim_is_sme_stop_bss_req_valid(pMsgBuf)) {
+ PELOGW(lim_log(pMac, LOGW,
+ FL("received invalid SME_STOP_BSS_REQ message"));)
+ /* Send Stop BSS response to host */
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+ eSIR_SME_INVALID_PARAMETERS, smesessionId,
+ smetransactionId);
+ return;
+ }
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ stopBssReq.bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGW,
+ FL("session does not exist for given BSSID "));
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+ eSIR_SME_INVALID_PARAMETERS, smesessionId,
+ smetransactionId);
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry,
+ 0, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE || /* Added For BT -AMP Support */
+ LIM_IS_STA_ROLE(psessionEntry)) {
+ /**
+ * Should not have received STOP_BSS_REQ in states
+ * other than 'normal' state or on STA in Infrastructure
+ * mode. Log error and return response to host.
+ */
+ lim_log(pMac, LOGE,
+ FL
+ ("received unexpected SME_STOP_BSS_REQ in state %X, for role %d"),
+ psessionEntry->limSmeState,
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+ lim_print_sme_state(pMac, LOGE, psessionEntry->limSmeState);
+ /* / Send Stop BSS response to host */
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, smesessionId,
+ smetransactionId);
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ lim_wpspbc_close(pMac, psessionEntry);
+
+ lim_log(pMac, LOGW,
+ FL("RECEIVED STOP_BSS_REQ with reason code=%d"),
+ stopBssReq.reasonCode);
+
+ prevState = psessionEntry->limSmeState;
+
+ psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+
+ /* Update SME session Id and Transaction Id */
+ psessionEntry->smeSessionId = smesessionId;
+ psessionEntry->transactionId = smetransactionId;
+
+ /* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */
+ if (!LIM_IS_IBSS_ROLE(psessionEntry) &&
+ !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ if (stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)
+ /* Send disassoc all stations associated thru TKIP */
+ __lim_counter_measures(pMac, psessionEntry);
+ else
+ lim_send_disassoc_mgmt_frame(pMac,
+ eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+ bcAddr, psessionEntry, false);
+ }
+
+ /* Free the buffer allocated in START_BSS_REQ */
+ cdf_mem_free(psessionEntry->addIeParams.probeRespData_buff);
+ psessionEntry->addIeParams.probeRespDataLen = 0;
+ psessionEntry->addIeParams.probeRespData_buff = NULL;
+
+ cdf_mem_free(psessionEntry->addIeParams.assocRespData_buff);
+ psessionEntry->addIeParams.assocRespDataLen = 0;
+ psessionEntry->addIeParams.assocRespData_buff = NULL;
+
+ cdf_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
+ psessionEntry->addIeParams.probeRespBCNDataLen = 0;
+ psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
+
+ /* lim_del_bss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. */
+ pMac->lim.gLimIbssCoalescingHappened = false;
+
+ for (i = 1; i < pMac->lim.gLimAssocStaLimit; i++) {
+ pStaDs =
+ dph_get_hash_entry(pMac, i, &psessionEntry->dph.dphHashTable);
+ if (NULL == pStaDs)
+ continue;
+ status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
+ if (eSIR_SUCCESS == status) {
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
+ pStaDs->assocId, psessionEntry);
+ lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
+ } else {
+ lim_log(pMac, LOGE,
+ FL("lim_del_sta failed with Status : %d"), status);
+ CDF_ASSERT(0);
+ }
+ }
+ /* send a delBss to HAL and wait for a response */
+ status = lim_del_bss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
+
+ if (status != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("delBss failed for bss %d"),
+ psessionEntry->bssIdx);
+ )
+ psessionEntry->limSmeState = prevState;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
+ psessionEntry->limSmeState));
+
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
+ eSIR_SME_STOP_BSS_FAILURE, smesessionId,
+ smetransactionId);
+ }
+}
+
+/**
+ * __lim_process_sme_stop_bss_req() - Process STOP_BSS from SME
+ * @pMac: Global MAC context
+ * @pMsg: Message from SME
+ *
+ * Wrapper for the function __lim_handle_sme_stop_bss_request
+ * This message will be defered until softmac come out of
+ * scan mode. Message should be handled even if we have
+ * detected radar in the current operating channel.
+ *
+ * Return: true - If we consumed the buffer
+ * false - If have defered the message.
+ */
+
+static bool __lim_process_sme_stop_bss_req(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ if (__lim_is_defered_msg_for_learn(pMac, pMsg)) {
+ /**
+ * If message defered, buffer is not consumed yet.
+ * So return false
+ */
+ return false;
+ }
+ __lim_handle_sme_stop_bss_request(pMac, (uint32_t *) pMsg->bodyptr);
+ return true;
+} /*** end __lim_process_sme_stop_bss_req() ***/
+
+void lim_process_sme_del_bss_rsp(tpAniSirGlobal pMac,
+ uint32_t body, tpPESession psessionEntry)
+{
+
+ (void)body;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ lim_ibss_delete(pMac, psessionEntry);
+ dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
+ lim_delete_pre_auth_list(pMac);
+ lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+ return;
+}
+
+/**
+ * __lim_process_sme_assoc_cnf_new() - process sme assoc/reassoc cnf
+ *
+ * @mac_ctx: pointer to mac context
+ * @msg_type: message type
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function handles SME_ASSOC_CNF/SME_REASSOC_CNF
+ * in BTAMP AP.
+ *
+ * Return: None
+ */
+
+void __lim_process_sme_assoc_cnf_new(tpAniSirGlobal mac_ctx, uint32_t msg_type,
+ uint32_t *msg_buf)
+{
+ tSirSmeAssocCnf assoc_cnf;
+ tpDphHashNode sta_ds = NULL;
+ tpPESession session_entry = NULL;
+ uint8_t session_id;
+ tpSirAssocReq assoc_req;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("msg_buf is NULL "));
+ goto end;
+ }
+
+ cdf_mem_copy(&assoc_cnf, msg_buf, sizeof(struct sSirSmeAssocCnf));
+ if (!__lim_is_sme_assoc_cnf_valid(&assoc_cnf)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Received invalid SME_RE(ASSOC)_CNF message "));
+ goto end;
+ }
+
+ session_entry = pe_find_session_by_bssid(mac_ctx, assoc_cnf.bssId,
+ &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("session does not exist for given bssId"));
+ goto end;
+ }
+
+ if ((!LIM_IS_AP_ROLE(session_entry) &&
+ !LIM_IS_BT_AMP_AP_ROLE(session_entry)) ||
+ ((session_entry->limSmeState != eLIM_SME_NORMAL_STATE) &&
+ (session_entry->limSmeState !=
+ eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Rcvd unexpected msg %X in state %X, in role %X"),
+ msg_type, session_entry->limSmeState,
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ goto end;
+ }
+ sta_ds = dph_get_hash_entry(mac_ctx, assoc_cnf.aid,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Rcvd invalid msg %X due to no STA ctx, aid %d, peer "),
+ msg_type, assoc_cnf.aid);
+ lim_print_mac_addr(mac_ctx, assoc_cnf.peerMacAddr, LOG1);
+
+ /*
+ * send a DISASSOC_IND message to WSM to make sure
+ * the state in WSM and LIM is the same
+ */
+ lim_send_sme_disassoc_ntf(mac_ctx, assoc_cnf.peerMacAddr,
+ eSIR_SME_STA_NOT_ASSOCIATED,
+ eLIM_PEER_ENTITY_DISASSOC, assoc_cnf.aid,
+ session_entry->smeSessionId,
+ session_entry->transactionId,
+ session_entry);
+ goto end;
+ }
+ if (!cdf_mem_compare((uint8_t *)sta_ds->staAddr,
+ (uint8_t *) assoc_cnf.peerMacAddr,
+ sizeof(tSirMacAddr))) {
+ lim_log(mac_ctx, LOG1, FL(
+ "peerMacAddr mismatched for aid %d, peer "),
+ assoc_cnf.aid);
+ lim_print_mac_addr(mac_ctx, assoc_cnf.peerMacAddr, LOG1);
+ goto end;
+ }
+
+ if ((sta_ds->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) ||
+ ((sta_ds->mlmStaContext.subType == LIM_ASSOC) &&
+ (msg_type != eWNI_SME_ASSOC_CNF)) ||
+ ((sta_ds->mlmStaContext.subType == LIM_REASSOC) &&
+ (msg_type != eWNI_SME_ASSOC_CNF))) {
+ lim_log(mac_ctx, LOG1, FL(
+ "not in MLM_WT_ASSOC_CNF_STATE, for aid %d, peer"
+ "StaD mlmState : %d"),
+ assoc_cnf.aid, sta_ds->mlmStaContext.mlmState);
+ lim_print_mac_addr(mac_ctx, assoc_cnf.peerMacAddr, LOG1);
+ goto end;
+ }
+ /*
+ * Deactivate/delet CNF_WAIT timer since ASSOC_CNF
+ * has been received
+ */
+ lim_log(mac_ctx, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer"));
+ lim_deactivate_and_change_per_sta_id_timer(mac_ctx,
+ eLIM_CNF_WAIT_TIMER, sta_ds->assocId);
+
+ if (assoc_cnf.statusCode == eSIR_SME_SUCCESS) {
+ /*
+ * In BTAMP-AP, PE already finished the WMA_ADD_STA sequence
+ * when it had received Assoc Request frame. Now, PE just needs
+ * to send association rsp frame to the requesting BTAMP-STA.
+ */
+ sta_ds->mlmStaContext.mlmState =
+ eLIM_MLM_LINK_ESTABLISHED_STATE;
+ lim_log(mac_ctx, LOG1,
+ FL("sending Assoc Rsp frame to STA (assoc id=%d) "),
+ sta_ds->assocId);
+ lim_send_assoc_rsp_mgmt_frame(mac_ctx, eSIR_SUCCESS,
+ sta_ds->assocId, sta_ds->staAddr,
+ sta_ds->mlmStaContext.subType, sta_ds,
+ session_entry);
+ goto end;
+ } else {
+ /*
+ * SME_ASSOC_CNF status is non-success, so STA is not allowed
+ * to be associated since the HAL sta entry is created for
+ * denied STA we need to remove this HAL entry.
+ * So to do that set updateContext to 1
+ */
+ if (!sta_ds->mlmStaContext.updateContext)
+ sta_ds->mlmStaContext.updateContext = 1;
+ lim_log(mac_ctx, LOG1,
+ FL("Recv Assoc Cnf, status Code : %d(assoc id=%d) "),
+ assoc_cnf.statusCode, sta_ds->assocId);
+ lim_reject_association(mac_ctx, sta_ds->staAddr,
+ sta_ds->mlmStaContext.subType,
+ true, sta_ds->mlmStaContext.authType,
+ sta_ds->assocId, true,
+ eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ session_entry);
+ }
+end:
+ if (((session_entry != NULL) && (sta_ds != NULL)) &&
+ (session_entry->parsedAssocReq[sta_ds->assocId] != NULL)) {
+ assoc_req = (tpSirAssocReq)
+ session_entry->parsedAssocReq[sta_ds->assocId];
+ if (assoc_req->assocReqFrame) {
+ cdf_mem_free(assoc_req->assocReqFrame);
+ assoc_req->assocReqFrame = NULL;
+ }
+ cdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
+ session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
+ }
+}
+
+static void __lim_process_sme_addts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpDphHashNode pStaDs;
+ tSirMacAddr peerMac;
+ tpSirAddtsReq pSirAddts;
+ uint32_t timeout;
+ tpPESession psessionEntry;
+ uint8_t sessionId; /* PE sessionId */
+ uint8_t smesessionId;
+ uint16_t smetransactionId;
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smesessionId,
+ &smetransactionId);
+
+ pSirAddts = (tpSirAddtsReq) pMsgBuf;
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pSirAddts->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE, "Session Does not exist for given bssId");
+ return;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ /* if sta
+ * - verify assoc state
+ * - send addts request to ap
+ * - wait for addts response from ap
+ * if ap, just ignore with error log
+ */
+ PELOG1(lim_log(pMac, LOG1,
+ FL("Received SME_ADDTS_REQ (TSid %d, UP %d)"),
+ pSirAddts->req.tspec.tsinfo.traffic.tsid,
+ pSirAddts->req.tspec.tsinfo.traffic.userPrio);
+ )
+
+ if (!LIM_IS_STA_ROLE(psessionEntry) &&
+ !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ PELOGE(lim_log(pMac, LOGE, "AddTs received on AP - ignoring");)
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+ /* Ignore the request if STA is in 11B mode. */
+ if (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ "AddTS received while Dot11Mode is 11B - ignoring");
+ )
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, "Cannot find AP context for addts req");
+ )
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ if ((!pStaDs->valid) || (pStaDs->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+ lim_log(pMac, LOGE, "AddTs received in invalid MLM state");
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ pSirAddts->req.wsmTspecPresent = 0;
+ pSirAddts->req.wmeTspecPresent = 0;
+ pSirAddts->req.lleTspecPresent = 0;
+
+ if ((pStaDs->wsmEnabled) &&
+ (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy !=
+ SIR_MAC_ACCESSPOLICY_EDCA))
+ pSirAddts->req.wsmTspecPresent = 1;
+ else if (pStaDs->wmeEnabled)
+ pSirAddts->req.wmeTspecPresent = 1;
+ else if (pStaDs->lleEnabled)
+ pSirAddts->req.lleTspecPresent = 1;
+ else {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("ADDTS_REQ ignore - qos is disabled"));
+ )
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+ lim_log(pMac, LOGE,
+ "AddTs received in invalid LIMsme state (%d)",
+ psessionEntry->limSmeState);
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ if (pMac->lim.gLimAddtsSent) {
+ lim_log(pMac, LOGE,
+ "Addts (token %d, tsid %d, up %d) is still pending",
+ pMac->lim.gLimAddtsReq.req.dialogToken,
+ pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
+ pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.
+ userPrio);
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ sir_copy_mac_addr(peerMac, psessionEntry->bssId);
+
+ /* save the addts request */
+ pMac->lim.gLimAddtsSent = true;
+ cdf_mem_copy((uint8_t *) &pMac->lim.gLimAddtsReq,
+ (uint8_t *) pSirAddts, sizeof(tSirAddtsReq));
+
+ /* ship out the message now */
+ lim_send_addts_req_action_frame(pMac, peerMac, &pSirAddts->req,
+ psessionEntry);
+ PELOG1(lim_log(pMac, LOG1, "Sent ADDTS request");)
+ /* start a timer to wait for the response */
+ if (pSirAddts->timeout)
+ timeout = pSirAddts->timeout;
+ else if (wlan_cfg_get_int(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &timeout) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to get Cfg param %d (Addts Rsp Timeout)"),
+ WNI_CFG_ADDTS_RSP_TIMEOUT);
+ return;
+ }
+
+ timeout = SYS_MS_TO_TICKS(timeout);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0)
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("AddtsRsp timer change failed!"));
+ return;
+ }
+ pMac->lim.gLimAddtsRspTimerCount++;
+ if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
+ pMac->lim.gLimAddtsRspTimerCount) !=
+ TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("AddtsRsp timer change failed!"));
+ return;
+ }
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
+ eLIM_ADDTS_RSP_TIMER));
+
+ /* add the sessionId to the timer object */
+ pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId;
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) !=
+ TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("AddtsRsp timer activation failed!"));
+ return;
+ }
+ return;
+}
+
+static void __lim_process_sme_delts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirMacAddr peerMacAddr;
+ uint8_t ac;
+ tSirMacTSInfo *pTsinfo;
+ tpSirDeltsReq pDeltsReq = (tpSirDeltsReq) pMsgBuf;
+ tpDphHashNode pStaDs = NULL;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+ uint32_t status = eSIR_SUCCESS;
+ uint8_t smesessionId;
+ uint16_t smetransactionId;
+
+ lim_get_session_info(pMac, (uint8_t *) pMsgBuf, &smesessionId,
+ &smetransactionId);
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pDeltsReq->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE, "Session Does not exist for given bssId");
+ status = eSIR_FAILURE;
+ goto end;
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ if (eSIR_SUCCESS !=
+ lim_validate_delts_req(pMac, pDeltsReq, peerMacAddr, psessionEntry)) {
+ PELOGE(lim_log(pMac, LOGE, FL("lim_validate_delts_req failed"));)
+ status = eSIR_FAILURE;
+ lim_send_sme_delts_rsp(pMac, pDeltsReq, eSIR_FAILURE, psessionEntry,
+ smesessionId, smetransactionId);
+ return;
+ }
+
+ lim_log(pMac, LOG1,
+ FL("Sent DELTS request to station with assocId = %d MacAddr = "
+ MAC_ADDRESS_STR),
+ pDeltsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));
+
+ lim_send_delts_req_action_frame(pMac, peerMacAddr,
+ pDeltsReq->req.wmeTspecPresent,
+ &pDeltsReq->req.tsinfo,
+ &pDeltsReq->req.tspec, psessionEntry);
+
+ pTsinfo =
+ pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.
+ tsinfo : &pDeltsReq->req.tsinfo;
+
+ /* We've successfully send DELTS frame to AP. Update the
+ * dynamic UAPSD mask. The AC for this TSPEC to be deleted
+ * is no longer trigger enabled or delivery enabled
+ */
+ lim_set_tspec_uapsd_mask_per_session(pMac, psessionEntry,
+ pTsinfo, CLEAR_UAPSD_MASK);
+
+ /* We're deleting the TSPEC, so this particular AC is no longer
+ * admitted. PE needs to downgrade the EDCA
+ * parameters(for the AC for which TS is being deleted) to the
+ * next best AC for which ACM is not enabled, and send the
+ * updated values to HAL.
+ */
+ ac = upToAc(pTsinfo->traffic.userPrio);
+
+ if (pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
+ psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+ ~(1 << ac);
+ } else if (pTsinfo->traffic.direction ==
+ SIR_MAC_DIRECTION_DNLINK) {
+ psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+ ~(1 << ac);
+ } else if (pTsinfo->traffic.direction ==
+ SIR_MAC_DIRECTION_BIDIR) {
+ psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
+ ~(1 << ac);
+ psessionEntry->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
+ ~(1 << ac);
+ }
+
+ lim_set_active_edca_params(pMac, psessionEntry->gLimEdcaParams,
+ psessionEntry);
+
+ pStaDs =
+ dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL) {
+ lim_send_edca_params(pMac, psessionEntry->gLimEdcaParamsActive,
+ pStaDs->bssId);
+ status = eSIR_SUCCESS;
+ } else {
+ lim_log(pMac, LOGE, FL("Self entry missing in Hash Table "));
+ status = eSIR_FAILURE;
+ }
+#ifdef FEATURE_WLAN_ESE
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+ lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
+#else
+ lim_deactivate_and_change_timer(pMac, eLIM_TSM_TIMER);
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+#endif
+
+ /* send an sme response back */
+end:
+ lim_send_sme_delts_rsp(pMac, pDeltsReq, eSIR_SUCCESS, psessionEntry,
+ smesessionId, smetransactionId);
+}
+
+void lim_process_sme_addts_rsp_timeout(tpAniSirGlobal pMac, uint32_t param)
+{
+ /* fetch the sessionEntry based on the sessionId */
+ tpPESession psessionEntry;
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMac->lim.limTimers.gLimAddtsRspTimer.
+ sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ if (!LIM_IS_STA_ROLE(psessionEntry) &&
+ !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
+ lim_log(pMac, LOGW, "AddtsRspTimeout in non-Sta role (%d)",
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+ pMac->lim.gLimAddtsSent = false;
+ return;
+ }
+
+ if (!pMac->lim.gLimAddtsSent) {
+ lim_log(pMac, LOGW, "AddtsRspTimeout but no AddtsSent");
+ return;
+ }
+
+ if (param != pMac->lim.gLimAddtsRspTimerCount) {
+ lim_log(pMac, LOGE,
+ FL("Invalid AddtsRsp Timer count %d (exp %d)"), param,
+ pMac->lim.gLimAddtsRspTimerCount);
+ return;
+ }
+ /* this a real response timeout */
+ pMac->lim.gLimAddtsSent = false;
+ pMac->lim.gLimAddtsRspTimerCount++;
+
+ lim_send_sme_addts_rsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT,
+ psessionEntry, pMac->lim.gLimAddtsReq.req.tspec,
+ psessionEntry->smeSessionId,
+ psessionEntry->transactionId);
+}
+
+/**
+ * __lim_process_sme_get_statistics_request()
+ *
+ ***FUNCTION:
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+static void
+__lim_process_sme_get_statistics_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpAniGetPEStatsReq pPEStatsReq;
+ tSirMsgQ msgQ;
+
+ pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf;
+
+ msgQ.type = WMA_GET_STATISTICS_REQ;
+
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMsgBuf;
+ msgQ.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+
+ if (eSIR_SUCCESS != (wma_post_ctrl_msg(pMac, &msgQ))) {
+ cdf_mem_free(pMsgBuf);
+ pMsgBuf = NULL;
+ lim_log(pMac, LOGP, "Unable to forward request");
+ return;
+ }
+
+ return;
+}
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/**
+ *FUNCTION: __lim_process_sme_get_tsm_stats_request()
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return None
+ */
+static void
+__lim_process_sme_get_tsm_stats_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tSirMsgQ msgQ;
+
+ msgQ.type = WMA_TSM_STATS_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMsgBuf;
+ msgQ.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+
+ if (eSIR_SUCCESS != (wma_post_ctrl_msg(pMac, &msgQ))) {
+ cdf_mem_free(pMsgBuf);
+ pMsgBuf = NULL;
+ lim_log(pMac, LOGP, "Unable to forward request");
+ return;
+ }
+}
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+
+static void
+__lim_process_sme_update_apwpsi_es(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq;
+ tpPESession psessionEntry;
+ uint8_t sessionId; /* PE sessionID */
+
+ PELOG1(lim_log(pMac, LOG1, FL("received UPDATE_APWPSIEs_REQ message")););
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pUpdateAPWPSIEsReq = cdf_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
+ if (NULL == pUpdateAPWPSIEsReq) {
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for pUpdateAPWPSIEsReq"));
+ return;
+ }
+ cdf_mem_copy(pUpdateAPWPSIEsReq, pMsgBuf,
+ sizeof(struct sSirUpdateAPWPSIEsReq));
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pUpdateAPWPSIEsReq->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGW,
+ FL("Session does not exist for given BSSID"));
+ goto end;
+ }
+
+ cdf_mem_copy(&psessionEntry->APWPSIEs, &pUpdateAPWPSIEsReq->APWPSIEs,
+ sizeof(tSirAPWPSIEs));
+
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ lim_send_beacon_ind(pMac, psessionEntry);
+
+end:
+ cdf_mem_free(pUpdateAPWPSIEsReq);
+ return;
+}
+
+void
+lim_send_vdev_restart(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, uint8_t sessionId)
+{
+ tpHalHiddenSsidVdevRestart pHalHiddenSsidVdevRestart = NULL;
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, "%s:%d: Invalid parameters", __func__,
+ __LINE__);
+ )
+ return;
+ }
+
+ pHalHiddenSsidVdevRestart =
+ cdf_mem_malloc(sizeof(tHalHiddenSsidVdevRestart));
+ if (NULL == pHalHiddenSsidVdevRestart) {
+ PELOGE(lim_log
+ (pMac, LOGE, "%s:%d: Unable to allocate memory",
+ __func__, __LINE__);
+ )
+ return;
+ }
+
+ pHalHiddenSsidVdevRestart->ssidHidden = psessionEntry->ssidHidden;
+ pHalHiddenSsidVdevRestart->sessionId = sessionId;
+
+ msgQ.type = WMA_HIDDEN_SSID_VDEV_RESTART;
+ msgQ.bodyptr = pHalHiddenSsidVdevRestart;
+ msgQ.bodyval = 0;
+
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ PELOGE(lim_log
+ (pMac, LOGE, "%s:%d: wma_post_ctrl_msg() failed", __func__,
+ __LINE__);
+ )
+ cdf_mem_free(pHalHiddenSsidVdevRestart);
+ }
+}
+
+static void __lim_process_sme_hide_ssid(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpSirUpdateParams pUpdateParams;
+ tpPESession psessionEntry;
+
+ PELOG1(lim_log(pMac, LOG1, FL("received HIDE_SSID message")););
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pUpdateParams = (tpSirUpdateParams) pMsgBuf;
+
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pUpdateParams->sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGW,
+ "Session does not exist for given sessionId %d",
+ pUpdateParams->sessionId);
+ return;
+ }
+
+ /* Update the session entry */
+ psessionEntry->ssidHidden = pUpdateParams->ssidHidden;
+
+ /* Send vdev restart */
+ lim_send_vdev_restart(pMac, psessionEntry, pUpdateParams->sessionId);
+
+ /* Update beacon */
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ lim_send_beacon_ind(pMac, psessionEntry);
+
+ return;
+} /*** end __lim_process_sme_hide_ssid(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
+
+static void __lim_process_sme_set_wparsni_es(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq;
+ tpPESession psessionEntry;
+ uint8_t sessionId; /* PE sessionID */
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pUpdateAPWPARSNIEsReq = cdf_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq));
+ if (NULL == pUpdateAPWPARSNIEsReq) {
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for pUpdateAPWPARSNIEsReq"));
+ return;
+ }
+ cdf_mem_copy(pUpdateAPWPARSNIEsReq, pMsgBuf,
+ sizeof(struct sSirUpdateAPWPARSNIEsReq));
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pUpdateAPWPARSNIEsReq->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGW,
+ FL("Session does not exist for given BSSID"));
+ goto end;
+ }
+
+ cdf_mem_copy(&psessionEntry->pLimStartBssReq->rsnIE,
+ &pUpdateAPWPARSNIEsReq->APWPARSNIEs, sizeof(tSirRSNie));
+
+ lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(pMac,
+ &psessionEntry->
+ pLimStartBssReq->rsnIE,
+ psessionEntry);
+
+ psessionEntry->pLimStartBssReq->privacy = 1;
+ psessionEntry->privacy = 1;
+
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ lim_send_beacon_ind(pMac, psessionEntry);
+
+end:
+ cdf_mem_free(pUpdateAPWPARSNIEsReq);
+ return;
+} /*** end __lim_process_sme_set_wparsni_es(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
+
+/*
+ Update the beacon Interval dynamically if beaconInterval is different in MCC
+ */
+static void __lim_process_sme_change_bi(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpSirChangeBIParams pChangeBIParams;
+ tpPESession psessionEntry;
+ uint8_t sessionId = 0;
+ tUpdateBeaconParams beaconParams;
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL("received Update Beacon Interval message"));
+ );
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ cdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
+ pChangeBIParams = (tpSirChangeBIParams) pMsgBuf;
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pChangeBIParams->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session does not exist for given BSSID"));
+ return;
+ }
+
+ /*Update sessionEntry Beacon Interval */
+ if (psessionEntry->beaconParams.beaconInterval !=
+ pChangeBIParams->beaconInterval) {
+ psessionEntry->beaconParams.beaconInterval =
+ pChangeBIParams->beaconInterval;
+ }
+
+ /*Update sch beaconInterval */
+ if (pMac->sch.schObject.gSchBeaconInterval !=
+ pChangeBIParams->beaconInterval) {
+ pMac->sch.schObject.gSchBeaconInterval =
+ pChangeBIParams->beaconInterval;
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("LIM send update BeaconInterval Indication : %d"),
+ pChangeBIParams->beaconInterval);
+ );
+
+ if (false == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+ /* Update beacon */
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+
+ beaconParams.bssIdx = psessionEntry->bssIdx;
+ /* Set change in beacon Interval */
+ beaconParams.beaconInterval =
+ pChangeBIParams->beaconInterval;
+ beaconParams.paramChangeBitmap =
+ PARAM_BCN_INTERVAL_CHANGED;
+ lim_send_beacon_params(pMac, &beaconParams, psessionEntry);
+ }
+ }
+
+ return;
+} /*** end __lim_process_sme_change_bi(tpAniSirGlobal pMac, uint32_t *pMsgBuf) ***/
+
+#ifdef QCA_HT_2040_COEX
+static void __lim_process_sme_set_ht2040_mode(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf)
+{
+ tpSirSetHT2040Mode pSetHT2040Mode;
+ tpPESession psessionEntry;
+ uint8_t sessionId = 0;
+ cds_msg_t msg;
+ tUpdateVHTOpMode *pHtOpMode = NULL;
+ uint16_t staId = 0;
+ tpDphHashNode pStaDs = NULL;
+
+ PELOG1(lim_log(pMac, LOG1, FL("received Set HT 20/40 mode message")););
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pSetHT2040Mode = (tpSirSetHT2040Mode) pMsgBuf;
+
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pSetHT2040Mode->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOG1,
+ FL("Session does not exist for given BSSID "));
+ lim_print_mac_addr(pMac, pSetHT2040Mode->bssId, LOG1);
+ return;
+ }
+
+ lim_log(pMac, LOG1, FL("Update session entry for cbMod=%d"),
+ pSetHT2040Mode->cbMode);
+ /*Update sessionEntry HT related fields */
+ switch (pSetHT2040Mode->cbMode) {
+ case PHY_SINGLE_CHANNEL_CENTERED:
+ psessionEntry->htSecondaryChannelOffset =
+ PHY_SINGLE_CHANNEL_CENTERED;
+ psessionEntry->htRecommendedTxWidthSet = 0;
+ if (pSetHT2040Mode->obssEnabled)
+ psessionEntry->htSupportedChannelWidthSet
+ = eHT_CHANNEL_WIDTH_40MHZ;
+ else
+ psessionEntry->htSupportedChannelWidthSet
+ = eHT_CHANNEL_WIDTH_20MHZ;
+ break;
+ case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+ psessionEntry->htSecondaryChannelOffset =
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+ psessionEntry->htRecommendedTxWidthSet = 1;
+ break;
+ case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+ psessionEntry->htSecondaryChannelOffset =
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+ psessionEntry->htRecommendedTxWidthSet = 1;
+ break;
+ default:
+ lim_log(pMac, LOGE, FL("Invalid cbMode"));
+ return;
+ }
+
+ /* Update beacon */
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ lim_send_beacon_ind(pMac, psessionEntry);
+
+ /* update OP Mode for each associated peer */
+ for (staId = 0; staId < psessionEntry->dph.dphHashTable.size; staId++) {
+ pStaDs = dph_get_hash_entry(pMac, staId,
+ &psessionEntry->dph.dphHashTable);
+ if (NULL == pStaDs)
+ continue;
+
+ if (pStaDs->valid && pStaDs->htSupportedChannelWidthSet) {
+ pHtOpMode = cdf_mem_malloc(sizeof(tUpdateVHTOpMode));
+ if (NULL == pHtOpMode) {
+ lim_log(pMac, LOGE,
+ FL
+ ("%s: Not able to allocate memory for setting OP mode"),
+ __func__);
+ return;
+ }
+ pHtOpMode->opMode =
+ (psessionEntry->htSecondaryChannelOffset ==
+ PHY_SINGLE_CHANNEL_CENTERED) ?
+ eHT_CHANNEL_WIDTH_20MHZ : eHT_CHANNEL_WIDTH_40MHZ;
+ pHtOpMode->staId = staId;
+ cdf_mem_copy(pHtOpMode->peer_mac, &pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+ pHtOpMode->smesessionId = sessionId;
+
+ msg.type = WMA_UPDATE_OP_MODE;
+ msg.reserved = 0;
+ msg.bodyptr = pHtOpMode;
+ if (!CDF_IS_STATUS_SUCCESS
+ (cds_mq_post_message(CDF_MODULE_ID_WMA, &msg))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("%s: Not able to post WMA_UPDATE_OP_MODE message to WMA"),
+ __func__);
+ cdf_mem_free(pHtOpMode);
+ return;
+ }
+ lim_log(pMac, LOG1,
+ FL
+ ("%s: Notifed FW about OP mode: %d for staId=%d"),
+ __func__, pHtOpMode->opMode, staId);
+
+ } else
+ lim_log(pMac, LOG1,
+ FL("%s: station %d does not support HT40\n"),
+ __func__, staId);
+ }
+
+ return;
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/**
+ * __lim_process_report_message
+ *
+ * FUNCTION: Processes the next received Radio Resource Management message
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void __lim_process_report_message(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+#ifdef WLAN_FEATURE_VOWIFI
+ switch (pMsg->type) {
+ case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+ rrm_process_neighbor_report_req(pMac, pMsg->bodyptr);
+ break;
+ case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+ {
+ rrm_process_beacon_report_xmit(pMac, pMsg->bodyptr);
+ }
+ break;
+ }
+#endif
+}
+
+#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_VOWIFI)
+/* -------------------------------------------------------------------- */
+/**
+ * lim_send_set_max_tx_power_req
+ *
+ * FUNCTION: Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus
+lim_send_set_max_tx_power_req(tpAniSirGlobal pMac, tPowerdBm txPower,
+ tpPESession pSessionEntry)
+{
+ tpMaxTxPowerParams pMaxTxParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ if (pSessionEntry == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, "%s:%d: Inavalid parameters", __func__,
+ __LINE__);
+ )
+ return eSIR_FAILURE;
+ }
+
+ pMaxTxParams = cdf_mem_malloc(sizeof(tMaxTxPowerParams));
+ if (NULL == pMaxTxParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory for pMaxTxParams "));
+ return eSIR_MEM_ALLOC_FAILED;
+
+ }
+#if defined(WLAN_VOWIFI_DEBUG) || defined(FEATURE_WLAN_ESE)
+ lim_log(pMac, LOG1,
+ FL("pMaxTxParams allocated...will be freed in other module"));
+#endif
+ if (pMaxTxParams == NULL) {
+ lim_log(pMac, LOGE, FL("pMaxTxParams is NULL"));
+ return eSIR_FAILURE;
+ }
+ pMaxTxParams->power = txPower;
+ cdf_mem_copy(pMaxTxParams->bssId, pSessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ cdf_mem_copy(pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ msgQ.type = WMA_SET_MAX_TX_POWER_REQ;
+ msgQ.bodyptr = pMaxTxParams;
+ msgQ.bodyval = 0;
+ PELOG1(lim_log
+ (pMac, LOG1, FL("Posting WMA_SET_MAX_TX_POWER_REQ to WMA"));
+ )
+ MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() failed"));
+ cdf_mem_free(pMaxTxParams);
+ }
+ return retCode;
+}
+#endif
+
+/**
+ * __lim_process_sme_register_mgmt_frame_req() - process sme reg mgmt frame req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message
+ * from SME. It Register this information within PE.
+ *
+ * Return: None
+ */
+static void __lim_process_sme_register_mgmt_frame_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ CDF_STATUS cdf_status;
+ tpSirRegisterMgmtFrame sme_req = (tpSirRegisterMgmtFrame)msg_buf;
+ struct mgmt_frm_reg_info *lim_mgmt_regn = NULL;
+ struct mgmt_frm_reg_info *next = NULL;
+ bool match = false;
+
+ lim_log(mac_ctx, LOG1, FL(
+ "registerFrame %d, frameType %d, matchLen %d"),
+ sme_req->registerFrame, sme_req->frameType,
+ sme_req->matchLen);
+ /* First check whether entry exists already */
+ cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+ cdf_list_peek_front(&mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+ (cdf_list_node_t **) &lim_mgmt_regn);
+ cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+
+ while (lim_mgmt_regn != NULL) {
+ if (lim_mgmt_regn->frameType != sme_req->frameType)
+ goto skip_match;
+ if (sme_req->matchLen) {
+ if ((lim_mgmt_regn->matchLen == sme_req->matchLen) &&
+ (cdf_mem_compare(lim_mgmt_regn->matchData,
+ sme_req->matchData,
+ lim_mgmt_regn->matchLen))) {
+ /* found match! */
+ match = true;
+ break;
+ }
+ } else {
+ /* found match! */
+ match = true;
+ break;
+ }
+skip_match:
+ cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+ cdf_status = cdf_list_peek_next(
+ &mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+ (cdf_list_node_t *)lim_mgmt_regn,
+ (cdf_list_node_t **)&next);
+ cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+ lim_mgmt_regn = next;
+ next = NULL;
+ }
+ if (match) {
+ cdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock);
+ cdf_list_remove_node(
+ &mac_ctx->lim.gLimMgmtFrameRegistratinQueue,
+ (cdf_list_node_t *)lim_mgmt_regn);
+ cdf_mutex_release(&mac_ctx->lim.lim_frame_register_lock);
+ cdf_mem_free(lim_mgmt_regn);
+ }
+
+ if (sme_req->registerFrame) {
+ lim_mgmt_regn =
+ cdf_mem_malloc(sizeof(struct mgmt_frm_reg_info) +
+ sme_req->matchLen);
+ if (lim_mgmt_regn != NULL) {
+ cdf_mem_set((void *)lim_mgmt_regn,
+ sizeof(struct mgmt_frm_reg_info) +
+ sme_req->matchLen, 0);
+ lim_mgmt_regn->frameType = sme_req->frameType;
+ lim_mgmt_regn->matchLen = sme_req->matchLen;
+ lim_mgmt_regn->sessionId = sme_req->sessionId;
+ if (sme_req->matchLen) {
+ cdf_mem_copy(lim_mgmt_regn->matchData,
+ sme_req->matchData,
+ sme_req->matchLen);
+ }
+ cdf_mutex_acquire(
+ &mac_ctx->lim.lim_frame_register_lock);
+ cdf_list_insert_front(&mac_ctx->lim.
+ gLimMgmtFrameRegistratinQueue,
+ &lim_mgmt_regn->node);
+ cdf_mutex_release(
+ &mac_ctx->lim.lim_frame_register_lock);
+ }
+ }
+ return;
+}
+
+static void __lim_deregister_deferred_sme_req_after_noa_start(tpAniSirGlobal pMac)
+{
+ lim_log(pMac, LOG1, FL("Dereg msgType %d"),
+ pMac->lim.gDeferMsgTypeForNOA);
+ pMac->lim.gDeferMsgTypeForNOA = 0;
+ if (pMac->lim.gpDefdSmeMsgForNOA != NULL) {
+ /* __lim_process_sme_scan_req consumed the buffer. We can free it. */
+ cdf_mem_free(pMac->lim.gpDefdSmeMsgForNOA);
+ pMac->lim.gpDefdSmeMsgForNOA = NULL;
+ }
+}
+
+/**
+ * lim_process_regd_defd_sme_req_after_noa_start()
+ *
+ * mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to process deferred sme req message
+ * after noa start.
+ *
+ * Return: None
+ */
+void lim_process_regd_defd_sme_req_after_noa_start(tpAniSirGlobal mac_ctx)
+{
+ bool buf_consumed = true;
+
+ lim_log(mac_ctx, LOG1, FL("Process defd sme req %d"),
+ mac_ctx->lim.gDeferMsgTypeForNOA);
+
+ if ((mac_ctx->lim.gDeferMsgTypeForNOA == 0) ||
+ (mac_ctx->lim.gpDefdSmeMsgForNOA == NULL)) {
+ lim_log(mac_ctx, LOGW,
+ FL("start rcvd from FW when no sme deferred msg pending. Do nothing. "));
+ lim_log(mac_ctx, LOGW,
+ FL("It may happen when NOA start ind and timeout happen at the same time"));
+ return;
+ }
+ switch (mac_ctx->lim.gDeferMsgTypeForNOA) {
+ case eWNI_SME_SCAN_REQ:
+ __lim_process_sme_scan_req(mac_ctx,
+ mac_ctx->lim.gpDefdSmeMsgForNOA);
+ break;
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case eWNI_SME_OEM_DATA_REQ:
+ __lim_process_sme_oem_data_req(mac_ctx,
+ mac_ctx->lim.gpDefdSmeMsgForNOA);
+ break;
+#endif
+ case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
+ buf_consumed = lim_process_remain_on_chnl_req(mac_ctx,
+ mac_ctx->lim.gpDefdSmeMsgForNOA);
+ /*
+ * lim_process_remain_on_chnl_req doesnt want us to free
+ * the buffer since it is freed in lim_remain_on_chn_rsp.
+ * this change is to avoid "double free"
+ */
+ if (false == buf_consumed)
+ mac_ctx->lim.gpDefdSmeMsgForNOA = NULL;
+ break;
+ case eWNI_SME_JOIN_REQ:
+ __lim_process_sme_join_req(mac_ctx,
+ mac_ctx->lim.gpDefdSmeMsgForNOA);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE, FL("Unknown deferred msg type %d"),
+ mac_ctx->lim.gDeferMsgTypeForNOA);
+ break;
+ }
+ __lim_deregister_deferred_sme_req_after_noa_start(mac_ctx);
+}
+
+static void
+__lim_process_sme_reset_ap_caps_change(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
+{
+ tpSirResetAPCapsChange pResetCapsChange;
+ tpPESession psessionEntry;
+ uint8_t sessionId = 0;
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pResetCapsChange = (tpSirResetAPCapsChange) pMsgBuf;
+ psessionEntry =
+ pe_find_session_by_bssid(pMac, pResetCapsChange->bssId, &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session does not exist for given BSSID"));
+ return;
+ }
+
+ psessionEntry->limSentCapsChangeNtf = false;
+ return;
+}
+
+/**
+ * lim_process_sme_req_messages()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the SME message type
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return Boolean - true - if pMsgBuf is consumed and can be freed.
+ * false - if pMsgBuf is not to be freed.
+ */
+
+bool lim_process_sme_req_messages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ bool bufConsumed = true; /* Set this flag to false within case block of any following message, that doesnt want pMsgBuf to be freed. */
+ uint32_t *pMsgBuf = pMsg->bodyptr;
+ tpSirSmeScanReq pScanReq;
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("LIM Received SME Message %s(%d) Global LimSmeState:%s(%d) Global LimMlmState: %s(%d)"),
+ lim_msg_str(pMsg->type), pMsg->type,
+ lim_sme_state_str(pMac->lim.gLimSmeState), pMac->lim.gLimSmeState,
+ lim_mlm_state_str(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState);
+ )
+
+ pScanReq = (tpSirSmeScanReq) pMsgBuf;
+ /* If no insert NOA required then execute the code below */
+
+ switch (pMsg->type) {
+ case eWNI_SME_SYS_READY_IND:
+ bufConsumed = __lim_process_sme_sys_ready_ind(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_START_BSS_REQ:
+ bufConsumed = __lim_process_sme_start_bss_req(pMac, pMsg);
+ break;
+
+ case eWNI_SME_SCAN_REQ:
+ __lim_process_sme_scan_req(pMac, pMsgBuf);
+ break;
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case eWNI_SME_OEM_DATA_REQ:
+ __lim_process_sme_oem_data_req(pMac, pMsgBuf);
+ break;
+#endif
+ case eWNI_SME_REMAIN_ON_CHANNEL_REQ:
+ bufConsumed = lim_process_remain_on_chnl_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_UPDATE_NOA:
+ __lim_process_sme_no_a_update(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_CLEAR_DFS_CHANNEL_LIST:
+ __lim_process_clear_dfs_channel_list(pMac, pMsg);
+ break;
+ case eWNI_SME_JOIN_REQ:
+ __lim_process_sme_join_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_REASSOC_REQ:
+ __lim_process_sme_reassoc_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DISASSOC_REQ:
+ __lim_process_sme_disassoc_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DISASSOC_CNF:
+ case eWNI_SME_DEAUTH_CNF:
+ __lim_process_sme_disassoc_cnf(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DEAUTH_REQ:
+ __lim_process_sme_deauth_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_SETCONTEXT_REQ:
+ __lim_process_sme_set_context_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_STOP_BSS_REQ:
+ bufConsumed = __lim_process_sme_stop_bss_req(pMac, pMsg);
+ break;
+
+ case eWNI_SME_ASSOC_CNF:
+ if (pMsg->type == eWNI_SME_ASSOC_CNF)
+ PELOG1(lim_log(pMac,
+ LOG1, FL("Received ASSOC_CNF message"));)
+ __lim_process_sme_assoc_cnf_new(pMac, pMsg->type,
+ pMsgBuf);
+ break;
+
+ case eWNI_SME_ADDTS_REQ:
+ PELOG1(lim_log(pMac, LOG1, FL("Received ADDTS_REQ message"));)
+ __lim_process_sme_addts_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DELTS_REQ:
+ PELOG1(lim_log(pMac, LOG1, FL("Received DELTS_REQ message"));)
+ __lim_process_sme_delts_req(pMac, pMsgBuf);
+ break;
+
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Received SIR_LIM_ADDTS_RSP_TIMEOUT message "));
+ )
+ lim_process_sme_addts_rsp_timeout(pMac, pMsg->bodyval);
+ break;
+
+ case eWNI_SME_GET_STATISTICS_REQ:
+ __lim_process_sme_get_statistics_request(pMac, pMsgBuf);
+ /* HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. */
+ bufConsumed = false;
+ break;
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+ case eWNI_SME_GET_TSM_STATS_REQ:
+ __lim_process_sme_get_tsm_stats_request(pMac, pMsgBuf);
+ bufConsumed = false;
+ break;
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+ case eWNI_SME_GET_ASSOC_STAS_REQ:
+ lim_process_sme_get_assoc_sta_info(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_TKIP_CNTR_MEAS_REQ:
+ lim_process_tkip_counter_measures(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_HIDE_SSID_REQ:
+ __lim_process_sme_hide_ssid(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_UPDATE_APWPSIE_REQ:
+ __lim_process_sme_update_apwpsi_es(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_GET_WPSPBC_SESSION_REQ:
+ lim_process_sme_get_wpspbc_sessions(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_SET_APWPARSNIEs_REQ:
+ __lim_process_sme_set_wparsni_es(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_CHNG_MCC_BEACON_INTERVAL:
+ /* Update the beaconInterval */
+ __lim_process_sme_change_bi(pMac, pMsgBuf);
+ break;
+
+#ifdef QCA_HT_2040_COEX
+ case eWNI_SME_SET_HT_2040_MODE:
+ __lim_process_sme_set_ht2040_mode(pMac, pMsgBuf);
+ break;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+ case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+ case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+ __lim_process_report_message(pMac, pMsg);
+ break;
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ case eWNI_SME_FT_PRE_AUTH_REQ:
+ bufConsumed = (bool) lim_process_ft_pre_auth_req(pMac, pMsg);
+ break;
+ case eWNI_SME_FT_UPDATE_KEY:
+ lim_process_ft_update_key(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_FT_AGGR_QOS_REQ:
+ lim_process_ft_aggr_qos_req(pMac, pMsgBuf);
+ break;
+#endif
+
+ case eWNI_SME_REGISTER_MGMT_FRAME_REQ:
+ __lim_process_sme_register_mgmt_frame_req(pMac, pMsgBuf);
+ break;
+#ifdef FEATURE_WLAN_TDLS
+ case eWNI_SME_TDLS_SEND_MGMT_REQ:
+ lim_process_sme_tdls_mgmt_send_req(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_TDLS_ADD_STA_REQ:
+ lim_process_sme_tdls_add_sta_req(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_TDLS_DEL_STA_REQ:
+ lim_process_sme_tdls_del_sta_req(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
+ lim_process_sme_tdls_link_establish_req(pMac, pMsgBuf);
+ break;
+#endif
+ case eWNI_SME_RESET_AP_CAPS_CHANGED:
+ __lim_process_sme_reset_ap_caps_change(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_CHANNEL_CHANGE_REQ:
+ lim_process_sme_channel_change_request(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_START_BEACON_REQ:
+ lim_process_sme_start_beacon_req(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_DFS_BEACON_CHAN_SW_IE_REQ:
+ lim_process_sme_dfs_csa_ie_request(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_UPDATE_ADDITIONAL_IES:
+ lim_process_update_add_ies(pMac, pMsgBuf);
+ break;
+
+ case eWNI_SME_MODIFY_ADDITIONAL_IES:
+ lim_process_modify_add_ies(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_SET_HW_MODE_REQ:
+ lim_process_set_hw_mode(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_NSS_UPDATE_REQ:
+ lim_process_nss_update_request(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_SET_DUAL_MAC_CFG_REQ:
+ lim_process_set_dual_mac_cfg_req(pMac, pMsgBuf);
+ break;
+ case eWNI_SME_SET_IE_REQ:
+ lim_process_set_ie_req(pMac, pMsgBuf);
+ break;
+ default:
+ cdf_mem_free((void *)pMsg->bodyptr);
+ pMsg->bodyptr = NULL;
+ break;
+ } /* switch (msgType) */
+
+ return bufConsumed;
+} /*** end lim_process_sme_req_messages() ***/
+
+/**
+ * lim_process_sme_start_beacon_req()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMessageQueue(). This
+ * function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the SME message type
+ * @param *pMsgBuf A pointer to the SME message buffer
+ * @return Boolean - true - if pMsgBuf is consumed and can be freed.
+ * false - if pMsgBuf is not to be freed.
+ */
+static void lim_process_sme_start_beacon_req(tpAniSirGlobal pMac, uint32_t *pMsg)
+{
+ tpSirStartBeaconIndication pBeaconStartInd;
+ tpPESession psessionEntry;
+ uint8_t sessionId; /* PE sessionID */
+
+ if (pMsg == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ pBeaconStartInd = (tpSirStartBeaconIndication) pMsg;
+ psessionEntry = pe_find_session_by_bssid(pMac,
+ pBeaconStartInd->bssid,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_print_mac_addr(pMac, pBeaconStartInd->bssid, LOGE);
+ lim_log(pMac, LOGE,
+ FL("Session does not exist for given bssId"));
+ return;
+ }
+
+ if (pBeaconStartInd->beaconStartStatus == true) {
+ /*
+ * Currently this Indication comes from SAP
+ * to start Beacon Tx on a DFS channel
+ * since beaconing has to be done on DFS
+ * channel only after CAC WAIT is completed.
+ * On a DFS Channel LIM does not start beacon
+ * Tx right after the WMA_ADD_BSS_RSP.
+ */
+ lim_apply_configuration(pMac, psessionEntry);
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("Start Beacon with ssid %s Ch %d"),
+ psessionEntry->ssId.ssId,
+ psessionEntry->currentOperChannel);
+ lim_send_beacon_ind(pMac, psessionEntry);
+ } else {
+ lim_log(pMac, LOGE, FL("Invalid Beacon Start Indication"));
+ return;
+ }
+}
+
+/**
+ * lim_process_sme_channel_change_request() - process sme ch change req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function is called to process SME_CHANNEL_CHANGE_REQ message
+ *
+ * Return: None
+ */
+static void lim_process_sme_channel_change_request(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tpSirChanChangeRequest ch_change_req;
+ tpPESession session_entry;
+ uint8_t session_id; /* PE session_id */
+ tPowerdBm max_tx_pwr;
+ uint32_t val = 0;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
+ return;
+ }
+ ch_change_req = (tpSirChanChangeRequest)msg_buf;
+
+ max_tx_pwr = cfg_get_regulatory_max_transmit_power(mac_ctx,
+ ch_change_req->targetChannel);
+
+ if ((ch_change_req->messageType != eWNI_SME_CHANNEL_CHANGE_REQ) ||
+ (max_tx_pwr == WMA_MAX_TXPOWER_INVALID)) {
+ lim_log(mac_ctx, LOGE, FL("Invalid Request/max_tx_pwr"));
+ return;
+ }
+
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ ch_change_req->bssid, &session_id);
+ if (session_entry == NULL) {
+ lim_print_mac_addr(mac_ctx, ch_change_req->bssid, LOGE);
+ lim_log(mac_ctx, LOGE, FL(
+ "Session does not exist for given bssId"));
+ return;
+ }
+
+ if (session_entry->currentOperChannel ==
+ ch_change_req->targetChannel) {
+ lim_log(mac_ctx, LOGE, FL("target CH is same as current CH"));
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(session_entry))
+ session_entry->channelChangeReasonCode =
+ LIM_SWITCH_CHANNEL_SAP_DFS;
+ else
+ session_entry->channelChangeReasonCode =
+ LIM_SWITCH_CHANNEL_OPERATION;
+
+ lim_log(mac_ctx, LOGW, FL(
+ "switch old chnl %d to new chnl %d, ch_bw %d"),
+ session_entry->currentOperChannel,
+ ch_change_req->targetChannel,
+ ch_change_req->channel_width);
+
+ /* Store the New Channel Params in session_entry */
+ session_entry->ch_width = ch_change_req->channel_width;
+ session_entry->ch_center_freq_seg0 =
+ ch_change_req->center_freq_seg_0;
+ session_entry->ch_center_freq_seg1 =
+ ch_change_req->center_freq_seg_1;
+ session_entry->htSecondaryChannelOffset = ch_change_req->cbMode;
+ session_entry->htSupportedChannelWidthSet =
+ (ch_change_req->channel_width ? 1 : 0);
+ session_entry->htRecommendedTxWidthSet =
+ session_entry->htSupportedChannelWidthSet;
+ session_entry->currentOperChannel =
+ ch_change_req->targetChannel;
+ session_entry->limRFBand =
+ lim_get_rf_band(session_entry->currentOperChannel);
+ /* Initialize 11h Enable Flag */
+ if (SIR_BAND_5_GHZ == session_entry->limRFBand) {
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val) !=
+ eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Fail to get WNI_CFG_11H_ENABLED"));
+ }
+
+ session_entry->lim11hEnable = val;
+ session_entry->dot11mode = ch_change_req->dot11mode;
+ cdf_mem_copy(&session_entry->rateSet,
+ &ch_change_req->operational_rateset,
+ sizeof(session_entry->rateSet));
+ cdf_mem_copy(&session_entry->extRateSet,
+ &ch_change_req->extended_rateset,
+ sizeof(session_entry->extRateSet));
+ lim_set_channel(mac_ctx, ch_change_req->targetChannel,
+ session_entry->ch_center_freq_seg0,
+ session_entry->ch_center_freq_seg1,
+ session_entry->ch_width,
+ max_tx_pwr, session_entry->peSessionId);
+}
+
+/******************************************************************************
+* lim_start_bss_update_add_ie_buffer()
+*
+***FUNCTION:
+* This function checks the src buffer and its length and then malloc for
+* dst buffer update the same
+*
+***LOGIC:
+*
+***ASSUMPTIONS:
+*
+***NOTE:
+*
+* @param pMac Pointer to Global MAC structure
+* @param **pDstData_buff A pointer to pointer of uint8_t dst buffer
+* @param *pDstDataLen A pointer to pointer of uint16_t dst buffer length
+* @param *pSrcData_buff A pointer of uint8_t src buffer
+* @param srcDataLen src buffer length
+******************************************************************************/
+
+static void
+lim_start_bss_update_add_ie_buffer(tpAniSirGlobal pMac,
+ uint8_t **pDstData_buff,
+ uint16_t *pDstDataLen,
+ uint8_t *pSrcData_buff, uint16_t srcDataLen)
+{
+
+ if (srcDataLen > 0 && pSrcData_buff != NULL) {
+ *pDstDataLen = srcDataLen;
+
+ *pDstData_buff = cdf_mem_malloc(*pDstDataLen);
+
+ if (NULL == *pDstData_buff) {
+ lim_log(pMac, LOGE,
+ FL("AllocateMemory failed for pDstData_buff"));
+ return;
+ }
+ cdf_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
+ } else {
+ *pDstData_buff = NULL;
+ *pDstDataLen = 0;
+ }
+}
+
+/******************************************************************************
+* lim_update_add_ie_buffer()
+*
+***FUNCTION:
+* This function checks the src buffer and length if src buffer length more
+* than dst buffer length then free the dst buffer and malloc for the new src
+* length, and update the dst buffer and length. But if dst buffer is bigger
+* than src buffer length then it just update the dst buffer and length
+*
+***LOGIC:
+*
+***ASSUMPTIONS:
+*
+***NOTE:
+*
+* @param pMac Pointer to Global MAC structure
+* @param **pDstData_buff A pointer to pointer of uint8_t dst buffer
+* @param *pDstDataLen A pointer to pointer of uint16_t dst buffer length
+* @param *pSrcData_buff A pointer of uint8_t src buffer
+* @param srcDataLen src buffer length
+******************************************************************************/
+
+static void
+lim_update_add_ie_buffer(tpAniSirGlobal pMac,
+ uint8_t **pDstData_buff,
+ uint16_t *pDstDataLen,
+ uint8_t *pSrcData_buff, uint16_t srcDataLen)
+{
+
+ if (NULL == pSrcData_buff) {
+ lim_log(pMac, LOGE, FL("src buffer is null."));
+ return;
+ }
+
+ if (srcDataLen > *pDstDataLen) {
+ *pDstDataLen = srcDataLen;
+ /* free old buffer */
+ cdf_mem_free(*pDstData_buff);
+ /* allocate a new */
+ *pDstData_buff = cdf_mem_malloc(*pDstDataLen);
+
+ if (NULL == *pDstData_buff) {
+ lim_log(pMac, LOGE, FL("Memory allocation failed."));
+ *pDstDataLen = 0;
+ return;
+ }
+ }
+
+ /* copy the content of buffer into dst buffer
+ */
+ *pDstDataLen = srcDataLen;
+ cdf_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen);
+
+}
+
+/*
+* lim_process_modify_add_ies() - process modify additional IE req.
+*
+* @mac_ctx: Pointer to Global MAC structure
+* @msg_buf: pointer to the SME message buffer
+*
+* This function update the PE buffers for additional IEs.
+*
+* Return: None
+*/
+static void lim_process_modify_add_ies(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tpSirModifyIEsInd modify_add_ies;
+ tpPESession session_entry;
+ uint8_t session_id;
+ bool ret = false;
+ tSirAddIeParams *add_ie_params;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
+ return;
+ }
+
+ modify_add_ies = (tpSirModifyIEsInd)msg_buf;
+ /* Incoming message has smeSession, use BSSID to find PE session */
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ modify_add_ies->modifyIE.bssid, &session_id);
+
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGE, FL("Session not found for given bssid. "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(modify_add_ies->modifyIE.bssid));
+ goto end;
+ }
+ if ((0 == modify_add_ies->modifyIE.ieBufferlength) ||
+ (0 == modify_add_ies->modifyIE.ieIDLen) ||
+ (NULL == modify_add_ies->modifyIE.pIEBuffer)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid request pIEBuffer %p ieBufferlength %d ieIDLen %d ieID %d. update Type %d"),
+ modify_add_ies->modifyIE.pIEBuffer,
+ modify_add_ies->modifyIE.ieBufferlength,
+ modify_add_ies->modifyIE.ieID,
+ modify_add_ies->modifyIE.ieIDLen,
+ modify_add_ies->updateType);
+ goto end;
+ }
+ add_ie_params = &session_entry->addIeParams;
+ switch (modify_add_ies->updateType) {
+ case eUPDATE_IE_PROBE_RESP:
+ /* Probe resp */
+ break;
+ case eUPDATE_IE_ASSOC_RESP:
+ /* assoc resp IE */
+ if (add_ie_params->assocRespDataLen == 0) {
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_ERROR, FL(
+ "assoc resp add ie not present %d"),
+ add_ie_params->assocRespDataLen);
+ }
+ /* search through the buffer and modify the IE */
+ break;
+ case eUPDATE_IE_PROBE_BCN:
+ /*probe beacon IE */
+ if (ret == true && modify_add_ies->modifyIE.notify) {
+ lim_handle_param_update(mac_ctx,
+ modify_add_ies->updateType);
+ }
+ break;
+ default:
+ lim_log(mac_ctx, LOGE, FL("unhandled buffer type %d"),
+ modify_add_ies->updateType);
+ break;
+ }
+end:
+ cdf_mem_free(modify_add_ies->modifyIE.pIEBuffer);
+ modify_add_ies->modifyIE.pIEBuffer = NULL;
+}
+
+/*
+* lim_process_update_add_ies() - process additional IE update req
+*
+* @mac_ctx: Pointer to Global MAC structure
+* @msg_buf: pointer to the SME message buffer
+*
+* This function update the PE buffers for additional IEs.
+*
+* Return: None
+*/
+static void lim_process_update_add_ies(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tpSirUpdateIEsInd update_add_ies = (tpSirUpdateIEsInd)msg_buf;
+ uint8_t session_id;
+ tpPESession session_entry;
+ tSirAddIeParams *addn_ie;
+ uint16_t new_length = 0;
+ uint8_t *new_ptr = NULL;
+ tSirUpdateIE *update_ie;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("msg_buf is NULL"));
+ return;
+ }
+ update_ie = &update_add_ies->updateIE;
+ /* incoming message has smeSession, use BSSID to find PE session */
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ update_ie->bssid, &session_id);
+
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGE, FL("Session not found for given bssid. "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(update_ie->bssid));
+ goto end;
+ }
+ addn_ie = &session_entry->addIeParams;
+ /* if len is 0, upper layer requested freeing of buffer */
+ if (0 == update_ie->ieBufferlength) {
+ switch (update_add_ies->updateType) {
+ case eUPDATE_IE_PROBE_RESP:
+ cdf_mem_free(addn_ie->probeRespData_buff);
+ addn_ie->probeRespData_buff = NULL;
+ addn_ie->probeRespDataLen = 0;
+ break;
+ case eUPDATE_IE_ASSOC_RESP:
+ cdf_mem_free(addn_ie->assocRespData_buff);
+ addn_ie->assocRespData_buff = NULL;
+ addn_ie->assocRespDataLen = 0;
+ break;
+ case eUPDATE_IE_PROBE_BCN:
+ cdf_mem_free(addn_ie->probeRespBCNData_buff);
+ addn_ie->probeRespBCNData_buff = NULL;
+ addn_ie->probeRespBCNDataLen = 0;
+
+ if (update_ie->notify)
+ lim_handle_param_update(mac_ctx,
+ update_add_ies->updateType);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+ switch (update_add_ies->updateType) {
+ case eUPDATE_IE_PROBE_RESP:
+ if (update_ie->append) {
+ /*
+ * In case of append, allocate new memory
+ * with combined length
+ */
+ new_length = update_ie->ieBufferlength +
+ addn_ie->probeRespDataLen;
+ new_ptr = cdf_mem_malloc(new_length);
+ if (NULL == new_ptr) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Memory allocation failed."));
+ goto end;
+ }
+ /* append buffer to end of local buffers */
+ cdf_mem_copy(new_ptr, addn_ie->probeRespData_buff,
+ addn_ie->probeRespDataLen);
+ cdf_mem_copy(&new_ptr[addn_ie->probeRespDataLen],
+ update_ie->pAdditionIEBuffer,
+ update_ie->ieBufferlength);
+ /* free old memory */
+ cdf_mem_free(addn_ie->probeRespData_buff);
+ /* adjust length accordingly */
+ addn_ie->probeRespDataLen = new_length;
+ /* save refernece of local buffer in PE session */
+ addn_ie->probeRespData_buff = new_ptr;
+ goto end;
+ }
+ lim_update_add_ie_buffer(mac_ctx, &addn_ie->probeRespData_buff,
+ &addn_ie->probeRespDataLen,
+ update_ie->pAdditionIEBuffer,
+ update_ie->ieBufferlength);
+ break;
+ case eUPDATE_IE_ASSOC_RESP:
+ /* assoc resp IE */
+ lim_update_add_ie_buffer(mac_ctx, &addn_ie->assocRespData_buff,
+ &addn_ie->assocRespDataLen,
+ update_ie->pAdditionIEBuffer,
+ update_ie->ieBufferlength);
+ break;
+ case eUPDATE_IE_PROBE_BCN:
+ /* probe resp Bcn IE */
+ lim_update_add_ie_buffer(mac_ctx,
+ &addn_ie->probeRespBCNData_buff,
+ &addn_ie->probeRespBCNDataLen,
+ update_ie->pAdditionIEBuffer,
+ update_ie->ieBufferlength);
+ if (update_ie->notify)
+ lim_handle_param_update(mac_ctx,
+ update_add_ies->updateType);
+ break;
+ default:
+ lim_log(mac_ctx, LOGE, FL("unhandled buffer type %d."),
+ update_add_ies->updateType);
+ break;
+ }
+end:
+ cdf_mem_free(update_ie->pAdditionIEBuffer);
+ update_ie->pAdditionIEBuffer = NULL;
+}
+
+/**
+ * lim_process_sme_dfs_csa_ie_request() - process sme dfs csa ie req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ * Return: None
+ */
+static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ tpSirDfsCsaIeRequest dfs_csa_ie_req;
+ tpPESession session_entry = NULL;
+ uint32_t ch_width = 0;
+ uint8_t session_id;
+ tLimWiderBWChannelSwitchInfo *wider_bw_ch_switch;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ dfs_csa_ie_req = (tSirDfsCsaIeRequest *)msg_buf;
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ dfs_csa_ie_req->bssid, &session_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Session not found for given BSSID" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(dfs_csa_ie_req->bssid));
+ return;
+ }
+
+ if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOGE, FL("Invalid SystemRole %d"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ return;
+ }
+
+ /* target channel */
+ session_entry->gLimChannelSwitch.primaryChannel =
+ dfs_csa_ie_req->targetChannel;
+
+ /* Channel switch announcement needs to be included in beacon */
+ session_entry->dfsIncludeChanSwIe = true;
+ session_entry->gLimChannelSwitch.switchCount = LIM_MAX_CSA_IE_UPDATES;
+ session_entry->gLimChannelSwitch.ch_width =
+ dfs_csa_ie_req->ch_bandwidth;
+ if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false)
+ session_entry->gLimChannelSwitch.switchMode = 1;
+
+ /*
+ * Validate if SAP is operating HT or VHT mode and set the Channel
+ * Switch Wrapper element with the Wide Band Switch subelement.
+ */
+ if (true != session_entry->vhtCapability)
+ goto skip_vht;
+
+ if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ ==
+ session_entry->vhtTxChannelWidthSet)
+ ch_width = eHT_CHANNEL_WIDTH_80MHZ;
+ else if (WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ ==
+ session_entry->vhtTxChannelWidthSet)
+ ch_width = session_entry->htSupportedChannelWidthSet;
+ /* Now encode the Wider Ch BW element depending on the ch width */
+ wider_bw_ch_switch = &session_entry->gLimWiderBWChannelSwitch;
+ switch (ch_width) {
+ case eHT_CHANNEL_WIDTH_20MHZ:
+ /*
+ * Wide channel BW sublement in channel wrapper element is not
+ * required in case of 20 Mhz operation. Currently It is set
+ * only set in case of 40/80 Mhz Operation.
+ */
+ session_entry->dfsIncludeChanWrapperIe = false;
+ wider_bw_ch_switch->newChanWidth =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ break;
+ case eHT_CHANNEL_WIDTH_40MHZ:
+ session_entry->dfsIncludeChanWrapperIe = true;
+ wider_bw_ch_switch->newChanWidth =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ break;
+ case eHT_CHANNEL_WIDTH_80MHZ:
+ session_entry->dfsIncludeChanWrapperIe = true;
+ wider_bw_ch_switch->newChanWidth =
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+ break;
+ case eHT_CHANNEL_WIDTH_160MHZ:
+ session_entry->dfsIncludeChanWrapperIe = true;
+ wider_bw_ch_switch->newChanWidth =
+ WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+ break;
+ default:
+ session_entry->dfsIncludeChanWrapperIe = false;
+ /*
+ * Need to handle 80+80 Mhz Scenario. When 80+80 is supported
+ * set the gLimWiderBWChannelSwitch.newChanWidth to 3
+ */
+ lim_log(mac_ctx, LOGE, FL("Invalid Channel Width"));
+ break;
+ }
+ /* Fetch the center channel based on the channel width */
+ wider_bw_ch_switch->newCenterChanFreq0 =
+ lim_get_center_channel(mac_ctx, dfs_csa_ie_req->targetChannel,
+ session_entry->htSecondaryChannelOffset,
+ wider_bw_ch_switch->newChanWidth);
+ /*
+ * This is not applicable for 20/40/80 Mhz.Only used when we support
+ * 80+80 Mhz operation. In case of 80+80 Mhz, this parameter indicates
+ * center channel frequency index of 80 Mhz channel of
+ * frequency segment 1.
+ */
+ wider_bw_ch_switch->newCenterChanFreq1 = 0;
+skip_vht:
+ /* Send CSA IE request from here */
+ if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE, FL("Unable to set CSA IE in beacon"));
+ return;
+ }
+
+ /*
+ * First beacon update request is sent here, the remaining updates are
+ * done when the FW responds back after sending the first beacon after
+ * the template update
+ */
+ lim_send_beacon_ind(mac_ctx, session_entry);
+ lim_log(mac_ctx, LOG1, FL("Updated CSA IE, IE COUNT = %d"),
+ session_entry->gLimChannelSwitch.switchCount);
+ session_entry->gLimChannelSwitch.switchCount--;
+}
+
+/**
+ * lim_process_nss_update_request() - process sme nss update req
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ * Return: None
+ */
+static void lim_process_nss_update_request(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ struct sir_nss_update_request *nss_update_req_ptr;
+ tpPESession session_entry = NULL;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ nss_update_req_ptr = (struct sir_nss_update_request *)msg_buf;
+ session_entry = pe_find_session_by_session_id(mac_ctx,
+ nss_update_req_ptr->vdev_id);
+ if (session_entry == NULL) {
+ lim_log(mac_ctx, LOGE, FL(
+ "Session not found for given session_id %d"),
+ nss_update_req_ptr->vdev_id);
+ return;
+ }
+
+ if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOGE, FL("Invalid SystemRole %d"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ return;
+ }
+
+ /* populate nss field in the beacon */
+ session_entry->gLimOperatingMode.present = 1;
+ session_entry->gLimOperatingMode.rxNSS = nss_update_req_ptr->new_nss;
+ /* Send nss update request from here */
+ if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
+ eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to set op mode IE in beacon"));
+ return;
+ }
+
+ lim_send_beacon_ind(mac_ctx, session_entry);
+}
+
+/**
+ * lim_process_set_ie_req() - process sme set IE request
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_buf: pointer to the SME message buffer
+ *
+ * This function processes SME request messages from HDD or upper layer
+ * application.
+ *
+ * Return: None
+ */
+static void lim_process_set_ie_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
+{
+ struct send_extcap_ie *msg;
+ CDF_STATUS status;
+
+ if (msg_buf == NULL) {
+ lim_log(mac_ctx, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ msg = (struct send_extcap_ie *)msg_buf;
+ status = lim_send_ext_cap_ie(mac_ctx, msg->session_id, NULL, false);
+ if (CDF_STATUS_SUCCESS != status)
+ lim_log(mac_ctx, LOGE, FL("Unable to send ExtCap to FW"));
+
+}
diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c
new file mode 100644
index 0000000..fa5a0ab
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_process_tdls.c
@@ -0,0 +1,3267 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+ * lim_process_tdls.c
+ * OVERVIEW:
+ *
+ * DEPENDENCIES:
+ *
+ * Are listed for each API below.
+ * ===========================================================================*/
+
+/*===========================================================================
+
+ * EDIT HISTORY FOR FILE
+
+ * This section contains comments describing changes made to the module.
+ * Notice that changes are listed in reverse chronological order.
+
+ * $Header$$DateTime$$Author$
+
+ * when who what, where, why
+ * ---------- --- ------------------------------------------------------
+ * 05/05/2010 Ashwani Initial Creation, added TDLS action frame
+ * functionality,TDLS message exchange with SME..etc..
+
+ ===========================================================================*/
+
+/**
+ * \file lim_process_tdls.c
+ *
+ * \brief Code for preparing,processing and sending 802.11z action frames
+ *
+ */
+
+#ifdef FEATURE_WLAN_TDLS
+
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "dot11f.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+#include "utils_parser.h"
+#include "lim_assoc_utils.h"
+#include "dph_hash_table.h"
+#include "wma_types.h"
+#include "cds_regdomain_common.h"
+
+/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630
+ There was IOT issue with cisco 1252 open mode, where it pads
+ discovery req/teardown frame with some junk value up to min size.
+ To avoid this issue, we pad QCOM_VENDOR_IE.
+ If there is other IOT issue because of this bandage, define NO_PAD...
+ */
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+#define MIN_IEEE_8023_SIZE 46
+#define MIN_VENDOR_SPECIFIC_IE_SIZE 5
+#endif
+
+static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
+ tSirTdlsAddStaReq * pAddStaReq, tpPESession psessionEntry);
+void populate_dot11f_link_iden(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ tDot11fIELinkIdentifier *linkIden,
+ tSirMacAddr peerMac, uint8_t reqType);
+void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIEExtCap *extCapability);
+
+void populate_dot11f_tdls_offchannel_params(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIESuppChannels *suppChannels,
+ tDot11fIESuppOperatingClasses *
+ suppOperClasses);
+void lim_log_vht_cap(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f);
+tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal pMac,
+ tpSirSupportedRates pRates,
+ tDot11fIEVHTCaps *pPeerVHTCaps,
+ tpPESession psessionEntry);
+ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode);
+
+/*
+ * TDLS data frames will go out/come in as non-qos data.
+ * so, eth_890d_header will be aligned access..
+ */
+static const uint8_t eth_890d_header[] = {
+ 0xaa, 0xaa, 0x03, 0x00,
+ 0x00, 0x00, 0x89, 0x0d,
+};
+
+/*
+ * type of links used in TDLS
+ */
+enum tdlsLinks {
+ TDLS_LINK_AP,
+ TDLS_LINK_DIRECT
+} e_tdls_link;
+
+/*
+ * node status in node searching
+ */
+enum tdlsLinkNodeStatus {
+ TDLS_NODE_NOT_FOUND,
+ TDLS_NODE_FOUND
+} e_tdls_link_node_status;
+
+enum tdlsReqType {
+ TDLS_INITIATOR,
+ TDLS_RESPONDER
+} e_tdls_req_type;
+
+typedef enum tdlsLinkSetupStatus {
+ TDLS_SETUP_STATUS_SUCCESS = 0,
+ TDLS_SETUP_STATUS_FAILURE = 37
+} etdlsLinkSetupStatus;
+
+/* These maps to Kernel TDLS peer capability
+ * flags and should get changed as and when necessary
+ */
+enum tdls_peer_capability {
+ TDLS_PEER_HT_CAP = 0,
+ TDLS_PEER_VHT_CAP = 1,
+ TDLS_PEER_WMM_CAP = 2
+} e_tdls_peer_capability;
+
+/* some local defines */
+#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier)
+#define PTI_LINK_IDEN_OFFSET (5)
+#define PTI_BUF_STATUS_OFFSET (25)
+
+/* TODO, Move this parameters to configuration */
+#define PEER_PSM_SUPPORT (0)
+#define TDLS_SUPPORT (1)
+#define TDLS_PROHIBITED (0)
+#define TDLS_CH_SWITCH_PROHIBITED (1)
+/** @brief Set bit manipulation macro */
+#define SET_BIT(value, mask) ((value) |= (1 << (mask)))
+/** @brief Clear bit manipulation macro */
+#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask)))
+/** @brief Check bit manipulation macro */
+#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
+
+#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \
+ do { \
+ if ((aid) < (sizeof(uint32_t) << 3)) \
+ SET_BIT(peer_bitmap[0], (aid)); \
+ else if ((aid) < (sizeof(uint32_t) << 4)) \
+ SET_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
+ } while (0);
+
+#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \
+ do { \
+ if ((aid) < (sizeof(uint32_t) << 3)) \
+ CLEAR_BIT(peer_bitmap[0], (aid)); \
+ else if ((aid) < (sizeof(uint32_t) << 4)) \
+ CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(uint32_t) << 3)));\
+ } while (0);
+
+#ifdef LIM_DEBUG_TDLS
+
+#ifdef FEATURE_WLAN_TDLS
+#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800)
+#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200)
+#endif
+
+#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \
+ SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) || \
+ (((psessionEntry)->limWmeEnabled) && \
+ LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps)))
+
+#define TID_AC_VI 4
+#define TID_AC_BK 1
+
+const uint8_t *lim_trace_tdls_action_string(uint8_t tdlsActionCode)
+{
+ switch (tdlsActionCode) {
+ CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ);
+ CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP);
+ }
+ return (const uint8_t *)"UNKNOWN";
+}
+#endif
+/*
+ * initialize TDLS setup list and related data structures.
+ */
+void lim_init_tdls_data(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+ lim_init_peer_idxpool(pMac, pSessionEntry);
+
+ return;
+}
+
+/*
+ * prepare TDLS frame header, it includes
+ * | | | |
+ * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD
+ * | | | |
+ */
+static uint32_t lim_prepare_tdls_frame_header(tpAniSirGlobal pMac, uint8_t *pFrame,
+ tDot11fIELinkIdentifier *link_iden,
+ uint8_t tdlsLinkType, uint8_t reqType,
+ uint8_t tid,
+ tpPESession psessionEntry)
+{
+ tpSirMacDataHdr3a pMacHdr;
+ uint32_t header_offset = 0;
+ uint8_t *addr1 = NULL;
+ uint8_t *addr3 = NULL;
+ uint8_t toDs = (tdlsLinkType == TDLS_LINK_AP)
+ ? ANI_TXDIR_TODS : ANI_TXDIR_IBSS;
+ uint8_t *peerMac = (reqType == TDLS_INITIATOR)
+ ? link_iden->RespStaAddr : link_iden->InitStaAddr;
+ uint8_t *staMac = (reqType == TDLS_INITIATOR)
+ ? link_iden->InitStaAddr : link_iden->RespStaAddr;
+
+ pMacHdr = (tpSirMacDataHdr3a) (pFrame);
+
+ /*
+ * if TDLS frame goes through the AP link, it follows normal address
+ * pattern, if TDLS frame goes thorugh the direct link, then
+ * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID
+ */
+ (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)),
+ (addr3 = (peerMac)))
+ : ((addr1 = (peerMac)), (addr3 = (link_iden->bssid)));
+ /*
+ * prepare 802.11 header
+ */
+ pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+ pMacHdr->fc.type = SIR_MAC_DATA_FRAME;
+ pMacHdr->fc.subType =
+ IS_QOS_ENABLED(psessionEntry) ? SIR_MAC_DATA_QOS_DATA :
+ SIR_MAC_DATA_DATA;
+
+ /*
+ * TL is not setting up below fields, so we are doing it here
+ */
+ pMacHdr->fc.toDS = toDs;
+ pMacHdr->fc.powerMgmt = 0;
+ pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE) ? 0 : 1;
+
+ cdf_mem_copy((uint8_t *) pMacHdr->addr1,
+ (uint8_t *) addr1, sizeof(tSirMacAddr));
+ cdf_mem_copy((uint8_t *) pMacHdr->addr2,
+ (uint8_t *) staMac, sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) pMacHdr->addr3,
+ (uint8_t *) (addr3), sizeof(tSirMacAddr));
+
+ lim_log(pMac, LOG1,
+ FL(
+ "Preparing TDLS frame header to %s A1:"
+ MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"
+ MAC_ADDRESS_STR
+ ),
+ (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT",
+ MAC_ADDR_ARRAY(pMacHdr->addr1),
+ MAC_ADDR_ARRAY(pMacHdr->addr2),
+ MAC_ADDR_ARRAY(pMacHdr->addr3));
+
+ if (IS_QOS_ENABLED(psessionEntry)) {
+ pMacHdr->qosControl.tid = tid;
+ header_offset += sizeof(tSirMacDataHdr3a);
+ } else
+ header_offset += sizeof(tSirMacMgmtHdr);
+
+ /*
+ * Now form RFC1042 header
+ */
+ cdf_mem_copy((uint8_t *) (pFrame + header_offset),
+ (uint8_t *) eth_890d_header, sizeof(eth_890d_header));
+
+ header_offset += sizeof(eth_890d_header);
+
+ /* add payload type as TDLS */
+ *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS;
+ header_offset += PAYLOAD_TYPE_TDLS_SIZE;
+ return header_offset;
+}
+
+/*
+ * TX Complete for Management frames
+ */
+CDF_STATUS lim_mgmt_tx_complete(tpAniSirGlobal pMac, uint32_t txCompleteSuccess)
+{
+ tpPESession psessionEntry = NULL;
+
+ if (0xff != pMac->lim.mgmtFrameSessionId) {
+ psessionEntry =
+ pe_find_session_by_session_id(pMac,
+ pMac->lim.mgmtFrameSessionId);
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE, FL("sessionID %d is not found"),
+ pMac->lim.mgmtFrameSessionId);
+ return CDF_STATUS_E_FAILURE;
+ }
+ lim_send_sme_mgmt_tx_completion(pMac, psessionEntry,
+ txCompleteSuccess);
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ }
+ return CDF_STATUS_SUCCESS;
+}
+
+/*
+ * This function can be used for bacst or unicast discovery request
+ * We are not differentiating it here, it will all depnds on peer MAC address,
+ */
+tSirRetStatus lim_send_tdls_dis_req_frame(tpAniSirGlobal pMac, tSirMacAddr peer_mac,
+ uint8_t dialog, tpPESession psessionEntry)
+{
+ tDot11fTDLSDisReq tdlsDisReq;
+ uint32_t status = 0;
+ uint32_t nPayload = 0;
+ uint32_t size = 0;
+ uint32_t nBytes = 0;
+ uint32_t header_offset = 0;
+ uint8_t *pFrame;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ uint32_t padLen = 0;
+#endif
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+ /*
+ * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ * and then hand it off to 'dot11f_pack_probe_request' (for
+ * serialization). We start by zero-initializing the structure:
+ */
+ cdf_mem_set((uint8_t *) &tdlsDisReq, sizeof(tDot11fTDLSDisReq), 0);
+
+ /*
+ * setup Fixed fields,
+ */
+ tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS;
+ tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ;
+ tdlsDisReq.DialogToken.token = dialog;
+
+ size = sizeof(tSirMacAddr);
+
+ populate_dot11f_link_iden(pMac, psessionEntry, &tdlsDisReq.LinkIdentifier,
+ peer_mac, TDLS_INITIATOR);
+
+ /*
+ * now we pack it. First, how much space are we going to need?
+ */
+ status = dot11f_get_packed_tdls_dis_req_size(pMac, &tdlsDisReq, &nPayload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGP,
+ FL(
+ "Failed to calculate the packed size for a discovery Request (0x%08x)."
+ ),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fTDLSDisReq);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while calculating the packed size for a discovery Request (0x%08x)."
+ ),
+ status);
+ }
+
+ /*
+ * This frame is going out from PE as data frames with special ethertype
+ * 89-0d.
+ * 8 bytes of RFC 1042 header
+ */
+
+ nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+ ? sizeof(tSirMacDataHdr3a) :
+ sizeof(tSirMacMgmtHdr))
+ + sizeof(eth_890d_header)
+ + PAYLOAD_TYPE_TDLS_SIZE;
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
+ Hence AP itself padding some bytes, which caused teardown packet is dropped at
+ receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
+ */
+ if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
+ padLen =
+ MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
+
+ /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
+ if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
+ padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
+
+ nBytes += padLen;
+ }
+#endif
+
+ /* Ok-- try to allocate memory from MGMT PKT pool */
+
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP,
+ FL(
+ "Failed to allocate %d bytes for a TDLS Discovery Request."
+ ),
+ nBytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* zero out the memory */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /*
+ * IE formation, memory allocation is completed, Now form TDLS discovery
+ * request frame
+ */
+
+ /* fill out the buffer descriptor */
+
+ header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+ LINK_IDEN_ADDR_OFFSET
+ (tdlsDisReq), TDLS_LINK_AP,
+ TDLS_INITIATOR, TID_AC_VI,
+ psessionEntry);
+
+ status = dot11f_pack_tdls_dis_req(pMac, &tdlsDisReq, pFrame
+ + header_offset, nPayload, &nPayload);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a TDLS discovery req (0x%08x)."),
+ status);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while packing TDLS Discovery Request (0x%08x)."
+ ),
+ status);
+ }
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ if (padLen != 0) {
+ /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
+ uint8_t *padVendorSpecific = pFrame + header_offset + nPayload;
+ /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
+ padVendorSpecific[0] = 221;
+ padVendorSpecific[1] = padLen - 2;
+ padVendorSpecific[2] = 0x00;
+ padVendorSpecific[3] = 0xA0;
+ padVendorSpecific[4] = 0xC6;
+
+ lim_log(pMac, LOGW,
+ FL("Padding Vendor Specific Ie Len = %d"), padLen);
+
+ /* padding zero if more than 5 bytes are required */
+ if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
+ cdf_mem_set(pFrame + header_offset + nPayload +
+ MIN_VENDOR_SPECIFIC_IE_SIZE,
+ padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
+ }
+#endif
+
+ lim_log(pMac, LOG1,
+ FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
+ SIR_MAC_TDLS_DIS_REQ,
+ lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_REQ),
+ MAC_ADDR_ARRAY(peer_mac));
+
+ pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
+ cdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_DATA,
+ ANI_TXDIR_TODS,
+ TID_AC_VI,
+ lim_tx_complete, pFrame,
+ lim_mgmt_tx_complete,
+ HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
+ smeSessionId, false, 0);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ lim_log(pMac, LOGE,
+ FL("could not send TDLS Discovery Request frame"));
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+}
+
+/*
+ * This static function is consistent with any kind of TDLS management
+ * frames we are sending. Currently it is being used by lim_send_tdls_dis_rsp_frame,
+ * lim_send_tdls_link_setup_req_frame and lim_send_tdls_setup_rsp_frame
+ */
+static void populate_dot11f_tdls_ht_vht_cap(tpAniSirGlobal pMac,
+ uint32_t selfDot11Mode,
+ tDot11fIEHTCaps *htCap,
+ tDot11fIEVHTCaps *vhtCap,
+ tpPESession psessionEntry)
+{
+ if (IS_DOT11_MODE_HT(selfDot11Mode)) {
+ /* Include HT Capability IE */
+ populate_dot11f_ht_caps(pMac, NULL, htCap);
+ /*
+ * Advertise ht capability and max supported channel bandwidth
+ * when populating HT IE in TDLS Setup Request/Setup Response/
+ * Setup Confirmation frames.
+ * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz
+ * off-channel direct link may be started if both TDLS peer STAs
+ * indicated 40 MHz support in the Supported Channel Width Set
+ * field of the HT Capabilities element (which is included in
+ * the TDLS Setup Request frame and the TDLS Setup Response
+ * frame). Switching to a 40 MHz off-channel direct link is
+ * achieved by including the following information in the TDLS
+ * Channel Switch Request
+ * 11.21.1 General: The channel width of the TDLS direct link on
+ * the base channel shall not exceed the channel width of the
+ * BSS to which the TDLS peer STAs are associated.
+ */
+ htCap->supportedChannelWidthSet = 1;
+ } else {
+ htCap->present = 0;
+ }
+ lim_log(pMac, LOG1, FL("HT present = %hu, Chan Width = %hu"),
+ htCap->present, htCap->supportedChannelWidthSet);
+#ifdef WLAN_FEATURE_11AC
+ if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
+ pMac->roam.configParam.enableVhtFor24GHz) ||
+ (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
+ if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
+ IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+ /* Include VHT Capability IE */
+ populate_dot11f_vht_caps(pMac, psessionEntry, vhtCap);
+ vhtCap->suBeamformeeCap = 0;
+ vhtCap->suBeamFormerCap = 0;
+ vhtCap->muBeamformeeCap = 0;
+ vhtCap->muBeamformerCap = 0;
+ } else {
+ vhtCap->present = 0;
+ }
+ } else {
+ /* Vht Disable from ini in 2.4 GHz */
+ vhtCap->present = 0;
+ }
+ lim_log(pMac, LOG1, FL("VHT present = %hu, Chan Width = %hu"),
+ vhtCap->present, vhtCap->supportedChannelWidthSet);
+#endif
+}
+
+/*
+ * Send TDLS discovery response frame on direct link.
+ */
+
+static tSirRetStatus lim_send_tdls_dis_rsp_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMac, uint8_t dialog,
+ tpPESession psessionEntry,
+ uint8_t *addIe, uint16_t addIeLen)
+{
+ tDot11fTDLSDisRsp tdlsDisRsp;
+ uint16_t caps = 0;
+ uint32_t status = 0;
+ uint32_t nPayload = 0;
+ uint32_t nBytes = 0;
+ uint8_t *pFrame;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint32_t selfDot11Mode;
+/* Placeholder to support different channel bonding mode of TDLS than AP. */
+/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
+/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
+/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
+/* uint32_t tdlsChannelBondingMode; */
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ /*
+ * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ * and then hand it off to 'dot11f_pack_probe_request' (for
+ * serialization). We start by zero-initializing the structure:
+ */
+ cdf_mem_set((uint8_t *) &tdlsDisRsp, sizeof(tDot11fTDLSDisRsp), 0);
+
+ /*
+ * setup Fixed fields,
+ */
+ tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE;
+ tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP;
+ tdlsDisRsp.DialogToken.token = dialog;
+
+ populate_dot11f_link_iden(pMac, psessionEntry,
+ &tdlsDisRsp.LinkIdentifier,
+ peerMac, TDLS_RESPONDER);
+
+ if (cfg_get_capability_info(pMac, &caps, psessionEntry)
+ != eSIR_SUCCESS) {
+ /*
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve Capabilities value"));
+ }
+ swap_bit_field16(caps, (uint16_t *) &tdlsDisRsp.Capabilities);
+
+ /* populate supported rate and ext supported rate IE */
+ if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
+ &tdlsDisRsp.SuppRates,
+ &tdlsDisRsp.ExtSuppRates))
+ lim_log(pMac, LOGE,
+ FL("could not populate supported data rates"));
+
+ /* populate extended capability IE */
+ populate_dot11f_tdls_ext_capability(pMac,
+ psessionEntry,
+ &tdlsDisRsp.ExtCap);
+
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+
+ /* Populate HT/VHT Capabilities */
+ populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsDisRsp.HTCaps,
+ &tdlsDisRsp.VHTCaps, psessionEntry);
+
+ /* Populate TDLS offchannel param only if offchannel is enabled
+ * and TDLS Channel Switching is not prohibited by AP in ExtCap
+ * IE in assoc/re-assoc response.
+ */
+ if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+ (!psessionEntry->tdls_chan_swit_prohibited)) {
+ populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
+ &tdlsDisRsp.SuppChannels,
+ &tdlsDisRsp.
+ SuppOperatingClasses);
+ if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
+ tdlsDisRsp.ht2040_bss_coexistence.present = 1;
+ tdlsDisRsp.ht2040_bss_coexistence.info_request = 1;
+ }
+ } else {
+ lim_log(pMac, LOG1,
+ FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
+ pMac->lim.gLimTDLSOffChannelEnabled,
+ psessionEntry->tdls_chan_swit_prohibited);
+ }
+ /*
+ * now we pack it. First, how much space are we going to need?
+ */
+ status = dot11f_get_packed_tdls_dis_rsp_size(pMac, &tdlsDisRsp, &nPayload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to calculate the packed size for a Discovery Response (0x%08x)."
+ ),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fProbeRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while calculating the packed size for a Discovery Response (0x%08x)."
+ ),
+ status);
+ }
+
+ /*
+ * This frame is going out from PE as data frames with special ethertype
+ * 89-0d.
+ * 8 bytes of RFC 1042 header
+ */
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr) + addIeLen;
+
+ /* Ok-- try to allocate memory from MGMT PKT pool */
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to allocate %d bytes for a TDLS Discovery Request."
+ ),
+ nBytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* zero out the memory */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /*
+ * IE formation, memory allocation is completed, Now form TDLS discovery
+ * response frame
+ */
+
+ /* Make public Action Frame */
+
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peerMac,
+ psessionEntry->selfMacAddr);
+
+ {
+ tpSirMacMgmtHdr pMacHdr;
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+ pMacHdr->fc.toDS = ANI_TXDIR_IBSS;
+ pMacHdr->fc.powerMgmt = 0;
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+ }
+
+ status = dot11f_pack_tdls_dis_rsp(pMac, &tdlsDisRsp, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to pack a TDLS discovery response (0x%08x)."
+ ),
+ status);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while packing TDLS Discovery Response (0x%08x)."
+ ),
+ status);
+ }
+ if (0 != addIeLen) {
+ lim_log(pMac, LOG1,
+ FL("Copy Additional Ie Len = %d"), addIeLen);
+ cdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe,
+ addIeLen);
+ }
+ lim_log(pMac, LOG1,
+ FL("[TDLS] action %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR),
+ SIR_MAC_TDLS_DIS_RSP,
+ lim_trace_tdls_action_string(SIR_MAC_TDLS_DIS_RSP),
+ MAC_ADDR_ARRAY(peerMac));
+
+ pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
+ /*
+ * Transmit Discovery response and watch if this is delivered to
+ * peer STA.
+ */
+ /* In CLD 2.0, pass Discovery Response as mgmt frame so that
+ * wma does not do header conversion to 802.3 before calling tx/rx
+ * routine and subsequenly target also sends frame as is OTA
+ */
+ cdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_IBSS,
+ 0,
+ lim_tx_complete, pFrame,
+ lim_mgmt_tx_complete,
+ HAL_USE_SELF_STA_REQUESTED_MASK,
+ smeSessionId, false, 0);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ lim_log(pMac, LOGE,
+ FL("could not send TDLS Discovery Response frame!"));
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+}
+
+/*
+ * This static function is currently used by lim_send_tdls_link_setup_req_frame and
+ * lim_send_tdls_setup_rsp_frame to populate the AID if device is 11ac capable.
+ */
+static void populate_dotf_tdls_vht_aid(tpAniSirGlobal pMac, uint32_t selfDot11Mode,
+ tSirMacAddr peerMac, tDot11fIEAID *Aid,
+ tpPESession psessionEntry)
+{
+ if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) &&
+ pMac->roam.configParam.enableVhtFor24GHz) ||
+ (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) {
+ if (IS_DOT11_MODE_VHT(selfDot11Mode) &&
+ IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
+
+ uint16_t aid;
+ tpDphHashNode pStaDs;
+
+ pStaDs =
+ dph_lookup_hash_entry(pMac, peerMac, &aid,
+ &psessionEntry->dph.
+ dphHashTable);
+ if (NULL != pStaDs) {
+ Aid->present = 1;
+ Aid->assocId = aid | LIM_AID_MASK; /* set bit 14 and 15 1's */
+ } else {
+ Aid->present = 0;
+ lim_log(pMac, LOGE,
+ FL("pStaDs is NULL for "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(peerMac));
+ }
+ }
+ } else {
+ Aid->present = 0;
+ lim_log(pMac, LOGW, FL("Vht not enable from ini for 2.4GHz."));
+ }
+}
+
+/*
+ * TDLS setup Request frame on AP link
+ */
+
+tSirRetStatus lim_send_tdls_link_setup_req_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMac, uint8_t dialog,
+ tpPESession psessionEntry,
+ uint8_t *addIe, uint16_t addIeLen)
+{
+ tDot11fTDLSSetupReq tdlsSetupReq;
+ uint16_t caps = 0;
+ uint32_t status = 0;
+ uint32_t nPayload = 0;
+ uint32_t nBytes = 0;
+ uint32_t header_offset = 0;
+ uint8_t *pFrame;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint32_t selfDot11Mode;
+ uint8_t smeSessionId = 0;
+/* Placeholder to support different channel bonding mode of TDLS than AP. */
+/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
+/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
+/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
+/* uint32_t tdlsChannelBondingMode; */
+
+ /*
+ * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ * and then hand it off to 'dot11f_pack_probe_request' (for
+ * serialization). We start by zero-initializing the structure:
+ */
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &tdlsSetupReq, sizeof(tDot11fTDLSSetupReq), 0);
+ tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS;
+ tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ;
+ tdlsSetupReq.DialogToken.token = dialog;
+
+ populate_dot11f_link_iden(pMac, psessionEntry,
+ &tdlsSetupReq.LinkIdentifier, peerMac,
+ TDLS_INITIATOR);
+
+ if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
+ /*
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve Capabilities value"));
+ }
+ swap_bit_field16(caps, (uint16_t *) &tdlsSetupReq.Capabilities);
+
+ /* populate supported rate and ext supported rate IE */
+ if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
+ &tdlsSetupReq.SuppRates,
+ &tdlsSetupReq.ExtSuppRates))
+ lim_log(pMac, LOGE,
+ FL("could not populate supported data rates"));
+
+ /* Populate extended capability IE */
+ populate_dot11f_tdls_ext_capability(pMac,
+ psessionEntry,
+ &tdlsSetupReq.ExtCap);
+
+ if (1 == pMac->lim.gLimTDLSWmmMode) {
+ uint32_t val = 0;
+
+ lim_log(pMac, LOG1,
+ FL("populate WMM IE in Setup Request Frame"));
+ /* include WMM IE */
+ tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
+ tdlsSetupReq.WMMInfoStation.acvo_uapsd =
+ (pMac->lim.gLimTDLSUapsdMask & 0x01);
+ tdlsSetupReq.WMMInfoStation.acvi_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+ tdlsSetupReq.WMMInfoStation.acbk_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+ tdlsSetupReq.WMMInfoStation.acbe_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGE,
+ FL("could not retrieve Max SP Length"));
+
+ tdlsSetupReq.WMMInfoStation.max_sp_length = (uint8_t) val;
+ tdlsSetupReq.WMMInfoStation.present = 1;
+ } else {
+ /*
+ * TODO: we need to see if we have to support conditions where
+ * we have EDCA parameter info element is needed a) if we need
+ * different QOS parameters for off channel operations or QOS
+ * is not supported on AP link and we wanted to QOS on direct
+ * link.
+ */
+
+ /* Populate QOS info, needed for Peer U-APSD session */
+
+ /*
+ * TODO: Now hardcoded, since populate_dot11f_qos_caps_station()
+ * depends on AP's capability, and TDLS doesn't want to depend
+ * on AP's capability
+ */
+
+ lim_log(pMac, LOG1,
+ FL("populate QOS IE in Setup Request Frame"));
+ tdlsSetupReq.QOSCapsStation.present = 1;
+ tdlsSetupReq.QOSCapsStation.max_sp_length = 0;
+ tdlsSetupReq.QOSCapsStation.qack = 0;
+ tdlsSetupReq.QOSCapsStation.acbe_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+ tdlsSetupReq.QOSCapsStation.acbk_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+ tdlsSetupReq.QOSCapsStation.acvi_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+ tdlsSetupReq.QOSCapsStation.acvo_uapsd =
+ (pMac->lim.gLimTDLSUapsdMask & 0x01);
+ }
+
+ /*
+ * we will always try to init TDLS link with 11n capabilities
+ * let TDLS setup response to come, and we will set our caps based
+ * of peer caps
+ */
+
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+
+ /* Populate HT/VHT Capabilities */
+ populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupReq.HTCaps,
+ &tdlsSetupReq.VHTCaps, psessionEntry);
+
+ /* Populate AID */
+ populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peerMac,
+ &tdlsSetupReq.AID, psessionEntry);
+
+ /* Populate TDLS offchannel param only if offchannel is enabled
+ * and TDLS Channel Switching is not prohibited by AP in ExtCap
+ * IE in assoc/re-assoc response.
+ */
+ if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+ (!psessionEntry->tdls_chan_swit_prohibited)) {
+ populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
+ &tdlsSetupReq.SuppChannels,
+ &tdlsSetupReq.
+ SuppOperatingClasses);
+ if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
+ tdlsSetupReq.ht2040_bss_coexistence.present = 1;
+ tdlsSetupReq.ht2040_bss_coexistence.info_request = 1;
+ }
+ } else {
+ lim_log(pMac, LOG1,
+ FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
+ pMac->lim.gLimTDLSOffChannelEnabled,
+ psessionEntry->tdls_chan_swit_prohibited);
+ }
+ /*
+ * now we pack it. First, how much space are we going to need?
+ */
+ status = dot11f_get_packed_tdls_setup_req_size(pMac, &tdlsSetupReq,
+ &nPayload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to calculate the packed size for a Setup Request (0x%08x)."
+ ),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fProbeRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while calculating the packed size for a Setup Request (0x%08x)."
+ ),
+ status);
+ }
+
+ /*
+ * This frame is going out from PE as data frames with special ethertype
+ * 89-0d.
+ * 8 bytes of RFC 1042 header
+ */
+
+ nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+ ? sizeof(tSirMacDataHdr3a) :
+ sizeof(tSirMacMgmtHdr))
+ + sizeof(eth_890d_header)
+ + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+ /* Ok-- try to allocate memory from MGMT PKT pool */
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to allocate %d bytes for a TDLS Setup Request."
+ ),
+ nBytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* zero out the memory */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /*
+ * IE formation, memory allocation is completed, Now form TDLS discovery
+ * request frame
+ */
+
+ /* fill out the buffer descriptor */
+
+ header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+ LINK_IDEN_ADDR_OFFSET
+ (tdlsSetupReq), TDLS_LINK_AP,
+ TDLS_INITIATOR, TID_AC_BK,
+ psessionEntry);
+
+ lim_log(pMac, LOGW,
+ FL(
+ "SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"
+ ),
+ tdlsSetupReq.VHTCaps.supportedChannelWidthSet,
+ tdlsSetupReq.VHTCaps.rxMCSMap,
+ tdlsSetupReq.VHTCaps.txMCSMap,
+ tdlsSetupReq.VHTCaps.txSupDataRate);
+
+ status = dot11f_pack_tdls_setup_req(pMac, &tdlsSetupReq, pFrame
+ + header_offset, nPayload, &nPayload);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a TDLS Setup request (0x%08x)."),
+ status);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while packing TDLS Setup Request (0x%08x)."
+ ),
+ status);
+ }
+ /* Copy the additional IE. */
+ /* TODO : addIe is added at the end of the frame. This means it doesnt */
+ /* follow the order. This should be ok, but we should consider changing this */
+ /* if there is any IOT issue. */
+ if (addIeLen != 0) {
+ lim_log(pMac, LOG1, FL("Copy Additional Ie Len = %d"),
+ addIeLen);
+ cdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+ addIeLen);
+ }
+
+ lim_log(pMac, LOG1,
+ FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
+ SIR_MAC_TDLS_SETUP_REQ,
+ lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_REQ),
+ MAC_ADDR_ARRAY(peerMac));
+
+ pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
+
+ cdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_DATA,
+ ANI_TXDIR_TODS,
+ TID_AC_BK,
+ lim_tx_complete, pFrame,
+ lim_mgmt_tx_complete,
+ HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
+ smeSessionId, false, 0);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ lim_log(pMac, LOGE,
+ FL("could not send TDLS Setup Request frame!"));
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+}
+
+/*
+ * Send TDLS Teardown frame on Direct link or AP link, depends on reason code.
+ */
+
+tSirRetStatus lim_send_tdls_teardown_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMac, uint16_t reason,
+ uint8_t responder,
+ tpPESession psessionEntry,
+ uint8_t *addIe, uint16_t addIeLen)
+{
+ tDot11fTDLSTeardown teardown;
+ uint32_t status = 0;
+ uint32_t nPayload = 0;
+ uint32_t nBytes = 0;
+ uint32_t header_offset = 0;
+ uint8_t *pFrame;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ uint32_t padLen = 0;
+#endif
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+ /*
+ * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ * and then hand it off to 'dot11f_pack_probe_request' (for
+ * serialization). We start by zero-initializing the structure:
+ */
+ cdf_mem_set((uint8_t *) &teardown, sizeof(tDot11fTDLSTeardown), 0);
+ teardown.Category.category = SIR_MAC_ACTION_TDLS;
+ teardown.Action.action = SIR_MAC_TDLS_TEARDOWN;
+ teardown.Reason.code = reason;
+
+ populate_dot11f_link_iden(pMac, psessionEntry, &teardown.LinkIdentifier,
+ peerMac,
+ (responder ==
+ true) ? TDLS_RESPONDER : TDLS_INITIATOR);
+
+ /*
+ * now we pack it. First, how much space are we going to need?
+ */
+ status = dot11f_get_packed_tdls_teardown_size(pMac, &teardown, &nPayload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to calculate the packed size for a discovery Request (0x%08x)."
+ ),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fProbeRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while calculating the packed size for a discovery Request (0x%08x)."
+ ),
+ status);
+ }
+
+ /*
+ * This frame is going out from PE as data frames with special ethertype
+ * 89-0d.
+ * 8 bytes of RFC 1042 header
+ */
+
+ nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+ ? sizeof(tSirMacDataHdr3a) :
+ sizeof(tSirMacMgmtHdr))
+ + sizeof(eth_890d_header)
+ + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
+ Hence AP itself padding some bytes, which caused teardown packet is dropped at
+ receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
+ */
+ if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
+ padLen =
+ MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
+
+ /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
+ if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
+ padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
+
+ nBytes += padLen;
+ }
+#endif
+
+ /* Ok-- try to allocate memory from MGMT PKT pool */
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to allocate %d bytes for a TDLS Teardown Frame."
+ ),
+ nBytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* zero out the memory */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /*
+ * IE formation, memory allocation is completed, Now form TDLS discovery
+ * request frame
+ */
+
+ /* fill out the buffer descriptor */
+ lim_log(pMac, LOGE, FL("Reason of TDLS Teardown: %d"), reason);
+ header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+ LINK_IDEN_ADDR_OFFSET
+ (teardown),
+ (reason ==
+ eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE)
+ ? TDLS_LINK_AP :
+ TDLS_LINK_DIRECT,
+ (responder ==
+ true) ? TDLS_RESPONDER :
+ TDLS_INITIATOR, TID_AC_VI,
+ psessionEntry);
+
+ status = dot11f_pack_tdls_teardown(pMac, &teardown, pFrame
+ + header_offset, nPayload, &nPayload);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a TDLS Teardown frame (0x%08x)."),
+ status);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while packing TDLS Teardown frame (0x%08x)."
+ ),
+ status);
+ }
+
+ if (addIeLen != 0) {
+ lim_log(pMac, LOGW,
+ FL("Copy Additional Ie Len = %d"), addIeLen);
+ cdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+ addIeLen);
+ }
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ if (padLen != 0) {
+ /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
+ uint8_t *padVendorSpecific =
+ pFrame + header_offset + nPayload + addIeLen;
+ /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
+ padVendorSpecific[0] = 221;
+ padVendorSpecific[1] = padLen - 2;
+ padVendorSpecific[2] = 0x00;
+ padVendorSpecific[3] = 0xA0;
+ padVendorSpecific[4] = 0xC6;
+
+ lim_log(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"),
+ padLen);
+
+ /* padding zero if more than 5 bytes are required */
+ if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
+ cdf_mem_set(pFrame + header_offset + nPayload +
+ addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
+ padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
+ }
+#endif
+ lim_log(pMac, LOG1,
+ FL("[TDLS] action %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR),
+ SIR_MAC_TDLS_TEARDOWN,
+ lim_trace_tdls_action_string(SIR_MAC_TDLS_TEARDOWN),
+ ((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? "AP" :
+ "DIRECT"),
+ MAC_ADDR_ARRAY(peerMac));
+
+ pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
+
+ cdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_DATA,
+ ANI_TXDIR_TODS,
+ TID_AC_VI,
+ lim_tx_complete, pFrame,
+ lim_mgmt_tx_complete,
+ HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
+ smeSessionId, false, 0);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ lim_log(pMac, LOGE,
+ FL("could not send TDLS Teardown frame"));
+ return eSIR_FAILURE;
+
+ }
+ return eSIR_SUCCESS;
+
+}
+
+/*
+ * Send Setup RSP frame on AP link.
+ */
+static tSirRetStatus lim_send_tdls_setup_rsp_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMac,
+ uint8_t dialog,
+ tpPESession psessionEntry,
+ etdlsLinkSetupStatus setupStatus,
+ uint8_t *addIe,
+ uint16_t addIeLen)
+{
+ tDot11fTDLSSetupRsp tdlsSetupRsp;
+ uint32_t status = 0;
+ uint16_t caps = 0;
+ uint32_t nPayload = 0;
+ uint32_t header_offset = 0;
+ uint32_t nBytes = 0;
+ uint8_t *pFrame;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint32_t selfDot11Mode;
+/* Placeholder to support different channel bonding mode of TDLS than AP. */
+/* Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP */
+/* To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE */
+/* As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) */
+/* uint32_t tdlsChannelBondingMode; */
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ lim_log(pMac, LOGE, FL("psessionEntry is NULL"));
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ /*
+ * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ * and then hand it off to 'dot11f_pack_probe_request' (for
+ * serialization). We start by zero-initializing the structure:
+ */
+ cdf_mem_set((uint8_t *) &tdlsSetupRsp, sizeof(tDot11fTDLSSetupRsp), 0);
+
+ /*
+ * setup Fixed fields,
+ */
+ tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS;
+ tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP;
+ tdlsSetupRsp.DialogToken.token = dialog;
+
+ populate_dot11f_link_iden(pMac, psessionEntry,
+ &tdlsSetupRsp.LinkIdentifier, peerMac,
+ TDLS_RESPONDER);
+
+ if (cfg_get_capability_info(pMac, &caps, psessionEntry) != eSIR_SUCCESS) {
+ /*
+ * Could not get Capabilities value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve Capabilities value"));
+ }
+ swap_bit_field16(caps, (uint16_t *) &tdlsSetupRsp.Capabilities);
+
+ /* populate supported rate and ext supported rate IE */
+ if (eSIR_FAILURE == populate_dot11f_rates_tdls(pMac,
+ &tdlsSetupRsp.SuppRates,
+ &tdlsSetupRsp.ExtSuppRates))
+ lim_log(pMac, LOGE,
+ FL("could not populate supported data rates"));
+
+ /* Populate extended capability IE */
+ populate_dot11f_tdls_ext_capability(pMac,
+ psessionEntry,
+ &tdlsSetupRsp.ExtCap);
+
+ if (1 == pMac->lim.gLimTDLSWmmMode) {
+ uint32_t val = 0;
+
+ lim_log(pMac, LOG1,
+ FL("populate WMM IE in Setup Response frame"));
+ /* include WMM IE */
+ tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1;
+ tdlsSetupRsp.WMMInfoStation.acvo_uapsd =
+ (pMac->lim.gLimTDLSUapsdMask & 0x01);
+ tdlsSetupRsp.WMMInfoStation.acvi_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+ tdlsSetupRsp.WMMInfoStation.acbk_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+ tdlsSetupRsp.WMMInfoStation.acbe_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGE,
+ FL("could not retrieve Max SP Length"));
+ tdlsSetupRsp.WMMInfoStation.max_sp_length = (uint8_t) val;
+ tdlsSetupRsp.WMMInfoStation.present = 1;
+ } else {
+ /*
+ * TODO: we need to see if we have to support conditions where
+ * we have EDCA parameter info element is needed a) if we need
+ * different QOS parameters for off channel operations or QOS
+ * is not supported on AP link and we wanted to QOS on direct
+ * link.
+ */
+ /* Populate QOS info, needed for Peer U-APSD session */
+ /*
+ * TODO: Now hardcoded, because
+ * populate_dot11f_qos_caps_station() depends on AP's
+ * capability, and TDLS doesn't want to depend on AP's
+ * capability
+ */
+ lim_log(pMac, LOG1,
+ FL("populate QOS IE in Setup Response frame"));
+ tdlsSetupRsp.QOSCapsStation.present = 1;
+ tdlsSetupRsp.QOSCapsStation.max_sp_length = 0;
+ tdlsSetupRsp.QOSCapsStation.qack = 0;
+ tdlsSetupRsp.QOSCapsStation.acbe_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3);
+ tdlsSetupRsp.QOSCapsStation.acbk_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2);
+ tdlsSetupRsp.QOSCapsStation.acvi_uapsd =
+ ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1);
+ tdlsSetupRsp.QOSCapsStation.acvo_uapsd =
+ (pMac->lim.gLimTDLSUapsdMask & 0x01);
+ }
+
+ wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfDot11Mode);
+
+ /* Populate HT/VHT Capabilities */
+ populate_dot11f_tdls_ht_vht_cap(pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps,
+ &tdlsSetupRsp.VHTCaps, psessionEntry);
+
+ /* Populate AID */
+ populate_dotf_tdls_vht_aid(pMac, selfDot11Mode, peerMac,
+ &tdlsSetupRsp.AID, psessionEntry);
+
+ /* Populate TDLS offchannel param only if offchannel is enabled
+ * and TDLS Channel Switching is not prohibited by AP in ExtCap
+ * IE in assoc/re-assoc response.
+ */
+ if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+ (!psessionEntry->tdls_chan_swit_prohibited)) {
+ populate_dot11f_tdls_offchannel_params(pMac, psessionEntry,
+ &tdlsSetupRsp.SuppChannels,
+ &tdlsSetupRsp.
+ SuppOperatingClasses);
+ if (pMac->roam.configParam.bandCapability != eCSR_BAND_24) {
+ tdlsSetupRsp.ht2040_bss_coexistence.present = 1;
+ tdlsSetupRsp.ht2040_bss_coexistence.info_request = 1;
+ }
+ } else {
+ lim_log(pMac, LOG1,
+ FL("TDLS offchan not enabled, or channel switch prohibited by AP, gLimTDLSOffChannelEnabled (%d), tdls_chan_swit_prohibited (%d)"),
+ pMac->lim.gLimTDLSOffChannelEnabled,
+ psessionEntry->tdls_chan_swit_prohibited);
+ }
+ tdlsSetupRsp.Status.status = setupStatus;
+ /*
+ * now we pack it. First, how much space are we going to need?
+ */
+ status = dot11f_get_packed_tdls_setup_rsp_size(pMac, &tdlsSetupRsp,
+ &nPayload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to calculate the packed size for a Setup Response (0x%08x)."
+ ),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fProbeRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while calculating the packed size for Setup Response (0x%08x)."
+ ),
+ status);
+ }
+
+ /*
+ * This frame is going out from PE as data frames with special ethertype
+ * 89-0d.
+ * 8 bytes of RFC 1042 header
+ */
+
+ nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+ ? sizeof(tSirMacDataHdr3a) :
+ sizeof(tSirMacMgmtHdr))
+ + sizeof(eth_890d_header)
+ + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+ /* Ok-- try to allocate memory from MGMT PKT pool */
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to allocate %d bytes for a TDLS Setup Response."
+ ),
+ nBytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* zero out the memory */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /*
+ * IE formation, memory allocation is completed, Now form TDLS discovery
+ * request frame
+ */
+
+ /* fill out the buffer descriptor */
+
+ header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+ LINK_IDEN_ADDR_OFFSET
+ (tdlsSetupRsp), TDLS_LINK_AP,
+ TDLS_RESPONDER, TID_AC_BK,
+ psessionEntry);
+
+ lim_log(pMac, LOG1,
+ FL(
+ "SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"
+ ),
+ tdlsSetupRsp.VHTCaps.supportedChannelWidthSet,
+ tdlsSetupRsp.VHTCaps.rxMCSMap,
+ tdlsSetupRsp.VHTCaps.txMCSMap,
+ tdlsSetupRsp.VHTCaps.txSupDataRate);
+ status = dot11f_pack_tdls_setup_rsp(pMac, &tdlsSetupRsp,
+ pFrame + header_offset,
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a TDLS Setup Response (0x%08x)."),
+ status);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while packing TDLS Setup Response (0x%08x)."
+ ),
+ status);
+ }
+ /* Copy the additional IE. */
+ /* TODO : addIe is added at the end of the frame. This means it doesnt */
+ /* follow the order. This should be ok, but we should consider changing this */
+ /* if there is any IOT issue. */
+ if (addIeLen != 0) {
+ cdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+ addIeLen);
+ }
+
+ lim_log(pMac, LOG1,
+ FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
+ SIR_MAC_TDLS_SETUP_RSP,
+ lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_RSP),
+ MAC_ADDR_ARRAY(peerMac));
+
+ pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
+
+ cdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_DATA,
+ ANI_TXDIR_TODS,
+ TID_AC_BK,
+ lim_tx_complete, pFrame,
+ lim_mgmt_tx_complete,
+ HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
+ smeSessionId, false, 0);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ lim_log(pMac, LOGE,
+ FL("could not send TDLS Dis Request frame!"));
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+}
+
+/*
+ * Send TDLS setup CNF frame on AP link
+ */
+
+tSirRetStatus lim_send_tdls_link_setup_cnf_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMac,
+ uint8_t dialog,
+ uint32_t peerCapability,
+ tpPESession psessionEntry,
+ uint8_t *addIe, uint16_t addIeLen)
+{
+ tDot11fTDLSSetupCnf tdlsSetupCnf;
+ uint32_t status = 0;
+ uint32_t nPayload = 0;
+ uint32_t nBytes = 0;
+ uint32_t header_offset = 0;
+ uint8_t *pFrame;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ uint32_t padLen = 0;
+#endif
+ uint8_t smeSessionId = 0;
+
+ /*
+ * The scheme here is to fill out a 'tDot11fProbeRequest' structure
+ * and then hand it off to 'dot11f_pack_probe_request' (for
+ * serialization). We start by zero-initializing the structure:
+ */
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &tdlsSetupCnf, sizeof(tDot11fTDLSSetupCnf), 0);
+
+ /*
+ * setup Fixed fields,
+ */
+ tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS;
+ tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF;
+ tdlsSetupCnf.DialogToken.token = dialog;
+
+ populate_dot11f_link_iden(pMac, psessionEntry,
+ &tdlsSetupCnf.LinkIdentifier, peerMac,
+ TDLS_INITIATOR);
+ /*
+ * TODO: we need to see if we have to support conditions where we have
+ * EDCA parameter info element is needed a) if we need different QOS
+ * parameters for off channel operations or QOS is not supported on
+ * AP link and we wanted to QOS on direct link.
+ */
+
+ /* Check self and peer WMM capable */
+ if ((1 == pMac->lim.gLimTDLSWmmMode) &&
+ (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) {
+ lim_log(pMac, LOG1, FL("populate WMM praram in Setup Confirm"));
+ populate_dot11f_wmm_params(pMac, &tdlsSetupCnf.WMMParams,
+ psessionEntry);
+ }
+
+ /* Check peer is VHT capable */
+ if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) {
+ populate_dot11f_vht_operation(pMac,
+ psessionEntry,
+ &tdlsSetupCnf.VHTOperation);
+ populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
+ } else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) { /* Check peer is HT capable */
+ populate_dot11f_ht_info(pMac, &tdlsSetupCnf.HTInfo, psessionEntry);
+ }
+
+ /*
+ * now we pack it. First, how much space are we going to need?
+ */
+ status = dot11f_get_packed_tdls_setup_cnf_size(pMac, &tdlsSetupCnf,
+ &nPayload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to calculate the packed size for a Setup Confirm (0x%08x)."
+ ),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fProbeRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while calculating the packed size for Setup Confirm (0x%08x)."
+ ),
+ status);
+ }
+
+ /*
+ * This frame is going out from PE as data frames with special ethertype
+ * 89-0d.
+ * 8 bytes of RFC 1042 header
+ */
+
+ nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry))
+ ? sizeof(tSirMacDataHdr3a) :
+ sizeof(tSirMacMgmtHdr))
+ + sizeof(eth_890d_header)
+ + PAYLOAD_TYPE_TDLS_SIZE + addIeLen;
+
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64)
+ Hence AP itself padding some bytes, which caused teardown packet is dropped at
+ receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64
+ */
+ if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) {
+ padLen =
+ MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE);
+
+ /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */
+ if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE)
+ padLen = MIN_VENDOR_SPECIFIC_IE_SIZE;
+
+ nBytes += padLen;
+ }
+#endif
+
+ /* Ok-- try to allocate memory from MGMT PKT pool */
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Failed to allocate %d bytes for a TDLS Setup Confirm."
+ ),
+ nBytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ /* zero out the memory */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /*
+ * IE formation, memory allocation is completed, Now form TDLS discovery
+ * request frame
+ */
+
+ /* fill out the buffer descriptor */
+
+ header_offset = lim_prepare_tdls_frame_header(pMac, pFrame,
+ LINK_IDEN_ADDR_OFFSET
+ (tdlsSetupCnf), TDLS_LINK_AP,
+ TDLS_INITIATOR, TID_AC_VI,
+ psessionEntry);
+
+ status = dot11f_pack_tdls_setup_cnf(pMac, &tdlsSetupCnf, pFrame
+ + header_offset, nPayload, &nPayload);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a TDLS discovery req (0x%08x)."),
+ status);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL(
+ "There were warnings while packing TDLS Discovery Request (0x%08x)."
+ ),
+ status);
+ }
+ /* Copy the additional IE. */
+ /* TODO : addIe is added at the end of the frame. This means it doesnt */
+ /* follow the order. This should be ok, but we should consider changing this */
+ /* if there is any IOT issue. */
+ if (addIeLen != 0) {
+ cdf_mem_copy(pFrame + header_offset + nPayload, addIe,
+ addIeLen);
+ }
+#ifndef NO_PAD_TDLS_MIN_8023_SIZE
+ if (padLen != 0) {
+ /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */
+ uint8_t *padVendorSpecific =
+ pFrame + header_offset + nPayload + addIeLen;
+ /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */
+ padVendorSpecific[0] = 221;
+ padVendorSpecific[1] = padLen - 2;
+ padVendorSpecific[2] = 0x00;
+ padVendorSpecific[3] = 0xA0;
+ padVendorSpecific[4] = 0xC6;
+
+ lim_log(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"),
+ padLen);
+
+ /* padding zero if more than 5 bytes are required */
+ if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE)
+ cdf_mem_set(pFrame + header_offset + nPayload +
+ addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE,
+ padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0);
+ }
+#endif
+
+ lim_log(pMac, LOG1,
+ FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR),
+ SIR_MAC_TDLS_SETUP_CNF,
+ lim_trace_tdls_action_string(SIR_MAC_TDLS_SETUP_CNF),
+ MAC_ADDR_ARRAY(peerMac));
+
+ pMac->lim.mgmtFrameSessionId = psessionEntry->peSessionId;
+
+ cdf_status = wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_DATA,
+ ANI_TXDIR_TODS,
+ TID_AC_VI,
+ lim_tx_complete, pFrame,
+ lim_mgmt_tx_complete,
+ HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME,
+ smeSessionId, false, 0);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pMac->lim.mgmtFrameSessionId = 0xff;
+ lim_log(pMac, LOGE,
+ FL("could not send TDLS Setup Confirm frame"));
+ return eSIR_FAILURE;
+
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/* This Function is similar to populate_dot11f_ht_caps, except that the HT Capabilities
+ * are considered from the AddStaReq rather from the cfg.dat as in populate_dot11f_ht_caps
+ */
+static tSirRetStatus lim_tdls_populate_dot11f_ht_caps(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tSirTdlsAddStaReq *
+ pTdlsAddStaReq,
+ tDot11fIEHTCaps *pDot11f)
+{
+ uint32_t nCfgValue;
+ uint8_t nCfgValue8;
+ tSirMacHTParametersInfo *pHTParametersInfo;
+ union {
+ uint16_t nCfgValue16;
+ tSirMacHTCapabilityInfo htCapInfo;
+ tSirMacExtendedHTCapabilityInfo extHtCapInfo;
+ } uHTCapabilityInfo;
+
+ tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
+ tSirMacASCapabilityInfo *pASCapabilityInfo;
+
+ nCfgValue = pTdlsAddStaReq->htCap.capInfo;
+
+ uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
+
+ pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap;
+ pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
+ pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField;
+ pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz;
+ pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz;
+ pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC;
+ pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC;
+ pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA;
+ pDot11f->maximalAMSDUsize =
+ uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
+ pDot11f->dsssCckMode40MHz =
+ uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
+ pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp;
+ pDot11f->stbcControlFrame =
+ uHTCapabilityInfo.htCapInfo.stbcControlFrame;
+ pDot11f->lsigTXOPProtection =
+ uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;
+
+ /*
+ * All sessionized entries will need the check below
+ * Only in case of NO session
+ */
+ if (psessionEntry == NULL) {
+ pDot11f->supportedChannelWidthSet =
+ uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet;
+ } else {
+ pDot11f->supportedChannelWidthSet =
+ psessionEntry->htSupportedChannelWidthSet;
+ }
+
+ /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
+ eHT_CHANNEL_WIDTH_20MHZ */
+ if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
+ pDot11f->shortGI40MHz = 0;
+ }
+
+ lim_log(pMac, LOG1,
+ FL(
+ "SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d"
+ ),
+ pDot11f->supportedChannelWidthSet,
+ pDot11f->mimoPowerSave,
+ pDot11f->greenField,
+ pDot11f->shortGI20MHz,
+ pDot11f->shortGI40MHz,
+ pDot11f->dsssCckMode40MHz);
+
+ nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo;
+
+ nCfgValue8 = (uint8_t) nCfgValue;
+ pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;
+
+ pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
+ pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
+ pDot11f->reserved1 = pHTParametersInfo->reserved;
+
+ lim_log(pMac, LOG1, FL("AMPDU Param: %x"), nCfgValue);
+
+ cdf_mem_copy(pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet,
+ SIZE_OF_SUPPORTED_MCS_SET);
+
+ nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo;
+
+ uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
+
+ pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
+ pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
+ pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
+
+ nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo;
+
+ pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
+ pDot11f->txBF = pTxBFCapabilityInfo->txBF;
+ pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
+ pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
+ pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
+ pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
+ pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
+ pDot11f->calibration = pTxBFCapabilityInfo->calibration;
+ pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
+ pDot11f->explicitUncompressedSteeringMatrix =
+ pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
+ pDot11f->explicitBFCSIFeedback =
+ pTxBFCapabilityInfo->explicitBFCSIFeedback;
+ pDot11f->explicitUncompressedSteeringMatrixFeedback =
+ pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
+ pDot11f->explicitCompressedSteeringMatrixFeedback =
+ pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
+ pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
+ pDot11f->uncompressedSteeringMatrixBFAntennae =
+ pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
+ pDot11f->compressedSteeringMatrixBFAntennae =
+ pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
+
+ nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo;
+
+ nCfgValue8 = (uint8_t) nCfgValue;
+
+ pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
+ pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
+ pDot11f->explicitCSIFeedbackTx =
+ pASCapabilityInfo->explicitCSIFeedbackTx;
+ pDot11f->antennaIndicesFeedbackTx =
+ pASCapabilityInfo->antennaIndicesFeedbackTx;
+ pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
+ pDot11f->antennaIndicesFeedback =
+ pASCapabilityInfo->antennaIndicesFeedback;
+ pDot11f->rxAS = pASCapabilityInfo->rxAS;
+ pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
+
+ pDot11f->present = pTdlsAddStaReq->htcap_present;
+
+ return eSIR_SUCCESS;
+
+}
+
+tSirRetStatus
+lim_tdls_populate_dot11f_vht_caps(tpAniSirGlobal pMac,
+ tSirTdlsAddStaReq *pTdlsAddStaReq,
+ tDot11fIEVHTCaps *pDot11f)
+{
+ uint32_t nCfgValue = 0;
+ union {
+ uint32_t nCfgValue32;
+ tSirMacVHTCapabilityInfo vhtCapInfo;
+ } uVHTCapabilityInfo;
+ union {
+ uint16_t nCfgValue16;
+ tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo;
+ tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo;
+ } uVHTSupDataRateInfo;
+
+ pDot11f->present = pTdlsAddStaReq->vhtcap_present;
+
+ nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo;
+ uVHTCapabilityInfo.nCfgValue32 = nCfgValue;
+
+ pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen;
+ pDot11f->supportedChannelWidthSet =
+ uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet;
+ pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap;
+ pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz;
+ pDot11f->shortGI160and80plus80MHz =
+ uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz;
+ pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC;
+ pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC;
+ pDot11f->suBeamFormerCap = 0;
+ pDot11f->suBeamformeeCap = 0;
+ pDot11f->csnofBeamformerAntSup =
+ uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup;
+ pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim;
+ pDot11f->muBeamformerCap = 0;
+ pDot11f->muBeamformeeCap = 0;
+ pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS;
+ pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap;
+ pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp;
+ pDot11f->vhtLinkAdaptCap =
+ uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap;
+ pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern;
+ pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern;
+ pDot11f->reserved1 = uVHTCapabilityInfo.vhtCapInfo.reserved1;
+
+ pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap;
+
+ nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest;
+ uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
+ pDot11f->rxHighSupDataRate =
+ uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate;
+
+ pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap;
+
+ nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest;
+ uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff;
+ pDot11f->txSupDataRate =
+ uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate;
+
+ pDot11f->reserved3 = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved;
+
+ lim_log_vht_cap(pMac, pDot11f);
+
+ return eSIR_SUCCESS;
+
+}
+
+/**
+ * lim_tdls_populate_matching_rate_set() - populate matching rate set
+ *
+ * @mac_ctx - global MAC context
+ * @stads - station hash entry
+ * @supp_rate_set - pointer to supported rate set
+ * @supp_rates_len - length of the supported rates
+ * @supp_mcs_set - pointer to supported MSC set
+ * @session_entry - pointer to PE session entry
+ * @vht_caps - pointer to VHT capability
+ *
+ *
+ * This function gets set of available rates from the config and compare them
+ * against the set of received supported rates. After the comparison station
+ * entry's rates is populated with 11A rates and 11B rates.
+ *
+ * Return: eSIR_SUCCESS on success, eSIR_FAILURE on failure.
+ */
+static tSirRetStatus
+lim_tdls_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode stads,
+ uint8_t *supp_rate_set,
+ uint8_t supp_rates_len,
+ uint8_t *supp_mcs_set,
+ tpPESession session_entry,
+ tDot11fIEVHTCaps *vht_caps)
+{
+ tSirMacRateSet temp_rate_set;
+ uint32_t i, j, val, min, is_a_rate;
+ tSirMacRateSet temp_rate_set2;
+ uint32_t phymode;
+ uint8_t mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
+ tpSirSupportedRates rates;
+ uint8_t a_rateindex = 0;
+ uint8_t b_rateindex = 0;
+ is_a_rate = 0;
+ temp_rate_set2.numRates = 0;
+
+ lim_get_phy_mode(mac_ctx, &phymode, NULL);
+
+ /* get own rate set */
+ val = WNI_CFG_OPERATIONAL_RATE_SET_LEN;
+ if (wlan_cfg_get_str(mac_ctx, WNI_CFG_OPERATIONAL_RATE_SET,
+ (uint8_t *) &temp_rate_set.rate,
+ &val) != eSIR_SUCCESS) {
+ /* Could not get rateset from CFG. Log error. */
+ lim_log(mac_ctx, LOGE, FL("could not retrieve rateset"));
+ val = 0;
+ }
+ temp_rate_set.numRates = val;
+
+ if (phymode == WNI_CFG_PHY_MODE_11G) {
+ /* get own extended rate set */
+ val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN;
+ if (wlan_cfg_get_str(mac_ctx,
+ WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
+ (uint8_t *) &temp_rate_set2.rate,
+ &val) != eSIR_SUCCESS)
+ temp_rate_set2.numRates = val;
+ }
+
+ if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
+ lim_log(mac_ctx, LOGE, FL("more than 12 rates in CFG"));
+ goto error;
+ }
+
+ /**
+ * Handling of the rate set IEs is the following:
+ * - keep only rates that we support and that the station supports
+ * - sort and the rates into the pSta->rate array
+ */
+
+ /* Copy all rates in temp_rate_set, there are 12 rates max */
+ for (i = 0; i < temp_rate_set2.numRates; i++)
+ temp_rate_set.rate[i + temp_rate_set.numRates] =
+ temp_rate_set2.rate[i];
+
+ temp_rate_set.numRates += temp_rate_set2.numRates;
+
+ /**
+ * Sort rates in temp_rate_set (they are likely to be already sorted)
+ * put the result in temp_rate_set2
+ */
+ temp_rate_set2.numRates = 0;
+
+ for (i = 0; i < temp_rate_set.numRates; i++) {
+ min = 0;
+ val = 0xff;
+
+ for (j = 0; j < temp_rate_set.numRates; j++)
+ if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
+ val = temp_rate_set.rate[j] & 0x7f;
+ min = j;
+ }
+
+ temp_rate_set2.rate[temp_rate_set2.numRates++] =
+ temp_rate_set.rate[min];
+ temp_rate_set.rate[min] = 0xff;
+ }
+
+ /**
+ * Copy received rates in temp_rate_set, the parser has ensured
+ * unicity of the rates so there cannot be more than 12 .
+ */
+ if (supp_rates_len > SIR_MAC_RATESET_EID_MAX) {
+ lim_log(mac_ctx, LOGW,
+ FL(
+ "Supported rates length %d more than the Max limit, reset to Max"
+ ),
+ supp_rates_len);
+ supp_rates_len = SIR_MAC_RATESET_EID_MAX;
+ }
+
+ for (i = 0; i < supp_rates_len; i++)
+ temp_rate_set.rate[i] = supp_rate_set[i];
+
+ temp_rate_set.numRates = supp_rates_len;
+
+ rates = &stads->supportedRates;
+ cdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
+
+ for (i = 0; i < temp_rate_set2.numRates; i++) {
+ for (j = 0; j < temp_rate_set.numRates; j++) {
+ if ((temp_rate_set2.rate[i] & 0x7F) !=
+ (temp_rate_set.rate[j] & 0x7F))
+ continue;
+
+#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
+ if ((b_rateindex > HAL_NUM_11B_RATES) ||
+ (a_rateindex > HAL_NUM_11A_RATES)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid number of rates (11b->%d, 11a->%d)"),
+ b_rateindex, a_rateindex);
+ return eSIR_FAILURE;
+ }
+#endif
+ if (sirIsArate(temp_rate_set2.rate[i] & 0x7f)) {
+ is_a_rate = 1;
+ if (a_rateindex < SIR_NUM_11A_RATES)
+ rates->llaRates[a_rateindex++] = temp_rate_set2.rate[i];
+ } else {
+ if (b_rateindex < SIR_NUM_11B_RATES)
+ rates->llbRates[b_rateindex++] = temp_rate_set2.rate[i];
+ }
+ break;
+ }
+ }
+
+ /* compute the matching MCS rate set, if peer is 11n capable and self mode is 11n */
+#ifdef FEATURE_WLAN_TDLS
+ if (stads->mlmStaContext.htCapability)
+#else
+ if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
+ (stads->mlmStaContext.htCapability))
+#endif
+ {
+ val = SIZE_OF_SUPPORTED_MCS_SET;
+ if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
+ mcsSet, &val) != eSIR_SUCCESS) {
+ /* Could not get rateset from CFG. Log error. */
+ lim_log(mac_ctx, LOGP,
+ FL("could not retrieve supportedMCSSet"));
+ goto error;
+ }
+
+ for (i = 0; i < val; i++)
+ stads->supportedRates.supportedMCSSet[i] =
+ mcsSet[i] & supp_mcs_set[i];
+
+ lim_log(mac_ctx, LOG1,
+ FL("MCS Rate Set Bitmap from CFG and DPH"));
+ for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
+ lim_log(mac_ctx, LOG1, FL("%x %x"), mcsSet[i],
+ stads->supportedRates.supportedMCSSet[i]);
+ }
+ }
+#ifdef WLAN_FEATURE_11AC
+ lim_populate_vht_mcs_set(mac_ctx, &stads->supportedRates, vht_caps,
+ session_entry);
+#endif
+ /**
+ * Set the erpEnabled bit if the phy is in G mode and at least
+ * one A rate is supported
+ */
+ if ((phymode == WNI_CFG_PHY_MODE_11G) && is_a_rate)
+ stads->erpEnabled = eHAL_SET;
+
+ return eSIR_SUCCESS;
+
+error:
+ return eSIR_FAILURE;
+}
+
+/*
+ * update HASH node entry info
+ */
+static void lim_tdls_update_hash_node_info(tpAniSirGlobal pMac,
+ tDphHashNode *pStaDs,
+ tSirTdlsAddStaReq *pTdlsAddStaReq,
+ tpPESession psessionEntry)
+{
+ tDot11fIEHTCaps htCap = {0,};
+ tDot11fIEHTCaps *htCaps;
+ tDot11fIEVHTCaps *pVhtCaps = NULL;
+ tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEVHTCaps vhtCap;
+ uint8_t cbMode;
+#endif
+ tpDphHashNode pSessStaDs = NULL;
+ uint16_t aid;
+
+ if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
+ populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
+ } else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) {
+ lim_tdls_populate_dot11f_ht_caps(pMac, NULL, pTdlsAddStaReq, &htCap);
+ }
+ htCaps = &htCap;
+ if (htCaps->present) {
+ pStaDs->mlmStaContext.htCapability = 1;
+ pStaDs->htGreenfield = htCaps->greenField;
+ pStaDs->htSupportedChannelWidthSet =
+ htCaps->supportedChannelWidthSet;
+ pStaDs->htMIMOPSState = htCaps->mimoPowerSave;
+ pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize;
+ pStaDs->htAMpduDensity = htCaps->mpduDensity;
+ pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz;
+ pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz;
+ pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz;
+ pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor;
+ lim_fill_rx_highest_supported_rate(pMac,
+ &pStaDs->supportedRates.
+ rxHighestDataRate,
+ htCaps->supportedMCSSet);
+ pStaDs->baPolicyFlag = 0xFF;
+ pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N;
+ pStaDs->ht_caps = pTdlsAddStaReq->htCap.capInfo;
+ } else {
+ pStaDs->mlmStaContext.htCapability = 0;
+ pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG;
+ }
+#ifdef WLAN_FEATURE_11AC
+ lim_tdls_populate_dot11f_vht_caps(pMac, pTdlsAddStaReq, &vhtCap);
+ pVhtCaps = &vhtCap;
+ if (pVhtCaps->present) {
+ pStaDs->mlmStaContext.vhtCapability = 1;
+
+ if (psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) {
+ /*
+ * if the channel is 2G then update the min channel
+ * widthset in pStaDs. These values are used when
+ * sending a AddSta request to firmware
+ * 11.21.1 General: The channel width of the TDLS direct
+ * link on the base channel shall not exceed the channel
+ * width of the BSS to which the TDLS peer STAs are
+ * associated.
+ */
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_20MHZ;
+ lim_log(pMac, LOG1, FL("vhtSupportedChannelWidthSet = %hu, htSupportedChannelWidthSet %hu"),
+ pStaDs->htSupportedChannelWidthSet,
+ pStaDs->htSupportedChannelWidthSet);
+ } else {
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ }
+
+ pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap;
+ pStaDs->vhtBeamFormerCapable = 0;
+ pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC;
+ pVhtCaps_txbf = (tDot11fIEVHTCaps *) (&pTdlsAddStaReq->vhtCap);
+ pVhtCaps_txbf->suBeamformeeCap = 0;
+ pVhtCaps_txbf->suBeamFormerCap = 0;
+ pVhtCaps_txbf->muBeamformerCap = 0;
+ pVhtCaps_txbf->muBeamformeeCap = 0;
+ pStaDs->vht_caps = pTdlsAddStaReq->vhtCap.vhtCapInfo;
+ } else {
+ pStaDs->mlmStaContext.vhtCapability = 0;
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ }
+#endif
+ /*Calculate the Secondary Coannel Offset */
+ cbMode = lim_select_cb_mode(pStaDs, psessionEntry,
+ psessionEntry->currentOperChannel,
+ pStaDs->vhtSupportedChannelWidthSet);
+
+ pStaDs->htSecondaryChannelOffset = cbMode;
+
+#ifdef WLAN_FEATURE_11AC
+ if (pStaDs->mlmStaContext.vhtCapability) {
+ pStaDs->htSecondaryChannelOffset = lim_get_htcb_state(cbMode);
+ }
+#endif
+
+ pSessStaDs = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
+ &psessionEntry->dph.dphHashTable);
+
+ /* Lets enable QOS parameter */
+ pStaDs->qosMode = 1;
+ pStaDs->wmeEnabled = 1;
+ pStaDs->lleEnabled = 0;
+ /* TDLS Dummy AddSTA does not have qosInfo , is it OK ??
+ */
+ pStaDs->qos.capability.qosInfo =
+ (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues);
+
+ /* populate matching rate set */
+
+ /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ??
+ */
+ lim_tdls_populate_matching_rate_set(pMac, pStaDs,
+ pTdlsAddStaReq->supported_rates,
+ pTdlsAddStaReq->supported_rates_length,
+ (uint8_t *) pTdlsAddStaReq->htCap.
+ suppMcsSet, psessionEntry, pVhtCaps);
+
+ /* TDLS Dummy AddSTA does not have right capability , is it OK ??
+ */
+ pStaDs->mlmStaContext.capabilityInfo =
+ (*(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability);
+
+ return;
+}
+
+/*
+ * Add STA for TDLS setup procedure
+ */
+static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
+ tSirTdlsAddStaReq *pAddStaReq,
+ tpPESession psessionEntry)
+{
+ tpDphHashNode pStaDs = NULL;
+ tSirRetStatus status = eSIR_SUCCESS;
+ uint16_t aid = 0;
+
+ pStaDs = dph_lookup_hash_entry(pMac, pAddStaReq->peerMac, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (NULL == pStaDs) {
+ aid = lim_assign_peer_idx(pMac, psessionEntry);
+
+ if (!aid) {
+ lim_log(pMac, LOGE,
+ FL("No more free AID for peer "
+ MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pAddStaReq->peerMac));
+ return eSIR_FAILURE;
+ }
+
+ /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */
+ SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid);
+
+ lim_log(pMac, LOG1, FL("Aid = %d, for peer =" MAC_ADDRESS_STR),
+ aid, MAC_ADDR_ARRAY(pAddStaReq->peerMac));
+ pStaDs =
+ dph_get_hash_entry(pMac, aid,
+ &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs) {
+ (void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
+ psessionEntry);
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, aid,
+ psessionEntry);
+ }
+
+ pStaDs = dph_add_hash_entry(pMac, pAddStaReq->peerMac, aid,
+ &psessionEntry->dph.dphHashTable);
+
+ if (NULL == pStaDs) {
+ lim_log(pMac, LOGE, FL("add hash entry failed"));
+ CDF_ASSERT(0);
+ return eSIR_FAILURE;
+ }
+ }
+
+ lim_tdls_update_hash_node_info(pMac, pStaDs, pAddStaReq, psessionEntry);
+
+ pStaDs->staType = STA_ENTRY_TDLS_PEER;
+
+ status =
+ lim_add_sta(pMac, pStaDs,
+ (pAddStaReq->tdlsAddOper ==
+ TDLS_OPER_UPDATE) ? true : false, psessionEntry);
+
+ if (eSIR_SUCCESS != status) {
+ /* should not fail */
+ CDF_ASSERT(0);
+ }
+ return status;
+}
+
+/*
+ * Del STA, after Link is teardown or discovery response sent on direct link
+ */
+static tpDphHashNode lim_tdls_del_sta(tpAniSirGlobal pMac, tSirMacAddr peerMac,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ uint16_t peerIdx = 0;
+ tpDphHashNode pStaDs = NULL;
+
+ pStaDs = dph_lookup_hash_entry(pMac, peerMac, &peerIdx,
+ &psessionEntry->dph.dphHashTable);
+
+ if (pStaDs) {
+
+ lim_log(pMac, LOG1, FL("DEL STA peer MAC: "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pStaDs->staAddr));
+
+ lim_log(pMac, LOG1, FL("STA type = %x, sta idx = %x"),
+ pStaDs->staType,
+ pStaDs->staIndex);
+
+ status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
+ }
+
+ return pStaDs;
+}
+
+/*
+ * Once Link is setup with PEER, send Add STA ind to SME
+ */
+static CDF_STATUS lim_send_sme_tdls_add_sta_rsp(tpAniSirGlobal pMac,
+ uint8_t sessionId,
+ tSirMacAddr peerMac,
+ uint8_t updateSta,
+ tDphHashNode *pStaDs, uint8_t status)
+{
+ tSirMsgQ mmhMsg = { 0 };
+ tSirTdlsAddStaRsp *addStaRsp = NULL;
+ mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP;
+
+ addStaRsp = cdf_mem_malloc(sizeof(tSirTdlsAddStaRsp));
+ if (NULL == addStaRsp) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory"));
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ addStaRsp->sessionId = sessionId;
+ addStaRsp->statusCode = status;
+ if (pStaDs) {
+ addStaRsp->staId = pStaDs->staIndex;
+ addStaRsp->ucastSig = pStaDs->ucUcastSig;
+ addStaRsp->bcastSig = pStaDs->ucBcastSig;
+ }
+ if (peerMac) {
+ cdf_mem_copy(addStaRsp->peerMac,
+ (uint8_t *) peerMac, sizeof(tSirMacAddr));
+ }
+ if (updateSta)
+ addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE;
+ else
+ addStaRsp->tdlsAddOper = TDLS_OPER_ADD;
+
+ addStaRsp->length = sizeof(tSirTdlsAddStaRsp);
+ addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP;
+
+ mmhMsg.bodyptr = addStaRsp;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return CDF_STATUS_SUCCESS;
+
+}
+
+/*
+ * STA RSP received from HAL
+ */
+CDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg,
+ tpPESession psessionEntry)
+{
+ tAddStaParams *pAddStaParams = (tAddStaParams *) msg;
+ uint8_t status = eSIR_SUCCESS;
+ tDphHashNode *pStaDs = NULL;
+ uint16_t aid = 0;
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
+ lim_log(pMac, LOG1, FL("staIdx=%d, staMac="MAC_ADDRESS_STR),
+ pAddStaParams->staIdx,
+ MAC_ADDR_ARRAY(pAddStaParams->staMac));
+
+ if (pAddStaParams->status != CDF_STATUS_SUCCESS) {
+ CDF_ASSERT(0);
+ lim_log(pMac, LOGE, FL("Add sta failed "));
+ status = eSIR_FAILURE;
+ goto add_sta_error;
+ }
+
+ pStaDs = dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (NULL == pStaDs) {
+ lim_log(pMac, LOGE, FL("pStaDs is NULL "));
+ status = eSIR_FAILURE;
+ goto add_sta_error;
+ }
+
+ pStaDs->bssId = pAddStaParams->bssIdx;
+ pStaDs->staIndex = pAddStaParams->staIdx;
+ pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
+ pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
+ pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
+ pStaDs->valid = 1;
+add_sta_error:
+ status = lim_send_sme_tdls_add_sta_rsp(pMac, psessionEntry->smeSessionId,
+ pAddStaParams->staMac,
+ pAddStaParams->updateSta, pStaDs,
+ status);
+ cdf_mem_free(pAddStaParams);
+ return status;
+}
+
+void populate_dot11f_tdls_offchannel_params(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIESuppChannels *suppChannels,
+ tDot11fIESuppOperatingClasses *
+ suppOperClasses)
+{
+ uint32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ uint8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+ uint8_t i;
+ uint8_t valid_count = 0;
+ uint8_t chanOffset;
+ uint8_t op_class;
+ uint8_t numClasses;
+ uint8_t classes[SIR_MAC_MAX_SUPP_OPER_CLASSES];
+ if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+ validChan, &numChans) != eSIR_SUCCESS) {
+ /**
+ * Could not get Valid channel list from CFG.
+ * Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve Valid channel list"));
+ return;
+ }
+
+ /* validating the channel list for DFS channels */
+ for (i = 0U; i < numChans; i++) {
+ if (CHANNEL_STATE_DFS ==
+ cds_get_channel_state(validChan[i])) {
+ lim_log(pMac, LOG1,
+ FL(
+ "skipping DFS channel %d from the valid channel list"
+ ),
+ validChan[i]);
+ continue;
+ }
+
+ if (valid_count >= ARRAY_SIZE(suppChannels->bands))
+ break;
+ suppChannels->bands[valid_count][0] = validChan[i];
+ suppChannels->bands[valid_count][1] = 1;
+ valid_count++;
+ }
+
+ suppChannels->num_bands = valid_count;
+ suppChannels->present = 1;
+
+ /* find channel offset and get op class for current operating channel */
+ switch (psessionEntry->htSecondaryChannelOffset) {
+ case PHY_SINGLE_CHANNEL_CENTERED:
+ chanOffset = BW20;
+ break;
+
+ case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+ chanOffset = BW40_LOW_PRIMARY;
+ break;
+
+ case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+ chanOffset = BW40_HIGH_PRIMARY;
+ break;
+
+ default:
+ chanOffset = BWALL;
+ break;
+
+ }
+
+ op_class = cds_regdm_get_opclass_from_channel(
+ pMac->scan.countryCodeCurrent,
+ psessionEntry->currentOperChannel,
+ chanOffset);
+
+ if (op_class == 0) {
+ lim_log(pMac, LOGE,
+ FL(
+ "Present Operating class is wrong, countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d, chanOffset: %d"
+ ),
+ pMac->scan.countryCodeCurrent,
+ psessionEntry->currentOperChannel,
+ psessionEntry->htSecondaryChannelOffset,
+ chanOffset);
+ } else {
+ lim_log(pMac, LOG1,
+ FL(
+ "Present Operating channel: %d chanOffset: %d, op class=%d"
+ ),
+ psessionEntry->currentOperChannel, chanOffset,
+ op_class);
+ }
+ suppOperClasses->present = 1;
+ suppOperClasses->classes[0] = op_class;
+
+ cds_regdm_get_curr_opclasses(&numClasses, &classes[0]);
+
+ for (i = 0; i < numClasses; i++) {
+ suppOperClasses->classes[i + 1] = classes[i];
+ }
+ /* add one for present operating class, added in the beginning */
+ suppOperClasses->num_classes = numClasses + 1;
+
+ return;
+}
+
+/*
+ * FUNCTION: Populate Link Identifier element IE
+ *
+ */
+
+void populate_dot11f_link_iden(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ tDot11fIELinkIdentifier *linkIden,
+ tSirMacAddr peerMac, uint8_t reqType)
+{
+ uint8_t *initStaAddr = NULL;
+ uint8_t *respStaAddr = NULL;
+
+ (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr),
+ (respStaAddr = linkIden->RespStaAddr))
+ : ((respStaAddr = linkIden->InitStaAddr),
+ (initStaAddr = linkIden->RespStaAddr));
+ cdf_mem_copy((uint8_t *) linkIden->bssid,
+ (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) initStaAddr,
+ psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) respStaAddr, (uint8_t *) peerMac,
+ sizeof(tSirMacAddr));
+
+ linkIden->present = 1;
+ return;
+
+}
+
+void populate_dot11f_tdls_ext_capability(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIEExtCap *extCapability)
+{
+ struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes;
+
+ p_ext_cap->tdls_peer_psm_supp = PEER_PSM_SUPPORT;
+ p_ext_cap->tdls_peer_uapsd_buffer_sta = pMac->lim.gLimTDLSBufStaEnabled;
+
+ /*
+ * Set TDLS channel switching bits only if offchannel is enabled
+ * and TDLS Channel Switching is not prohibited by AP in ExtCap
+ * IE in assoc/re-assoc response.
+ */
+ if ((1 == pMac->lim.gLimTDLSOffChannelEnabled) &&
+ (!psessionEntry->tdls_chan_swit_prohibited)) {
+ p_ext_cap->tdls_channel_switching = 1;
+ p_ext_cap->tdls_chan_swit_prohibited = 0;
+ } else {
+ p_ext_cap->tdls_channel_switching = 0;
+ p_ext_cap->tdls_chan_swit_prohibited = TDLS_CH_SWITCH_PROHIBITED;
+ }
+ p_ext_cap->tdls_support = TDLS_SUPPORT;
+ p_ext_cap->tdls_prohibited = TDLS_PROHIBITED;
+
+ extCapability->present = 1;
+ /* For STA cases we alwasy support 11mc - Allow MAX length */
+ extCapability->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+
+ return;
+}
+
+/**
+ * lim_process_sme_tdls_mgmt_send_req() - send out tdls management frames
+ *
+ * @mac_ctx - global mac context
+ * @msg - message buffer received from SME.
+ *
+ * Process Send Mgmt Request from SME and transmit to AP.
+ *
+ * Return: eSIR_SUCCESS on success, error code otherwise
+ */
+tSirRetStatus lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg)
+{
+ /* get all discovery request parameters */
+ tSirTdlsSendMgmtReq *send_req = (tSirTdlsSendMgmtReq *) msg;
+ tpPESession session_entry;
+ uint8_t session_id;
+ tSirResultCodes result_code = eSIR_SME_INVALID_PARAMETERS;
+
+ lim_log(mac_ctx, LOG1, FL("Send Mgmt Recieved"));
+ session_entry = pe_find_session_by_bssid(mac_ctx,
+ send_req->bssid, &session_id);
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGE,
+ FL("PE Session does not exist for given sme session_id %d"),
+ send_req->sessionId);
+ goto lim_tdls_send_mgmt_error;
+ }
+
+ /* check if we are in proper state to work as TDLS client */
+ if (!LIM_IS_STA_ROLE(session_entry)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ FL("send mgmt received in wrong system Role %d"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ goto lim_tdls_send_mgmt_error;
+ }
+
+ /*
+ * if we are still good, go ahead and check if we are in proper state to
+ * do TDLS discovery req/rsp/....frames.
+ */
+ if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+ lim_log(mac_ctx, LOGE,
+ FL("send mgmt received in invalid LIMsme state (%d)"),
+ session_entry->limSmeState);
+ goto lim_tdls_send_mgmt_error;
+ }
+
+ switch (send_req->reqType) {
+ case SIR_MAC_TDLS_DIS_REQ:
+ lim_log(mac_ctx, LOG1, FL("Transmit Discovery Request Frame"));
+ /* format TDLS discovery request frame and transmit it */
+ lim_send_tdls_dis_req_frame(mac_ctx, send_req->peerMac,
+ send_req->dialog, session_entry);
+ result_code = eSIR_SME_SUCCESS;
+ break;
+ case SIR_MAC_TDLS_DIS_RSP:
+ lim_log(mac_ctx, LOG1, FL("Transmit Discovery Response Frame"));
+ /* Send a response mgmt action frame */
+ lim_send_tdls_dis_rsp_frame(mac_ctx, send_req->peerMac,
+ send_req->dialog, session_entry, &send_req->addIe[0],
+ (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
+ result_code = eSIR_SME_SUCCESS;
+ break;
+ case SIR_MAC_TDLS_SETUP_REQ:
+ lim_log(mac_ctx, LOG1, FL("Transmit Setup Request Frame"));
+ lim_send_tdls_link_setup_req_frame(mac_ctx,
+ send_req->peerMac, send_req->dialog, session_entry,
+ &send_req->addIe[0],
+ (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
+ result_code = eSIR_SME_SUCCESS;
+ break;
+ case SIR_MAC_TDLS_SETUP_RSP:
+ lim_log(mac_ctx, LOG1, FL("Transmit Setup Response Frame"));
+ lim_send_tdls_setup_rsp_frame(mac_ctx,
+ send_req->peerMac, send_req->dialog, session_entry,
+ send_req->statusCode, &send_req->addIe[0],
+ (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
+ result_code = eSIR_SME_SUCCESS;
+ break;
+ case SIR_MAC_TDLS_SETUP_CNF:
+ lim_log(mac_ctx, LOG1, FL("Transmit Setup Confirm Frame"));
+ lim_send_tdls_link_setup_cnf_frame(mac_ctx,
+ send_req->peerMac, send_req->dialog,
+ send_req->peerCapability, session_entry,
+ &send_req->addIe[0],
+ (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
+ result_code = eSIR_SME_SUCCESS;
+ break;
+ case SIR_MAC_TDLS_TEARDOWN:
+ lim_log(mac_ctx, LOG1, FL("Transmit Teardown Frame"));
+ lim_send_tdls_teardown_frame(mac_ctx,
+ send_req->peerMac, send_req->statusCode,
+ send_req->responder, session_entry,
+ &send_req->addIe[0],
+ (send_req->length - sizeof(tSirTdlsSendMgmtReq)));
+ result_code = eSIR_SME_SUCCESS;
+ break;
+ case SIR_MAC_TDLS_PEER_TRAFFIC_IND:
+ break;
+ case SIR_MAC_TDLS_CH_SWITCH_REQ:
+ break;
+ case SIR_MAC_TDLS_CH_SWITCH_RSP:
+ break;
+ case SIR_MAC_TDLS_PEER_TRAFFIC_RSP:
+ break;
+ default:
+ break;
+ }
+
+lim_tdls_send_mgmt_error:
+ lim_send_sme_rsp(mac_ctx, eWNI_SME_TDLS_SEND_MGMT_RSP,
+ result_code, send_req->sessionId,
+ send_req->transactionId);
+
+ return eSIR_SUCCESS;
+}
+
+/*
+ * Send Response to Link Establish Request to SME
+ */
+void lim_send_sme_tdls_link_establish_req_rsp(tpAniSirGlobal pMac,
+ uint8_t sessionId, tSirMacAddr peerMac,
+ tDphHashNode *pStaDs, uint8_t status)
+{
+ tSirMsgQ mmhMsg = { 0 };
+
+ tSirTdlsLinkEstablishReqRsp *pTdlsLinkEstablishReqRsp = NULL;
+
+ pTdlsLinkEstablishReqRsp =
+ cdf_mem_malloc(sizeof(tSirTdlsLinkEstablishReqRsp));
+ if (NULL == pTdlsLinkEstablishReqRsp) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory"));
+ return;
+ }
+ pTdlsLinkEstablishReqRsp->statusCode = status;
+ if (peerMac) {
+ cdf_mem_copy(pTdlsLinkEstablishReqRsp->peerMac, peerMac,
+ sizeof(tSirMacAddr));
+ }
+ pTdlsLinkEstablishReqRsp->sessionId = sessionId;
+ mmhMsg.type = eWNI_SME_TDLS_LINK_ESTABLISH_RSP;
+ mmhMsg.bodyptr = pTdlsLinkEstablishReqRsp;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+
+}
+
+/*
+ * Once link is teardown, send Del Peer Ind to SME
+ */
+static CDF_STATUS lim_send_sme_tdls_del_sta_rsp(tpAniSirGlobal pMac,
+ uint8_t sessionId,
+ tSirMacAddr peerMac,
+ tDphHashNode *pStaDs, uint8_t status)
+{
+ tSirMsgQ mmhMsg = { 0 };
+ tSirTdlsDelStaRsp *pDelSta = NULL;
+ mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP;
+
+ pDelSta = cdf_mem_malloc(sizeof(tSirTdlsDelStaRsp));
+ if (NULL == pDelSta) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory"));
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ pDelSta->sessionId = sessionId;
+ pDelSta->statusCode = status;
+ if (pStaDs) {
+ pDelSta->staId = pStaDs->staIndex;
+ } else
+ pDelSta->staId = STA_INVALID_IDX;
+
+ if (peerMac) {
+ cdf_mem_copy(pDelSta->peerMac, peerMac, sizeof(tSirMacAddr));
+ }
+
+ pDelSta->length = sizeof(tSirTdlsDelStaRsp);
+ pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP;
+
+ mmhMsg.bodyptr = pDelSta;
+
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return CDF_STATUS_SUCCESS;
+
+}
+
+/*
+ * Process Send Mgmt Request from SME and transmit to AP.
+ */
+tSirRetStatus lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf)
+{
+ /* get all discovery request parameters */
+ tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq *) pMsgBuf;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+
+ lim_log(pMac, LOG1, FL("TDLS Add STA Request Recieved"));
+ psessionEntry =
+ pe_find_session_by_bssid(pMac, pAddStaReq->bssid, &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL(
+ "PE Session does not exist for given sme sessionId %d"
+ ),
+ pAddStaReq->sessionId);
+ goto lim_tdls_add_sta_error;
+ }
+
+ /* check if we are in proper state to work as TDLS client */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "send mgmt received in wrong system Role %d",
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+ goto lim_tdls_add_sta_error;
+ }
+
+ /*
+ * if we are still good, go ahead and check if we are in proper state to
+ * do TDLS discovery req/rsp/....frames.
+ */
+ if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+
+ lim_log(pMac, LOGE,
+ FL("send mgmt received in invalid LIMsme state (%d)"),
+ psessionEntry->limSmeState);
+ goto lim_tdls_add_sta_error;
+ }
+
+ pMac->lim.gLimAddStaTdls = true;
+
+ /* To start with, send add STA request to HAL */
+ if (eSIR_FAILURE == lim_tdls_setup_add_sta(pMac, pAddStaReq, psessionEntry)) {
+ lim_log(pMac, LOGE,
+ FL("Add TDLS Station request failed"));
+ goto lim_tdls_add_sta_error;
+ }
+ return eSIR_SUCCESS;
+lim_tdls_add_sta_error:
+ lim_send_sme_tdls_add_sta_rsp(pMac,
+ pAddStaReq->sessionId, pAddStaReq->peerMac,
+ (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE),
+ NULL, eSIR_FAILURE);
+
+ return eSIR_SUCCESS;
+}
+
+/*
+ * Process Del Sta Request from SME .
+ */
+tSirRetStatus lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf)
+{
+ /* get all discovery request parameters */
+ tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+ tpDphHashNode pStaDs = NULL;
+
+ lim_log(pMac, LOG1, FL("TDLS Delete STA Request Recieved"));
+ psessionEntry =
+ pe_find_session_by_bssid(pMac, pDelStaReq->bssid, &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL(
+ "PE Session does not exist for given sme sessionId %d"
+ ),
+ pDelStaReq->sessionId);
+ lim_send_sme_tdls_del_sta_rsp(pMac, pDelStaReq->sessionId,
+ pDelStaReq->peerMac, NULL,
+ eSIR_FAILURE);
+ return eSIR_FAILURE;
+ }
+
+ /* check if we are in proper state to work as TDLS client */
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ "Del sta received in wrong system Role %d",
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+ goto lim_tdls_del_sta_error;
+ }
+
+ /*
+ * if we are still good, go ahead and check if we are in proper state to
+ * do TDLS discovery req/rsp/....frames.
+ */
+ if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+
+ lim_log(pMac, LOGE,
+ FL("Del Sta received in invalid LIMsme state (%d)"),
+ psessionEntry->limSmeState);
+ goto lim_tdls_del_sta_error;
+ }
+
+ pStaDs = lim_tdls_del_sta(pMac, pDelStaReq->peerMac, psessionEntry);
+
+ /* now send indication to SME-->HDD->TL to remove STA from TL */
+
+ if (pStaDs) {
+ lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
+ pDelStaReq->peerMac, pStaDs,
+ eSIR_SUCCESS);
+ lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
+
+ /* Clear the aid in peerAIDBitmap as this aid is now in freepool */
+ CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap,
+ pStaDs->assocId);
+ lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
+ psessionEntry);
+
+ return eSIR_SUCCESS;
+
+ }
+
+lim_tdls_del_sta_error:
+ lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
+ pDelStaReq->peerMac, NULL, eSIR_FAILURE);
+
+ return eSIR_SUCCESS;
+}
+
+/* Intersects the two input arrays and outputs an array */
+/* For now the array length of uint8_t suffices */
+static void lim_tdls_get_intersection(uint8_t *input_array1,
+ uint8_t input1_length,
+ uint8_t *input_array2,
+ uint8_t input2_length,
+ uint8_t *output_array,
+ uint8_t *output_length)
+{
+ uint8_t i, j, k = 0, flag = 0;
+ for (i = 0; i < input1_length; i++) {
+ flag = 0;
+ for (j = 0; j < input2_length; j++) {
+ if (input_array1[i] == input_array2[j]) {
+ flag = 1;
+ break;
+ }
+ }
+ if (flag == 1) {
+ output_array[k] = input_array1[i];
+ k++;
+ }
+ }
+ *output_length = k;
+}
+
+/**
+ * lim_process_sme_tdls_link_establish_req() - process tdls link establishment
+ * request
+ *
+ * @mac_ctx - global MAC context
+ * @msg_buf - message buffer from SME
+ *
+ * Process Link Establishment Request from SME
+ *
+ * Return: eSIR_SUCCESS on success, failure code otherwise.
+ */
+tSirRetStatus lim_process_sme_tdls_link_establish_req(tpAniSirGlobal mac_ctx,
+ uint32_t *msg_buf)
+{
+ /* get all discovery request parameters */
+ tSirTdlsLinkEstablishReq *tdls_req =
+ (tSirTdlsLinkEstablishReq *) msg_buf;
+ tpPESession session_entry;
+ uint8_t session_id;
+ tpTdlsLinkEstablishParams tdls_req_params;
+ tSirMsgQ msg;
+ uint16_t peer_idx = 0;
+ tpDphHashNode stads = NULL;
+ uint32_t self_num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ uint8_t self_supp_chan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("Send Mgmt Recieved"));
+
+ session_entry = pe_find_session_by_bssid(mac_ctx, tdls_req->bssid,
+ &session_id);
+ if (NULL == session_entry) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ FL("PE Session does not exist for sme session_id %d"),
+ tdls_req->sessionId);
+ lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
+ tdls_req->sessionId, tdls_req->peerMac, NULL,
+ eSIR_FAILURE);
+ return eSIR_FAILURE;
+ }
+
+ /* check if we are in proper state to work as TDLS client */
+ if (!LIM_IS_STA_ROLE(session_entry)) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ FL("TDLS Link Establish Request received in wrong system Role %d"),
+ GET_LIM_SYSTEM_ROLE(session_entry));
+ goto lim_tdls_link_establish_error;
+ }
+
+ /*
+ * if we are still good, go ahead and check if we are in proper state to
+ * do TDLS discovery req/rsp/....frames.
+ */
+ if ((session_entry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (session_entry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
+ lim_log(mac_ctx, LOGE,
+ FL("TDLS Link Establish Request received in invalid LIMsme state (%d)"),
+ session_entry->limSmeState);
+ goto lim_tdls_link_establish_error;
+ }
+
+ stads = dph_lookup_hash_entry(mac_ctx, tdls_req->peerMac, &peer_idx,
+ &session_entry->dph.dphHashTable);
+ if (NULL == stads) {
+ lim_log(mac_ctx, LOGE, FL("stads is NULL"));
+ goto lim_tdls_link_establish_error;
+ }
+ tdls_req_params = cdf_mem_malloc(sizeof(tTdlsLinkEstablishParams));
+ if (NULL == tdls_req_params) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to allocate memory TDLS Link Establish Request"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set((uint8_t *) tdls_req_params,
+ sizeof(tTdlsLinkEstablishParams), 0);
+
+ tdls_req_params->staIdx = stads->staIndex;
+ tdls_req_params->isResponder = tdls_req->isResponder;
+ tdls_req_params->uapsdQueues = tdls_req->uapsdQueues;
+ tdls_req_params->maxSp = tdls_req->maxSp;
+ tdls_req_params->isBufsta = tdls_req->isBufSta;
+ tdls_req_params->isOffChannelSupported =
+ tdls_req->isOffChannelSupported;
+
+ if (0 == tdls_req->supportedChannelsLen)
+ goto send_tdls_establish_request;
+
+ if (wlan_cfg_get_str(mac_ctx, WNI_CFG_VALID_CHANNEL_LIST,
+ self_supp_chan,
+ &self_num_chan) != eSIR_SUCCESS) {
+ /**
+ * Could not get Valid channel list from CFG.
+ * Log error.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("could not retrieve Valid channel list"));
+ }
+
+ if (self_num_chan > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+ lim_log(mac_ctx, LOGE,
+ FL("Channel List more than Valid Channel list"));
+ self_num_chan = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ }
+
+ if (tdls_req->supportedChannelsLen > SIR_MAC_MAX_SUPP_CHANNELS) {
+ lim_log(mac_ctx, LOGE,
+ FL("Channel List is more than the supported Channel list"));
+ tdls_req->supportedChannelsLen = SIR_MAC_MAX_SUPP_CHANNELS;
+ }
+
+ lim_tdls_get_intersection(self_supp_chan, self_num_chan,
+ tdls_req->supportedChannels, tdls_req->supportedChannelsLen,
+ tdls_req_params->validChannels,
+ &tdls_req_params->validChannelsLen);
+
+send_tdls_establish_request:
+ cdf_mem_copy(tdls_req_params->validOperClasses,
+ tdls_req->supportedOperClasses,
+ tdls_req->supportedOperClassesLen);
+ tdls_req_params->validOperClassesLen =
+ tdls_req->supportedOperClassesLen;
+
+ msg.type = WMA_SET_TDLS_LINK_ESTABLISH_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = tdls_req_params;
+ msg.bodyval = 0;
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(mac_ctx, &msg)) {
+ lim_log(mac_ctx, LOGE, FL("halPostMsgApi failed"));
+ goto lim_tdls_link_establish_error;
+ }
+ return eSIR_SUCCESS;
+
+lim_tdls_link_establish_error:
+ lim_send_sme_tdls_link_establish_req_rsp(mac_ctx,
+ session_entry->smeSessionId, tdls_req->peerMac, NULL,
+ eSIR_FAILURE);
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_delete_tdls_peers() - delete tdls peers
+ *
+ * @mac_ctx - global MAC context
+ * @session_entry - PE session entry
+ *
+ * Delete all the TDLS peer connected before leaving the BSS
+ *
+ * Return: eSIR_SUCCESS on success, error code otherwise
+ */
+tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry)
+{
+ tpDphHashNode stads = NULL;
+ int i, aid;
+ size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap);
+
+ if (NULL == session_entry) {
+ lim_log(mac_ctx, LOGE, FL("NULL session_entry"));
+ return eSIR_FAILURE;
+ }
+
+ /*
+ * Check all the set bit in peerAIDBitmap and delete the peer
+ * (with that aid) entry from the hash table and add the aid
+ * in free pool
+ */
+ for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) {
+ for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) {
+ if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid))
+ continue;
+ stads = dph_get_hash_entry(mac_ctx,
+ (aid + i * (sizeof(uint32_t) << 3)),
+ &session_entry->dph.dphHashTable);
+
+ if (NULL != stads) {
+ lim_log(mac_ctx, LOGE,
+ FL("Deleting "MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(stads->staAddr));
+
+ lim_send_deauth_mgmt_frame(mac_ctx,
+ eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
+ stads->staAddr, session_entry, false);
+ dph_delete_hash_entry(mac_ctx,
+ stads->staAddr, stads->assocId,
+ &session_entry->dph.dphHashTable);
+ }
+ lim_release_peer_idx(mac_ctx,
+ (aid + i * (sizeof(uint32_t) << 3)),
+ session_entry);
+ CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
+ }
+ }
+ lim_send_sme_tdls_delete_all_peer_ind(mac_ctx, session_entry);
+
+ return eSIR_SUCCESS;
+}
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.c b/core/mac/src/pe/lim/lim_prop_exts_utils.c
new file mode 100644
index 0000000..d534905
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_prop_exts_utils.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_prop_exts_utils.cc contains the utility functions
+ * to populate, parse proprietary extensions required to
+ * support ANI feature set.
+ *
+ * Author: Chandra Modumudi
+ * Date: 11/27/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "sir_common.h"
+#include "sir_debug.h"
+#include "utils_api.h"
+#include "cfg_api.h"
+#include "lim_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_trace.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#define LIM_GET_NOISE_MAX_TRY 5
+/**
+ * lim_extract_ap_capability() - extract AP's HCF/WME/WSM capability
+ * @mac_ctx: Pointer to Global MAC structure
+ * @p_ie: Pointer to starting IE in Beacon/Probe Response
+ * @ie_len: Length of all IEs combined
+ * @qos_cap: Bits are set according to capabilities
+ * @prop_cap: Pointer to prop info IE.
+ * @uapsd: pointer to uapsd
+ * @local_constraint: Pointer to local power constraint.
+ * @session: A pointer to session entry.
+ *
+ * This function is called to extract AP's HCF/WME/WSM capability
+ * from the IEs received from it in Beacon/Probe Response frames
+ *
+ * Return: None
+ */
+void
+lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
+ uint16_t ie_len, uint8_t *qos_cap, uint16_t *prop_cap, uint8_t *uapsd,
+ tPowerdBm *local_constraint, tpPESession session)
+{
+ tSirProbeRespBeacon *beacon_struct;
+#if !defined WLAN_FEATURE_VOWIFI
+ uint32_t local_power_constraints = 0;
+#endif
+ uint32_t enable_txbf_20mhz;
+ tSirRetStatus cfg_set_status = eSIR_FAILURE;
+ tSirRetStatus cfg_get_status = eSIR_FAILURE;
+
+ beacon_struct = cdf_mem_malloc(sizeof(tSirProbeRespBeacon));
+ if (NULL == beacon_struct) {
+ lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) beacon_struct, sizeof(tSirProbeRespBeacon), 0);
+ *qos_cap = 0;
+ *prop_cap = 0;
+ *uapsd = 0;
+ lim_log(mac_ctx, LOG3,
+ FL("In lim_extract_ap_capability: The IE's being received:"));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG3, p_ie, ie_len);
+ if (sir_parse_beacon_ie(mac_ctx, beacon_struct, p_ie,
+ (uint32_t) ie_len) == eSIR_SUCCESS) {
+ if (beacon_struct->wmeInfoPresent
+ || beacon_struct->wmeEdcaPresent)
+ LIM_BSS_CAPS_SET(WME, *qos_cap);
+ if (LIM_BSS_CAPS_GET(WME, *qos_cap)
+ && beacon_struct->wsmCapablePresent)
+ LIM_BSS_CAPS_SET(WSM, *qos_cap);
+ if (beacon_struct->propIEinfo.capabilityPresent)
+ *prop_cap = beacon_struct->propIEinfo.capability;
+ if (beacon_struct->HTCaps.present)
+ mac_ctx->lim.htCapabilityPresentInBeacon = 1;
+ else
+ mac_ctx->lim.htCapabilityPresentInBeacon = 0;
+
+#ifdef WLAN_FEATURE_11AC
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
+ "beacon.VHTCaps.present = %d BSS_VHT_Capable:%d",
+ beacon_struct->VHTCaps.present,
+ IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps));
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO_MED,
+ "***beacon.SU Beamformer Capable*****=%d",
+ beacon_struct->VHTCaps.suBeamFormerCap);
+
+ if (IS_BSS_VHT_CAPABLE(beacon_struct->VHTCaps) &&
+ beacon_struct->VHTOperation.present &&
+ session->vhtCapability) {
+ session->vhtCapabilityPresentInBeacon = 1;
+ if (((beacon_struct->Vendor1IEPresent &&
+ beacon_struct->vendor2_ie.present &&
+ beacon_struct->Vendor3IEPresent)) &&
+ (((beacon_struct->VHTCaps.txMCSMap &
+ VHT_MCS_3x3_MASK) == VHT_MCS_3x3_MASK) &&
+ ((beacon_struct->VHTCaps.txMCSMap &
+ VHT_MCS_2x2_MASK) != VHT_MCS_2x2_MASK))) {
+ session->txBFIniFeatureEnabled = 0;
+ }
+ } else {
+ session->vhtCapabilityPresentInBeacon = 0;
+ }
+ if (session->vhtCapabilityPresentInBeacon == 1 &&
+ session->txBFIniFeatureEnabled == 0) {
+ cfg_set_status = cfg_set_int(mac_ctx,
+ WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
+ 0);
+ if (cfg_set_status != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Set VHT_SU_BEAMFORMEE_CAP Fail"));
+ }
+ if (session->vhtCapabilityPresentInBeacon == 1 &&
+ !session->htSupportedChannelWidthSet) {
+ cfg_get_status = wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
+ &enable_txbf_20mhz);
+ if ((IS_SIR_STATUS_SUCCESS(cfg_get_status)) &&
+ (false == enable_txbf_20mhz))
+ session->txBFIniFeatureEnabled = 0;
+ } else if (session->vhtCapabilityPresentInBeacon == 1 &&
+ beacon_struct->VHTOperation.chanWidth) {
+ session->ch_center_freq_seg0 =
+ beacon_struct->VHTOperation.chanCenterFreqSeg1;
+ session->ch_center_freq_seg1 =
+ beacon_struct->VHTOperation.chanCenterFreqSeg2;
+ session->ch_width =
+ beacon_struct->VHTOperation.chanWidth + 1;
+ if (CH_WIDTH_80MHZ < session->ch_width) {
+ session->enable_su_tx_bformer = 0;
+ session->nss = 1;
+ }
+ }
+ if (session->vhtCapabilityPresentInBeacon == 1 &&
+ !session->htSupportedChannelWidthSet &&
+ session->txBFIniFeatureEnabled == 0) {
+ cfg_set_status = cfg_set_int(mac_ctx,
+ WNI_CFG_VHT_SU_BEAMFORMEE_CAP,
+ 0);
+ if (cfg_set_status != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Set VHT_SU_BEAMFORMEE_CAP Fail"));
+ }
+#endif
+ /* Extract the UAPSD flag from WMM Parameter element */
+ if (beacon_struct->wmeEdcaPresent)
+ *uapsd = beacon_struct->edcaParams.qosInfo.uapsd;
+#if defined FEATURE_WLAN_ESE
+ /* If there is Power Constraint Element specifically,
+ * adapt to it. Hence there is else condition check
+ * for this if statement.
+ */
+ if (beacon_struct->eseTxPwr.present)
+ *local_constraint = beacon_struct->eseTxPwr.power_limit;
+ session->is_ese_version_ie_present =
+ beacon_struct->is_ese_ver_ie_present;
+#endif
+ if (beacon_struct->powerConstraintPresent) {
+#if defined WLAN_FEATURE_VOWIFI
+ *local_constraint -=
+ beacon_struct->localPowerConstraint.
+ localPowerConstraints;
+#else
+ local_power_constraints =
+ (uint32_t) beacon_struct->localPowerConstraint.
+ localPowerConstraints;
+#endif
+ }
+#if !defined WLAN_FEATURE_VOWIFI
+ if (cfg_set_int
+ (mac_ctx, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ local_power_constraints) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL
+ ("Could not update local power constraint to cfg."));
+ }
+#endif
+ session->country_info_present = false;
+ /* Initializing before first use */
+ if (beacon_struct->countryInfoPresent)
+ session->country_info_present = true;
+ }
+ cdf_mem_free(beacon_struct);
+ return;
+} /****** end lim_extract_ap_capability() ******/
+
+/**
+ * lim_get_htcb_state
+ *
+ ***FUNCTION:
+ * This routing provides the translation of Airgo Enum to HT enum for determining
+ * secondary channel offset.
+ * Airgo Enum is required for backward compatibility purposes.
+ *
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return The corresponding HT enumeration
+ */
+ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode)
+{
+ switch (aniCBMode) {
+#ifdef WLAN_FEATURE_11AC
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW:
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED:
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH:
+#endif
+ case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
+ return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+#ifdef WLAN_FEATURE_11AC
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW:
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED:
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH:
+#endif
+ case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
+ return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+#ifdef WLAN_FEATURE_11AC
+ case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED:
+ return PHY_SINGLE_CHANNEL_CENTERED;
+#endif
+ default:
+ return PHY_SINGLE_CHANNEL_CENTERED;
+ }
+}
+
+/*
+ * lim_get_sta_peer_type
+ *
+ ***FUNCTION:
+ * This API returns STA peer type
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pStaDs - Pointer to the tpDphHashNode of the STA
+ * under consideration
+ * @return tStaRateMode
+ */
+tStaRateMode lim_get_sta_peer_type(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs, tpPESession psessionEntry)
+{
+ tStaRateMode staPeerType = eSTA_11b;
+#ifdef WLAN_FEATURE_11AC
+ if (pStaDs->mlmStaContext.vhtCapability)
+ staPeerType = eSTA_11ac;
+#endif
+ else if (pStaDs->mlmStaContext.htCapability)
+ staPeerType = eSTA_11n;
+ else if (pStaDs->erpEnabled)
+ staPeerType = eSTA_11bg;
+ else if (psessionEntry->limRFBand == SIR_BAND_5_GHZ)
+ staPeerType = eSTA_11a;
+ return staPeerType;
+}
diff --git a/core/mac/src/pe/lim/lim_prop_exts_utils.h b/core/mac/src/pe/lim/lim_prop_exts_utils.h
new file mode 100644
index 0000000..a648a78
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_prop_exts_utils.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_prop_exts_utils.h contains the definitions
+ * used by all LIM modules to support proprietary features.
+ * Author: Chandra Modumudi
+ * Date: 12/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_PROP_EXTS_UTILS_H
+#define __LIM_PROP_EXTS_UTILS_H
+
+/* Function templates */
+void limQuietBss(tpAniSirGlobal, uint32_t);
+void lim_cleanupMeasData(tpAniSirGlobal);
+void limDeleteMeasTimers(tpAniSirGlobal);
+void limStopMeasTimers(tpAniSirGlobal pMac);
+void lim_cleanupMeasResources(tpAniSirGlobal);
+void limRestorePreLearnState(tpAniSirGlobal);
+void limCollectMeasurementData(tpAniSirGlobal, uint32_t *, tpSchBeaconStruct);
+void limCollectRSSI(tpAniSirGlobal);
+void limDeleteCurrentBssWdsNode(tpAniSirGlobal);
+uint32_t limComputeAvg(tpAniSirGlobal, uint32_t, uint32_t);
+
+/* / Function to extract AP's HCF capability from IE fields */
+void lim_extract_ap_capability(tpAniSirGlobal, uint8_t *, uint16_t, uint8_t *,
+ uint16_t *, uint8_t *, tPowerdBm *, tpPESession);
+
+tStaRateMode lim_get_sta_peer_type(tpAniSirGlobal, tpDphHashNode, tpPESession);
+#ifdef WLAN_FEATURE_11AC
+ePhyChanBondState lim_get_htcb_state(ePhyChanBondState aniCBMode);
+#endif
+
+#endif /* __LIM_PROP_EXTS_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_scan_result_utils.c b/core/mac/src/pe/lim/lim_scan_result_utils.c
new file mode 100644
index 0000000..387152e
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_scan_result_utils.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_scan_result_utils.cc contains the utility functions
+ * LIM uses for maintaining and accessing scan results on STA.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_api.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+#include "cds_utils.h"
+
+
+/**
+ * lim_collect_bss_description()
+ *
+ ***FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * frame matches scan criteria, collect BSS description
+ * and add it to cached scan results.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pBPR - Pointer to parsed Beacon/Probe Response structure
+ * @param pRxPacketInfo - Pointer to Received frame's BD
+ * ---------if defined WLAN_FEATURE_VOWIFI------
+ * @param fScanning - flag to indicate if it is during scan.
+ * ---------------------------------------------
+ *
+ * @return None
+ */
+#if defined WLAN_FEATURE_VOWIFI
+CDF_STATUS
+lim_collect_bss_description(tpAniSirGlobal pMac,
+ tSirBssDescription *pBssDescr,
+ tpSirProbeRespBeacon pBPR,
+ uint8_t *pRxPacketInfo, uint8_t fScanning)
+#else
+CDF_STATUS
+lim_collect_bss_description(tpAniSirGlobal pMac,
+ tSirBssDescription *pBssDescr,
+ tpSirProbeRespBeacon pBPR, uint8_t *pRxPacketInfo)
+#endif
+{
+ uint8_t *pBody;
+ uint32_t ieLen = 0;
+ tpSirMacMgmtHdr pHdr;
+ uint8_t channelNum;
+ uint8_t rxChannel;
+ uint8_t rfBand = 0;
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ if (SIR_MAC_B_PR_SSID_OFFSET > WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)) {
+ CDF_ASSERT(WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >=
+ SIR_MAC_B_PR_SSID_OFFSET);
+ return CDF_STATUS_E_FAILURE;
+ }
+ ieLen =
+ WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
+ rxChannel = WMA_GET_RX_CH(pRxPacketInfo);
+ pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
+ rfBand = WMA_GET_RX_RFBAND(pRxPacketInfo);
+
+ /**
+ * Length of BSS desription is without length of
+ * length itself and length of pointer that holds ieFields.
+ *
+ * tSirBssDescription
+ * +--------+---------------------------------+---------------+
+ * | length | other fields | pointer to IEs|
+ * +--------+---------------------------------+---------------+
+ * ^
+ * ieFields
+ */
+ pBssDescr->length = (uint16_t)(offsetof(tSirBssDescription, ieFields[0])
+ - sizeof(pBssDescr->length) + ieLen);
+
+ /* Copy BSS Id */
+ cdf_mem_copy((uint8_t *) &pBssDescr->bssId,
+ (uint8_t *) pHdr->bssId, sizeof(tSirMacAddr));
+
+ /* Copy Timestamp, Beacon Interval and Capability Info */
+ pBssDescr->scanSysTimeMsec = cdf_mc_timer_get_system_time();
+
+ pBssDescr->timeStamp[0] = pBPR->timeStamp[0];
+ pBssDescr->timeStamp[1] = pBPR->timeStamp[1];
+ pBssDescr->beaconInterval = pBPR->beaconInterval;
+ pBssDescr->capabilityInfo =
+ lim_get_u16((uint8_t *) &pBPR->capabilityInfo);
+
+ if (!pBssDescr->beaconInterval) {
+ lim_log(pMac, LOGW,
+ FL("Beacon Interval is ZERO, making it to default 100 "
+ MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->bssId));
+ pBssDescr->beaconInterval = 100;
+ }
+ /*
+ * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut
+ * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz
+ * band, so not relying on the 'last Scanned Channel' stored in LIM.
+ * Instead use the value returned by RXP in BD. This the the same value which HAL programs into
+ * RXP before every channel switch.
+ * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from
+ * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen.
+ * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it
+ * is not present in the beacon, we go for the channel info present in RXP.
+ * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel.
+ * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices.
+ */
+ pBssDescr->channelId = lim_get_channel_from_beacon(pMac, pBPR);
+
+ if (pBssDescr->channelId == 0) {
+ /* If the channel Id is not retrieved from Beacon, extract the channel from BD */
+ if (!rxChannel) {
+ rxChannel = pMac->lim.gLimCurrentScanChannelId;
+ }
+ pBssDescr->channelId = rxChannel;
+ }
+
+ pBssDescr->channelIdSelf = pBssDescr->channelId;
+ /* set the network type in bss description */
+ channelNum = pBssDescr->channelId;
+ pBssDescr->nwType =
+ lim_get_nw_type(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR);
+
+ /* Copy RSSI & SINR from BD */
+
+ lim_log(pMac, LOG4, "*********BSS Description for BSSID:********* ");
+ sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6);
+ sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG4,
+ (uint8_t *) pRxPacketInfo, 36);
+
+ pBssDescr->rssi = (int8_t) WMA_GET_RX_RSSI_DB(pRxPacketInfo);
+
+ /* SINR no longer reported by HW */
+ pBssDescr->sinr = 0;
+
+ pBssDescr->nReceivedTime = (uint32_t) cdf_mc_timer_get_system_ticks();
+ pBssDescr->tsf_delta = WMA_GET_RX_TSF_DELTA(pRxPacketInfo);
+
+ lim_log(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR " tsf_delta = %u"),
+ MAC_ADDR_ARRAY(pHdr->bssId), pBssDescr->tsf_delta);
+
+#if defined WLAN_FEATURE_VOWIFI
+ if (fScanning) {
+ rrm_get_start_tsf(pMac, pBssDescr->startTSF);
+ pBssDescr->parentTSF = WMA_GET_RX_TIMESTAMP(pRxPacketInfo);
+ }
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ /* MobilityDomain */
+ pBssDescr->mdie[0] = 0;
+ pBssDescr->mdie[1] = 0;
+ pBssDescr->mdie[2] = 0;
+ pBssDescr->mdiePresent = false;
+ /* If mdie is present in the probe resp we */
+ /* fill it in the bss description */
+ if (pBPR->mdiePresent) {
+ pBssDescr->mdiePresent = true;
+ pBssDescr->mdie[0] = pBPR->mdie[0];
+ pBssDescr->mdie[1] = pBPR->mdie[1];
+ pBssDescr->mdie[2] = pBPR->mdie[2];
+ }
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ pBssDescr->QBSSLoad_present = false;
+ pBssDescr->QBSSLoad_avail = 0;
+ if (pBPR->QBSSLoad.present) {
+ pBssDescr->QBSSLoad_present = true;
+ pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail;
+ }
+#endif
+ /* Copy IE fields */
+ cdf_mem_copy((uint8_t *) &pBssDescr->ieFields,
+ pBody + SIR_MAC_B_PR_SSID_OFFSET, ieLen);
+
+ /*set channel number in beacon in case it is not present */
+ pBPR->channelNumber = pBssDescr->channelId;
+
+ lim_log(pMac, LOG3,
+ FL("Collected BSS Description for Channel(%1d), length(%u), IE Fields(%u)"),
+ pBssDescr->channelId, pBssDescr->length, ieLen);
+
+ return CDF_STATUS_SUCCESS;
+} /*** end lim_collect_bss_description() ***/
+
+/**
+ * lim_is_scan_requested_ssid()
+ *
+ ***FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * SSID is present in the list of requested SSIDs in scan
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param ssId - SSID Received in beacons/Probe responses that is compared against the
+ requeusted SSID in scan list
+ * ---------------------------------------------
+ *
+ * @return bool - true if SSID is present in requested list, false otherwise
+ */
+
+bool lim_is_scan_requested_ssid(tpAniSirGlobal pMac, tSirMacSSid *ssId)
+{
+ uint8_t i = 0;
+
+ for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++) {
+ if (true == cdf_mem_compare((uint8_t *) ssId,
+ (uint8_t *) &pMac->lim.
+ gpLimMlmScanReq->ssId[i],
+ (uint8_t) (pMac->lim.
+ gpLimMlmScanReq->ssId[i].
+ length + 1))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * lim_check_and_add_bss_description()
+ * @mac_ctx: Pointer to Global MAC structure
+ * @bpr: Pointer to parsed Beacon/Probe Response structure
+ * @rx_packet_info: Pointer to Received frame's BD
+ * @scanning: bool to indicate whether the BSS is from current scan
+ * or just happens to receive a beacon
+ *
+ * FUNCTION:
+ * This function is called during scan upon receiving
+ * Beacon/Probe Response frame to check if the received
+ * frame matches scan criteria, collect BSS description
+ * and add it to cached scan results.
+ *
+ * Return: None
+ */
+
+void
+lim_check_and_add_bss_description(tpAniSirGlobal mac_ctx,
+ tpSirProbeRespBeacon bpr, uint8_t *rx_packet_info,
+ bool scanning, uint8_t fProbeRsp)
+{
+ tSirBssDescription *bssdescr = NULL;
+ uint32_t frame_len, ie_len = 0;
+ uint8_t rx_chan_in_beacon = 0;
+ CDF_STATUS status;
+ uint8_t dont_update_all = 0;
+ uint8_t rf_band = 0;
+ uint8_t rx_chan_bd = 0;
+
+ tSirMacAddr bssid_zero = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ tpSirMacDataHdr3a hdr;
+
+ hdr = WMA_GET_RX_MPDUHEADER3A((uint8_t *) rx_packet_info);
+
+ /* Check For Null BSSID and Skip in case of P2P */
+ if (cdf_mem_compare(bssid_zero, &hdr->addr3, 6))
+ return;
+
+ /*
+ * SSID/BSSID policy:
+ * Accept beacons/probe responses with any SSID or BSSID because
+ * multiple scan requests may be running at the same time and
+ * firmware may forward results to CLD from scans requested through a
+ * different path.
+ *
+ * CSA Policy:
+ * There is no point in caching & reporting the scan results for APs
+ * which are in the process of switching the channel. So, we are not
+ * caching the scan results for APs which are adverzing the
+ * channel-switch element in their beacons and probe responses.
+ */
+ if (bpr->channelSwitchPresent)
+ return;
+
+ /*
+ * If beacon/probe resp DS param channel does not match with
+ * RX BD channel then don't save the results. It might be a beacon
+ * from another channel heard as noise on the current scanning channel
+ */
+
+ if ((bpr->dsParamsPresent) || (bpr->HTInfo.present)) {
+ /* This means that we are in 2.4GHz mode or 5GHz 11n mode */
+ rx_chan_in_beacon = lim_get_channel_from_beacon(mac_ctx, bpr);
+ rf_band = WMA_GET_RX_RFBAND(rx_packet_info);
+ rx_chan_bd = WMA_GET_RX_CH(rx_packet_info);
+
+ if (rx_chan_bd != rx_chan_in_beacon) {
+ /* BCAST Frame, if CH do not match, Drop */
+ if (WMA_IS_RX_BCAST(rx_packet_info)) {
+ lim_log(mac_ctx, LOG3,
+ FL("Beacon/Probe Rsp dropped. Channel in BD %d. Channel in beacon %d"),
+ WMA_GET_RX_CH(rx_packet_info),
+ lim_get_channel_from_beacon(mac_ctx,
+ bpr));
+ return;
+ }
+ /* Unit cast frame, Probe RSP, do not drop */
+ else {
+ dont_update_all = 1;
+ lim_log(mac_ctx, LOG3,
+ FL("SSID %s, CH in ProbeRsp %d, CH in BD %d, mismatch, Do Not Drop"),
+ bpr->ssId.ssId, rx_chan_in_beacon,
+ WMA_GET_RX_CH(rx_packet_info));
+ WMA_GET_RX_CH(rx_packet_info) =
+ rx_chan_in_beacon;
+ }
+ }
+ }
+
+ /*
+ * Allocate buffer to hold BSS description from
+ * received Beacon frame.
+ * Include size of fixed fields and IEs length
+ */
+
+ ie_len = WMA_GET_RX_PAYLOAD_LEN(rx_packet_info);
+ if (ie_len <= SIR_MAC_B_PR_SSID_OFFSET) {
+ lim_log(mac_ctx, LOGP,
+ FL("RX packet has invalid length %d"), ie_len);
+ return;
+ }
+
+ ie_len -= SIR_MAC_B_PR_SSID_OFFSET;
+
+ /* IEs will be overlap ieFields field. Adjust the length accordingly */
+ frame_len = sizeof(*bssdescr) + ie_len - sizeof(bssdescr->ieFields[1]);
+ bssdescr = (tSirBssDescription *) cdf_mem_malloc(frame_len);
+
+ if (NULL == bssdescr) {
+ /* Log error */
+ lim_log(mac_ctx, LOGE,
+ FL("cdf_mem_malloc(length=%d) failed"), frame_len);
+ return;
+ }
+ /* In scan state, store scan result. */
+#if defined WLAN_FEATURE_VOWIFI
+ status = lim_collect_bss_description(mac_ctx, bssdescr,
+ bpr, rx_packet_info, scanning);
+ if (CDF_STATUS_SUCCESS != status)
+ goto last;
+#else
+ status = lim_collect_bss_description(mac_ctx, bssdescr,
+ bpr, rx_packet_info);
+ if (CDF_STATUS_SUCCESS != status)
+ goto last;
+#endif
+ bssdescr->fProbeRsp = fProbeRsp;
+
+ /*
+ * Send the beacon to CSR with registered callback routine.
+ * scan_id and flags parameters are currently unused and set to 0.
+ */
+ if (mac_ctx->lim.add_bssdescr_callback) {
+ (mac_ctx->lim.add_bssdescr_callback) (mac_ctx, bssdescr, 0, 0);
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("No CSR callback routine to send beacons"));
+ status = CDF_STATUS_E_INVAL;
+ }
+last:
+ cdf_mem_free(bssdescr);
+ return;
+}
+
diff --git a/core/mac/src/pe/lim/lim_scan_result_utils.h b/core/mac/src/pe/lim/lim_scan_result_utils.h
new file mode 100644
index 0000000..c622dc2
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_scan_result_utils.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_scan_result_utils.h contains the utility definitions
+ * LIM uses for maintaining and accessing scan results on STA.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SCAN_UTILS_H
+#define __LIM_SCAN_UTILS_H
+
+#include "parser_api.h"
+#include "lim_types.h"
+
+/* Scan result hash related functions */
+uint8_t lim_scan_hash_function(tSirMacAddr);
+void lim_restore_pre_scan_state(tpAniSirGlobal);
+void lim_copy_scan_result(tpAniSirGlobal, uint8_t *);
+void lim_check_and_add_bss_description(tpAniSirGlobal, tpSirProbeRespBeacon,
+ uint8_t *, bool, uint8_t);
+#if defined WLAN_FEATURE_VOWIFI
+CDF_STATUS lim_collect_bss_description(tpAniSirGlobal,
+ tSirBssDescription *,
+ tpSirProbeRespBeacon, uint8_t *, uint8_t);
+#else
+CDF_STATUS lim_collect_bss_description(tpAniSirGlobal,
+ tSirBssDescription *,
+ tpSirProbeRespBeacon, uint8_t *);
+#endif
+
+#endif /* __LIM_SCAN_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c
new file mode 100644
index 0000000..ae0a422
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_security_utils.c
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_utils.cc contains the utility functions
+ * LIM uses.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "ani_global.h"
+#include "wni_api.h"
+
+#include "sir_common.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+
+#define LIM_SEED_LENGTH 16
+/*
+ * preauth node timeout value in interval of 10msec
+ */
+#define LIM_OPENAUTH_TIMEOUT 500
+
+/**
+ * lim_is_auth_algo_supported()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed authentication algorithm is enabled
+ * or not
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param authType Indicates MAC based authentication type
+ * (eSIR_OPEN_SYSTEM or eSIR_SHARED_KEY)
+ * If Shared Key authentication to be used,
+ * 'Privacy Option Implemented' flag is also
+ * checked.
+ *
+ * @return true if passed authType is enabled else false
+ */
+uint8_t
+lim_is_auth_algo_supported(tpAniSirGlobal pMac, tAniAuthType authType,
+ tpPESession psessionEntry)
+{
+ uint32_t algoEnable, privacyOptImp;
+
+ if (authType == eSIR_OPEN_SYSTEM) {
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if ((psessionEntry->authType == eSIR_OPEN_SYSTEM)
+ || (psessionEntry->authType == eSIR_AUTO_SWITCH))
+ return true;
+ else
+ return false;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE,
+ &algoEnable) != eSIR_SUCCESS) {
+ /**
+ * Could not get AuthAlgo1 Enable value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve AuthAlgo1 Enable value"));
+
+ return false;
+ } else
+ return ((algoEnable > 0 ? true : false));
+ } else {
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if ((psessionEntry->authType == eSIR_SHARED_KEY)
+ || (psessionEntry->authType == eSIR_AUTO_SWITCH))
+ algoEnable = true;
+ else
+ algoEnable = false;
+
+ } else
+
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_SHARED_KEY_AUTH_ENABLE,
+ &algoEnable) != eSIR_SUCCESS) {
+ /**
+ * Could not get AuthAlgo2 Enable value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL("could not retrieve AuthAlgo2 Enable value"));
+
+ return false;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ privacyOptImp = psessionEntry->privacy;
+ } else
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &privacyOptImp) != eSIR_SUCCESS)
+ {
+ /**
+ * Could not get PrivacyOptionImplemented value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGE,
+ FL
+ ("could not retrieve PrivacyOptImplemented value"));
+
+ return false;
+ }
+ return (algoEnable && privacyOptImp);
+ }
+} /****** end lim_is_auth_algo_supported() ******/
+
+/**
+ * lim_init_pre_auth_list
+ *
+ ***FUNCTION:
+ * This function is called while starting a BSS at AP
+ * to initialize MAC authenticated STA list. This may also be called
+ * while joining/starting an IBSS if MAC authentication is allowed
+ * in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_init_pre_auth_list(tpAniSirGlobal pMac)
+{
+ pMac->lim.pLimPreAuthList = NULL;
+
+} /*** end lim_init_pre_auth_list() ***/
+
+/**
+ * lim_delete_pre_auth_list
+ *
+ ***FUNCTION:
+ * This function is called cleanup Pre-auth list either on
+ * AP or on STA when moving from one persona to other.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_delete_pre_auth_list(tpAniSirGlobal pMac)
+{
+ struct tLimPreAuthNode *pCurrNode, *pTempNode;
+
+ pCurrNode = pTempNode = pMac->lim.pLimPreAuthList;
+ while (pCurrNode != NULL) {
+ pTempNode = pCurrNode->next;
+
+ PELOG1(lim_log(pMac, LOG1, FL("=====> lim_delete_pre_auth_list "));)
+ lim_release_pre_auth_node(pMac, pCurrNode);
+
+ pCurrNode = pTempNode;
+ }
+ pMac->lim.pLimPreAuthList = NULL;
+} /*** end lim_delete_pre_auth_list() ***/
+
+/**
+ * lim_search_pre_auth_list
+ *
+ ***FUNCTION:
+ * This function is called when Authentication frame is received
+ * by AP (or at a STA in IBSS supporting MAC based authentication)
+ * to search if a STA is in the middle of MAC Authentication
+ * transaction sequence.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param macAddr - MAC address of the STA that sent
+ * Authentication frame.
+ *
+ * @return Pointer to pre-auth node if found, else NULL
+ */
+
+struct tLimPreAuthNode *lim_search_pre_auth_list(tpAniSirGlobal pMac,
+ tSirMacAddr macAddr)
+{
+ struct tLimPreAuthNode *pTempNode = pMac->lim.pLimPreAuthList;
+
+ while (pTempNode != NULL) {
+ if (cdf_mem_compare((uint8_t *) macAddr,
+ (uint8_t *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr)))
+ break;
+
+ pTempNode = pTempNode->next;
+ }
+
+ return pTempNode;
+} /*** end lim_search_pre_auth_list() ***/
+
+/**
+ * lim_delete_open_auth_pre_auth_node() - delete any stale preauth nodes
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * This function is called to delete any stale preauth nodes on
+ * receiving authentication frame and existing preauth nodes
+ * reached the maximum allowed limit.
+ *
+ * Return: return true if any preauthnode deleted else false
+ */
+uint8_t
+lim_delete_open_auth_pre_auth_node(tpAniSirGlobal mac_ctx)
+{
+ struct tLimPreAuthNode *prev_node, *temp_node, *found_node;
+ uint8_t auth_node_freed = false;
+
+ temp_node = prev_node = mac_ctx->lim.pLimPreAuthList;
+
+ if (temp_node == NULL)
+ return auth_node_freed;
+
+ while (temp_node != NULL) {
+ if (temp_node->mlmState == eLIM_MLM_AUTHENTICATED_STATE &&
+ temp_node->authType == eSIR_OPEN_SYSTEM &&
+ (cdf_mc_timer_get_system_ticks() >
+ (LIM_OPENAUTH_TIMEOUT + temp_node->timestamp) ||
+ cdf_mc_timer_get_system_ticks() < temp_node->timestamp)) {
+ /* Found node to be deleted */
+ auth_node_freed = true;
+ found_node = temp_node;
+ if (mac_ctx->lim.pLimPreAuthList == temp_node) {
+ prev_node = mac_ctx->lim.pLimPreAuthList =
+ temp_node = found_node->next;
+ } else {
+ prev_node->next = temp_node->next;
+ temp_node = prev_node->next;
+ }
+
+ lim_release_pre_auth_node(mac_ctx, found_node);
+ } else {
+ prev_node = temp_node;
+ temp_node = prev_node->next;
+ }
+ }
+
+ return auth_node_freed;
+}
+
+/**
+ * lim_add_pre_auth_node
+ *
+ ***FUNCTION:
+ * This function is called at AP while sending Authentication
+ * frame2.
+ * This may also be called on a STA in IBSS if MAC authentication is
+ * allowed in IBSS mode.
+ *
+ ***LOGIC:
+ * Node is always added to the front of the list
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAuthNode - Pointer to pre-auth node to be added to the list.
+ *
+ * @return None
+ */
+
+void lim_add_pre_auth_node(tpAniSirGlobal pMac, struct tLimPreAuthNode *pAuthNode)
+{
+ pMac->lim.gLimNumPreAuthContexts++;
+
+ pAuthNode->next = pMac->lim.pLimPreAuthList;
+
+ pMac->lim.pLimPreAuthList = pAuthNode;
+} /*** end lim_add_pre_auth_node() ***/
+
+/**
+ * lim_release_pre_auth_node
+ *
+ ***FUNCTION:
+ * This function is called to realease the accquired
+ * pre auth node from list.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param pAuthNode - Pointer to Pre Auth node to be released
+ * @return None
+ */
+
+void lim_release_pre_auth_node(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode)
+{
+ pAuthNode->fFree = 1;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION,
+ eLIM_PRE_AUTH_CLEANUP_TIMER));
+ tx_timer_deactivate(&pAuthNode->timer);
+ pMac->lim.gLimNumPreAuthContexts--;
+} /*** end lim_release_pre_auth_node() ***/
+
+/**
+ * lim_delete_pre_auth_node
+ *
+ ***FUNCTION:
+ * This function is called at AP when a pre-authenticated STA is
+ * Associated/Reassociated or when AuthFrame4 is received after
+ * Auth Response timeout.
+ * This may also be called on a STA in IBSS if MAC authentication and
+ * Association/Reassociation is allowed in IBSS mode.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param peerMacAddr - MAC address of the STA that need to be deleted
+ * from pre-auth node list.
+ *
+ * @return None
+ */
+
+void lim_delete_pre_auth_node(tpAniSirGlobal pMac, tSirMacAddr macAddr)
+{
+ struct tLimPreAuthNode *pPrevNode, *pTempNode;
+
+ pTempNode = pPrevNode = pMac->lim.pLimPreAuthList;
+
+ if (pTempNode == NULL)
+ return;
+
+ if (cdf_mem_compare((uint8_t *) macAddr,
+ (uint8_t *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr))) {
+ /* First node to be deleted */
+
+ pMac->lim.pLimPreAuthList = pTempNode->next;
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("=====> lim_delete_pre_auth_node : first node to delete"));
+ )
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("Release data entry: %x id %d peer "), pTempNode,
+ pTempNode->authNodeIdx);
+ lim_print_mac_addr(pMac, macAddr, LOG1);
+ )
+ lim_release_pre_auth_node(pMac, pTempNode);
+
+ return;
+ }
+
+ pTempNode = pTempNode->next;
+
+ while (pTempNode != NULL) {
+ if (cdf_mem_compare((uint8_t *) macAddr,
+ (uint8_t *) &pTempNode->peerMacAddr,
+ sizeof(tSirMacAddr))) {
+ /* Found node to be deleted */
+
+ pPrevNode->next = pTempNode->next;
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("=====> lim_delete_pre_auth_node : subsequent node to delete"));
+ lim_log(pMac, LOG1,
+ FL("Release data entry: %x id %d peer "),
+ pTempNode, pTempNode->authNodeIdx);
+ lim_print_mac_addr(pMac, macAddr, LOG1);
+ )
+ lim_release_pre_auth_node(pMac, pTempNode);
+
+ return;
+ }
+
+ pPrevNode = pTempNode;
+ pTempNode = pTempNode->next;
+ }
+
+ /* Should not be here */
+ /* Log error */
+ lim_log(pMac, LOGP, FL("peer not found in pre-auth list, addr= "));
+ lim_print_mac_addr(pMac, macAddr, LOGP);
+
+} /*** end lim_delete_pre_auth_node() ***/
+
+/**
+ * limRestoreFromPreAuthState
+ *
+ ***FUNCTION:
+ * This function is called on STA whenever an Authentication
+ * sequence is complete and state prior to auth need to be
+ * restored.
+ *
+ ***LOGIC:
+ * MLM_AUTH_CNF is prepared and sent to SME state machine.
+ * In case of restoring from pre-auth:
+ * - Channel Id is programmed at LO/RF synthesizer
+ * - BSSID is programmed at RHP
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param resultCode - result of authentication attempt
+ * @return None
+ */
+
+void
+lim_restore_from_auth_state(tpAniSirGlobal pMac, tSirResultCodes resultCode,
+ uint16_t protStatusCode, tpPESession sessionEntry)
+{
+ tSirMacAddr currentBssId;
+ tLimMlmAuthCnf mlmAuthCnf;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_AUTH_COMP_EVENT, sessionEntry,
+ resultCode, protStatusCode);
+#endif
+
+ cdf_mem_copy((uint8_t *) &mlmAuthCnf.peerMacAddr,
+ (uint8_t *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType;
+ mlmAuthCnf.resultCode = resultCode;
+ mlmAuthCnf.protStatusCode = protStatusCode;
+
+ /* Update PE session ID */
+ mlmAuthCnf.sessionId = sessionEntry->peSessionId;
+
+ /* / Free up buffer allocated */
+ /* / for pMac->lim.gLimMlmAuthReq */
+ cdf_mem_free(pMac->lim.gpLimMlmAuthReq);
+ pMac->lim.gpLimMlmAuthReq = NULL;
+
+ sessionEntry->limMlmState = sessionEntry->limPrevMlmState;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId,
+ sessionEntry->limMlmState));
+
+ /* 'Change' timer for future activations */
+ lim_deactivate_and_change_timer(pMac, eLIM_AUTH_FAIL_TIMER);
+
+ sir_copy_mac_addr(currentBssId, sessionEntry->bssId);
+
+ if (sessionEntry->limSmeState == eLIM_SME_WT_PRE_AUTH_STATE) {
+ pMac->lim.gLimPreAuthChannelNumber = 0;
+ }
+
+ lim_post_sme_message(pMac, LIM_MLM_AUTH_CNF, (uint32_t *) &mlmAuthCnf);
+} /*** end lim_restore_from_auth_state() ***/
+
+/**
+ * lim_encrypt_auth_frame()
+ *
+ ***FUNCTION:
+ * This function is called in lim_process_auth_frame() function
+ * to encrypt Authentication frame3 body.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param keyId key id to used
+ * @param pKey Pointer to the key to be used for encryption
+ * @param pPlainText Pointer to the body to be encrypted
+ * @param pEncrBody Pointer to the encrypted auth frame body
+ * @param keyLength 8 (WEP40) or 16 (WEP104)
+ * @return None
+ */
+
+void
+lim_encrypt_auth_frame(tpAniSirGlobal pMac, uint8_t keyId, uint8_t *pKey,
+ uint8_t *pPlainText, uint8_t *pEncrBody,
+ uint32_t keyLength)
+{
+ uint8_t seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+
+ keyLength += 3;
+
+ /* Bytes 3-7 of seed is key */
+ cdf_mem_copy((uint8_t *) &seed[3], pKey, keyLength - 3);
+
+ /* Compute CRC-32 and place them in last 4 bytes of plain text */
+ lim_compute_crc32(icv, pPlainText, sizeof(tSirMacAuthFrameBody));
+
+ cdf_mem_copy(pPlainText + sizeof(tSirMacAuthFrameBody),
+ icv, SIR_MAC_WEP_ICV_LENGTH);
+
+ /* Run RC4 on plain text with the seed */
+ lim_rc4(pEncrBody + SIR_MAC_WEP_IV_LENGTH,
+ (uint8_t *) pPlainText, seed, keyLength,
+ LIM_ENCR_AUTH_BODY_LEN - SIR_MAC_WEP_IV_LENGTH);
+
+ /* Prepare IV */
+ pEncrBody[0] = seed[0];
+ pEncrBody[1] = seed[1];
+ pEncrBody[2] = seed[2];
+ pEncrBody[3] = keyId << 6;
+} /****** end lim_encrypt_auth_frame() ******/
+
+/**
+ * lim_compute_crc32()
+ *
+ ***FUNCTION:
+ * This function is called to compute CRC-32 on a given source.
+ * Used while encrypting/decrypting Authentication frame 3.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pDest Destination location for computed CRC
+ * @param pSrc Source location to be CRC computed
+ * @param len Length over which CRC to be computed
+ * @return None
+ */
+
+void lim_compute_crc32(uint8_t *pDest, uint8_t *pSrc, uint8_t len)
+{
+ uint32_t crc;
+ int i;
+
+ crc = 0;
+ crc = ~crc;
+
+ while (len-- > 0)
+ crc = lim_crc_update(crc, *pSrc++);
+
+ crc = ~crc;
+
+ for (i = 0; i < SIR_MAC_WEP_IV_LENGTH; i++) {
+ pDest[i] = (uint8_t) crc;
+ crc >>= 8;
+ }
+} /****** end lim_compute_crc32() ******/
+
+/**
+ * lim_rc4()
+ *
+ ***FUNCTION:
+ * This function is called to run RC4 algorithm. Called while
+ * encrypting/decrypting Authentication frame 3.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pDest Destination location for encrypted text
+ * @param pSrc Source location to be encrypted
+ * @param seed Contains seed (IV + key) for PRNG
+ * @param keyLength 8 (WEP40) or 16 (WEP104)
+ * @param frameLen Length of the frame
+ *
+ * @return None
+ */
+
+void
+lim_rc4(uint8_t *pDest, uint8_t *pSrc, uint8_t *seed, uint32_t keyLength,
+ uint16_t frameLen)
+{
+ typedef struct {
+ uint8_t i, j;
+ uint8_t sbox[256];
+ } tRC4Context;
+
+ tRC4Context ctx;
+
+ {
+ uint16_t i, j, k;
+
+ /* */
+ /* Initialize sbox using seed */
+ /* */
+
+ ctx.i = ctx.j = 0;
+ for (i = 0; i < 256; i++)
+ ctx.sbox[i] = (uint8_t) i;
+
+ j = 0;
+ k = 0;
+ for (i = 0; i < 256; i++) {
+ uint8_t temp;
+ if (k < LIM_SEED_LENGTH)
+ j = (uint8_t) (j + ctx.sbox[i] + seed[k]);
+ temp = ctx.sbox[i];
+ ctx.sbox[i] = ctx.sbox[j];
+ ctx.sbox[j] = temp;
+
+ if (++k >= keyLength)
+ k = 0;
+ }
+ }
+
+ {
+ uint8_t i = ctx.i;
+ uint8_t j = ctx.j;
+ uint8_t len = (uint8_t) frameLen;
+
+ while (len-- > 0) {
+ uint8_t temp1, temp2;
+
+ i = (uint8_t) (i + 1);
+ temp1 = ctx.sbox[i];
+ j = (uint8_t) (j + temp1);
+
+ ctx.sbox[i] = temp2 = ctx.sbox[j];
+ ctx.sbox[j] = temp1;
+
+ temp1 = (uint8_t) (temp1 + temp2);
+ temp1 = ctx.sbox[temp1];
+ temp2 = (uint8_t) (pSrc ? *pSrc++ : 0);
+
+ *pDest++ = (uint8_t) (temp1 ^ temp2);
+ }
+
+ ctx.i = i;
+ ctx.j = j;
+ }
+} /****** end lim_rc4() ******/
+
+/**
+ * lim_decrypt_auth_frame()
+ *
+ ***FUNCTION:
+ * This function is called in lim_process_auth_frame() function
+ * to decrypt received Authentication frame3 body.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pKey Pointer to the key to be used for decryption
+ * @param pEncrBody Pointer to the body to be decrypted
+ * @param pPlainBody Pointer to the decrypted body
+ * @param keyLength 8 (WEP40) or 16 (WEP104)
+ *
+ * @return Decrypt result - eSIR_SUCCESS for success and
+ * LIM_DECRYPT_ICV_FAIL for ICV mismatch.
+ * If decryption is a success, pBody will
+ * have decrypted auth frame body.
+ */
+
+uint8_t
+lim_decrypt_auth_frame(tpAniSirGlobal pMac, uint8_t *pKey, uint8_t *pEncrBody,
+ uint8_t *pPlainBody, uint32_t keyLength, uint16_t frameLen)
+{
+ uint8_t seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH];
+ int i;
+ keyLength += 3;
+
+ /* Bytes 0-2 of seed is received IV */
+ cdf_mem_copy((uint8_t *) seed, pEncrBody, SIR_MAC_WEP_IV_LENGTH - 1);
+
+ /* Bytes 3-7 of seed is key */
+ cdf_mem_copy((uint8_t *) &seed[3], pKey, keyLength - 3);
+
+ /* Run RC4 on encrypted text with the seed */
+ lim_rc4(pPlainBody,
+ pEncrBody + SIR_MAC_WEP_IV_LENGTH, seed, keyLength, frameLen);
+
+ PELOG4(lim_log(pMac, LOG4, FL("plainbody is "));
+ sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG4, pPlainBody, frameLen);
+ )
+ /* Compute CRC-32 and place them in last 4 bytes of encrypted body */
+ lim_compute_crc32(icv,
+ (uint8_t *) pPlainBody,
+ (uint8_t) (frameLen - SIR_MAC_WEP_ICV_LENGTH));
+
+ /* Compare RX_ICV with computed ICV */
+ for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++) {
+ PELOG4(lim_log
+ (pMac, LOG4, FL(" computed ICV%d[%x], rxed ICV%d[%x]"),
+ i, icv[i], i,
+ pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]);
+ )
+ if (icv[i] !=
+ pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i])
+ return LIM_DECRYPT_ICV_FAIL;
+ }
+
+ return eSIR_SUCCESS;
+} /****** end lim_decrypt_auth_frame() ******/
+
+/**
+ * lim_post_sme_set_keys_cnf
+ *
+ * A utility API to send MLM_SETKEYS_CNF to SME
+ */
+void lim_post_sme_set_keys_cnf(tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ tLimMlmSetKeysCnf *mlmSetKeysCnf)
+{
+ /* Prepare and Send LIM_MLM_SETKEYS_CNF */
+ cdf_mem_copy((uint8_t *) &mlmSetKeysCnf->peerMacAddr,
+ (uint8_t *) pMlmSetKeysReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy((uint8_t *) &mlmSetKeysCnf->peerMacAddr,
+ (uint8_t *) pMlmSetKeysReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+
+ /* / Free up buffer allocated for mlmSetKeysReq */
+ cdf_mem_free(pMlmSetKeysReq);
+ pMac->lim.gpLimMlmSetKeysReq = NULL;
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_SETKEYS_CNF, (uint32_t *) mlmSetKeysCnf);
+}
+
+/**
+ * lim_send_set_bss_key_req()
+ *
+ ***FUNCTION:
+ * This function is called from lim_process_mlm_set_keys_req(),
+ * when PE is trying to setup the Group Keys related
+ * to a specified encryption type
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer
+ * @return none
+ */
+void lim_send_set_bss_key_req(tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpSetBssKeyParams pSetBssKeyParams = NULL;
+ tLimMlmSetKeysCnf mlmSetKeysCnf;
+ tSirRetStatus retCode;
+ uint32_t val = 0;
+
+ if (pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+ lim_log(pMac, LOG1,
+ FL
+ ("numKeys = %d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS"),
+ pMlmSetKeysReq->numKeys);
+
+ /* Respond to SME with error code */
+ mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ /* Package WMA_SET_BSSKEY_REQ message parameters */
+
+ pSetBssKeyParams = cdf_mem_malloc(sizeof(tSetBssKeyParams));
+ if (NULL == pSetBssKeyParams) {
+ lim_log(pMac, LOGE,
+ FL("Unable to allocate memory during SET_BSSKEY"));
+
+ /* Respond to SME with error code */
+ mlmSetKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ goto end;
+ } else
+ cdf_mem_set((void *)pSetBssKeyParams,
+ sizeof(tSetBssKeyParams), 0);
+
+ /* Update the WMA_SET_BSSKEY_REQ parameters */
+ pSetBssKeyParams->bssIdx = psessionEntry->bssIdx;
+ pSetBssKeyParams->encType = pMlmSetKeysReq->edType;
+
+ if (eSIR_SUCCESS != wlan_cfg_get_int(pMac, WNI_CFG_SINGLE_TID_RC, &val)) {
+ lim_log(pMac, LOGP, FL("Unable to read WNI_CFG_SINGLE_TID_RC"));
+ }
+
+ pSetBssKeyParams->singleTidRc = (uint8_t) val;
+
+ /* Update PE session Id */
+ pSetBssKeyParams->sessionId = psessionEntry->peSessionId;
+
+ pSetBssKeyParams->smesessionId = pMlmSetKeysReq->smesessionId;
+
+ if (pMlmSetKeysReq->key[0].keyId &&
+ ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) ||
+ (pMlmSetKeysReq->edType == eSIR_ED_WEP104))
+ ) {
+ /* IF the key id is non-zero and encryption type is WEP, Send all the 4
+ * keys to HAL with filling the key at right index in pSetBssKeyParams->key. */
+ pSetBssKeyParams->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+ cdf_mem_copy((uint8_t *) &pSetBssKeyParams->
+ key[pMlmSetKeysReq->key[0].keyId],
+ (uint8_t *) &pMlmSetKeysReq->key[0],
+ sizeof(pMlmSetKeysReq->key[0]));
+
+ } else {
+ pSetBssKeyParams->numKeys = pMlmSetKeysReq->numKeys;
+ cdf_mem_copy((uint8_t *) &pSetBssKeyParams->key,
+ (uint8_t *) &pMlmSetKeysReq->key,
+ sizeof(tSirKeys) * pMlmSetKeysReq->numKeys);
+ }
+
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ msgQ.type = WMA_SET_BSSKEY_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pSetBssKeyParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOGW, FL("Sending WMA_SET_BSSKEY_REQ..."));
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ if (eSIR_SUCCESS != (retCode = wma_post_ctrl_msg(pMac, &msgQ))) {
+ lim_log(pMac, LOGE,
+ FL("Posting SET_BSSKEY to HAL failed, reason=%X"),
+ retCode);
+
+ /* Respond to SME with LIM_MLM_SETKEYS_CNF */
+ mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ } else
+ return; /* Continue after WMA_SET_BSSKEY_RSP... */
+
+end:
+ lim_post_sme_set_keys_cnf(pMac, pMlmSetKeysReq, &mlmSetKeysCnf);
+
+}
+
+/**
+ * @function : lim_send_set_sta_key_req()
+ *
+ * @brief : This function is called from lim_process_mlm_set_keys_req(),
+ * when PE is trying to setup the Unicast Keys related
+ * to a specified STA with specified encryption type
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer
+ * @param staIdx STA index for which the keys are being set
+ * @param defWEPIdx The default WEP key index [0..3]
+ * @return none
+ */
+void lim_send_set_sta_key_req(tpAniSirGlobal pMac,
+ tLimMlmSetKeysReq *pMlmSetKeysReq,
+ uint16_t staIdx,
+ uint8_t defWEPIdx,
+ tpPESession sessionEntry, bool sendRsp)
+{
+ tSirMsgQ msgQ;
+ tpSetStaKeyParams pSetStaKeyParams = NULL;
+ tLimMlmSetKeysCnf mlmSetKeysCnf;
+ tSirRetStatus retCode;
+ uint32_t val = 0;
+
+ /* Package WMA_SET_STAKEY_REQ message parameters */
+ pSetStaKeyParams = cdf_mem_malloc(sizeof(tSetStaKeyParams));
+ if (NULL == pSetStaKeyParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during SET_BSSKEY"));
+ return;
+ } else
+ cdf_mem_set((void *)pSetStaKeyParams, sizeof(tSetStaKeyParams),
+ 0);
+
+ /* Update the WMA_SET_STAKEY_REQ parameters */
+ pSetStaKeyParams->staIdx = staIdx;
+ pSetStaKeyParams->encType = pMlmSetKeysReq->edType;
+
+ if (eSIR_SUCCESS != wlan_cfg_get_int(pMac, WNI_CFG_SINGLE_TID_RC, &val)) {
+ lim_log(pMac, LOGP, FL("Unable to read WNI_CFG_SINGLE_TID_RC"));
+ }
+
+ pSetStaKeyParams->singleTidRc = (uint8_t) val;
+
+ /* Update PE session ID */
+ pSetStaKeyParams->sessionId = sessionEntry->peSessionId;
+
+ /**
+ * For WEP - defWEPIdx indicates the default WEP
+ * Key to be used for TX
+ * For all others, there's just one key that can
+ * be used and hence it is assumed that
+ * defWEPIdx = 0 (from the caller)
+ */
+
+ pSetStaKeyParams->defWEPIdx = defWEPIdx;
+
+ pSetStaKeyParams->smesessionId = pMlmSetKeysReq->smesessionId;
+ cdf_mem_copy(pSetStaKeyParams->peerMacAddr,
+ pMlmSetKeysReq->peerMacAddr, sizeof(tSirMacAddr));
+
+ if (sendRsp == true) {
+ /** Store the Previous MlmState*/
+ sessionEntry->limPrevMlmState = sessionEntry->limMlmState;
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ }
+
+ if (LIM_IS_IBSS_ROLE(sessionEntry)
+ && !pMlmSetKeysReq->key[0].unicast) {
+ if (sendRsp == true)
+ sessionEntry->limMlmState =
+ eLIM_MLM_WT_SET_STA_BCASTKEY_STATE;
+ msgQ.type = WMA_SET_STA_BCASTKEY_REQ;
+ } else {
+ if (sendRsp == true)
+ sessionEntry->limMlmState =
+ eLIM_MLM_WT_SET_STA_KEY_STATE;
+ msgQ.type = WMA_SET_STAKEY_REQ;
+ }
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId,
+ sessionEntry->limMlmState));
+
+ /**
+ * In the Case of WEP_DYNAMIC, ED_TKIP and ED_CCMP
+ * the Key[0] contains the KEY, so just copy that alone,
+ * for the case of WEP_STATIC the hal gets the key from cfg
+ */
+ switch (pMlmSetKeysReq->edType) {
+ case eSIR_ED_WEP40:
+ case eSIR_ED_WEP104:
+ /* FIXME! Is this OK? */
+ if (0 == pMlmSetKeysReq->numKeys) {
+ uint32_t i;
+
+ for (i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) {
+ cdf_mem_copy((uint8_t *) &pSetStaKeyParams->
+ key[i],
+ (uint8_t *) &pMlmSetKeysReq->
+ key[i], sizeof(tSirKeys));
+ }
+ pSetStaKeyParams->wepType = eSIR_WEP_STATIC;
+ sessionEntry->limMlmState =
+ eLIM_MLM_WT_SET_STA_KEY_STATE;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE,
+ sessionEntry->peSessionId,
+ sessionEntry->limMlmState));
+ } else {
+ /*This case the keys are coming from upper layer so need to fill the
+ * key at the default wep key index and send to the HAL */
+ if (defWEPIdx < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) {
+ cdf_mem_copy((uint8_t *) &pSetStaKeyParams->
+ key[defWEPIdx],
+ (uint8_t *) &pMlmSetKeysReq->
+ key[0],
+ sizeof(pMlmSetKeysReq->key[0]));
+ pMlmSetKeysReq->numKeys =
+ SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS;
+ } else {
+ lim_log(pMac, LOGE, FL("Wrong Key Index %d"),
+ defWEPIdx);
+ cdf_mem_free(pSetStaKeyParams);
+ return;
+ }
+ }
+ break;
+ case eSIR_ED_TKIP:
+ case eSIR_ED_CCMP:
+#ifdef FEATURE_WLAN_WAPI
+ case eSIR_ED_WPI:
+#endif
+ {
+ cdf_mem_copy((uint8_t *) &pSetStaKeyParams->key,
+ (uint8_t *) &pMlmSetKeysReq->key[0],
+ sizeof(tSirKeys));
+ }
+ break;
+ default:
+ break;
+ }
+
+ pSetStaKeyParams->sendRsp = sendRsp;
+
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pSetStaKeyParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG1, FL("Sending WMA_SET_STAKEY_REQ..."));
+ MTRACE(mac_trace_msg_tx(pMac, sessionEntry->peSessionId, msgQ.type));
+ if (eSIR_SUCCESS != (retCode = wma_post_ctrl_msg(pMac, &msgQ))) {
+ lim_log(pMac, LOGE,
+ FL("Posting SET_STAKEY to HAL failed, reason=%X"),
+ retCode);
+ /* Respond to SME with LIM_MLM_SETKEYS_CNF */
+ mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL;
+ } else
+ return; /* Continue after WMA_SET_STAKEY_RSP... */
+
+ if (sendRsp == true)
+ lim_post_sme_set_keys_cnf(pMac, pMlmSetKeysReq, &mlmSetKeysCnf);
+}
diff --git a/core/mac/src/pe/lim/lim_security_utils.h b/core/mac/src/pe/lim/lim_security_utils.h
new file mode 100644
index 0000000..c5b30ba
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_security_utils.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_security_utils.h contains the utility definitions
+ * related to WEP encryption/decryption etc.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SECURITY_UTILS_H
+#define __LIM_SECURITY_UTILS_H
+#include "sir_mac_prot_def.h" /* for tSirMacAuthFrameBody */
+
+#define LIM_ENCR_AUTH_BODY_LEN (sizeof(tSirMacAuthFrameBody) + \
+ SIR_MAC_WEP_IV_LENGTH + \
+ SIR_MAC_WEP_ICV_LENGTH)
+struct tLimPreAuthNode;
+
+uint8_t lim_is_auth_algo_supported(tpAniSirGlobal, tAniAuthType, tpPESession);
+
+/* MAC based authentication related functions */
+void lim_init_pre_auth_list(tpAniSirGlobal);
+void lim_delete_pre_auth_list(tpAniSirGlobal);
+struct tLimPreAuthNode *lim_search_pre_auth_list(tpAniSirGlobal, tSirMacAddr);
+void lim_add_pre_auth_node(tpAniSirGlobal, struct tLimPreAuthNode *);
+void lim_delete_pre_auth_node(tpAniSirGlobal, tSirMacAddr);
+void lim_release_pre_auth_node(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode);
+void lim_restore_from_auth_state(tpAniSirGlobal,
+ tSirResultCodes, uint16_t, tpPESession);
+uint8_t lim_delete_open_auth_pre_auth_node(tpAniSirGlobal mac_ctx);
+
+/* Encryption/Decryption related functions */
+void lim_compute_crc32(uint8_t *, uint8_t *, uint8_t);
+void lim_rc4(uint8_t *, uint8_t *, uint8_t *, uint32_t, uint16_t);
+void lim_encrypt_auth_frame(tpAniSirGlobal, uint8_t, uint8_t *, uint8_t *,
+ uint8_t *, uint32_t);
+uint8_t lim_decrypt_auth_frame(tpAniSirGlobal, uint8_t *, uint8_t *, uint8_t *,
+ uint32_t, uint16_t);
+
+void lim_send_set_bss_key_req(tpAniSirGlobal, tLimMlmSetKeysReq *, tpPESession);
+void lim_send_set_sta_key_req(tpAniSirGlobal, tLimMlmSetKeysReq *, uint16_t, uint8_t,
+ tpPESession, bool sendRsp);
+void lim_post_sme_set_keys_cnf(tpAniSirGlobal, tLimMlmSetKeysReq *,
+ tLimMlmSetKeysCnf *);
+
+#define PTAPS 0xedb88320
+
+static inline uint32_t lim_crc_update(uint32_t crc, uint8_t x)
+{
+
+ /* Update CRC computation for 8 bits contained in x */
+ /* */
+ uint32_t z;
+ uint32_t fb;
+ int i;
+
+ z = crc ^ x;
+ for (i = 0; i < 8; i++) {
+ fb = z & 1;
+ z >>= 1;
+ if (fb)
+ z ^= PTAPS;
+ }
+ return z;
+}
+
+#endif /* __LIM_SECURITY_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
new file mode 100644
index 0000000..c7f4220
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -0,0 +1,5130 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**
+ * \file lim_send_management_frames.c
+ *
+ * \brief Code for preparing and sending 802.11 Management frames
+ *
+ *
+ */
+
+#include "sir_api.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+#include "cfg_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "dot11f.h"
+#include "lim_sta_hash_api.h"
+#include "sch_api.h"
+#include "lim_send_messages.h"
+#include "lim_assoc_utils.h"
+#include "lim_ft.h"
+#ifdef WLAN_FEATURE_11W
+#include "wni_cfg.h"
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "cdf_types.h"
+#include "cdf_trace.h"
+#include "cds_utils.h"
+#include "sme_trace.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+#include "wma_types.h"
+
+/**
+ *
+ * \brief This function is called to add the sequence number to the
+ * management frames
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pMacHdr Pointer to MAC management header
+ *
+ * The pMacHdr argument points to the MAC management header. The
+ * sequence number stored in the pMac structure will be incremented
+ * and updated to the MAC management header. The start sequence
+ * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
+ * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
+ * number will roll over.
+ *
+ */
+void lim_add_mgmt_seq_num(tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr)
+{
+ if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) {
+ pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
+ }
+
+ pMac->mgmtSeqNum++;
+
+ pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK);
+ pMacHdr->seqControl.seqNumHi =
+ ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET);
+}
+
+/**
+ *
+ * \brief This function is called before sending a p2p action frame
+ * inorder to add sequence numbers to action packets
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pBD Pointer to the frame buffer that needs to be populate
+ *
+ * The pMacHdr argument points to the MAC management header. The
+ * sequence number stored in the pMac structure will be incremented
+ * and updated to the MAC management header. The start sequence
+ * number is WLAN_HOST_SEQ_NUM_MIN and the end value is
+ * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence
+ * number will roll over.
+ *
+ */
+void lim_populate_p2p_mac_header(tpAniSirGlobal pMac, uint8_t *pBD)
+{
+ tpSirMacMgmtHdr pMacHdr;
+
+ /* / Prepare MAC management header */
+ pMacHdr = (tpSirMacMgmtHdr) (pBD);
+
+ /* Prepare sequence number */
+ lim_add_mgmt_seq_num(pMac, pMacHdr);
+ lim_log(pMac, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
+ pMacHdr->seqControl.seqNumLo,
+ pMacHdr->seqControl.seqNumHi, pMac->mgmtSeqNum);
+}
+
+/**
+ * lim_populate_mac_header() - Fill in 802.11 header of frame
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @buf: Pointer to the frame buffer that needs to be populate
+ * @type: 802.11 Type of the frame
+ * @sub_type: 802.11 Subtype of the frame
+ * @peer_addr: dst address
+ * @self_mac_addr: local mac address
+ *
+ * This function is called by various LIM modules to prepare the
+ * 802.11 frame MAC header
+ *
+ * The buf argument points to the beginning of the frame buffer to
+ * which - a) The 802.11 MAC header is set b) Following this MAC header
+ * will be the MGMT frame payload The payload itself is populated by the
+ * caller API
+ *
+ * Return: None
+ */
+
+void lim_populate_mac_header(tpAniSirGlobal mac_ctx, uint8_t *buf,
+ uint8_t type, uint8_t sub_type, tSirMacAddr peer_addr,
+ tSirMacAddr self_mac_addr)
+{
+ tpSirMacMgmtHdr mac_hdr;
+
+ /* Prepare MAC management header */
+ mac_hdr = (tpSirMacMgmtHdr) (buf);
+
+ /* Prepare FC */
+ mac_hdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+ mac_hdr->fc.type = type;
+ mac_hdr->fc.subType = sub_type;
+
+ /* Prepare Address 1 */
+ cdf_mem_copy((uint8_t *) mac_hdr->da,
+ (uint8_t *) peer_addr, sizeof(tSirMacAddr));
+
+ /* Prepare Address 2 */
+ sir_copy_mac_addr(mac_hdr->sa, self_mac_addr);
+
+ /* Prepare Address 3 */
+ cdf_mem_copy((uint8_t *) mac_hdr->bssId,
+ (uint8_t *) peer_addr, sizeof(tSirMacAddr));
+
+ /* Prepare sequence number */
+ lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
+ lim_log(mac_ctx, LOG1, "seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d",
+ mac_hdr->seqControl.seqNumLo,
+ mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
+}
+
+/**
+ * lim_send_probe_req_mgmt_frame() - send probe request management frame
+ * @mac_ctx: Pointer to Global MAC structure
+ * @ssid: SSID to be sent in Probe Request frame
+ * @bssid: BSSID to be sent in Probe Request frame
+ * @channel: Channel # on which the Probe Request is going out
+ * @self_macaddr: self MAC address
+ * @dot11mode: self dotllmode
+ * @additional_ielen: if non-zero, include additional_ie in the Probe Request
+ * frame
+ * @additional_ie: if additional_ielen is non zero, include this field in the
+ * Probe Request frame
+ *
+ * This function is called by various LIM modules to send Probe Request frame
+ * during active scan/learn phase.
+ * Probe request is sent out in the following scenarios:
+ * --heartbeat failure: session needed
+ * --join req: session needed
+ * --foreground scan: no session
+ * --background scan: no session
+ * --sch_beacon_processing: to get EDCA parameters: session needed
+ *
+ * Return: tSirRetStatus (eSIR_SUCCESS on success and error codes otherwise)
+ */
+tSirRetStatus
+lim_send_probe_req_mgmt_frame(tpAniSirGlobal mac_ctx,
+ tSirMacSSid *ssid,
+ tSirMacAddr bssid,
+ uint8_t channel,
+ tSirMacAddr self_macaddr,
+ uint32_t dot11mode,
+ uint32_t additional_ielen, uint8_t *additional_ie)
+{
+ tDot11fProbeRequest pr;
+ uint32_t status, bytes, payload;
+ uint8_t *frame;
+ void *packet;
+ CDF_STATUS cdf_status, extcap_status;
+ tpPESession pesession;
+ uint8_t sessionid;
+ uint8_t *p2pie = NULL;
+ uint8_t txflag = 0;
+ uint8_t sme_sessionid = 0;
+ bool is_vht_enabled = false;
+ uint8_t txPower;
+ uint16_t addn_ielen = additional_ielen;
+
+ /* The probe req should not send 11ac capabilieties if band is 2.4GHz,
+ * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz
+ * is false and dot11mode is 11ac set it to 11n.
+ */
+ if (channel <= SIR_11B_CHANNEL_END &&
+ (false == mac_ctx->roam.configParam.enableVhtFor24GHz) &&
+ (WNI_CFG_DOT11_MODE_11AC == dot11mode ||
+ WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode))
+ dot11mode = WNI_CFG_DOT11_MODE_11N;
+ /*
+ * session context may or may not be present, when probe request needs
+ * to be sent out. Following cases exist:
+ * --heartbeat failure: session needed
+ * --join req: session needed
+ * --foreground scan: no session
+ * --background scan: no session
+ * --sch_beacon_processing: to get EDCA parameters: session needed
+ * If session context does not exist, some IEs will be populated from
+ * CFGs, e.g. Supported and Extended rate set IEs
+ */
+ pesession = pe_find_session_by_bssid(mac_ctx, bssid, &sessionid);
+
+ if (pesession != NULL)
+ sme_sessionid = pesession->smeSessionId;
+
+ /* The scheme here is to fill out a 'tDot11fProbeRequest' structure */
+ /* and then hand it off to 'dot11f_pack_probe_request' (for */
+ /* serialization). We start by zero-initializing the structure: */
+ cdf_mem_set((uint8_t *) &pr, sizeof(pr), 0);
+
+ /* & delegating to assorted helpers: */
+ populate_dot11f_ssid(mac_ctx, ssid, &pr.SSID);
+
+ if (addn_ielen && additional_ie)
+ p2pie = limGetP2pIEPtr(mac_ctx, additional_ie, addn_ielen);
+
+ /*
+ * Don't include 11b rate if it is a P2P serach or probe request is
+ * sent by P2P Client
+ */
+ if ((WNI_CFG_DOT11_MODE_11B != dot11mode) && (p2pie != NULL) &&
+ (((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
+ mac_ctx->lim.gpLimMlmScanReq->p2pSearch) ||
+ ((pesession != NULL) &&
+ (CDF_P2P_CLIENT_MODE == pesession->pePersona))
+ )
+ ) {
+ /*
+ * In the below API pass channel number > 14, do that it fills
+ * only 11a rates in supported rates
+ */
+ populate_dot11f_supp_rates(mac_ctx, 15, &pr.SuppRates,
+ pesession);
+ } else {
+ populate_dot11f_supp_rates(mac_ctx, channel,
+ &pr.SuppRates, pesession);
+
+ if (WNI_CFG_DOT11_MODE_11B != dot11mode) {
+ populate_dot11f_ext_supp_rates1(mac_ctx, channel,
+ &pr.ExtSuppRates);
+ }
+ }
+
+#if defined WLAN_FEATURE_VOWIFI
+ /*
+ * Table 7-14 in IEEE Std. 802.11k-2008 says
+ * DS params "can" be present in RRM is disabled and "is" present if
+ * RRM is enabled. It should be ok even if we add it into probe req when
+ * RRM is not enabled.
+ */
+ populate_dot11f_ds_params(mac_ctx, &pr.DSParams, channel);
+ /* Call RRM module to get the tx power for management used. */
+ txPower = (uint8_t) rrm_get_mgmt_tx_power(mac_ctx, pesession);
+ populate_dot11f_wfatpc(mac_ctx, &pr.WFATPC, txPower, 0);
+
+#endif
+
+ if (pesession != NULL) {
+ pesession->htCapability = IS_DOT11_MODE_HT(dot11mode);
+ /* Include HT Capability IE */
+ if (pesession->htCapability)
+ populate_dot11f_ht_caps(mac_ctx, pesession, &pr.HTCaps);
+ } else { /* pesession == NULL */
+ if (IS_DOT11_MODE_HT(dot11mode))
+ populate_dot11f_ht_caps(mac_ctx, NULL, &pr.HTCaps);
+ }
+
+ /*
+ * Set channelbonding information as "disabled" when tunned to a
+ * 2.4 GHz channel
+ */
+ if (channel <= SIR_11B_CHANNEL_END) {
+ if (mac_ctx->roam.configParam.channelBondingMode24GHz
+ == PHY_SINGLE_CHANNEL_CENTERED) {
+ pr.HTCaps.supportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_20MHZ;
+ pr.HTCaps.shortGI40MHz = 0;
+ } else {
+ pr.HTCaps.supportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ }
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pesession != NULL) {
+ pesession->vhtCapability = IS_DOT11_MODE_VHT(dot11mode);
+ /* Include VHT Capability IE */
+ if (pesession->vhtCapability) {
+ populate_dot11f_vht_caps(mac_ctx, pesession,
+ &pr.VHTCaps);
+ is_vht_enabled = true;
+ }
+ } else {
+ if (IS_DOT11_MODE_VHT(dot11mode)) {
+ populate_dot11f_vht_caps(mac_ctx, pesession,
+ &pr.VHTCaps);
+ is_vht_enabled = true;
+ }
+ }
+#endif
+ if (pesession != NULL)
+ populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &pr.ExtCap,
+ pesession);
+
+ /* That's it-- now we pack it. First, how much space are we going to */
+ status = dot11f_get_packed_probe_request_size(mac_ctx, &pr, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGP, FL("Failed to calculate the packed size for a Probe Request (0x%08x)."), status);
+ /* We'll fall back on the worst case scenario: */
+ payload = sizeof(tDot11fProbeRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("There were warnings while calculating the packed size for a Probe Request (0x%08x)."), status);
+ }
+
+ /* Strip extended capability IE (if present). FW will add that IE */
+ if (addn_ielen) {
+ extcap_status = lim_strip_extcap_ie(mac_ctx, additional_ie,
+ &addn_ielen, NULL);
+ if (CDF_STATUS_SUCCESS != extcap_status)
+ lim_log(mac_ctx, LOGE,
+ FL("Error:%d stripping extcap IE"), extcap_status);
+ }
+
+ bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen;
+
+ /* Ok-- try to allocate some memory: */
+ cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+ (void **)&packet);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes for a Probe Request."), bytes);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ /* Paranoia: */
+ cdf_mem_set(frame, bytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_PROBE_REQ, bssid, self_macaddr);
+
+ /* That done, pack the Probe Request: */
+ status = dot11f_pack_probe_request(mac_ctx, &pr, frame +
+ sizeof(tSirMacMgmtHdr),
+ payload, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to pack a Probe Request (0x%08x)."), status);
+ cds_packet_free((void *)packet);
+ return eSIR_FAILURE; /* allocated! */
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW, FL("There were warnings while packing a Probe Request (0x%08x)."), status);
+ }
+ /* Append any AddIE if present. */
+ if (addn_ielen) {
+ cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+ additional_ie, addn_ielen);
+ payload += addn_ielen;
+ }
+
+ /* If this probe request is sent during P2P Search State, then we need
+ * to send it at OFDM rate.
+ */
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(channel))
+ || ((mac_ctx->lim.gpLimMlmScanReq != NULL) &&
+ mac_ctx->lim.gpLimMlmScanReq->p2pSearch)
+ /*
+ * For unicast probe req mgmt from Join function we don't set
+ * above variables. So we need to add one more check whether it
+ * is pePersona is P2P_CLIENT or not
+ */
+ || ((pesession != NULL) &&
+ (CDF_P2P_CLIENT_MODE == pesession->pePersona))
+ ) {
+ txflag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ cdf_status =
+ wma_tx_frame(mac_ctx, packet,
+ (uint16_t) sizeof(tSirMacMgmtHdr) + payload,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, frame, txflag, sme_sessionid,
+ 0);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("could not send Probe Request frame!"));
+ /* Pkt will be freed up by the callback */
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+} /* End lim_send_probe_req_mgmt_frame. */
+
+tSirRetStatus lim_get_addn_ie_for_probe_resp(tpAniSirGlobal pMac,
+ uint8_t *addIE, uint16_t *addnIELen,
+ uint8_t probeReqP2pIe)
+{
+ /* If Probe request doesn't have P2P IE, then take out P2P IE
+ from additional IE */
+ if (!probeReqP2pIe) {
+ uint8_t *tempbuf = NULL;
+ uint16_t tempLen = 0;
+ int left = *addnIELen;
+ uint8_t *ptr = addIE;
+ uint8_t elem_id, elem_len;
+
+ if (NULL == addIE) {
+ PELOGE(lim_log(pMac, LOGE, FL(" NULL addIE pointer"));)
+ return eSIR_FAILURE;
+ }
+
+ tempbuf = cdf_mem_malloc(left);
+ if (NULL == tempbuf) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("Unable to allocate memory to store addn IE"));
+ )
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ while (left >= 2) {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if (elem_len > left) {
+ lim_log(pMac, LOGE,
+ FL
+ ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
+ elem_id, elem_len, left);
+ cdf_mem_free(tempbuf);
+ return eSIR_FAILURE;
+ }
+ if (!((SIR_MAC_EID_VENDOR == elem_id) &&
+ (memcmp
+ (&ptr[2], SIR_MAC_P2P_OUI,
+ SIR_MAC_P2P_OUI_SIZE) == 0))) {
+ cdf_mem_copy(tempbuf + tempLen, &ptr[0],
+ elem_len + 2);
+ tempLen += (elem_len + 2);
+ }
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ cdf_mem_copy(addIE, tempbuf, tempLen);
+ *addnIELen = tempLen;
+ cdf_mem_free(tempbuf);
+ }
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_send_probe_rsp_mgmt_frame() - Send probe response
+ *
+ * @mac_ctx: Handle for mac context
+ * @peer_macaddr: Mac address of requesting peer
+ * @ssid: SSID for response
+ * @n_staid: Station ID, currently unused.
+ * @pe_session: PE session id
+ * @keepalive: Keep alive flag. Currently unused.
+ * @preq_p2pie: P2P IE in incoming probe request
+ *
+ * Builds and sends probe response frame to the requesting peer
+ *
+ * Return: void
+ */
+
+void
+lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
+ tSirMacAddr peer_macaddr,
+ tpAniSSID ssid,
+ short n_staid,
+ uint8_t keepalive,
+ tpPESession pe_session, uint8_t preq_p2pie)
+{
+ tDot11fProbeResponse *frm;
+ tSirRetStatus sir_status;
+ uint32_t cfg, payload, bytes, status;
+ tpSirMacMgmtHdr mac_hdr;
+ uint8_t *frame;
+ void *packet;
+ CDF_STATUS cdf_status;
+ uint32_t addn_ie_present = false;
+
+ uint16_t addn_ie_len = 0;
+ uint32_t wps_ap = 0, tmp;
+ uint8_t tx_flag = 0;
+ uint8_t *add_ie = NULL;
+ uint8_t *p2p_ie = NULL;
+ uint8_t noalen = 0;
+ uint8_t total_noalen = 0;
+ uint8_t noa_stream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+ uint8_t noa_ie[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+ uint8_t sme_sessionid = 0;
+ bool is_vht_enabled = false;
+ tDot11fIEExtCap extracted_ext_cap;
+ bool extracted_ext_cap_flag = true;
+
+ /* We don't answer requests in this case*/
+ if (ANI_DRIVER_TYPE(mac_ctx) == eDRIVER_TYPE_MFG)
+ return;
+
+ if (NULL == pe_session)
+ return;
+
+ /*
+ * In case when cac timer is running for this SAP session then
+ * avoid sending probe rsp out. It is violation of dfs specification.
+ */
+ if (((pe_session->pePersona == CDF_SAP_MODE) ||
+ (pe_session->pePersona == CDF_P2P_GO_MODE)) &&
+ (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+ CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
+ FL("CAC timer is running, probe response dropped"));
+ return;
+ }
+ sme_sessionid = pe_session->smeSessionId;
+ frm = cdf_mem_malloc(sizeof(tDot11fProbeResponse));
+ if (NULL == frm) {
+ lim_log(mac_ctx, LOGE,
+ FL("Unable to allocate memory"));
+ return;
+ }
+
+ cdf_mem_zero(&extracted_ext_cap, sizeof(extracted_ext_cap));
+
+ /*
+ * Fill out 'frm', after which we'll just hand the struct off to
+ * 'dot11f_pack_probe_response'.
+ */
+ cdf_mem_set((uint8_t *) frm, sizeof(tDot11fProbeResponse), 0);
+
+ /*
+ * Timestamp to be updated by TFP, below.
+ *
+ * Beacon Interval:
+ */
+ if (LIM_IS_AP_ROLE(pe_session)) {
+ frm->BeaconInterval.interval =
+ mac_ctx->sch.schObject.gSchBeaconInterval;
+ } else {
+ sir_status = wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_BEACON_INTERVAL, &cfg);
+ if (eSIR_SUCCESS != sir_status) {
+ lim_log(mac_ctx, LOGP,
+ FL("Failed to get WNI_CFG_BEACON_INTERVAL (%d)."),
+ sir_status);
+ goto err_ret;
+ }
+ frm->BeaconInterval.interval = (uint16_t) cfg;
+ }
+
+ populate_dot11f_capabilities(mac_ctx, &frm->Capabilities, pe_session);
+ populate_dot11f_ssid(mac_ctx, (tSirMacSSid *) ssid, &frm->SSID);
+ populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm->SuppRates, pe_session);
+
+ populate_dot11f_ds_params(mac_ctx, &frm->DSParams,
+ pe_session->currentOperChannel);
+ populate_dot11f_ibss_params(mac_ctx, &frm->IBSSParams, pe_session);
+
+ if (LIM_IS_AP_ROLE(pe_session)) {
+ if (pe_session->wps_state != SAP_WPS_DISABLED)
+ populate_dot11f_probe_res_wpsi_es(mac_ctx,
+ &frm->WscProbeRes,
+ pe_session);
+ } else {
+ if (wlan_cfg_get_int(mac_ctx, (uint16_t) WNI_CFG_WPS_ENABLE,
+ &tmp) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP, "Failed to cfg get id %d",
+ WNI_CFG_WPS_ENABLE);
+
+ wps_ap = tmp & WNI_CFG_WPS_ENABLE_AP;
+
+ if (wps_ap)
+ populate_dot11f_wsc_in_probe_res(mac_ctx,
+ &frm->WscProbeRes);
+
+ if (mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState ==
+ eLIM_WSC_ENROLL_BEGIN) {
+ populate_dot11f_wsc_registrar_info_in_probe_res(mac_ctx,
+ &frm->WscProbeRes);
+ mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
+ eLIM_WSC_ENROLL_IN_PROGRESS;
+ }
+
+ if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
+ eLIM_WSC_ENROLL_END) {
+ de_populate_dot11f_wsc_registrar_info_in_probe_res(
+ mac_ctx, &frm->WscProbeRes);
+ mac_ctx->lim.wscIeInfo.probeRespWscEnrollmentState =
+ eLIM_WSC_ENROLL_NOOP;
+ }
+ }
+
+ populate_dot11f_country(mac_ctx, &frm->Country, pe_session);
+ populate_dot11f_edca_param_set(mac_ctx, &frm->EDCAParamSet, pe_session);
+
+ if (pe_session->dot11mode != WNI_CFG_DOT11_MODE_11B)
+ populate_dot11f_erp_info(mac_ctx, &frm->ERPInfo, pe_session);
+
+ populate_dot11f_ext_supp_rates(mac_ctx,
+ POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm->ExtSuppRates, pe_session);
+
+ /* Populate HT IEs, when operating in 11n */
+ if (pe_session->htCapability) {
+ populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
+ populate_dot11f_ht_info(mac_ctx, &frm->HTInfo, pe_session);
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pe_session->vhtCapability) {
+ lim_log(mac_ctx, LOG1, FL("Populate VHT IE in Probe Response"));
+ populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
+ populate_dot11f_vht_operation(mac_ctx, pe_session,
+ &frm->VHTOperation);
+ /*
+ * we do not support multi users yet.
+ * populate_dot11f_vht_ext_bss_load( mac_ctx,
+ * &frm.VHTExtBssLoad );
+ */
+ is_vht_enabled = true;
+ }
+#endif
+
+ populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &frm->ExtCap,
+ pe_session);
+
+ if (pe_session->pLimStartBssReq) {
+ populate_dot11f_wpa(mac_ctx,
+ &(pe_session->pLimStartBssReq->rsnIE),
+ &frm->WPA);
+ populate_dot11f_rsn_opaque(mac_ctx,
+ &(pe_session->pLimStartBssReq->rsnIE),
+ &frm->RSNOpaque);
+ }
+
+ populate_dot11f_wmm(mac_ctx, &frm->WMMInfoAp, &frm->WMMParams,
+ &frm->WMMCaps, pe_session);
+
+#if defined(FEATURE_WLAN_WAPI)
+ if (pe_session->pLimStartBssReq)
+ populate_dot11f_wapi(mac_ctx,
+ &(pe_session->pLimStartBssReq->rsnIE),
+ &frm->WAPI);
+#endif /* defined(FEATURE_WLAN_WAPI) */
+
+ status = dot11f_get_packed_probe_response_size(mac_ctx, frm, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGP,
+ FL("Probe Response size error (0x%08x)."),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ payload = sizeof(tDot11fProbeResponse);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Probe Response size warning (0x%08x)."),
+ status);
+ }
+
+ bytes = payload + sizeof(tSirMacMgmtHdr);
+
+ if (mac_ctx->lim.gpLimRemainOnChanReq)
+ bytes += (mac_ctx->lim.gpLimRemainOnChanReq->length -
+ sizeof(tSirRemainOnChnReq));
+ else
+ /*
+ * Only use CFG for non-listen mode. This CFG is not working for
+ * concurrency. In listening mode, probe rsp IEs is passed in
+ * the message from SME to PE.
+ */
+ addn_ie_present =
+ (pe_session->addIeParams.probeRespDataLen != 0);
+
+ if (addn_ie_present) {
+
+ add_ie = cdf_mem_malloc(
+ pe_session->addIeParams.probeRespDataLen);
+ if (NULL == add_ie) {
+ lim_log(mac_ctx, LOGE,
+ FL("add_ie allocation failed"));
+ goto err_ret;
+ }
+
+ cdf_mem_copy(add_ie,
+ pe_session->addIeParams.probeRespData_buff,
+ pe_session->addIeParams.probeRespDataLen);
+ addn_ie_len = pe_session->addIeParams.probeRespDataLen;
+
+ if (eSIR_SUCCESS != lim_get_addn_ie_for_probe_resp(mac_ctx,
+ add_ie, &addn_ie_len, preq_p2pie)) {
+ lim_log(mac_ctx, LOGP,
+ FL("Unable to get addn_ie"));
+ goto err_ret;
+ }
+
+ sir_status = lim_strip_extcap_update_struct(mac_ctx,
+ add_ie, &addn_ie_len,
+ &extracted_ext_cap);
+ if (eSIR_SUCCESS != sir_status) {
+ extracted_ext_cap_flag = false;
+ lim_log(mac_ctx, LOG1,
+ FL("Unable to strip off ExtCap IE"));
+ }
+
+ bytes = bytes + addn_ie_len;
+
+ if (preq_p2pie)
+ p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0],
+ addn_ie_len);
+
+ if (p2p_ie != NULL) {
+ /* get NoA attribute stream P2P IE */
+ noalen = lim_get_noa_attr_stream(mac_ctx,
+ noa_stream, pe_session);
+ if (noalen != 0) {
+ total_noalen =
+ lim_build_p2p_ie(mac_ctx, &noa_ie[0],
+ &noa_stream[0], noalen);
+ bytes = bytes + total_noalen;
+ }
+ }
+ }
+
+ cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+ (void **)&packet);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGP, FL("Probe Response allocation failed"));
+ goto err_ret;
+ }
+ /* Paranoia: */
+ cdf_mem_set(frame, bytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_PROBE_RSP, peer_macaddr,
+ pe_session->selfMacAddr);
+
+ mac_hdr = (tpSirMacMgmtHdr) frame;
+
+ sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
+
+ /* merge ExtCap IE */
+ if (extracted_ext_cap_flag)
+ lim_merge_extcap_struct(&frm->ExtCap, &extracted_ext_cap);
+
+ /* That done, pack the Probe Response: */
+ status =
+ dot11f_pack_probe_response(mac_ctx, frm,
+ frame + sizeof(tSirMacMgmtHdr),
+ payload, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Probe Response pack failure (0x%08x)."),
+ status);
+ goto err_ret;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Probe Response pack warning (0x%08x)."),
+ status);
+ }
+
+ lim_log(mac_ctx, LOG3, FL("Sending Probe Response frame to "));
+ lim_print_mac_addr(mac_ctx, peer_macaddr, LOG3);
+
+ mac_ctx->sys.probeRespond++;
+
+ if (mac_ctx->lim.gpLimRemainOnChanReq)
+ cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+ mac_ctx->lim.gpLimRemainOnChanReq->probeRspIe,
+ (mac_ctx->lim.gpLimRemainOnChanReq->length -
+ sizeof(tSirRemainOnChnReq)));
+
+ if (addn_ie_present)
+ cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+ &add_ie[0], addn_ie_len);
+
+ if (noalen != 0) {
+ if (total_noalen >
+ (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Not able to insert NoA, total len=%d"),
+ total_noalen);
+ goto err_ret;
+ } else {
+ cdf_mem_copy(&frame[bytes - (total_noalen)],
+ &noa_ie[0], total_noalen);
+ }
+ }
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
+ || (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (pe_session->pePersona == CDF_P2P_GO_MODE)
+ )
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+ /* Queue Probe Response frame in high priority WQ */
+ cdf_status = wma_tx_frame((tHalHandle) mac_ctx, packet,
+ (uint16_t) bytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, frame, tx_flag,
+ sme_sessionid, 0);
+
+ /* Pkt will be freed up by the callback */
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status))
+ lim_log(mac_ctx, LOGE, FL("Could not send Probe Response."));
+
+ if (add_ie != NULL)
+ cdf_mem_free(add_ie);
+
+ cdf_mem_free(frm);
+ return;
+
+err_ret:
+ if (add_ie != NULL)
+ cdf_mem_free(add_ie);
+ if (frm != NULL)
+ cdf_mem_free(frm);
+ if (packet != NULL)
+ cds_packet_free((void *)packet);
+ return;
+
+} /* End lim_send_probe_rsp_mgmt_frame. */
+
+void
+lim_send_addts_req_action_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirAddtsReqInfo *pAddTS, tpPESession psessionEntry)
+{
+ uint16_t i;
+ uint8_t *pFrame;
+ tDot11fAddTSRequest AddTSReq;
+ tDot11fWMMAddTSRequest WMMAddTSReq;
+ uint32_t nPayload, nBytes, nStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ void *pPacket;
+#ifdef FEATURE_WLAN_ESE
+ uint32_t phyMode;
+#endif
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ return;
+ }
+
+ smeSessionId = psessionEntry->smeSessionId;
+
+ if (!pAddTS->wmeTspecPresent) {
+ cdf_mem_set((uint8_t *) &AddTSReq, sizeof(AddTSReq), 0);
+
+ AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
+ AddTSReq.DialogToken.token = pAddTS->dialogToken;
+ AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+ if (pAddTS->lleTspecPresent) {
+ populate_dot11f_tspec(&pAddTS->tspec, &AddTSReq.TSPEC);
+ } else {
+ populate_dot11f_wmmtspec(&pAddTS->tspec,
+ &AddTSReq.WMMTSPEC);
+ }
+
+ if (pAddTS->lleTspecPresent) {
+ AddTSReq.num_WMMTCLAS = 0;
+ AddTSReq.num_TCLAS = pAddTS->numTclas;
+ for (i = 0; i < pAddTS->numTclas; ++i) {
+ populate_dot11f_tclas(pMac, &pAddTS->tclasInfo[i],
+ &AddTSReq.TCLAS[i]);
+ }
+ } else {
+ AddTSReq.num_TCLAS = 0;
+ AddTSReq.num_WMMTCLAS = pAddTS->numTclas;
+ for (i = 0; i < pAddTS->numTclas; ++i) {
+ populate_dot11f_wmmtclas(pMac,
+ &pAddTS->tclasInfo[i],
+ &AddTSReq.WMMTCLAS[i]);
+ }
+ }
+
+ if (pAddTS->tclasProcPresent) {
+ if (pAddTS->lleTspecPresent) {
+ AddTSReq.TCLASSPROC.processing =
+ pAddTS->tclasProc;
+ AddTSReq.TCLASSPROC.present = 1;
+ } else {
+ AddTSReq.WMMTCLASPROC.version = 1;
+ AddTSReq.WMMTCLASPROC.processing =
+ pAddTS->tclasProc;
+ AddTSReq.WMMTCLASPROC.present = 1;
+ }
+ }
+
+ nStatus =
+ dot11f_get_packed_add_ts_request_size(pMac, &AddTSReq, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to calculate the packed size f"
+ "or an Add TS Request (0x%08x)."), nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fAddTSRequest);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while calculating"
+ "the packed size for an Add TS Request"
+ " (0x%08x)."), nStatus);
+ }
+ } else {
+ cdf_mem_set((uint8_t *) &WMMAddTSReq, sizeof(WMMAddTSReq), 0);
+
+ WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ;
+ WMMAddTSReq.DialogToken.token = pAddTS->dialogToken;
+ WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME;
+
+ /* WMM spec 2.2.10 - status code is only filled in for ADDTS response */
+ WMMAddTSReq.StatusCode.statusCode = 0;
+
+ populate_dot11f_wmmtspec(&pAddTS->tspec, &WMMAddTSReq.WMMTSPEC);
+#ifdef FEATURE_WLAN_ESE
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ if (phyMode == WNI_CFG_PHY_MODE_11G
+ || phyMode == WNI_CFG_PHY_MODE_11A) {
+ pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS;
+ } else {
+ pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS;
+ }
+ populate_dot11_tsrsie(pMac, &pAddTS->tsrsIE,
+ &WMMAddTSReq.ESETrafStrmRateSet,
+ sizeof(uint8_t));
+#endif
+ /* fillWmeTspecIE */
+
+ nStatus =
+ dot11f_get_packed_wmm_add_ts_request_size(pMac, &WMMAddTSReq,
+ &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to calculate the packed size f"
+ "or a WMM Add TS Request (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fAddTSRequest);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while calculating"
+ "the packed size for a WMM Add TS Requ"
+ "est (0x%08x)."), nStatus);
+ }
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
+ "d TS Request."), nBytes);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peerMacAddr, psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peerMacAddr, pMacHdr);
+#endif
+
+ /* That done, pack the struct: */
+ if (!pAddTS->wmeTspecPresent) {
+ nStatus = dot11f_pack_add_ts_request(pMac, &AddTSReq,
+ pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack an Add TS Request "
+ "(0x%08x)."), nStatus);
+ cds_packet_free((void *)pPacket);
+ return; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing "
+ "an Add TS Request (0x%08x)."), nStatus);
+ }
+ } else {
+ nStatus = dot11f_pack_wmm_add_ts_request(pMac, &WMMAddTSReq,
+ pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a WMM Add TS Reque"
+ "st (0x%08x)."), nStatus);
+ cds_packet_free((void *)pPacket);
+ return; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing "
+ "a WMM Add TS Request (0x%08x)."), nStatus);
+ }
+ }
+
+ PELOG3(lim_log(pMac, LOG3, FL("Sending an Add TS Request frame to "));
+ lim_print_mac_addr(pMac, peerMacAddr, LOG3);
+ )
+
+ if ((SIR_BAND_5_GHZ ==
+ lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
+ || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+
+ /* Queue Addts Response frame in high priority WQ */
+ cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE, FL("*** Could not send an Add TS Request"
+ " (%X) ***"), cdf_status);
+ /* Pkt will be freed up by the callback */
+ }
+
+} /* End lim_send_addts_req_action_frame. */
+
+/**
+ * lim_send_assoc_rsp_mgmt_frame() - Send assoc response
+ * @mac_ctx: Handle for mac context
+ * @status_code: Status code for assoc response frame
+ * @aid: Association ID
+ * @peer_addr: Mac address of requesting peer
+ * @subtype: Assoc/Reassoc
+ * @sta: Pointer to station node
+ * @pe_session: PE session id.
+ *
+ * Builds and sends association response frame to the requesting peer.
+ *
+ * Return: void
+ */
+
+void
+lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal mac_ctx,
+ uint16_t status_code, uint16_t aid, tSirMacAddr peer_addr,
+ uint8_t subtype, tpDphHashNode sta, tpPESession pe_session)
+{
+ static tDot11fAssocResponse frm;
+ uint8_t *frame;
+ tpSirMacMgmtHdr mac_hdr;
+ tSirRetStatus sir_status;
+ uint8_t lle_mode = 0, addts;
+ tHalBitVal qos_mode, wme_mode;
+ uint32_t payload, bytes, status;
+ void *packet;
+ CDF_STATUS cdf_status;
+ tUpdateBeaconParams beacon_params;
+ uint8_t tx_flag = 0;
+ uint32_t addn_ie_len = 0;
+ uint8_t add_ie[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN];
+ tpSirAssocReq assoc_req = NULL;
+ uint8_t sme_session = 0;
+ bool is_vht = false;
+ uint16_t stripoff_len = 0;
+ tDot11fIEExtCap extracted_ext_cap;
+ bool extracted_flag = false;
+#ifdef WLAN_FEATURE_11W
+ uint32_t retry_int;
+ uint32_t max_retries;
+#endif
+
+ if (NULL == pe_session) {
+ lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
+ return;
+ }
+
+ sme_session = pe_session->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ limGetQosMode(pe_session, &qos_mode);
+ limGetWmeMode(pe_session, &wme_mode);
+
+ /*
+ * An Add TS IE is added only if the AP supports it and
+ * the requesting STA sent a traffic spec.
+ */
+ addts = (qos_mode && sta && sta->qos.addtsPresent) ? 1 : 0;
+
+ frm.Status.status = status_code;
+
+ frm.AID.associd = aid | LIM_AID_MASK;
+
+ if (NULL == sta) {
+ populate_dot11f_supp_rates(mac_ctx,
+ POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates, pe_session);
+ populate_dot11f_ext_supp_rates(mac_ctx,
+ POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, pe_session);
+ } else {
+ populate_dot11f_assoc_rsp_rates(mac_ctx, &frm.SuppRates,
+ &frm.ExtSuppRates,
+ sta->supportedRates.llbRates,
+ sta->supportedRates.llaRates);
+ }
+
+ if (LIM_IS_AP_ROLE(pe_session) && sta != NULL &&
+ eSIR_SUCCESS == status_code) {
+ assoc_req = (tpSirAssocReq)
+ pe_session->parsedAssocReq[sta->assocId];
+ /*
+ * populate P2P IE in AssocRsp when assocReq from the peer
+ * includes P2P IE
+ */
+ if (assoc_req != NULL && assoc_req->addIEPresent)
+ populate_dot11_assoc_res_p2p_ie(mac_ctx,
+ &frm.P2PAssocRes,
+ assoc_req);
+ }
+
+ if (NULL != sta) {
+ if (eHAL_SET == qos_mode) {
+ if (sta->lleEnabled) {
+ lle_mode = 1;
+ populate_dot11f_edca_param_set(mac_ctx,
+ &frm.EDCAParamSet, pe_session);
+ }
+ }
+
+ if ((!lle_mode) && (eHAL_SET == wme_mode) && sta->wmeEnabled) {
+ populate_dot11f_wmm_params(mac_ctx, &frm.WMMParams,
+ pe_session);
+
+ if (sta->wsmEnabled)
+ populate_dot11f_wmm_caps(&frm.WMMCaps);
+ }
+
+ if (sta->mlmStaContext.htCapability &&
+ pe_session->htCapability) {
+ lim_log(mac_ctx, LOG1,
+ FL("Populate HT IEs in Assoc Response"));
+ populate_dot11f_ht_caps(mac_ctx, pe_session,
+ &frm.HTCaps);
+ populate_dot11f_ht_info(mac_ctx, &frm.HTInfo,
+ pe_session);
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (sta->mlmStaContext.vhtCapability &&
+ pe_session->vhtCapability) {
+ lim_log(mac_ctx, LOG1,
+ FL("Populate VHT IEs in Assoc Response"));
+ populate_dot11f_vht_caps(mac_ctx, pe_session,
+ &frm.VHTCaps);
+ populate_dot11f_vht_operation(mac_ctx, pe_session,
+ &frm.VHTOperation);
+ is_vht = true;
+ }
+#endif
+
+ populate_dot11f_ext_cap(mac_ctx, is_vht, &frm.ExtCap,
+ pe_session);
+
+#ifdef WLAN_FEATURE_11W
+ if (eSIR_MAC_TRY_AGAIN_LATER == status_code) {
+ if (wlan_cfg_get_int
+ (mac_ctx, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
+ &max_retries) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ FL("get WNI_CFG_PMF_SA_QUERY_MAX_RETRIES failure"));
+ else if (wlan_cfg_get_int
+ (mac_ctx,
+ WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
+ &retry_int) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE,
+ FL("get WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL failure"));
+ else
+ populate_dot11f_timeout_interval(mac_ctx,
+ &frm.TimeoutInterval,
+ SIR_MAC_TI_TYPE_ASSOC_COMEBACK,
+ (max_retries -
+ sta->pmfSaQueryRetryCount)
+ * retry_int);
+ }
+#endif
+ }
+
+ cdf_mem_set((uint8_t *) &beacon_params, sizeof(beacon_params), 0);
+
+ if (LIM_IS_AP_ROLE(pe_session) &&
+ (pe_session->gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE))
+ lim_decide_ap_protection(mac_ctx, peer_addr,
+ &beacon_params, pe_session);
+
+ lim_update_short_preamble(mac_ctx, peer_addr, &beacon_params,
+ pe_session);
+ lim_update_short_slot_time(mac_ctx, peer_addr, &beacon_params,
+ pe_session);
+
+ /*
+ * Populate Do11capabilities after updating session with
+ * Assos req details
+ */
+ populate_dot11f_capabilities(mac_ctx, &frm.Capabilities, pe_session);
+
+ beacon_params.bssIdx = pe_session->bssIdx;
+
+ /* Send message to HAL about beacon parameter change. */
+ if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+ && beacon_params.paramChangeBitmap) {
+ sch_set_fixed_beacon_fields(mac_ctx, pe_session);
+ lim_send_beacon_params(mac_ctx, &beacon_params, pe_session);
+ }
+ /* Allocate a buffer for this frame: */
+ status = dot11f_get_packed_assoc_response_size(mac_ctx, &frm, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("get Association Response size failure (0x%08x)."),
+ status);
+ return;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("get Association Response size warning (0x%08x)."),
+ status);
+ }
+
+ bytes = sizeof(tSirMacMgmtHdr) + payload;
+
+ if (assoc_req != NULL) {
+ addn_ie_len = (pe_session->addIeParams.assocRespDataLen != 0);
+
+ /* Nonzero length indicates Assoc rsp IE available */
+ if (addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN
+ && (bytes + addn_ie_len) <= SIR_MAX_PACKET_SIZE) {
+ cdf_mem_copy(add_ie,
+ pe_session->addIeParams.assocRespData_buff,
+ pe_session->addIeParams.assocRespDataLen);
+
+ cdf_mem_set((uint8_t *) &extracted_ext_cap,
+ sizeof(extracted_ext_cap), 0);
+
+ stripoff_len = addn_ie_len;
+ sir_status =
+ lim_strip_extcap_update_struct
+ (mac_ctx, &add_ie[0], &stripoff_len,
+ &extracted_ext_cap);
+ if (eSIR_SUCCESS != sir_status) {
+ lim_log(mac_ctx, LOG1,
+ FL("strip off extcap IE failed"));
+ } else {
+ addn_ie_len = stripoff_len;
+ extracted_flag = true;
+ }
+ bytes = bytes + addn_ie_len;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("addn_ie_len = %d for Assoc Resp : %d"),
+ addn_ie_len, assoc_req->addIEPresent);
+ }
+ cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+ (void **)&packet);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGP, FL("cds_packet_alloc failed."));
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(frame, bytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+ (LIM_ASSOC == subtype) ?
+ SIR_MAC_MGMT_ASSOC_RSP : SIR_MAC_MGMT_REASSOC_RSP,
+ peer_addr,
+ pe_session->selfMacAddr);
+ mac_hdr = (tpSirMacMgmtHdr) frame;
+
+ sir_copy_mac_addr(mac_hdr->bssId, pe_session->bssId);
+
+ /* merge the ExtCap struct */
+ if (extracted_flag)
+ lim_merge_extcap_struct(&(frm.ExtCap), &extracted_ext_cap);
+ status = dot11f_pack_assoc_response(mac_ctx, &frm,
+ frame + sizeof(tSirMacMgmtHdr),
+ payload, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Association Response pack failure(0x%08x)."),
+ status);
+ cds_packet_free((void *)packet);
+ return;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Association Response pack warning (0x%08x)."),
+ status);
+ }
+
+ if (subtype == LIM_ASSOC)
+ lim_log(mac_ctx, LOG1,
+ FL("*** Sending Assoc Resp status %d aid %d to "),
+ status_code, aid);
+ else
+ lim_log(mac_ctx, LOG1,
+ FL("*** Sending ReAssoc Resp status %d aid %d to "),
+ status_code, aid);
+
+ lim_print_mac_addr(mac_ctx, mac_hdr->da, LOG1);
+
+ if (addn_ie_len && addn_ie_len <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN)
+ cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+ &add_ie[0], addn_ie_len);
+
+ if ((SIR_BAND_5_GHZ ==
+ lim_get_rf_band(pe_session->currentOperChannel)) ||
+ (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (pe_session->pePersona == CDF_P2P_GO_MODE))
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ pe_session->peSessionId, mac_hdr->fc.subType));
+ /* Queue Association Response frame in high priority WQ */
+ cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) bytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, frame, tx_flag,
+ sme_session, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ pe_session->peSessionId, cdf_status));
+
+ /* Pkt will be freed up by the callback */
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status))
+ lim_log(mac_ctx, LOGE,
+ FL("*** Could not Send Re/AssocRsp, retCode=%X ***"),
+ cdf_status);
+
+ /*
+ * update the ANI peer station count.
+ * FIXME_PROTECTION : take care of different type of station
+ * counter inside this function.
+ */
+ lim_util_count_sta_add(mac_ctx, sta, pe_session);
+
+}
+
+void
+lim_send_delts_req_action_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ uint8_t wmmTspecPresent,
+ tSirMacTSInfo *pTsinfo,
+ tSirMacTspecIE *pTspecIe, tpPESession psessionEntry)
+{
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ tDot11fDelTS DelTS;
+ tDot11fWMMDelTS WMMDelTS;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ return;
+ }
+
+ smeSessionId = psessionEntry->smeSessionId;
+
+ if (!wmmTspecPresent) {
+ cdf_mem_set((uint8_t *) &DelTS, sizeof(DelTS), 0);
+
+ DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT;
+ DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
+ populate_dot11f_ts_info(pTsinfo, &DelTS.TSInfo);
+
+ nStatus = dot11f_get_packed_del_ts_size(pMac, &DelTS, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to calculate the packed si"
+ "ze for a Del TS (0x%08x)."), nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fDelTS);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while calcula"
+ "ting the packed size for a Del TS"
+ " (0x%08x)."), nStatus);
+ }
+ } else {
+ cdf_mem_set((uint8_t *) &WMMDelTS, sizeof(WMMDelTS), 0);
+
+ WMMDelTS.Category.category = SIR_MAC_ACTION_WME;
+ WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ;
+ WMMDelTS.DialogToken.token = 0;
+ WMMDelTS.StatusCode.statusCode = 0;
+ populate_dot11f_wmmtspec(pTspecIe, &WMMDelTS.WMMTSPEC);
+ nStatus =
+ dot11f_get_packed_wmm_del_ts_size(pMac, &WMMDelTS, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to calculate the packed si"
+ "ze for a WMM Del TS (0x%08x)."), nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fDelTS);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while calcula"
+ "ting the packed size for a WMM De"
+ "l TS (0x%08x)."), nStatus);
+ }
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for an Ad"
+ "d TS Response."), nBytes);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ /* That done, pack the struct: */
+ if (!wmmTspecPresent) {
+ nStatus = dot11f_pack_del_ts(pMac, &DelTS,
+ pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a Del TS frame (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing "
+ "a Del TS frame (0x%08x)."), nStatus);
+ }
+ } else {
+ nStatus = dot11f_pack_wmm_del_ts(pMac, &WMMDelTS,
+ pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to pack a WMM Del TS frame (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing "
+ "a WMM Del TS frame (0x%08x)."), nStatus);
+ }
+ }
+
+ PELOG1(lim_log
+ (pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes);
+ lim_print_mac_addr(pMac, pMacHdr->da, LOG1);
+ )
+
+ if ((SIR_BAND_5_GHZ ==
+ lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE)
+ || (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ /* Pkt will be freed up by the callback */
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status))
+ lim_log(pMac, LOGE, FL("Failed to send Del TS (%X)!"),
+ cdf_status);
+
+} /* End lim_send_delts_req_action_frame. */
+
+/**
+ * lim_send_assoc_req_mgmt_frame() - Send association request
+ * @mac_ctx: Handle to MAC context
+ * @mlm_assoc_req: Association request information
+ * @pe_session: PE session information
+ *
+ * Builds and transmits association request frame to AP.
+ *
+ * Return: Void
+ */
+
+void
+lim_send_assoc_req_mgmt_frame(tpAniSirGlobal mac_ctx,
+ tLimMlmAssocReq *mlm_assoc_req,
+ tpPESession pe_session)
+{
+ tDot11fAssocRequest *frm;
+ uint16_t caps;
+ uint8_t *frame;
+ tSirRetStatus sir_status;
+ tLimMlmAssocCnf assoc_cnf;
+ uint32_t bytes, payload, status;
+ uint8_t qos_enabled, wme_enabled, wsm_enabled;
+ void *packet;
+ CDF_STATUS cdf_status;
+ uint16_t add_ie_len;
+ uint8_t *add_ie;
+ uint8_t *wps_ie = NULL;
+#if defined WLAN_FEATURE_VOWIFI
+ uint8_t power_caps = false;
+#endif
+ uint8_t tx_flag = 0;
+ uint8_t sme_sessionid = 0;
+ bool vht_enabled = false;
+ tDot11fIEExtCap extr_ext_cap;
+ bool extr_ext_flag = true;
+ tpSirMacMgmtHdr mac_hdr;
+
+ if (NULL == pe_session) {
+ lim_log(mac_ctx, LOGE, FL("pe_session is NULL"));
+ return;
+ }
+
+ sme_sessionid = pe_session->smeSessionId;
+
+ /* check this early to avoid unncessary operation */
+ if (NULL == pe_session->pLimJoinReq) {
+ lim_log(mac_ctx, LOGE, FL("pe_session->pLimJoinReq is NULL"));
+ return;
+ }
+ add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
+ add_ie = pe_session->pLimJoinReq->addIEAssoc.addIEdata;
+
+ frm = cdf_mem_malloc(sizeof(tDot11fAssocRequest));
+ if (NULL == frm) {
+ lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
+
+ if (add_ie_len) {
+ cdf_mem_set((uint8_t *) &extr_ext_cap, sizeof(tDot11fIEExtCap),
+ 0);
+ sir_status = lim_strip_extcap_update_struct(mac_ctx,
+ add_ie, &add_ie_len, &extr_ext_cap);
+ if (eSIR_SUCCESS != sir_status) {
+ extr_ext_flag = false;
+ lim_log(mac_ctx, LOG1,
+ FL("Unable to Stripoff ExtCap IE from Assoc Req"));
+ } else {
+ struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)
+ extr_ext_cap.bytes;
+
+ if (p_ext_cap->interworking_service)
+ p_ext_cap->qos_map = 1;
+ else {
+ /*
+ * No need to merge the EXT Cap from Supplicant
+ * if interworkingService is not set, as currently
+ * driver is only interested in interworkingService
+ * capability from supplicant. if in future any other
+ * EXT Cap info is required from supplicant
+ * it needs to be handled here.
+ */
+ extr_ext_flag = false;
+ }
+ }
+ } else {
+ lim_log(mac_ctx, LOG1, FL("No additional IE for Assoc Req"));
+ extr_ext_flag = false;
+ }
+
+ caps = mlm_assoc_req->capabilityInfo;
+#if defined(FEATURE_WLAN_WAPI)
+ /*
+ * According to WAPI standard:
+ * 7.3.1.4 Capability Information field
+ * In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0
+ * in transmitted Association or Reassociation management frames.
+ * APs ignore the Privacy subfield within received Association and
+ * Reassociation management frames.
+ */
+ if (pe_session->encryptType == eSIR_ED_WPI)
+ ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+ swap_bit_field16(caps, (uint16_t *) &frm->Capabilities);
+
+ frm->ListenInterval.interval = mlm_assoc_req->listenInterval;
+ populate_dot11f_ssid2(mac_ctx, &frm->SSID);
+ populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm->SuppRates, pe_session);
+
+ qos_enabled = (pe_session->limQosEnabled) &&
+ SIR_MAC_GET_QOS(pe_session->limCurrentBssCaps);
+
+ wme_enabled = (pe_session->limWmeEnabled) &&
+ LIM_BSS_CAPS_GET(WME, pe_session->limCurrentBssQosCaps);
+
+ /* We prefer .11e asociations: */
+ if (qos_enabled)
+ wme_enabled = false;
+
+ wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
+ LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
+
+ if (pe_session->lim11hEnable &&
+ pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
+#if defined WLAN_FEATURE_VOWIFI
+ power_caps = true;
+
+ populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
+ LIM_ASSOC, pe_session);
+#endif
+ populate_dot11f_supp_channels(mac_ctx, &frm->SuppChannels,
+ LIM_ASSOC, pe_session);
+
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
+ if (power_caps == false) {
+ power_caps = true;
+ populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
+ LIM_ASSOC, pe_session);
+ }
+ }
+#endif
+
+ if (qos_enabled)
+ populate_dot11f_qos_caps_station(mac_ctx, &frm->QOSCapsStation);
+
+ populate_dot11f_ext_supp_rates(mac_ctx,
+ POPULATE_DOT11F_RATES_OPERATIONAL, &frm->ExtSuppRates,
+ pe_session);
+
+#if defined WLAN_FEATURE_VOWIFI
+ if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps))
+ populate_dot11f_rrm_ie(mac_ctx, &frm->RRMEnabledCap,
+ pe_session);
+#endif
+ /*
+ * The join request *should* contain zero or one of the WPA and RSN
+ * IEs. The payload send along with the request is a
+ * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+ * typedef struct sSirRSNie
+ * {
+ * uint16_t length;
+ * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+ * } tSirRSNie, *tpSirRSNie;
+ * So, we should be able to make the following two calls harmlessly,
+ * since they do nothing if they don't find the given IE in the
+ * bytestream with which they're provided.
+ * The net effect of this will be to faithfully transmit whatever
+ * security IE is in the join request.
+ * However, if we're associating for the purpose of WPS
+ * enrollment, and we've been configured to indicate that by
+ * eliding the WPA or RSN IE, we just skip this:
+ */
+ if (add_ie_len && add_ie)
+ wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
+
+ if (NULL == wps_ie) {
+ populate_dot11f_rsn_opaque(mac_ctx,
+ &(pe_session->pLimJoinReq->rsnIE),
+ &frm->RSNOpaque);
+ populate_dot11f_wpa_opaque(mac_ctx,
+ &(pe_session->pLimJoinReq->rsnIE),
+ &frm->WPAOpaque);
+#if defined(FEATURE_WLAN_WAPI)
+ populate_dot11f_wapi_opaque(mac_ctx,
+ &(pe_session->pLimJoinReq->rsnIE),
+ &frm->WAPIOpaque);
+#endif /* defined(FEATURE_WLAN_WAPI) */
+ }
+ /* include WME EDCA IE as well */
+ if (wme_enabled) {
+ populate_dot11f_wmm_info_station_per_session(mac_ctx,
+ pe_session, &frm->WMMInfoStation);
+
+ if (wsm_enabled)
+ populate_dot11f_wmm_caps(&frm->WMMCaps);
+ }
+
+ /*
+ * Populate HT IEs, when operating in 11n and
+ * when AP is also operating in 11n mode
+ */
+ if (pe_session->htCapability &&
+ mac_ctx->lim.htCapabilityPresentInBeacon) {
+ lim_log(mac_ctx, LOG1, FL("Populate HT Caps in Assoc Request"));
+ populate_dot11f_ht_caps(mac_ctx, pe_session, &frm->HTCaps);
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pe_session->vhtCapability &&
+ pe_session->vhtCapabilityPresentInBeacon) {
+ lim_log(mac_ctx, LOG1, FL("Populate VHT IEs in Assoc Request"));
+ populate_dot11f_vht_caps(mac_ctx, pe_session, &frm->VHTCaps);
+ vht_enabled = true;
+ }
+ if (!vht_enabled &&
+ pe_session->is_vendor_specific_vhtcaps) {
+ lim_log(mac_ctx, LOG1,
+ FL("Populate Vendor VHT IEs in Assoc Request"));
+ frm->vendor2_ie.present = 1;
+ frm->vendor2_ie.type =
+ pe_session->vendor_specific_vht_ie_type;
+ frm->vendor2_ie.sub_type =
+ pe_session->vendor_specific_vht_ie_sub_type;
+
+ frm->vendor2_ie.VHTCaps.present = 1;
+ populate_dot11f_vht_caps(mac_ctx, pe_session,
+ &frm->vendor2_ie.VHTCaps);
+ vht_enabled = true;
+ }
+
+#endif
+
+ populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm->ExtCap, pe_session);
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (pe_session->pLimJoinReq->is11Rconnection) {
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ tSirBssDescription *bssdescr;
+
+ bssdescr = &pe_session->pLimJoinReq->bssDescription;
+ lim_log(mac_ctx, LOG1, FL("mdie = %02x %02x %02x"),
+ (unsigned int) bssdescr->mdie[0],
+ (unsigned int) bssdescr->mdie[1],
+ (unsigned int) bssdescr->mdie[2]);
+#endif
+ populate_mdie(mac_ctx, &frm->MobilityDomain,
+ pe_session->pLimJoinReq->bssDescription.mdie);
+ } else {
+ /* No 11r IEs dont send any MDIE */
+ lim_log(mac_ctx, LOG1, FL("MDIE not present"));
+ }
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ /*
+ * ESE Version IE will be included in association request
+ * when ESE is enabled on DUT through ini and it is also
+ * advertised by the peer AP to which we are trying to
+ * associate to.
+ */
+ if (pe_session->is_ese_version_ie_present &&
+ mac_ctx->roam.configParam.isEseIniFeatureEnabled)
+ populate_dot11f_ese_version(&frm->ESEVersion);
+ /* For ESE Associations fill the ESE IEs */
+ if (pe_session->isESEconnection &&
+ pe_session->pLimJoinReq->isESEFeatureIniEnabled) {
+#ifndef FEATURE_DISABLE_RM
+ populate_dot11f_ese_rad_mgmt_cap(&frm->ESERadMgmtCap);
+#endif
+ }
+#endif
+
+ status = dot11f_get_packed_assoc_request_size(mac_ctx, frm, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGP,
+ FL("Association Request packet size failure(0x%08x)."),
+ status);
+ /* We'll fall back on the worst case scenario: */
+ payload = sizeof(tDot11fAssocRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Association request packet size warning (0x%08x)."),
+ status);
+ }
+
+ bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
+
+ cdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
+ (void **)&packet);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGP, FL("Failed to allocate %d bytes."),
+ bytes);
+
+ pe_session->limMlmState = pe_session->limPrevMlmState;
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
+ pe_session->peSessionId,
+ pe_session->limMlmState));
+
+ /* Update PE session id */
+ assoc_cnf.sessionId = pe_session->peSessionId;
+
+ assoc_cnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+
+ cds_packet_free((void *)packet);
+
+ lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
+ (uint32_t *) &assoc_cnf);
+
+ cdf_mem_free(frm);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(frame, bytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ASSOC_REQ, pe_session->bssId,
+ pe_session->selfMacAddr);
+ /* merge the ExtCap struct */
+ if (extr_ext_flag)
+ lim_merge_extcap_struct(&frm->ExtCap, &extr_ext_cap);
+ /* That done, pack the Assoc Request: */
+ status = dot11f_pack_assoc_request(mac_ctx, frm,
+ frame + sizeof(tSirMacMgmtHdr), payload, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Assoc request pack failure (0x%08x)"), status);
+ cds_packet_free((void *)packet);
+ cdf_mem_free(frm);
+ return;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Assoc request pack warning (0x%08x)"), status);
+ }
+
+ lim_log(mac_ctx, LOG1,
+ FL("*** Sending Association Request length %d to "), bytes);
+ if (pe_session->assocReq != NULL) {
+ cdf_mem_free(pe_session->assocReq);
+ pe_session->assocReq = NULL;
+ }
+
+ if (add_ie_len) {
+ cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+ add_ie, add_ie_len);
+ payload += add_ie_len;
+ }
+
+ pe_session->assocReq = cdf_mem_malloc(payload);
+ if (NULL == pe_session->assocReq) {
+ lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
+ } else {
+ /*
+ * Store the Assoc request. This is sent to csr/hdd in
+ * join cnf response.
+ */
+ cdf_mem_copy(pe_session->assocReq,
+ frame + sizeof(tSirMacMgmtHdr), payload);
+ pe_session->assocReqLen = payload;
+ }
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(pe_session->currentOperChannel))
+ || (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
+ || (pe_session->pePersona == CDF_P2P_GO_MODE)
+ )
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+ if (pe_session->pePersona == CDF_P2P_CLIENT_MODE)
+ tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_ASSOC_START_EVENT,
+ pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ mac_hdr = (tpSirMacMgmtHdr) frame;
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ pe_session->peSessionId, mac_hdr->fc.subType));
+ cdf_status =
+ wma_tx_frame(mac_ctx, packet,
+ (uint16_t) (sizeof(tSirMacMgmtHdr) + payload),
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, frame, tx_flag, sme_sessionid, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ pe_session->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to send Association Request (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ cdf_mem_free(frm);
+ return;
+ }
+ /* Free up buffer allocated for mlm_assoc_req */
+ cdf_mem_free(mlm_assoc_req);
+ mlm_assoc_req = NULL;
+ cdf_mem_free(frm);
+ return;
+}
+
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+/**
+ * lim_send_reassoc_req_with_ft_ies_mgmt_frame() - Send Reassoc Req with FTIEs.
+ *
+ * @mac_ctx: Handle to mac context
+ * @mlm_reassoc_req: Original reassoc request
+ * @pe_session: PE session information
+ *
+ * It builds a reassoc request with FT IEs and sends it to AP through WMA.
+ * Then it creates assoc request and stores it for sending after join
+ * confirmation.
+ *
+ * Return: void
+ */
+
+void
+lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal mac_ctx,
+ tLimMlmReassocReq *mlm_reassoc_req,
+ tpPESession pe_session)
+{
+ static tDot11fReAssocRequest frm;
+ uint16_t caps;
+ uint8_t *frame;
+ uint32_t bytes, payload, status;
+ uint8_t qos_enabled, wme_enabled, wsm_enabled;
+ void *packet;
+ CDF_STATUS cdf_status;
+#if defined WLAN_FEATURE_VOWIFI
+ uint8_t power_caps_populated = false;
+#endif
+ uint16_t ft_ies_length = 0;
+ uint8_t *body;
+ uint16_t add_ie_len;
+ uint8_t *add_ie;
+#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ uint8_t *wps_ie = NULL;
+#endif
+ uint8_t tx_flag = 0;
+ uint8_t sme_sessionid = 0;
+ bool vht_enabled = false;
+ tpSirMacMgmtHdr mac_hdr;
+ tftSMEContext *ft_sme_context;
+
+ if (NULL == pe_session)
+ return;
+
+ sme_sessionid = pe_session->smeSessionId;
+
+ /* check this early to avoid unncessary operation */
+ if (NULL == pe_session->pLimReAssocReq)
+ return;
+
+ add_ie_len = pe_session->pLimReAssocReq->addIEAssoc.length;
+ add_ie = pe_session->pLimReAssocReq->addIEAssoc.addIEdata;
+ lim_log(mac_ctx, LOG1,
+ FL("called in state (%d)."), pe_session->limMlmState);
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ caps = mlm_reassoc_req->capabilityInfo;
+#if defined(FEATURE_WLAN_WAPI)
+ /*
+ * According to WAPI standard:
+ * 7.3.1.4 Capability Information field
+ * In WAPI, non-AP STAs within an ESS set the Privacy subfield
+ * to 0 in transmitted Association or Reassociation management
+ * frames. APs ignore the Privacy subfield within received
+ * Association and Reassociation management frames.
+ */
+ if (pe_session->encryptType == eSIR_ED_WPI)
+ ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+ swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
+
+ frm.ListenInterval.interval = mlm_reassoc_req->listenInterval;
+
+ /*
+ * Get the old bssid of the older AP.
+ * The previous ap bssid is stored in the FT Session
+ * while creating the PE FT Session for reassociation.
+ */
+ cdf_mem_copy((uint8_t *)frm.CurrentAPAddress.mac,
+ pe_session->prev_ap_bssid, sizeof(tSirMacAddr));
+
+ populate_dot11f_ssid2(mac_ctx, &frm.SSID);
+ populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates, pe_session);
+
+ qos_enabled = (pe_session->limQosEnabled) &&
+ SIR_MAC_GET_QOS(pe_session->limReassocBssCaps);
+
+ wme_enabled = (pe_session->limWmeEnabled) &&
+ LIM_BSS_CAPS_GET(WME, pe_session->limReassocBssQosCaps);
+
+ wsm_enabled = (pe_session->limWsmEnabled) && wme_enabled &&
+ LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);
+
+ if (pe_session->lim11hEnable &&
+ pe_session->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
+#if defined WLAN_FEATURE_VOWIFI
+ power_caps_populated = true;
+
+ populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
+ LIM_REASSOC, pe_session);
+ populate_dot11f_supp_channels(mac_ctx, &frm.SuppChannels,
+ LIM_REASSOC, pe_session);
+#endif
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM(pe_session->limCurrentBssCaps)) {
+ if (power_caps_populated == false) {
+ power_caps_populated = true;
+ populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
+ LIM_REASSOC, pe_session);
+ }
+ }
+#endif
+
+ if (qos_enabled)
+ populate_dot11f_qos_caps_station(mac_ctx, &frm.QOSCapsStation);
+
+ populate_dot11f_ext_supp_rates(mac_ctx,
+ POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates,
+ pe_session);
+
+#if defined WLAN_FEATURE_VOWIFI
+ if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM(pe_session->limReassocBssCaps)) {
+ populate_dot11f_rrm_ie(mac_ctx, &frm.RRMEnabledCap, pe_session);
+ }
+#endif
+
+ /*
+ * Ideally this should be enabled for 11r also. But 11r does
+ * not follow the usual norm of using the Opaque object
+ * for rsnie and fties. Instead we just add the rsnie and fties
+ * at the end of the pack routine for 11r.
+ * This should ideally! be fixed.
+ */
+#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ /*
+ * The join request *should* contain zero or one of the WPA and RSN
+ * IEs. The payload send along with the request is a
+ * 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie':
+ *
+ * typedef struct sSirRSNie
+ * {
+ * uint16_t length;
+ * uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2];
+ * } tSirRSNie, *tpSirRSNie;
+ *
+ * So, we should be able to make the following two calls harmlessly,
+ * since they do nothing if they don't find the given IE in the
+ * bytestream with which they're provided.
+ *
+ * The net effect of this will be to faithfully transmit whatever
+ * security IE is in the join request.
+
+ * However, if we're associating for the purpose of WPS
+ * enrollment, and we've been configured to indicate that by
+ * eliding the WPA or RSN IE, we just skip this:
+ */
+ if (!pe_session->is11Rconnection) {
+ if (add_ie_len && add_ie)
+ wps_ie = limGetWscIEPtr(mac_ctx, add_ie, add_ie_len);
+ if (NULL == wps_ie) {
+ populate_dot11f_rsn_opaque(mac_ctx,
+ &(pe_session->pLimReAssocReq->rsnIE),
+ &frm.RSNOpaque);
+ populate_dot11f_wpa_opaque(mac_ctx,
+ &(pe_session->pLimReAssocReq->rsnIE),
+ &frm.WPAOpaque);
+ }
+#ifdef FEATURE_WLAN_ESE
+ if (pe_session->pLimReAssocReq->cckmIE.length) {
+ populate_dot11f_ese_cckm_opaque(mac_ctx,
+ &(pe_session->pLimReAssocReq->cckmIE),
+ &frm.ESECckmOpaque);
+ }
+#endif
+ }
+#ifdef FEATURE_WLAN_ESE
+ /*
+ * ESE Version IE will be included in re-association request
+ * when ESE is enabled on DUT through ini and it is also
+ * advertised by the peer AP to which we are trying to
+ * associate to.
+ */
+ if (pe_session->is_ese_version_ie_present &&
+ mac_ctx->roam.configParam.isEseIniFeatureEnabled)
+ populate_dot11f_ese_version(&frm.ESEVersion);
+ /* For ESE Associations fill the ESE IEs */
+ if (pe_session->isESEconnection &&
+ pe_session->pLimReAssocReq->isESEFeatureIniEnabled) {
+#ifndef FEATURE_DISABLE_RM
+ populate_dot11f_ese_rad_mgmt_cap(&frm.ESERadMgmtCap);
+#endif
+ }
+#endif /* FEATURE_WLAN_ESE */
+#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
+
+ /* include WME EDCA IE as well */
+ if (wme_enabled) {
+ populate_dot11f_wmm_info_station_per_session(mac_ctx,
+ pe_session, &frm.WMMInfoStation);
+ if (wsm_enabled)
+ populate_dot11f_wmm_caps(&frm.WMMCaps);
+#ifdef FEATURE_WLAN_ESE
+ if (pe_session->isESEconnection) {
+ uint32_t phymode;
+ uint8_t rate;
+
+ populate_dot11f_re_assoc_tspec(mac_ctx, &frm,
+ pe_session);
+
+ /*
+ * Populate the TSRS IE if TSPEC is included in
+ * the reassoc request
+ */
+ lim_get_phy_mode(mac_ctx, &phymode, pe_session);
+ if (phymode == WNI_CFG_PHY_MODE_11G ||
+ phymode == WNI_CFG_PHY_MODE_11A)
+ rate = TSRS_11AG_RATE_6MBPS;
+ else
+ rate = TSRS_11B_RATE_5_5MBPS;
+
+ if (pe_session->pLimReAssocReq->eseTspecInfo.
+ numTspecs) {
+ tSirMacESETSRSIE tsrs_ie;
+
+ tsrs_ie.tsid = 0;
+ tsrs_ie.rates[0] = rate;
+ populate_dot11_tsrsie(mac_ctx, &tsrs_ie,
+ &frm.ESETrafStrmRateSet,
+ sizeof(uint8_t));
+ }
+ }
+#endif
+ }
+
+ ft_sme_context = &mac_ctx->roam.roamSession[sme_sessionid].ftSmeContext;
+ if (pe_session->htCapability &&
+ mac_ctx->lim.htCapabilityPresentInBeacon) {
+ populate_dot11f_ht_caps(mac_ctx, pe_session, &frm.HTCaps);
+ }
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (pe_session->pLimReAssocReq->bssDescription.mdiePresent &&
+ (ft_sme_context->addMDIE == true)
+#if defined FEATURE_WLAN_ESE
+ && !pe_session->isESEconnection
+#endif
+ ) {
+ populate_mdie(mac_ctx, &frm.MobilityDomain,
+ pe_session->pLimReAssocReq->bssDescription.mdie);
+ }
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+ if (pe_session->vhtCapability &&
+ pe_session->vhtCapabilityPresentInBeacon) {
+ lim_log(mac_ctx, LOG1,
+ FL("Populate VHT IEs in Re-Assoc Request"));
+ populate_dot11f_vht_caps(mac_ctx, pe_session, &frm.VHTCaps);
+ vht_enabled = true;
+ populate_dot11f_ext_cap(mac_ctx, vht_enabled, &frm.ExtCap,
+ pe_session);
+ }
+ if (!vht_enabled &&
+ pe_session->is_vendor_specific_vhtcaps) {
+ lim_log(mac_ctx, LOG1,
+ FL("Populate Vendor VHT IEs in Re-Assoc Request"));
+ frm.vendor2_ie.present = 1;
+ frm.vendor2_ie.type =
+ pe_session->vendor_specific_vht_ie_type;
+ frm.vendor2_ie.sub_type =
+ pe_session->vendor_specific_vht_ie_sub_type;
+ frm.vendor2_ie.VHTCaps.present = 1;
+ populate_dot11f_vht_caps(mac_ctx, pe_session,
+ &frm.vendor2_ie.VHTCaps);
+ vht_enabled = true;
+ }
+#endif
+
+ status = dot11f_get_packed_re_assoc_request_size(mac_ctx, &frm,
+ &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGP,
+ FL("Failure in size calculation (0x%08x)."), status);
+ /* We'll fall back on the worst case scenario: */
+ payload = sizeof(tDot11fReAssocRequest);
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Warnings in size calculation(0x%08x)."), status);
+ }
+
+ bytes = payload + sizeof(tSirMacMgmtHdr) + add_ie_len;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("FT IE Reassoc Req (%d)."),
+ ft_sme_context->reassoc_ft_ies_length);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (pe_session->is11Rconnection)
+ ft_ies_length = ft_sme_context->reassoc_ft_ies_length;
+#endif
+
+ cdf_status = cds_packet_alloc((uint16_t) bytes + ft_ies_length,
+ (void **)&frame, (void **)&packet);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ pe_session->limMlmState = pe_session->limPrevMlmState;
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
+ pe_session->peSessionId,
+ pe_session->limMlmState));
+ lim_log(mac_ctx, LOGP, FL("Failed to alloc memory %d"), bytes);
+ goto end;
+ }
+ /* Paranoia: */
+ cdf_mem_set(frame, bytes + ft_ies_length, 0);
+
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ lim_print_mac_addr(mac_ctx, pe_session->limReAssocbssId, LOG1);
+#endif
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_REASSOC_REQ, pe_session->limReAssocbssId,
+ pe_session->selfMacAddr);
+ mac_hdr = (tpSirMacMgmtHdr) frame;
+ /* That done, pack the ReAssoc Request: */
+ status = dot11f_pack_re_assoc_request(mac_ctx, &frm, frame +
+ sizeof(tSirMacMgmtHdr),
+ payload, &payload);
+ if (DOT11F_FAILED(status)) {
+ lim_log(mac_ctx, LOGE, FL("Failure in pack (0x%08x)."), status);
+ cds_packet_free((void *)packet);
+ goto end;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(mac_ctx, LOGW, FL("Warnings in pack (0x%08x)."),
+ status);
+ }
+
+ lim_log(mac_ctx, LOG3,
+ FL("*** Sending Re-Assoc Request length %d %d to "),
+ bytes, payload);
+
+ if (pe_session->assocReq != NULL) {
+ cdf_mem_free(pe_session->assocReq);
+ pe_session->assocReq = NULL;
+ }
+
+ if (add_ie_len) {
+ cdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
+ add_ie, add_ie_len);
+ payload += add_ie_len;
+ }
+
+ pe_session->assocReq = cdf_mem_malloc(payload);
+ if (NULL == pe_session->assocReq) {
+ lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
+ } else {
+ /*
+ * Store the Assoc request. This is sent to csr/hdd in
+ * join cnf response.
+ */
+ cdf_mem_copy(pe_session->assocReq,
+ frame + sizeof(tSirMacMgmtHdr), payload);
+ pe_session->assocReqLen = payload;
+ }
+
+ if (pe_session->is11Rconnection && ft_sme_context->reassoc_ft_ies) {
+ int i = 0;
+
+ body = frame + bytes;
+ for (i = 0; i < ft_ies_length; i++) {
+ *body = ft_sme_context->reassoc_ft_ies[i];
+ body++;
+ }
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ PELOGE(lim_log(mac_ctx, LOG1, FL("Re-assoc Req Frame is: "));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG1,
+ (uint8_t *) frame, (bytes + ft_ies_length));
+ )
+#endif
+ if ((SIR_BAND_5_GHZ ==
+ lim_get_rf_band(pe_session->currentOperChannel)) ||
+ (pe_session->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (pe_session->pePersona == CDF_P2P_GO_MODE)) {
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if (NULL != pe_session->assocReq) {
+ cdf_mem_free(pe_session->assocReq);
+ pe_session->assocReq = NULL;
+ }
+
+ pe_session->assocReq = cdf_mem_malloc(ft_ies_length);
+ if (NULL == pe_session->assocReq) {
+ lim_log(mac_ctx, LOGE, FL("Failed to alloc memory"));
+ pe_session->assocReqLen = 0;
+ } else {
+ /*
+ * Store the Assoc request. This is sent to csr/hdd in
+ * join cnf response.
+ */
+ cdf_mem_copy(pe_session->assocReq,
+ ft_sme_context->reassoc_ft_ies, (ft_ies_length));
+ pe_session->assocReqLen = (ft_ies_length);
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_START_EVENT,
+ pe_session, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ pe_session->peSessionId, mac_hdr->fc.subType));
+ cdf_status = wma_tx_frame(mac_ctx, packet,
+ (uint16_t) (bytes + ft_ies_length),
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, frame, tx_flag, sme_sessionid,
+ 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ pe_session->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Failed to send Re-Assoc Request (%X)!"),
+ cdf_status);
+ }
+
+end:
+ /* Free up buffer allocated for mlmAssocReq */
+ cdf_mem_free(mlm_reassoc_req);
+ pe_session->pLimMlmReassocReq = NULL;
+
+}
+
+void lim_send_retry_reassoc_req_frame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,
+ tpPESession psessionEntry)
+{
+ tLimMlmReassocCnf mlmReassocCnf; /* keep sme */
+ tLimMlmReassocReq *pTmpMlmReassocReq = NULL;
+ if (NULL == pTmpMlmReassocReq) {
+ pTmpMlmReassocReq = cdf_mem_malloc(sizeof(tLimMlmReassocReq));
+ if (NULL == pTmpMlmReassocReq)
+ goto end;
+ cdf_mem_set(pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0);
+ cdf_mem_copy(pTmpMlmReassocReq, pMlmReassocReq,
+ sizeof(tLimMlmReassocReq));
+ }
+ /* Prepare and send Reassociation request frame */
+ /* start reassoc timer. */
+ pMac->lim.limTimers.gLimReassocFailureTimer.sessionId =
+ psessionEntry->peSessionId;
+ /* Start reassociation failure timer */
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TIMER_ACTIVATE,
+ psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER));
+ if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer)
+ != TX_SUCCESS) {
+ /* Could not start reassoc failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("could not start Reassociation failure timer"));
+ /* Return Reassoc confirm with */
+ /* Resources Unavailable */
+ mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ goto end;
+ }
+
+ lim_send_reassoc_req_with_ft_ies_mgmt_frame(pMac, pTmpMlmReassocReq,
+ psessionEntry);
+ return;
+
+end:
+ /* Free up buffer allocated for reassocReq */
+ if (pMlmReassocReq != NULL) {
+ cdf_mem_free(pMlmReassocReq);
+ pMlmReassocReq = NULL;
+ }
+ if (pTmpMlmReassocReq != NULL) {
+ cdf_mem_free(pTmpMlmReassocReq);
+ pTmpMlmReassocReq = NULL;
+ }
+ mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE;
+ mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS;
+ /* Update PE sessio Id */
+ mlmReassocCnf.sessionId = psessionEntry->peSessionId;
+
+ lim_post_sme_message(pMac, LIM_MLM_REASSOC_CNF,
+ (uint32_t *) &mlmReassocCnf);
+}
+
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+
+void
+lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,
+ tpPESession psessionEntry)
+{
+ static tDot11fReAssocRequest frm;
+ uint16_t caps;
+ uint8_t *pFrame;
+ uint32_t nBytes, nPayload, nStatus;
+ uint8_t fQosEnabled, fWmeEnabled, fWsmEnabled;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint16_t nAddIELen;
+ uint8_t *pAddIE;
+ uint8_t *wpsIe = NULL;
+ uint8_t txFlag = 0;
+#if defined WLAN_FEATURE_VOWIFI
+ uint8_t PowerCapsPopulated = false;
+#endif
+ uint8_t smeSessionId = 0;
+ bool isVHTEnabled = false;
+ tpSirMacMgmtHdr pMacHdr;
+
+ if (NULL == psessionEntry) {
+ return;
+ }
+
+ smeSessionId = psessionEntry->smeSessionId;
+
+ /* check this early to avoid unncessary operation */
+ if (NULL == psessionEntry->pLimReAssocReq) {
+ return;
+ }
+ nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length;
+ pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ caps = pMlmReassocReq->capabilityInfo;
+#if defined(FEATURE_WLAN_WAPI)
+ /* CR: 262463 :
+ According to WAPI standard:
+ 7.3.1.4 Capability Information field
+ In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted
+ Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and
+ Reassociation management frames. */
+ if (psessionEntry->encryptType == eSIR_ED_WPI)
+ ((tSirMacCapabilityInfo *) &caps)->privacy = 0;
+#endif
+ swap_bit_field16(caps, (uint16_t *) &frm.Capabilities);
+
+ frm.ListenInterval.interval = pMlmReassocReq->listenInterval;
+
+ cdf_mem_copy((uint8_t *) frm.CurrentAPAddress.mac,
+ (uint8_t *) psessionEntry->bssId, 6);
+
+ populate_dot11f_ssid2(pMac, &frm.SSID);
+ populate_dot11f_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.SuppRates, psessionEntry);
+
+ fQosEnabled = (psessionEntry->limQosEnabled) &&
+ SIR_MAC_GET_QOS(psessionEntry->limReassocBssCaps);
+
+ fWmeEnabled = (psessionEntry->limWmeEnabled) &&
+ LIM_BSS_CAPS_GET(WME, psessionEntry->limReassocBssQosCaps);
+
+ fWsmEnabled = (psessionEntry->limWsmEnabled) && fWmeEnabled &&
+ LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
+
+ if (psessionEntry->lim11hEnable &&
+ psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
+#if defined WLAN_FEATURE_VOWIFI
+ PowerCapsPopulated = true;
+ populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
+ psessionEntry);
+ populate_dot11f_supp_channels(pMac, &frm.SuppChannels, LIM_REASSOC,
+ psessionEntry);
+#endif
+ }
+#if defined WLAN_FEATURE_VOWIFI
+ if (pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM(psessionEntry->limCurrentBssCaps)) {
+ if (PowerCapsPopulated == false) {
+ PowerCapsPopulated = true;
+ populate_dot11f_power_caps(pMac, &frm.PowerCaps,
+ LIM_REASSOC, psessionEntry);
+ }
+ }
+#endif
+
+ if (fQosEnabled)
+ populate_dot11f_qos_caps_station(pMac, &frm.QOSCapsStation);
+
+ populate_dot11f_ext_supp_rates(pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &frm.ExtSuppRates, psessionEntry);
+
+#if defined WLAN_FEATURE_VOWIFI
+ if (pMac->rrm.rrmPEContext.rrmEnable &&
+ SIR_MAC_GET_RRM(psessionEntry->limReassocBssCaps)) {
+ populate_dot11f_rrm_ie(pMac, &frm.RRMEnabledCap, psessionEntry);
+ }
+#endif
+ /* The join request *should* contain zero or one of the WPA and RSN */
+ /* IEs. The payload send along with the request is a */
+ /* 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': */
+
+ /* typedef struct sSirRSNie */
+ /* { */
+ /* uint16_t length; */
+ /* uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
+ /* } tSirRSNie, *tpSirRSNie; */
+
+ /* So, we should be able to make the following two calls harmlessly, */
+ /* since they do nothing if they don't find the given IE in the */
+ /* bytestream with which they're provided. */
+
+ /* The net effect of this will be to faithfully transmit whatever */
+ /* security IE is in the join request. */
+
+ /**However*, if we're associating for the purpose of WPS */
+ /* enrollment, and we've been configured to indicate that by */
+ /* eliding the WPA or RSN IE, we just skip this: */
+ if (nAddIELen && pAddIE) {
+ wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen);
+ }
+ if (NULL == wpsIe) {
+ populate_dot11f_rsn_opaque(pMac,
+ &(psessionEntry->pLimReAssocReq->rsnIE),
+ &frm.RSNOpaque);
+ populate_dot11f_wpa_opaque(pMac,
+ &(psessionEntry->pLimReAssocReq->rsnIE),
+ &frm.WPAOpaque);
+#if defined(FEATURE_WLAN_WAPI)
+ populate_dot11f_wapi_opaque(pMac,
+ &(psessionEntry->pLimReAssocReq->
+ rsnIE), &frm.WAPIOpaque);
+#endif /* defined(FEATURE_WLAN_WAPI) */
+ }
+ /* include WME EDCA IE as well */
+ if (fWmeEnabled) {
+ populate_dot11f_wmm_info_station_per_session(pMac,
+ psessionEntry,
+ &frm.WMMInfoStation);
+
+ if (fWsmEnabled)
+ populate_dot11f_wmm_caps(&frm.WMMCaps);
+ }
+
+ if (psessionEntry->htCapability &&
+ pMac->lim.htCapabilityPresentInBeacon) {
+ populate_dot11f_ht_caps(pMac, psessionEntry, &frm.HTCaps);
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (psessionEntry->vhtCapability &&
+ psessionEntry->vhtCapabilityPresentInBeacon) {
+ lim_log(pMac, LOGW, FL("Populate VHT IEs in Re-Assoc Request"));
+ populate_dot11f_vht_caps(pMac, psessionEntry, &frm.VHTCaps);
+ isVHTEnabled = true;
+ }
+#endif
+
+ populate_dot11f_ext_cap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry);
+
+ nStatus = dot11f_get_packed_re_assoc_request_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Re-Association Request (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fReAssocRequest);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Re-Association Re "
+ "quest(0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr) + nAddIELen;
+
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ psessionEntry->limMlmState = psessionEntry->limPrevMlmState;
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_MLM_STATE,
+ psessionEntry->peSessionId,
+ psessionEntry->limMlmState));
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate %d bytes for a Re-As"
+ "sociation Request."), nBytes);
+ goto end;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_REASSOC_REQ, psessionEntry->limReAssocbssId,
+ psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ /* That done, pack the Probe Request: */
+ nStatus = dot11f_pack_re_assoc_request(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE, FL("Failed to pack a Re-Association Reque"
+ "st (0x%08x)."), nStatus);
+ cds_packet_free((void *)pPacket);
+ goto end;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a R"
+ "e-Association Request (0x%08x)."),
+ nStatus);
+ }
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("*** Sending Re-Association Request length %d" "to "),
+ nBytes);
+ )
+
+ if (psessionEntry->assocReq != NULL) {
+ cdf_mem_free(psessionEntry->assocReq);
+ psessionEntry->assocReq = NULL;
+ }
+
+ if (nAddIELen) {
+ cdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
+ pAddIE, nAddIELen);
+ nPayload += nAddIELen;
+ }
+
+ psessionEntry->assocReq = cdf_mem_malloc(nPayload);
+ if (NULL == psessionEntry->assocReq) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("Unable to allocate memory to store assoc request"));
+ )
+ } else {
+ /* Store the Assoc request. This is sent to csr/hdd in join cnf response. */
+ cdf_mem_copy(psessionEntry->assocReq,
+ pFrame + sizeof(tSirMacMgmtHdr), nPayload);
+ psessionEntry->assocReqLen = nPayload;
+ }
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) {
+ txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT,
+ psessionEntry, eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status =
+ wma_tx_frame(pMac, pPacket,
+ (uint16_t) (sizeof(tSirMacMgmtHdr) + nPayload),
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, pFrame, txFlag, smeSessionId, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send Re-Association Request (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ }
+
+end:
+ /* Free up buffer allocated for mlmAssocReq */
+ cdf_mem_free(pMlmReassocReq);
+ psessionEntry->pLimMlmReassocReq = NULL;
+
+} /* lim_send_reassoc_req_mgmt_frame */
+
+/**
+ * lim_send_auth_mgmt_frame() - Send an Authentication frame
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @auth_frame: Pointer to Authentication frame structure
+ * @peer_addr: MAC address of destination peer
+ * @wep_bit: wep bit in frame control for Authentication frame3
+ * @session: PE session information
+ *
+ * This function is called by lim_process_mlm_messages(). Authentication frame
+ * is formatted and sent when this function is called.
+ *
+ * Return: void
+ */
+
+void
+lim_send_auth_mgmt_frame(tpAniSirGlobal mac_ctx,
+ tpSirMacAuthFrameBody auth_frame,
+ tSirMacAddr peer_addr,
+ uint8_t wep_bit, tpPESession session)
+{
+ uint8_t *frame, *body;
+ uint32_t frame_len = 0, body_len = 0;
+ tpSirMacMgmtHdr mac_hdr;
+ void *packet;
+ CDF_STATUS cdf_status;
+ uint8_t tx_flag = 0;
+ uint8_t sme_sessionid = 0;
+ uint16_t ft_ies_length = 0;
+
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGE, FL("Error: psession Entry is NULL"));
+ return;
+ }
+
+ sme_sessionid = session->smeSessionId;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Sending Auth seq# %d status %d (%d) to " MAC_ADDRESS_STR),
+ auth_frame->authTransactionSeqNumber,
+ auth_frame->authStatusCode,
+ (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
+ MAC_ADDR_ARRAY(peer_addr));
+
+ switch (auth_frame->authTransactionSeqNumber) {
+ case SIR_MAC_AUTH_FRAME_1:
+ /*
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus 2 bytes
+ * each for auth algorithm number, transaction number
+ * and status code.
+ */
+
+ frame_len = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (auth_frame->authAlgoNumber == eSIR_FT_AUTH) {
+ if (NULL != session->ftPEContext.pFTPreAuthReq &&
+ 0 != session->ftPEContext.pFTPreAuthReq->
+ ft_ies_length) {
+ ft_ies_length = session->ftPEContext.
+ pFTPreAuthReq->ft_ies_length;
+ frame_len += ft_ies_length;
+ lim_log(mac_ctx, LOG3,
+ FL("Auth frame, FTIES length added=%d"),
+ ft_ies_length);
+ } else {
+ lim_log(mac_ctx, LOG3,
+ FL("Auth frame, Does not contain FTIES!!!"));
+ frame_len += (2 + SIR_MDIE_SIZE);
+ }
+ }
+#endif
+ break;
+
+ case SIR_MAC_AUTH_FRAME_2:
+ if ((auth_frame->authAlgoNumber == eSIR_OPEN_SYSTEM) ||
+ ((auth_frame->authAlgoNumber == eSIR_SHARED_KEY) &&
+ (auth_frame->authStatusCode !=
+ eSIR_MAC_SUCCESS_STATUS))) {
+ /*
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus
+ * 2 bytes each for auth algorithm number,
+ * transaction number and status code.
+ */
+
+ frame_len = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ } else {
+ /*
+ * Shared Key algorithm with challenge text
+ * to be sent.
+ *
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus
+ * 2 bytes each for auth algorithm number,
+ * transaction number, status code and 128 bytes
+ * for challenge text.
+ */
+
+ frame_len = sizeof(tSirMacMgmtHdr) +
+ sizeof(tSirMacAuthFrame);
+ body_len = sizeof(tSirMacAuthFrameBody);
+ }
+ break;
+
+ case SIR_MAC_AUTH_FRAME_3:
+ if (wep_bit == LIM_WEP_IN_FC) {
+ /*
+ * Auth frame3 to be sent with encrypted framebody
+ *
+ * Allocate buffer for Authenticaton frame of size
+ * equal to management frame header length plus 2 bytes
+ * each for auth algorithm number, transaction number,
+ * status code, 128 bytes for challenge text and
+ * 4 bytes each for IV & ICV.
+ */
+
+ frame_len = sizeof(tSirMacMgmtHdr) +
+ LIM_ENCR_AUTH_BODY_LEN;
+ body_len = LIM_ENCR_AUTH_BODY_LEN;
+ } else {
+
+ /*
+ * Auth frame3 to be sent without encrypted framebody
+ *
+ * Allocate buffer for Authenticaton frame of size equal
+ * to management frame header length plus 2 bytes each
+ * for auth algorithm number, transaction number and
+ * status code.
+ */
+
+ frame_len = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ }
+ break;
+
+ case SIR_MAC_AUTH_FRAME_4:
+ /*
+ * Allocate buffer for Authenticaton frame of size equal
+ * to management frame header length plus 2 bytes each
+ * for auth algorithm number, transaction number and
+ * status code.
+ */
+
+ frame_len = sizeof(tSirMacMgmtHdr) +
+ SIR_MAC_AUTH_CHALLENGE_OFFSET;
+ body_len = SIR_MAC_AUTH_CHALLENGE_OFFSET;
+
+ break;
+ } /* switch (auth_frame->authTransactionSeqNumber) */
+
+ cdf_status = cds_packet_alloc((uint16_t) frame_len, (void **)&frame,
+ (void **)&packet);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(mac_ctx, LOGP,
+ FL("call to bufAlloc failed for AUTH frame"));
+ return;
+ }
+
+ cdf_mem_zero(frame, frame_len);
+
+ /* Prepare BD */
+ lim_populate_mac_header(mac_ctx, frame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_AUTH, peer_addr, session->selfMacAddr);
+ mac_hdr = (tpSirMacMgmtHdr) frame;
+ mac_hdr->fc.wep = wep_bit;
+
+ /* Prepare BSSId */
+ if (LIM_IS_AP_ROLE(session) ||
+ LIM_IS_BT_AMP_AP_ROLE(session))
+ cdf_mem_copy((uint8_t *) mac_hdr->bssId,
+ (uint8_t *) session->bssId,
+ sizeof(tSirMacAddr));
+
+ /* Prepare Authentication frame body */
+ body = frame + sizeof(tSirMacMgmtHdr);
+
+ if (wep_bit == LIM_WEP_IN_FC) {
+ cdf_mem_copy(body, (uint8_t *) auth_frame, body_len);
+
+ lim_log(mac_ctx, LOG1,
+ FL("*** Sending Auth seq# 3 status %d (%d) to"
+ MAC_ADDRESS_STR),
+ auth_frame->authStatusCode,
+ (auth_frame->authStatusCode == eSIR_MAC_SUCCESS_STATUS),
+ MAC_ADDR_ARRAY(mac_hdr->da));
+
+ } else {
+ *((uint16_t *) (body)) =
+ sir_swap_u16if_needed(auth_frame->authAlgoNumber);
+ body += sizeof(uint16_t);
+ body_len -= sizeof(uint16_t);
+
+ *((uint16_t *) (body)) =
+ sir_swap_u16if_needed(
+ auth_frame->authTransactionSeqNumber);
+ body += sizeof(uint16_t);
+ body_len -= sizeof(uint16_t);
+
+ *((uint16_t *) (body)) =
+ sir_swap_u16if_needed(auth_frame->authStatusCode);
+ body += sizeof(uint16_t);
+ body_len -= sizeof(uint16_t);
+ if (body_len <= (sizeof(auth_frame->type) +
+ sizeof(auth_frame->length) +
+ sizeof(auth_frame->challengeText)))
+ cdf_mem_copy(body, (uint8_t *) &auth_frame->type,
+ body_len);
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if ((auth_frame->authAlgoNumber == eSIR_FT_AUTH) &&
+ (auth_frame->authTransactionSeqNumber ==
+ SIR_MAC_AUTH_FRAME_1) &&
+ (session->ftPEContext.pFTPreAuthReq != NULL)) {
+
+ if (ft_ies_length > 0) {
+ cdf_mem_copy(body,
+ session->ftPEContext.
+ pFTPreAuthReq->ft_ies,
+ ft_ies_length);
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG2,
+ FL("Auth1 Frame FTIE is: "));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
+ (uint8_t *) body,
+ ft_ies_length);
+#endif
+ } else if (NULL != session->ftPEContext.
+ pFTPreAuthReq->pbssDescription) {
+ /* MDID attr is 54 */
+ *body = SIR_MDIE_ELEMENT_ID;
+ body++;
+ *body = SIR_MDIE_SIZE;
+ body++;
+ cdf_mem_copy(body,
+ &session->ftPEContext.pFTPreAuthReq->
+ pbssDescription->mdie[0],
+ SIR_MDIE_SIZE);
+ }
+ }
+#endif
+
+ lim_log(mac_ctx, LOG1,
+ FL("*** Sending Auth seq# %d status %d (%d) to "
+ MAC_ADDRESS_STR),
+ auth_frame->authTransactionSeqNumber,
+ auth_frame->authStatusCode,
+ (auth_frame->authStatusCode ==
+ eSIR_MAC_SUCCESS_STATUS),
+ MAC_ADDR_ARRAY(mac_hdr->da));
+ }
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2, frame, frame_len);
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(session->currentOperChannel))
+ || (session->pePersona == CDF_P2P_CLIENT_MODE)
+ || (session->pePersona == CDF_P2P_GO_MODE)
+#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ || ((NULL != session->ftPEContext.pFTPreAuthReq) &&
+ (SIR_BAND_5_GHZ ==
+ lim_get_rf_band(session->ftPEContext.pFTPreAuthReq->
+ preAuthchannelNum)))
+#endif
+ )
+ tx_flag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+
+
+ if (session->pePersona == CDF_P2P_CLIENT_MODE)
+ tx_flag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ session->peSessionId, mac_hdr->fc.subType));
+ /* Queue Authentication frame in high priority WQ */
+ cdf_status = wma_tx_frame(mac_ctx, packet, (uint16_t) frame_len,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS, 7, lim_tx_complete,
+ frame, tx_flag, sme_sessionid, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ session->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status))
+ lim_log(mac_ctx, LOGE,
+ FL("*** Could not send Auth frame, retCode=%X ***"),
+ cdf_status);
+
+ return;
+}
+
+CDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac)
+{
+ uint16_t aid;
+ tpDphHashNode pStaDs;
+ tLimMlmDeauthReq *pMlmDeauthReq;
+ tLimMlmDeauthCnf mlmDeauthCnf;
+ tpPESession psessionEntry;
+
+ pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
+ if (pMlmDeauthReq) {
+ if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) {
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_DEAUTH_ACK_TIMER);
+ }
+
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMlmDeauthReq->sessionId);
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("session does not exist for given sessionId"));
+ )
+ mlmDeauthCnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ pStaDs =
+ dph_lookup_hash_entry(pMac, pMlmDeauthReq->peerMacAddr, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs == NULL) {
+ mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ /* / Receive path cleanup with dummy packet */
+ lim_ft_cleanup_pre_auth_info(pMac, psessionEntry);
+ lim_cleanup_rx_path(pMac, pStaDs, psessionEntry);
+ /* / Free up buffer allocated for mlmDeauthReq */
+ cdf_mem_free(pMlmDeauthReq);
+ pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL;
+ }
+ return CDF_STATUS_SUCCESS;
+end:
+ cdf_mem_copy((uint8_t *) &mlmDeauthCnf.peerMacAddr,
+ (uint8_t *) pMlmDeauthReq->peerMacAddr,
+ sizeof(tSirMacAddr));
+ mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger;
+ mlmDeauthCnf.aid = pMlmDeauthReq->aid;
+ mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId;
+
+ /* Free up buffer allocated */
+ /* for mlmDeauthReq */
+ cdf_mem_free(pMlmDeauthReq);
+
+ lim_post_sme_message(pMac,
+ LIM_MLM_DEAUTH_CNF, (uint32_t *) &mlmDeauthCnf);
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_send_disassoc_cnf() - Send disassoc confirmation to SME
+ *
+ * @mac_ctx: Handle to MAC context
+ *
+ * Sends disassoc confirmation to SME. Removes disassoc request stored
+ * in lim.
+ *
+ * Return: CDF_STATUS_SUCCESS
+ */
+
+CDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal mac_ctx)
+{
+ uint16_t aid;
+ tpDphHashNode sta_ds;
+ tLimMlmDisassocCnf disassoc_cnf;
+ tpPESession pe_session;
+ tLimMlmDisassocReq *disassoc_req;
+
+ disassoc_req = mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
+ if (disassoc_req) {
+ if (tx_timer_running(
+ &mac_ctx->lim.limTimers.gLimDisassocAckTimer))
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_DISASSOC_ACK_TIMER);
+
+ pe_session = pe_find_session_by_session_id(
+ mac_ctx, disassoc_req->sessionId);
+ if (pe_session == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("No session for given sessionId"));
+ disassoc_cnf.resultCode =
+ eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+
+ sta_ds = dph_lookup_hash_entry(mac_ctx,
+ disassoc_req->peerMacAddr, &aid,
+ &pe_session->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGE, FL("StaDs Null"));
+ disassoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
+ goto end;
+ }
+ /* Receive path cleanup with dummy packet */
+ if (eSIR_SUCCESS !=
+ lim_cleanup_rx_path(mac_ctx, sta_ds, pe_session)) {
+ disassoc_cnf.resultCode =
+ eSIR_SME_RESOURCES_UNAVAILABLE;
+ lim_log(mac_ctx, LOGE, FL("cleanup_rx_path error"));
+ goto end;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (LIM_IS_STA_ROLE(pe_session) && (
+#ifdef FEATURE_WLAN_ESE
+ (pe_session->isESEconnection) ||
+#endif
+#ifdef FEATURE_WLAN_LFR
+ (pe_session->isFastRoamIniFeatureEnabled) ||
+#endif
+ (pe_session->is11Rconnection)) &&
+ (disassoc_req->reasonCode !=
+ eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) {
+ lim_log(mac_ctx, LOGE,
+ FL("FT Preauth Session (%p,%d) Clean up"),
+ pe_session, pe_session->peSessionId);
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+ /* Delete FT session if there exists one */
+ lim_ft_cleanup_pre_auth_info(mac_ctx, pe_session);
+#endif
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("No FT Preauth Session Clean up in role %d"
+#ifdef FEATURE_WLAN_ESE
+ " isESE %d"
+#endif
+#ifdef FEATURE_WLAN_LFR
+ " isLFR %d"
+#endif
+ " is11r %d reason %d"),
+ GET_LIM_SYSTEM_ROLE(pe_session),
+#ifdef FEATURE_WLAN_ESE
+ pe_session->isESEconnection,
+#endif
+#ifdef FEATURE_WLAN_LFR
+ pe_session->isFastRoamIniFeatureEnabled,
+#endif
+ pe_session->is11Rconnection,
+ disassoc_req->reasonCode);
+ }
+#endif
+ /* Free up buffer allocated for mlmDisassocReq */
+ cdf_mem_free(disassoc_req);
+ mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
+ return CDF_STATUS_SUCCESS;
+ } else {
+ return CDF_STATUS_SUCCESS;
+ }
+end:
+ cdf_mem_copy((uint8_t *) &disassoc_cnf.peerMacAddr,
+ (uint8_t *) disassoc_req->peerMacAddr,
+ sizeof(tSirMacAddr));
+ disassoc_cnf.aid = disassoc_req->aid;
+ disassoc_cnf.disassocTrigger = disassoc_req->disassocTrigger;
+
+ /* Update PE session ID */
+ disassoc_cnf.sessionId = disassoc_req->sessionId;
+
+ if (disassoc_req != NULL) {
+ /* / Free up buffer allocated for mlmDisassocReq */
+ cdf_mem_free(disassoc_req);
+ mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL;
+ }
+
+ lim_post_sme_message(mac_ctx, LIM_MLM_DISASSOC_CNF,
+ (uint32_t *) &disassoc_cnf);
+ return CDF_STATUS_SUCCESS;
+}
+
+CDF_STATUS lim_disassoc_tx_complete_cnf(tpAniSirGlobal pMac,
+ uint32_t txCompleteSuccess)
+{
+ return lim_send_disassoc_cnf(pMac);
+}
+
+CDF_STATUS lim_deauth_tx_complete_cnf(tpAniSirGlobal pMac,
+ uint32_t txCompleteSuccess)
+{
+ return lim_send_deauth_cnf(pMac);
+}
+
+/**
+ * \brief This function is called to send Disassociate frame.
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param nReason Indicates the reason that need to be sent in
+ * Disassociation frame
+ *
+ * \param peerMacAddr MAC address of the STA to which Disassociation frame is
+ * sent
+ *
+ *
+ */
+
+void
+lim_send_disassoc_mgmt_frame(tpAniSirGlobal pMac,
+ uint16_t nReason,
+ tSirMacAddr peer,
+ tpPESession psessionEntry, bool waitForAck)
+{
+ tDot11fDisassociation frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint32_t val = 0;
+ uint8_t smeSessionId = 0;
+ if (NULL == psessionEntry) {
+ return;
+ }
+
+ /*
+ * In case when cac timer is running for this SAP session then
+ * avoid sending disassoc out. It is violation of dfs specification.
+ */
+ if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
+ (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+ CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
+ FL
+ ("CAC timer is running, drop disassoc from going out"));
+ return;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Reason.code = nReason;
+
+ nStatus = dot11f_get_packed_disassociation_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Disassociation (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fDisassociation);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Disassociation "
+ "(0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Dis"
+ "association."), nBytes);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_DISASSOC, peer, psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ /* Prepare the BSSID */
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ nStatus = dot11f_pack_disassociation(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a Disassociation (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a D"
+ "isassociation (0x%08x)."), nStatus);
+ }
+
+ lim_log(pMac, LOG1,
+ FL("***Sessionid %d Sending Disassociation frame with "
+ "reason %u and waitForAck %d to " MAC_ADDRESS_STR " ,From "
+ MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason,
+ waitForAck, MAC_ADDR_ARRAY(pMacHdr->da),
+ MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if ((psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
+ txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+ }
+
+ if (waitForAck) {
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId,
+ pMacHdr->fc.subType));
+ /* Queue Disassociation frame in high priority WQ */
+ /* get the duration from the request */
+ cdf_status =
+ wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS, 7, lim_tx_complete,
+ pFrame, lim_disassoc_tx_complete_cnf,
+ txFlag, smeSessionId, false, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+
+ val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
+
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimDisassocAckTimer, val, 0)
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to change Disassoc ack Timer val"));
+ return;
+ } else if (TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.
+ gLimDisassocAckTimer)) {
+ lim_log(pMac, LOGP,
+ FL("Unable to activate Disassoc ack Timer"));
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_DISASSOC_ACK_TIMER);
+ return;
+ }
+ } else {
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId,
+ pMacHdr->fc.subType));
+ /* Queue Disassociation frame in high priority WQ */
+ cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7,
+ lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send Disassociation (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ }
+ }
+} /* End lim_send_disassoc_mgmt_frame. */
+
+/**
+ * \brief This function is called to send a Deauthenticate frame
+ *
+ *
+ * \param pMac Pointer to global MAC structure
+ *
+ * \param nReason Indicates the reason that need to be sent in the
+ * Deauthenticate frame
+ *
+ * \param peeer address of the STA to which the frame is to be sent
+ *
+ *
+ */
+
+void
+lim_send_deauth_mgmt_frame(tpAniSirGlobal pMac,
+ uint16_t nReason,
+ tSirMacAddr peer,
+ tpPESession psessionEntry, bool waitForAck)
+{
+ tDot11fDeAuth frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint32_t val = 0;
+#ifdef FEATURE_WLAN_TDLS
+ uint16_t aid;
+ tpDphHashNode pStaDs;
+#endif
+ uint8_t smeSessionId = 0;
+
+ if (NULL == psessionEntry) {
+ return;
+ }
+
+ /*
+ * In case when cac timer is running for this SAP session then
+ * avoid deauth frame out. It is violation of dfs specification.
+ */
+ if (((psessionEntry->pePersona == CDF_SAP_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) &&
+ (true == pMac->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+ CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_INFO,
+ FL
+ ("CAC timer is running, drop the deauth from going out"));
+ return;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Reason.code = nReason;
+
+ nStatus = dot11f_get_packed_de_auth_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a De-Authentication (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fDeAuth);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a De-Authentication "
+ "(0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status = cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
+ "Authentication."), nBytes);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_DEAUTH, peer, psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ /* Prepare the BSSID */
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ nStatus = dot11f_pack_de_auth(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr), nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a DeAuthentication (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a D"
+ "e-Authentication (0x%08x)."), nStatus);
+ }
+ lim_log(pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with "
+ "reason %u and waitForAck %d to " MAC_ADDRESS_STR
+ " ,From " MAC_ADDRESS_STR),
+ psessionEntry->peSessionId, nReason, waitForAck,
+ MAC_ADDR_ARRAY(pMacHdr->da),
+ MAC_ADDR_ARRAY(psessionEntry->selfMacAddr));
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ if ((psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
+ txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK;
+ }
+#ifdef FEATURE_WLAN_TDLS
+ pStaDs =
+ dph_lookup_hash_entry(pMac, peer, &aid,
+ &psessionEntry->dph.dphHashTable);
+#endif
+
+ if (waitForAck) {
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId,
+ pMacHdr->fc.subType));
+ /* Queue Disassociation frame in high priority WQ */
+ cdf_status =
+ wma_tx_frameWithTxComplete(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS, 7, lim_tx_complete,
+ pFrame, lim_deauth_tx_complete_cnf,
+ txFlag, smeSessionId, false, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ /* Pkt will be freed up by the callback lim_tx_complete */
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send De-Authentication (%X)!"),
+ cdf_status);
+
+ /* Call lim_process_deauth_ack_timeout which will send
+ * DeauthCnf for this frame
+ */
+ lim_process_deauth_ack_timeout(pMac);
+ return;
+ }
+
+ val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT);
+
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimDeauthAckTimer, val, 0)
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to change Deauth ack Timer val"));
+ return;
+ } else if (TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.
+ gLimDeauthAckTimer)) {
+ lim_log(pMac, LOGP,
+ FL("Unable to activate Deauth ack Timer"));
+ lim_deactivate_and_change_timer(pMac,
+ eLIM_DEAUTH_ACK_TIMER);
+ return;
+ }
+ } else {
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId,
+ pMacHdr->fc.subType));
+#ifdef FEATURE_WLAN_TDLS
+ if ((NULL != pStaDs)
+ && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) {
+ /* Queue Disassociation frame in high priority WQ */
+ cdf_status =
+ wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_IBSS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ } else {
+#endif
+ /* Queue Disassociation frame in high priority WQ */
+ cdf_status =
+ wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+#ifdef FEATURE_WLAN_TDLS
+ }
+#endif
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send De-Authentication (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ }
+ }
+
+} /* End lim_send_deauth_mgmt_frame. */
+
+#ifdef ANI_SUPPORT_11H
+/**
+ * \brief Send a Measurement Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_meas_report_frame(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ tSirMacAddr peer, tpPESession psessionEntry)
+{
+ tDot11fMeasurementReport frm;
+ uint8_t *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID;
+ frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken;
+
+ switch (pMeasReqFrame->measReqIE.measType) {
+ case SIR_MAC_BASIC_MEASUREMENT_TYPE:
+ nSirStatus =
+ populate_dot11f_measurement_report0(pMac, pMeasReqFrame,
+ &frm.MeasurementReport);
+ break;
+ case SIR_MAC_CCA_MEASUREMENT_TYPE:
+ nSirStatus =
+ populate_dot11f_measurement_report1(pMac, pMeasReqFrame,
+ &frm.MeasurementReport);
+ break;
+ case SIR_MAC_RPI_MEASUREMENT_TYPE:
+ nSirStatus =
+ populate_dot11f_measurement_report2(pMac, pMeasReqFrame,
+ &frm.MeasurementReport);
+ break;
+ default:
+ lim_log(pMac, LOGE, FL("Unknown measurement type %d in limSen"
+ "dMeasReportFrame."),
+ pMeasReqFrame->measReqIE.measType);
+ return eSIR_FAILURE;
+ }
+
+ if (eSIR_SUCCESS != nSirStatus)
+ return eSIR_FAILURE;
+
+ nStatus = dot11f_get_packed_measurement_report_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Measurement Report (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fMeasurementReport);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Measurement Rep"
+ "ort (0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
+ (uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a De-"
+ "Authentication."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ nStatus = dot11f_pack_measurement_report(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a Measurement Report (0x%08x)."),
+ nStatus);
+ cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
+ (void *)pFrame, (void *)pPacket);
+ return eSIR_FAILURE; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a M"
+ "easurement Report (0x%08x)."), nStatus);
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ ((psessionEntry) ? psessionEntry->
+ peSessionId : NO_SESSION), pMacHdr->fc.subType));
+ cdf_status =
+ wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, pFrame, 0, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
+ cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send a Measurement Report (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ return eSIR_FAILURE; /* just allocated... */
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End lim_send_meas_report_frame. */
+
+/**
+ * \brief Send a TPC Request Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which the frame should be sent
+ *
+ *
+ */
+
+void
+lim_send_tpc_request_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer, tpPESession psessionEntry)
+{
+ tDot11fTPCRequest frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID;
+ frm.DialogToken.token = 1;
+ frm.TPCRequest.present = 1;
+
+ nStatus = dot11f_get_packed_tpc_request_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a TPC Request (0x%08x)."), nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fTPCRequest);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a TPC Request (0x"
+ "%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
+ (uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Request."), nBytes);
+ return;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ nStatus = dot11f_pack_tpc_request(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."),
+ nStatus);
+ cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
+ (void *)pFrame, (void *)pPacket);
+ return; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a T"
+ "PC Request (0x%08x)."), nStatus);
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ ((psessionEntry) ? psessionEntry->
+ peSessionId : NO_SESSION), pMacHdr->fc.subType));
+ cdf_status =
+ wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, pFrame, 0, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
+ cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send a TPC Request (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ }
+
+} /* End lim_send_tpc_request_frame. */
+
+/**
+ * \brief Send a TPC Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param pTpcReqFrame Pointer to the received TPC Request
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_tpc_report_frame(tpAniSirGlobal pMac,
+ tpSirMacTpcReqActionFrame pTpcReqFrame,
+ tSirMacAddr peer, tpPESession psessionEntry)
+{
+ tDot11fTPCReport frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID;
+ frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken;
+
+ frm.TPCReport.tx_power = 0;
+ frm.TPCReport.link_margin = 0;
+ frm.TPCReport.present = 1;
+
+ nStatus = dot11f_get_packed_tpc_report_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a TPC Report (0x%08x)."), nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fTPCReport);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a TPC Report (0x"
+ "%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc(pMac->hHdd, TXRX_FRM_802_11_MGMT,
+ (uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Report."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer);
+
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ cdf_mem_copy(pMacHdr->bssId, psessionEntry->bssId, sizeof(tSirMacAddr));
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ nStatus = dot11f_pack_tpc_report(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."),
+ nStatus);
+ cds_packet_free(pMac->hHdd, TXRX_FRM_802_11_MGMT,
+ (void *)pFrame, (void *)pPacket);
+ return eSIR_FAILURE; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a T"
+ "PC Report (0x%08x)."), nStatus);
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ ((psessionEntry) ? psessionEntry->
+ peSessionId : NO_SESSION), pMacHdr->fc.subType));
+ cdf_status =
+ wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, 7,
+ lim_tx_complete, pFrame, 0, 0);
+ MTRACE(cdf_trace
+ (CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ ((psessionEntry) ? psessionEntry->peSessionId : NO_SESSION),
+ cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send a TPC Report (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ return eSIR_FAILURE; /* just allocated... */
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End lim_send_tpc_report_frame. */
+#endif /* ANI_SUPPORT_11H */
+
+/**
+ * \brief Send a Channel Switch Announcement
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which this frame will be sent
+ *
+ * \param nMode
+ *
+ * \param nNewChannel
+ *
+ * \param nCount
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ uint8_t nMode,
+ uint8_t nNewChannel,
+ uint8_t nCount, tpPESession psessionEntry)
+{
+ tDot11fChannelSwitch frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+
+ uint8_t smeSessionId = 0;
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
+ frm.ChanSwitchAnn.switchMode = nMode;
+ frm.ChanSwitchAnn.newChannel = nNewChannel;
+ frm.ChanSwitchAnn.switchCount = nCount;
+ frm.ChanSwitchAnn.present = 1;
+
+ nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Channel Switch (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fChannelSwitch);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Channel Switch (0x"
+ "%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Report."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer,
+ psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+ cdf_mem_copy((uint8_t *) pMacHdr->bssId,
+ (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a Channel Switch (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a C"
+ "hannel Switch (0x%08x)."), nStatus);
+ }
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send a Channel Switch (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End lim_send_channel_switch_mgmt_frame. */
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus
+lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ uint8_t nMode, tpPESession psessionEntry)
+{
+ tDot11fOperatingMode frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload = 0, nStatus; /* , nCfg; */
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+
+ uint8_t smeSessionId = 0;
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_VHT;
+ frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION;
+ frm.OperatingMode.chanWidth = nMode;
+ frm.OperatingMode.rxNSS = 0;
+ frm.OperatingMode.rxNSSType = 0;
+
+ nStatus = dot11f_get_packed_operating_mode_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Operating Mode (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fOperatingMode);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Operating Mode (0x"
+ "%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate %d bytes for a Operating Mode"
+ " Report."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ if (psessionEntry->pePersona == CDF_SAP_MODE)
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer,
+ psessionEntry->selfMacAddr);
+ else
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, psessionEntry->bssId,
+ psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+ cdf_mem_copy((uint8_t *) pMacHdr->bssId,
+ (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
+ nStatus = dot11f_pack_operating_mode(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a Operating Mode (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing a Operating Mode"
+ " (0x%08x)."), nStatus);
+ }
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send a Channel Switch (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * \brief Send a VHT Channel Switch Announcement
+ *
+ *
+ * \param pMac Pointer to the global MAC datastructure
+ *
+ * \param peer MAC address to which this frame will be sent
+ *
+ * \param nChanWidth
+ *
+ * \param nNewChannel
+ *
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_vht_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ uint8_t nChanWidth,
+ uint8_t nNewChannel,
+ uint8_t ncbMode, tpPESession psessionEntry)
+{
+ tDot11fChannelSwitch frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus; /* , nCfg; */
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+
+ uint8_t smeSessionId = 0;
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Session entry is NULL!!!"));)
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT;
+ frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID;
+ frm.ChanSwitchAnn.switchMode = 1;
+ frm.ChanSwitchAnn.newChannel = nNewChannel;
+ frm.ChanSwitchAnn.switchCount = 1;
+ frm.sec_chan_offset_ele.secondaryChannelOffset =
+ lim_get_htcb_state(ncbMode);
+ frm.sec_chan_offset_ele.present = 1;
+ frm.WiderBWChanSwitchAnn.newChanWidth = nChanWidth;
+ frm.WiderBWChanSwitchAnn.newCenterChanFreq0 =
+ lim_get_center_channel(pMac, nNewChannel, ncbMode, nChanWidth);
+ frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 0;
+ frm.ChanSwitchAnn.present = 1;
+ frm.WiderBWChanSwitchAnn.present = 1;
+
+ nStatus = dot11f_get_packed_channel_switch_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Channel Switch (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fChannelSwitch);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Channel Switch (0x"
+ "%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a TPC"
+ " Report."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+ cdf_mem_copy((uint8_t *) pMacHdr->bssId,
+ (uint8_t *) psessionEntry->bssId, sizeof(tSirMacAddr));
+ nStatus = dot11f_pack_channel_switch(pMac, &frm, pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack a Channel Switch (0x%08x)."),
+ nStatus);
+ cds_packet_free((void *)pPacket);
+ return eSIR_FAILURE; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while packing a C"
+ "hannel Switch (0x%08x)."), nStatus);
+ }
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac, pPacket, (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to send a Channel Switch (%X)!"),
+ cdf_status);
+ /* Pkt will be freed up by the callback */
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End lim_send_vht_channel_switch_mgmt_frame. */
+
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+
+/**
+ * \brief Send a Neighbor Report Request Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pNeighborReq Address of a tSirMacNeighborReportReq
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_neighbor_report_request_frame(tpAniSirGlobal pMac,
+ tpSirMacNeighborReportReq pNeighborReq,
+ tSirMacAddr peer, tpPESession psessionEntry)
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ tDot11fNeighborReportRequest frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL
+ ("(psession == NULL) in Request to send Neighbor Report request action frame"));
+ return eSIR_FAILURE;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_RRM;
+ frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ;
+ frm.DialogToken.token = pNeighborReq->dialogToken;
+
+ if (pNeighborReq->ssid_present) {
+ populate_dot11f_ssid(pMac, &pNeighborReq->ssid, &frm.SSID);
+ }
+
+ nStatus =
+ dot11f_get_packed_neighbor_report_request_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Neighbor Report Request(0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fNeighborReportRequest);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Neighbor Rep"
+ "ort Request(0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate %d bytes for a Neighbor "
+ "Report Request."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Copy necessary info to BD */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+ /* Update A3 with the BSSID */
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ /* Now, we're ready to "pack" the frames */
+ nStatus = dot11f_pack_neighbor_report_request(pMac,
+ &frm,
+ pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to pack an Neighbor Report Request (0x%08x)."),
+ nStatus);
+
+ /* FIXME - Need to convert to tSirRetStatus */
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing Neighbor Report "
+ "Request (0x%08x)."), nStatus);
+ }
+
+ lim_log(pMac, LOGW, FL("Sending a Neighbor Report Request to "));
+ lim_print_mac_addr(pMac, peer, LOGW);
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac,
+ pPacket,
+ (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (CDF_STATUS_SUCCESS != cdf_status) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
+ cdf_status);
+ )
+ statusCode = eSIR_FAILURE;
+ /* Pkt will be freed up by the callback */
+ return statusCode;
+ } else
+ return eSIR_SUCCESS;
+
+returnAfterError:
+ cds_packet_free((void *)pPacket);
+
+ return statusCode;
+} /* End lim_send_neighbor_report_request_frame. */
+
+/**
+ * \brief Send a Link Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pLinkReport Address of a tSirMacLinkReport
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_link_report_action_frame(tpAniSirGlobal pMac,
+ tpSirMacLinkReport pLinkReport,
+ tSirMacAddr peer, tpPESession psessionEntry)
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ tDot11fLinkMeasurementReport frm;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL
+ ("(psession == NULL) in Request to send Link Report action frame"));
+ return eSIR_FAILURE;
+ }
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+
+ frm.Category.category = SIR_MAC_ACTION_RRM;
+ frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT;
+ frm.DialogToken.token = pLinkReport->dialogToken;
+
+ /* IEEE Std. 802.11 7.3.2.18. for the report element. */
+ /* Even though TPC report an IE, it is represented using fixed fields since it is positioned */
+ /* in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 */
+ /* and frame parser always expects IEs to come after all fixed fields. It is easier to handle */
+ /* such case this way than changing the frame parser. */
+ frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID;
+ frm.TPCEleLen.TPCLen = 2;
+ frm.TxPower.txPower = pLinkReport->txPower;
+ frm.LinkMargin.linkMargin = 0;
+
+ frm.RxAntennaId.antennaId = pLinkReport->rxAntenna;
+ frm.TxAntennaId.antennaId = pLinkReport->txAntenna;
+ frm.RCPI.rcpi = pLinkReport->rcpi;
+ frm.RSNI.rsni = pLinkReport->rsni;
+
+ nStatus =
+ dot11f_get_packed_link_measurement_report_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Link Report (0x%08x)."), nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fLinkMeasurementReport);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Link Rep"
+ "ort (0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP, FL("Failed to allocate %d bytes for a Link "
+ "Report."), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Copy necessary info to BD */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+ /* Update A3 with the BSSID */
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ /* Now, we're ready to "pack" the frames */
+ nStatus = dot11f_pack_link_measurement_report(pMac,
+ &frm,
+ pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack an Link Report (0x%08x)."), nStatus);
+
+ /* FIXME - Need to convert to tSirRetStatus */
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while packing Link Report (0x%08x)."),
+ nStatus);
+ }
+
+ lim_log(pMac, LOGW, FL("Sending a Link Report to "));
+ lim_print_mac_addr(pMac, peer, LOGW);
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac,
+ pPacket,
+ (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (CDF_STATUS_SUCCESS != cdf_status) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
+ cdf_status);
+ )
+ statusCode = eSIR_FAILURE;
+ /* Pkt will be freed up by the callback */
+ return statusCode;
+ } else
+ return eSIR_SUCCESS;
+
+returnAfterError:
+ cds_packet_free((void *)pPacket);
+
+ return statusCode;
+} /* End lim_send_link_report_action_frame. */
+
+/**
+ * \brief Send a Beacon Report Action frame
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param dialog_token dialog token to be used in the action frame.
+ *
+ * \param num_report number of reports in pRRMReport.
+ *
+ * \param pRRMReport Address of a tSirMacRadioMeasureReport.
+ *
+ * \param peer mac address of peer station.
+ *
+ * \param psessionEntry address of session entry.
+ *
+ * \return eSIR_SUCCESS on success, eSIR_FAILURE else
+ *
+ *
+ */
+
+tSirRetStatus
+lim_send_radio_measure_report_action_frame(tpAniSirGlobal pMac,
+ uint8_t dialog_token,
+ uint8_t num_report,
+ tpSirMacRadioMeasureReport pRRMReport,
+ tSirMacAddr peer,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus statusCode = eSIR_SUCCESS;
+ uint8_t *pFrame;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t i;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ tDot11fRadioMeasurementReport *frm =
+ cdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
+ if (!frm) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Not enough memory to allocate tDot11fRadioMeasurementReport"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL
+ ("(psession == NULL) in Request to send Beacon Report action frame"));
+ cdf_mem_free(frm);
+ return eSIR_FAILURE;
+ }
+ cdf_mem_set((uint8_t *) frm, sizeof(*frm), 0);
+
+ frm->Category.category = SIR_MAC_ACTION_RRM;
+ frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT;
+ frm->DialogToken.token = dialog_token;
+
+ frm->num_MeasurementReport =
+ (num_report >
+ RADIO_REPORTS_MAX_IN_A_FRAME) ? RADIO_REPORTS_MAX_IN_A_FRAME :
+ num_report;
+
+ for (i = 0; i < frm->num_MeasurementReport; i++) {
+ frm->MeasurementReport[i].type = pRRMReport[i].type;
+ frm->MeasurementReport[i].token = pRRMReport[i].token;
+ frm->MeasurementReport[i].late = 0; /* IEEE 802.11k section 7.3.22. (always zero in rrm) */
+ switch (pRRMReport[i].type) {
+ case SIR_MAC_RRM_BEACON_TYPE:
+ populate_dot11f_beacon_report(pMac,
+ &frm->MeasurementReport[i],
+ &pRRMReport[i].report.
+ beaconReport);
+ frm->MeasurementReport[i].incapable =
+ pRRMReport[i].incapable;
+ frm->MeasurementReport[i].refused =
+ pRRMReport[i].refused;
+ frm->MeasurementReport[i].present = 1;
+ break;
+ default:
+ frm->MeasurementReport[i].incapable =
+ pRRMReport[i].incapable;
+ frm->MeasurementReport[i].refused =
+ pRRMReport[i].refused;
+ frm->MeasurementReport[i].present = 1;
+ break;
+ }
+ }
+
+ nStatus =
+ dot11f_get_packed_radio_measurement_report_size(pMac, frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a Radio Measure Report (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fLinkMeasurementReport);
+ cdf_mem_free(frm);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for a Radio Measure Rep"
+ "ort (0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ cdf_status =
+ cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
+ (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate %d bytes for a Radio Measure "
+ "Report."), nBytes);
+ cdf_mem_free(frm);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Copy necessary info to BD */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+ /* Update A3 with the BSSID */
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+#ifdef WLAN_FEATURE_11W
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+#endif
+
+ /* Now, we're ready to "pack" the frames */
+ nStatus = dot11f_pack_radio_measurement_report(pMac,
+ frm,
+ pFrame +
+ sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack an Radio Measure Report (0x%08x)."),
+ nStatus);
+
+ /* FIXME - Need to convert to tSirRetStatus */
+ statusCode = eSIR_FAILURE;
+ goto returnAfterError;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL("There were warnings while packing Radio "
+ "Measure Report (0x%08x)."), nStatus);
+ }
+
+ lim_log(pMac, LOGW, FL("Sending a Radio Measure Report to "));
+ lim_print_mac_addr(pMac, peer, LOGW);
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac,
+ pPacket,
+ (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (CDF_STATUS_SUCCESS != cdf_status) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
+ cdf_status);
+ )
+ statusCode = eSIR_FAILURE;
+ /* Pkt will be freed up by the callback */
+ cdf_mem_free(frm);
+ return statusCode;
+ } else {
+ cdf_mem_free(frm);
+ return eSIR_SUCCESS;
+ }
+
+returnAfterError:
+ cdf_mem_free(frm);
+ cds_packet_free((void *)pPacket);
+ return statusCode;
+}
+
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * \brief Send SA query request action frame to peer
+ *
+ * \sa lim_send_sa_query_request_frame
+ *
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param transId Transaction identifier
+ *
+ * \param peer The Mac address of the station to which this action frame is addressed
+ *
+ * \param psessionEntry The PE session entry
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+
+tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
+ tSirMacAddr peer,
+ tpPESession psessionEntry)
+{
+
+ tDot11fSaQueryReq frm; /* SA query request action frame */
+ uint8_t *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+ frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
+ /* 11w action field is :
+ action: 0 --> SA Query Request action frame
+ action: 1 --> SA Query Response action frame */
+ frm.Action.action = SIR_MAC_SA_QUERY_REQ;
+ /* 11w SA Query Request transId */
+ cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
+
+ nStatus = dot11f_get_packed_sa_query_req_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size "
+ "for an SA Query Request (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fSaQueryReq);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for an SA Query Request"
+ " (0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+ cdf_status =
+ cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate %d bytes for a SA Query Request "
+ "action frame"), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Copy necessary info to BD */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+ /* Update A3 with the BSSID */
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+ /* Since this is a SA Query Request, set the "protect" (aka WEP) bit */
+ /* in the FC */
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+ /* Pack 11w SA Query Request frame */
+ nStatus = dot11f_pack_sa_query_req(pMac,
+ &frm,
+ pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack an SA Query Request (0x%08x)."),
+ nStatus);
+ /* FIXME - Need to convert to tSirRetStatus */
+ nSirStatus = eSIR_FAILURE;
+ goto returnAfterError;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while packing SA Query Request (0x%08x)."),
+ nStatus);
+ }
+
+ lim_log(pMac, LOG1, FL("Sending an SA Query Request to "));
+ lim_print_mac_addr(pMac, peer, LOG1);
+ lim_log(pMac, LOG1, FL("Sending an SA Query Request from "));
+ lim_print_mac_addr(pMac, psessionEntry->selfMacAddr, LOG1);
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+#endif
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_status = wma_tx_frame(pMac,
+ pPacket,
+ (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ if (CDF_STATUS_SUCCESS != cdf_status) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
+ cdf_status);
+ )
+ nSirStatus = eSIR_FAILURE;
+ /* Pkt will be freed up by the callback */
+ return nSirStatus;
+ } else {
+ return eSIR_SUCCESS;
+ }
+
+returnAfterError:
+ cds_packet_free((void *)pPacket);
+ return nSirStatus;
+} /* End lim_send_sa_query_request_frame */
+
+/**
+ * \brief Send SA query response action frame to peer
+ *
+ * \sa lim_send_sa_query_response_frame
+ *
+ *
+ * \param pMac The global tpAniSirGlobal object
+ *
+ * \param transId Transaction identifier received in SA query request action frame
+ *
+ * \param peer The Mac address of the AP to which this action frame is addressed
+ *
+ * \param psessionEntry The PE session entry
+ *
+ * \return eSIR_SUCCESS if setup completes successfully
+ * eSIR_FAILURE is some problem is encountered
+ */
+
+tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
+ uint8_t *transId, tSirMacAddr peer,
+ tpPESession psessionEntry)
+{
+
+ tDot11fSaQueryRsp frm; /* SA query reponse action frame */
+ uint8_t *pFrame;
+ tSirRetStatus nSirStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t nBytes, nPayload, nStatus;
+ void *pPacket;
+ CDF_STATUS cdf_status;
+ uint8_t txFlag = 0;
+ uint8_t smeSessionId = 0;
+
+ smeSessionId = psessionEntry->smeSessionId;
+
+ cdf_mem_set((uint8_t *) &frm, sizeof(frm), 0);
+ frm.Category.category = SIR_MAC_ACTION_SA_QUERY;
+ /*11w action field is :
+ action: 0 --> SA query request action frame
+ action: 1 --> SA query response action frame */
+ frm.Action.action = SIR_MAC_SA_QUERY_RSP;
+ /*11w SA query response transId is same as
+ SA query request transId */
+ cdf_mem_copy(&frm.TransactionId.transId[0], &transId[0], 2);
+
+ nStatus = dot11f_get_packed_sa_query_rsp_size(pMac, &frm, &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGP, FL("Failed to calculate the packed size f"
+ "or a SA Query Response (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fSaQueryRsp);
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW, FL("There were warnings while calculating "
+ "the packed size for an SA Query Response"
+ " (0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+ cdf_status =
+ cds_packet_alloc(nBytes, (void **)&pFrame, (void **)&pPacket);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate %d bytes for a SA query response"
+ " action frame"), nBytes);
+ return eSIR_FAILURE;
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame, nBytes, 0);
+
+ /* Copy necessary info to BD */
+ lim_populate_mac_header(pMac, pFrame, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr);
+
+ /* Update A3 with the BSSID */
+ pMacHdr = (tpSirMacMgmtHdr) pFrame;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+ /* Since this is a SA Query Response, set the "protect" (aka WEP) bit */
+ /* in the FC */
+ lim_set_protected_bit(pMac, psessionEntry, peer, pMacHdr);
+
+ /* Pack 11w SA query response frame */
+ nStatus = dot11f_pack_sa_query_rsp(pMac,
+ &frm,
+ pFrame + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(nStatus)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to pack an SA Query Response (0x%08x)."),
+ nStatus);
+ /* FIXME - Need to convert to tSirRetStatus */
+ nSirStatus = eSIR_FAILURE;
+ goto returnAfterError;
+ } else if (DOT11F_WARNED(nStatus)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while packing SA Query Response (0x%08x)."),
+ nStatus);
+ }
+
+ lim_log(pMac, LOG1, FL("Sending a SA Query Response to "));
+ lim_print_mac_addr(pMac, peer, LOGW);
+
+ if ((SIR_BAND_5_GHZ == lim_get_rf_band(psessionEntry->currentOperChannel))
+#ifdef WLAN_FEATURE_P2P
+ || (psessionEntry->pePersona == CDF_P2P_CLIENT_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)
+#endif
+ ) {
+ txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME;
+ }
+
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+ psessionEntry->peSessionId, pMacHdr->fc.subType));
+ cdf_status = wma_tx_frame(pMac,
+ pPacket,
+ (uint16_t) nBytes,
+ TXRX_FRM_802_11_MGMT,
+ ANI_TXDIR_TODS,
+ 7, lim_tx_complete, pFrame, txFlag,
+ smeSessionId, 0);
+ MTRACE(cdf_trace(CDF_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+ psessionEntry->peSessionId, cdf_status));
+ if (CDF_STATUS_SUCCESS != cdf_status) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("wma_tx_frame FAILED! Status [%d]"),
+ cdf_status);
+ )
+ nSirStatus = eSIR_FAILURE;
+ /* Pkt will be freed up by the callback */
+ return nSirStatus;
+ } else {
+ return eSIR_SUCCESS;
+ }
+
+returnAfterError:
+ cds_packet_free((void *)pPacket);
+ return nSirStatus;
+} /* End lim_send_sa_query_response_frame */
+#endif
diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c
new file mode 100644
index 0000000..e47bf2f
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_messages.c
@@ -0,0 +1,854 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * lim_send_messages.c: Provides functions to send messages or Indications to HAL.
+ * Author: Sunit Bhatia
+ * Date: 09/21/2006
+ * History:-
+ * Date Modified by Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+#include "lim_send_messages.h"
+#include "cfg_api.h"
+#include "lim_trace.h"
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+/* When beacon filtering is enabled, firmware will
+ * analyze the selected beacons received during BMPS,
+ * and monitor any changes in the IEs as listed below.
+ * The format of the table is:
+ * - EID
+ * - Check for IE presence
+ * - Byte offset
+ * - Byte value
+ * - Bit Mask
+ * - Byte refrence
+ */
+static tBeaconFilterIe beacon_filter_table[] = {
+ {SIR_MAC_DS_PARAM_SET_EID, 0, {0, 0, DS_PARAM_CHANNEL_MASK, 0} },
+ {SIR_MAC_ERP_INFO_EID, 0, {0, 0, ERP_FILTER_MASK, 0} },
+ {SIR_MAC_EDCA_PARAM_SET_EID, 0, {0, 0, EDCA_FILTER_MASK, 0} },
+ {SIR_MAC_QOS_CAPABILITY_EID, 0, {0, 0, QOS_FILTER_MASK, 0} },
+ {SIR_MAC_CHNL_SWITCH_ANN_EID, 1, {0, 0, 0, 0} },
+ {SIR_MAC_HT_INFO_EID, 0, {0, 0, HT_BYTE0_FILTER_MASK, 0} },
+ {SIR_MAC_HT_INFO_EID, 0, {2, 0, HT_BYTE2_FILTER_MASK, 0} },
+ {SIR_MAC_HT_INFO_EID, 0, {5, 0, HT_BYTE5_FILTER_MASK, 0} }
+#if defined WLAN_FEATURE_VOWIFI
+ , {SIR_MAC_PWR_CONSTRAINT_EID, 0, {0, 0, 0, 0} }
+#endif
+#ifdef WLAN_FEATURE_11AC
+ , {SIR_MAC_VHT_OPMODE_EID, 0, {0, 0, 0, 0} }
+ , {SIR_MAC_VHT_OPERATION_EID, 0, {0, 0, VHTOP_CHWIDTH_MASK, 0} }
+#endif
+};
+
+/**
+ * lim_send_cf_params()
+ *
+ ***FUNCTION:
+ * This function is called to send CFP Parameters to WMA, when they are changed.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param bssIdx Bss Index of the BSS to which STA is associated.
+ * @param cfpCount CFP Count, if that is changed.
+ * @param cfpPeriod CFP Period if that is changed.
+ *
+ * @return success if message send is ok, else false.
+ */
+tSirRetStatus lim_send_cf_params(tpAniSirGlobal pMac, uint8_t bssIdx,
+ uint8_t cfpCount, uint8_t cfpPeriod)
+{
+ tpUpdateCFParams pCFParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ pCFParams = cdf_mem_malloc(sizeof(tUpdateCFParams));
+ if (NULL == pCFParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update CF Params"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ goto returnFailure;
+ }
+ cdf_mem_set((uint8_t *) pCFParams, sizeof(tUpdateCFParams), 0);
+ pCFParams->cfpCount = cfpCount;
+ pCFParams->cfpPeriod = cfpPeriod;
+ pCFParams->bssIdx = bssIdx;
+
+ msgQ.type = WMA_UPDATE_CF_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pCFParams;
+ msgQ.bodyval = 0;
+ lim_log(pMac, LOG3, FL("Sending WMA_UPDATE_CF_IND..."));
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pCFParams);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_CF_IND failed, reason=%X"),
+ retCode);
+ }
+returnFailure:
+ return retCode;
+}
+
+/**
+ * lim_send_beacon_params() - updates bcn params to WMA
+ *
+ * @pMac : pointer to Global Mac structure.
+ * @tpUpdateBeaconParams : pointer to the structure, which contains the beacon
+ * parameters which are changed.
+ *
+ * This function is called to send beacon interval, short preamble or other
+ * parameters to WMA, which are changed and indication is received in beacon.
+ *
+ * @return success if message send is ok, else false.
+ */
+tSirRetStatus lim_send_beacon_params(tpAniSirGlobal pMac,
+ tpUpdateBeaconParams pUpdatedBcnParams,
+ tpPESession psessionEntry)
+{
+ tpUpdateBeaconParams pBcnParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ pBcnParams = cdf_mem_malloc(sizeof(*pBcnParams));
+ if (NULL == pBcnParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update Beacon Params"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_copy((uint8_t *) pBcnParams, pUpdatedBcnParams,
+ sizeof(*pBcnParams));
+ msgQ.type = WMA_UPDATE_BEACON_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pBcnParams;
+ msgQ.bodyval = 0;
+ PELOG3(lim_log(pMac, LOG3,
+ FL("Sending WMA_UPDATE_BEACON_IND, paramChangeBitmap in hex = %x"),
+ pUpdatedBcnParams->paramChangeBitmap);)
+ if (NULL == psessionEntry) {
+ cdf_mem_free(pBcnParams);
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ return eSIR_FAILURE;
+ } else {
+ MTRACE(mac_trace_msg_tx(pMac,
+ psessionEntry->peSessionId,
+ msgQ.type));
+ }
+ pBcnParams->smeSessionId = psessionEntry->smeSessionId;
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pBcnParams);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_BEACON_IND, reason=%X"),
+ retCode);
+ }
+ lim_send_beacon_ind(pMac, psessionEntry);
+ return retCode;
+}
+
+/**
+ * lim_send_switch_chnl_params()
+ *
+ ***FUNCTION:
+ * This function is called to send Channel Switch Indication to WMA
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param chnlNumber New Channel Number to be switched to.
+ * @param ch_width an enum for channel width.
+ * @param localPowerConstraint 11h local power constraint value
+ *
+ * @return success if message send is ok, else false.
+ */
+#if !defined WLAN_FEATURE_VOWIFI
+tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac,
+ uint8_t chnlNumber,
+ uint8_t ch_center_freq_seg0,
+ uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width,
+ uint8_t localPwrConstraint,
+ uint8_t peSessionId,
+ uint8_t is_restart)
+#else
+tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac,
+ uint8_t chnlNumber,
+ uint8_t ch_center_freq_seg0,
+ uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width,
+ tPowerdBm maxTxPower,
+ uint8_t peSessionId,
+ uint8_t is_restart)
+#endif
+{
+ tpSwitchChannelParams pChnlParams = NULL;
+ tSirMsgQ msgQ;
+ tpPESession pSessionEntry;
+ pSessionEntry = pe_find_session_by_session_id(pMac, peSessionId);
+ if (pSessionEntry == NULL) {
+ lim_log(pMac, LOGP, FL(
+ "Unable to get Session for session Id %d"),
+ peSessionId);
+ return eSIR_FAILURE;
+ }
+ pChnlParams = cdf_mem_malloc(sizeof(tSwitchChannelParams));
+ if (NULL == pChnlParams) {
+ lim_log(pMac, LOGP, FL(
+ "Unable to allocate memory for Switch Ch Params"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set((uint8_t *) pChnlParams, sizeof(tSwitchChannelParams), 0);
+ pChnlParams->channelNumber = chnlNumber;
+ pChnlParams->ch_center_freq_seg0 = ch_center_freq_seg0;
+ pChnlParams->ch_center_freq_seg1 = ch_center_freq_seg1;
+ pChnlParams->ch_width = ch_width;
+ cdf_mem_copy(pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr,
+ sizeof(tSirMacAddr));
+#if defined WLAN_FEATURE_VOWIFI
+ pChnlParams->maxTxPower = maxTxPower;
+#else
+ pChnlParams->localPowerConstraint = localPwrConstraint;
+#endif
+ cdf_mem_copy(pChnlParams->bssId, pSessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ pChnlParams->peSessionId = peSessionId;
+ pChnlParams->vhtCapable = pSessionEntry->vhtCapability;
+ pChnlParams->dot11_mode = pSessionEntry->dot11mode;
+ pChnlParams->nss = pSessionEntry->nss;
+ lim_log(pMac, LOG2, FL("nss value: %d"), pChnlParams->nss);
+
+ /*Set DFS flag for DFS channel */
+ if (cds_get_channel_state(chnlNumber) == CHANNEL_STATE_DFS)
+ pChnlParams->isDfsChannel = true;
+ else
+ pChnlParams->isDfsChannel = false;
+
+ pChnlParams->restart_on_chan_switch = is_restart;
+
+ /* we need to defer the message until we
+ * get the response back from WMA
+ */
+ SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
+ msgQ.type = WMA_CHNL_SWITCH_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pChnlParams;
+ msgQ.bodyval = 0;
+#if defined WLAN_FEATURE_VOWIFI
+ PELOG3(lim_log(pMac, LOG3, FL(
+ "Sending CH_SWITCH_REQ, ch_width %d, ch_num %d, maxTxPower %d"),
+ pChnlParams->ch_width,
+ pChnlParams->channelNumber, pChnlParams->maxTxPower);)
+#else
+ PELOG3(lim_log(pMac, LOG3, FL(
+ "Sending CH_SWITCH_REQ, ch_width %d, ch_num %d, local_pwr_constraint %d"),
+ pChnlParams->ch_width,
+ pChnlParams->channelNumber,
+ pChnlParams->localPowerConstraint);)
+#endif
+ MTRACE(mac_trace_msg_tx(pMac, peSessionId, msgQ.type));
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msgQ)) {
+ cdf_mem_free(pChnlParams);
+ lim_log(pMac, LOGP, FL(
+ "Posting CH_SWITCH_REQ to WMA failed"));
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_send_edca_params()
+ *
+ ***FUNCTION:
+ * This function is called to send dynamically changing EDCA Parameters to WMA.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param tpUpdatedEdcaParams pointer to the structure which contains
+ * dynamically changing EDCA parameters.
+ * @param highPerformance If the peer is Airgo (taurus) then switch to highPerformance is true.
+ *
+ * @return success if message send is ok, else false.
+ */
+tSirRetStatus lim_send_edca_params(tpAniSirGlobal pMac,
+ tSirMacEdcaParamRecord *pUpdatedEdcaParams,
+ uint16_t bssIdx)
+{
+ tEdcaParams *pEdcaParams = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ uint8_t i;
+
+ pEdcaParams = cdf_mem_malloc(sizeof(tEdcaParams));
+ if (NULL == pEdcaParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update EDCA Params"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ return retCode;
+ }
+ pEdcaParams->bssIdx = bssIdx;
+ pEdcaParams->acbe = pUpdatedEdcaParams[EDCA_AC_BE];
+ pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK];
+ pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI];
+ pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO];
+ msgQ.type = WMA_UPDATE_EDCA_PROFILE_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pEdcaParams;
+ msgQ.bodyval = 0;
+ PELOG1(lim_log(pMac, LOG1,
+ FL("Sending WMA_UPDATE_EDCA_PROFILE_IND, EDCA Parameters:"));)
+ for (i = 0; i < MAX_NUM_AC; i++) {
+ PELOG1(lim_log(pMac, LOG1,
+ FL("AC[%d]: AIFSN %d, ACM %d, CWmin %d, CWmax %d, TxOp %d "),
+ i, pUpdatedEdcaParams[i].aci.aifsn,
+ pUpdatedEdcaParams[i].aci.acm,
+ pUpdatedEdcaParams[i].cw.min,
+ pUpdatedEdcaParams[i].cw.max,
+ pUpdatedEdcaParams[i].txoplimit);)
+ }
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pEdcaParams);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_EDCA_PROFILE_IND failed, reason=%X"),
+ retCode);
+ }
+ return retCode;
+}
+
+/**
+ * lim_set_active_edca_params() - Choose best EDCA parameters
+ *
+ * @mac_ctx: pointer to Global Mac structure.
+ * @edca_params: pointer to the local EDCA parameters
+ * @pe_session: point to the session entry
+ *
+ * This function is called to set the most up-to-date EDCA parameters
+ * given the default local EDCA parameters. The rules are as following:
+ * - If ACM bit is set for all ACs, then downgrade everything to Best Effort.
+ * - If ACM is not set for any AC, then PE will use the default EDCA
+ * parameters as advertised by AP.
+ * - If ACM is set in any of the ACs, PE will use the EDCA parameters
+ * from the next best AC for which ACM is not enabled.
+ *
+ * Return: none
+ */
+
+void lim_set_active_edca_params(tpAniSirGlobal mac_ctx,
+ tSirMacEdcaParamRecord *edca_params,
+ tpPESession pe_session)
+{
+ uint8_t ac, new_ac, i;
+ uint8_t ac_admitted;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ host_log_qos_edca_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ /* Initialize gLimEdcaParamsActive[] to be same as localEdcaParams */
+ pe_session->gLimEdcaParamsActive[EDCA_AC_BE] = edca_params[EDCA_AC_BE];
+ pe_session->gLimEdcaParamsActive[EDCA_AC_BK] = edca_params[EDCA_AC_BK];
+ pe_session->gLimEdcaParamsActive[EDCA_AC_VI] = edca_params[EDCA_AC_VI];
+ pe_session->gLimEdcaParamsActive[EDCA_AC_VO] = edca_params[EDCA_AC_VO];
+ /* An AC requires downgrade if the ACM bit is set, and the AC has not
+ * yet been admitted in uplink or bi-directions.
+ * If an AC requires downgrade, it will downgrade to the next beset AC
+ * for which ACM is not enabled.
+ *
+ * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence
+ * start the for loop with AC_BK.
+ * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then
+ * traverse thru the AC list. If we do find the next best AC which is
+ * better than AC_BE, then use that one. For example, if ACM bits are set
+ * such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0
+ * then all AC will be downgraded to AC_BE.
+ */
+ lim_log(mac_ctx, LOG1, FL("adAdmitMask[UPLINK] = 0x%x "),
+ pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK]);
+ lim_log(mac_ctx, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x "),
+ pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK]);
+ for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++) {
+ ac_admitted =
+ ((pe_session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &
+ (1 << ac)) >> ac);
+
+ lim_log(mac_ctx, LOG1,
+ FL("For AC[%d]: acm=%d, ac_admitted=%d "),
+ ac, edca_params[ac].aci.acm, ac_admitted);
+ if ((edca_params[ac].aci.acm == 1) && (ac_admitted == 0)) {
+ lim_log(mac_ctx, LOG1,
+ FL("We need to downgrade AC %d!! "), ac);
+ /* Loop backwards through AC values until it finds
+ * acm == 0 or reaches EDCA_AC_BE.
+ * Note that for block has no executable statements.
+ */
+ for (i = ac - 1;
+ (i > EDCA_AC_BE &&
+ (edca_params[i].aci.acm != 0));
+ i--)
+ ;
+ new_ac = i;
+ lim_log(mac_ctx, LOGW,
+ FL("Downgrading AC %d ---> AC %d "),
+ ac, new_ac);
+ pe_session->gLimEdcaParamsActive[ac] =
+ edca_params[new_ac];
+ }
+ }
+/* log: LOG_WLAN_QOS_EDCA_C */
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
+ LOG_WLAN_QOS_EDCA_C);
+ if (log_ptr) {
+ tSirMacEdcaParamRecord *rec;
+
+ rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_BE];
+ log_ptr->aci_be = rec->aci.aci;
+ log_ptr->cw_be = rec->cw.max << 4 | rec->cw.min;
+ log_ptr->txoplimit_be = rec->txoplimit;
+
+ rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_BK];
+ log_ptr->aci_bk = rec->aci.aci;
+ log_ptr->cw_bk = rec->cw.max << 4 | rec->cw.min;
+ log_ptr->txoplimit_bk = rec->txoplimit;
+
+ rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_VI];
+ log_ptr->aci_vi = rec->aci.aci;
+ log_ptr->cw_vi = rec->cw.max << 4 | rec->cw.min;
+ log_ptr->txoplimit_vi = rec->txoplimit;
+
+ rec = &pe_session->gLimEdcaParamsActive[EDCA_AC_VO];
+ log_ptr->aci_vo = rec->aci.aci;
+ log_ptr->cw_vo = rec->cw.max << 4 | rec->cw.min;
+ log_ptr->txoplimit_vo = rec->txoplimit;
+ }
+ WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ return;
+}
+
+/** ---------------------------------------------------------
+ \fn lim_set_link_state
+ \brief LIM sends a message to WMA to set the link state
+ \param tpAniSirGlobal pMac
+ \param tSirLinkState state
+ \return None
+ -----------------------------------------------------------*/
+tSirRetStatus lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
+ tSirMacAddr bssId, tSirMacAddr selfMacAddr,
+ tpSetLinkStateCallback callback,
+ void *callbackArg)
+{
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode;
+ tpLinkStateParams pLinkStateParams = NULL;
+ /* Allocate memory. */
+ pLinkStateParams = cdf_mem_malloc(sizeof(tLinkStateParams));
+ if (NULL == pLinkStateParams) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory while sending Set Link State"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ return retCode;
+ }
+ cdf_mem_set((uint8_t *) pLinkStateParams, sizeof(tLinkStateParams), 0);
+ pLinkStateParams->state = state;
+ pLinkStateParams->callback = callback;
+ pLinkStateParams->callbackArg = callbackArg;
+
+ /* Copy Mac address */
+ sir_copy_mac_addr(pLinkStateParams->bssid, bssId);
+ sir_copy_mac_addr(pLinkStateParams->selfMacAddr, selfMacAddr);
+
+ msgQ.type = WMA_SET_LINK_STATE;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pLinkStateParams;
+ msgQ.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+
+ retCode = (uint32_t) wma_post_ctrl_msg(pMac, &msgQ);
+ if (retCode != eSIR_SUCCESS) {
+ cdf_mem_free(pLinkStateParams);
+ lim_log(pMac, LOGP,
+ FL("Posting link state %d failed, reason = %x "), state,
+ retCode);
+ }
+ return retCode;
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+extern tSirRetStatus lim_set_link_state_ft(tpAniSirGlobal pMac, tSirLinkState
+ state, tSirMacAddr bssId,
+ tSirMacAddr selfMacAddr, int ft,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tSirRetStatus retCode;
+ tpLinkStateParams pLinkStateParams = NULL;
+ /* Allocate memory. */
+ pLinkStateParams = cdf_mem_malloc(sizeof(tLinkStateParams));
+ if (NULL == pLinkStateParams) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory while sending Set Link State"));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ return retCode;
+ }
+ cdf_mem_set((uint8_t *) pLinkStateParams, sizeof(tLinkStateParams), 0);
+ pLinkStateParams->state = state;
+ /* Copy Mac address */
+ sir_copy_mac_addr(pLinkStateParams->bssid, bssId);
+ sir_copy_mac_addr(pLinkStateParams->selfMacAddr, selfMacAddr);
+ pLinkStateParams->ft = 1;
+ pLinkStateParams->session = psessionEntry;
+
+ msgQ.type = WMA_SET_LINK_STATE;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pLinkStateParams;
+ msgQ.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, msgQ.type));
+ }
+
+ retCode = (uint32_t) wma_post_ctrl_msg(pMac, &msgQ);
+ if (retCode != eSIR_SUCCESS) {
+ cdf_mem_free(pLinkStateParams);
+ lim_log(pMac, LOGP,
+ FL("Posting link state %d failed, reason = %x "), state,
+ retCode);
+ }
+ return retCode;
+}
+#endif
+
+/** ---------------------------------------------------------
+ \fn lim_send_beacon_filter_info
+ \brief LIM sends beacon filtering info to WMA
+ \param tpAniSirGlobal pMac
+ \return None
+ -----------------------------------------------------------*/
+tSirRetStatus lim_send_beacon_filter_info(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ tpBeaconFilterMsg pBeaconFilterMsg = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ uint8_t *ptr;
+ uint32_t i;
+ uint32_t msgSize;
+ tpBeaconFilterIe pIe;
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE, FL("Fail to find the right session "));
+ retCode = eSIR_FAILURE;
+ return retCode;
+ }
+ msgSize = sizeof(tBeaconFilterMsg) + sizeof(beacon_filter_table);
+ pBeaconFilterMsg = cdf_mem_malloc(msgSize);
+ if (NULL == pBeaconFilterMsg) {
+ lim_log(pMac, LOGP,
+ FL("Fail to allocate memory for beaconFiilterMsg "));
+ retCode = eSIR_MEM_ALLOC_FAILED;
+ return retCode;
+ }
+ cdf_mem_set((uint8_t *) pBeaconFilterMsg, msgSize, 0);
+ /* Fill in capability Info and mask */
+ /* Don't send this message if no active Infra session is found. */
+ pBeaconFilterMsg->capabilityInfo = psessionEntry->limCurrentBssCaps;
+ pBeaconFilterMsg->capabilityMask = CAPABILITY_FILTER_MASK;
+ pBeaconFilterMsg->beaconInterval =
+ (uint16_t) psessionEntry->beaconParams.beaconInterval;
+ /* Fill in number of IEs in beacon_filter_table */
+ pBeaconFilterMsg->ieNum =
+ (uint16_t) (sizeof(beacon_filter_table) / sizeof(tBeaconFilterIe));
+ /* Fill the BSSIDX */
+ pBeaconFilterMsg->bssIdx = psessionEntry->bssIdx;
+
+ /* Fill message with info contained in the beacon_filter_table */
+ ptr = (uint8_t *) pBeaconFilterMsg + sizeof(tBeaconFilterMsg);
+ for (i = 0; i < (pBeaconFilterMsg->ieNum); i++) {
+ pIe = (tpBeaconFilterIe) ptr;
+ pIe->elementId = beacon_filter_table[i].elementId;
+ pIe->checkIePresence = beacon_filter_table[i].checkIePresence;
+ pIe->byte.offset = beacon_filter_table[i].byte.offset;
+ pIe->byte.value = beacon_filter_table[i].byte.value;
+ pIe->byte.bitMask = beacon_filter_table[i].byte.bitMask;
+ pIe->byte.ref = beacon_filter_table[i].byte.ref;
+ ptr += sizeof(tBeaconFilterIe);
+ }
+ msgQ.type = WMA_BEACON_FILTER_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pBeaconFilterMsg;
+ msgQ.bodyval = 0;
+ lim_log(pMac, LOG3, FL("Sending WMA_BEACON_FILTER_IND..."));
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pBeaconFilterMsg);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_BEACON_FILTER_IND failed, reason=%X"),
+ retCode);
+ return retCode;
+ }
+ return retCode;
+}
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus lim_send_mode_update(tpAniSirGlobal pMac,
+ tUpdateVHTOpMode *pTempParam,
+ tpPESession psessionEntry)
+{
+ tUpdateVHTOpMode *pVhtOpMode = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ pVhtOpMode = cdf_mem_malloc(sizeof(tUpdateVHTOpMode));
+ if (NULL == pVhtOpMode) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update Op Mode"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_copy((uint8_t *) pVhtOpMode, pTempParam,
+ sizeof(tUpdateVHTOpMode));
+ msgQ.type = WMA_UPDATE_OP_MODE;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pVhtOpMode;
+ msgQ.bodyval = 0;
+ lim_log(pMac, LOG3, FL(
+ "Sending WMA_UPDATE_OP_MODE, op_mode %d, sta_id %d"),
+ pVhtOpMode->opMode, pVhtOpMode->staId);
+ if (NULL == psessionEntry)
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ else
+ MTRACE(mac_trace_msg_tx(pMac,
+ psessionEntry->peSessionId,
+ msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pVhtOpMode);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_OP_MODE failed, reason=%X"),
+ retCode);
+ }
+
+ return retCode;
+}
+
+tSirRetStatus lim_send_rx_nss_update(tpAniSirGlobal pMac,
+ tUpdateRxNss *pTempParam,
+ tpPESession psessionEntry)
+{
+ tUpdateRxNss *pRxNss = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ pRxNss = cdf_mem_malloc(sizeof(tUpdateRxNss));
+ if (NULL == pRxNss) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update Rx Nss"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_copy((uint8_t *) pRxNss, pTempParam, sizeof(tUpdateRxNss));
+ msgQ.type = WMA_UPDATE_RX_NSS;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pRxNss;
+ msgQ.bodyval = 0;
+ PELOG3(lim_log(pMac, LOG3, FL("Sending WMA_UPDATE_RX_NSS"));)
+ if (NULL == psessionEntry)
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ else
+ MTRACE(mac_trace_msg_tx(pMac,
+ psessionEntry->peSessionId,
+ msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pRxNss);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_RX_NSS failed, reason=%X"),
+ retCode);
+ }
+
+ return retCode;
+}
+
+tSirRetStatus lim_set_membership(tpAniSirGlobal pMac,
+ tUpdateMembership *pTempParam,
+ tpPESession psessionEntry)
+{
+ tUpdateMembership *pMembership = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ pMembership = cdf_mem_malloc(sizeof(tUpdateMembership));
+ if (NULL == pMembership) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update Membership Mode"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_copy((uint8_t *) pMembership, pTempParam,
+ sizeof(tUpdateMembership));
+
+ msgQ.type = WMA_UPDATE_MEMBERSHIP;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMembership;
+ msgQ.bodyval = 0;
+ PELOG3(lim_log(pMac, LOG3, FL("Sending WMA_UPDATE_MEMBERSHIP"));)
+ if (NULL == psessionEntry)
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ else
+ MTRACE(mac_trace_msg_tx(pMac,
+ psessionEntry->peSessionId,
+ msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pMembership);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_MEMBERSHIP failed, reason=%X"),
+ retCode);
+ }
+
+ return retCode;
+}
+
+tSirRetStatus lim_set_user_pos(tpAniSirGlobal pMac,
+ tUpdateUserPos *pTempParam,
+ tpPESession psessionEntry)
+{
+ tUpdateUserPos *pUserPos = NULL;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ pUserPos = cdf_mem_malloc(sizeof(tUpdateUserPos));
+ if (NULL == pUserPos) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during Update User Position"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_copy((uint8_t *) pUserPos, pTempParam, sizeof(tUpdateUserPos));
+
+ msgQ.type = WMA_UPDATE_USERPOS;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pUserPos;
+ msgQ.bodyval = 0;
+ PELOG3(lim_log(pMac, LOG3, FL("Sending WMA_UPDATE_USERPOS"));)
+ if (NULL == psessionEntry)
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ else
+ MTRACE(mac_trace_msg_tx(pMac,
+ psessionEntry->peSessionId,
+ msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pUserPos);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_UPDATE_USERPOS failed, reason=%X"),
+ retCode);
+ }
+
+ return retCode;
+}
+
+#endif
+
+#ifdef WLAN_FEATURE_11W
+/**
+ * lim_send_exclude_unencrypt_ind() - sends WMA_EXCLUDE_UNENCRYPTED_IND to HAL
+ * @pMac: mac global context
+ * @excludeUnenc: true: ignore, false: indicate
+ * @psessionEntry: session context
+ *
+ * LIM sends a message to HAL to indicate whether to ignore or indicate the
+ * unprotected packet error.
+ *
+ * Return: status of operation
+ */
+tSirRetStatus lim_send_exclude_unencrypt_ind(tpAniSirGlobal pMac,
+ bool excludeUnenc,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ tSirWlanExcludeUnencryptParam *pExcludeUnencryptParam;
+
+ pExcludeUnencryptParam =
+ cdf_mem_malloc(sizeof(tSirWlanExcludeUnencryptParam));
+ if (NULL == pExcludeUnencryptParam) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory during lim_send_exclude_unencrypt_ind"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ pExcludeUnencryptParam->excludeUnencrypt = excludeUnenc;
+ sir_copy_mac_addr(pExcludeUnencryptParam->bssId, psessionEntry->bssId);
+
+ msgQ.type = WMA_EXCLUDE_UNENCRYPTED_IND;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pExcludeUnencryptParam;
+ msgQ.bodyval = 0;
+ PELOG3(lim_log(pMac, LOG3, FL("Sending WMA_EXCLUDE_UNENCRYPTED_IND"));)
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ cdf_mem_free(pExcludeUnencryptParam);
+ lim_log(pMac, LOGP,
+ FL("Posting WMA_EXCLUDE_UNENCRYPTED_IND failed, reason=%X"),
+ retCode);
+ }
+
+ return retCode;
+}
+#endif
diff --git a/core/mac/src/pe/lim/lim_send_messages.h b/core/mac/src/pe/lim/lim_send_messages.h
new file mode 100644
index 0000000..d884de7
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_messages.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * lim_send_messages.h: Provides functions to send messages or Indications to HAL.
+ * Author: Sunit Bhatia
+ * Date: 09/21/2006
+ * History:-
+ * Date Modified by Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_SEND_MESSAGES_H
+#define __LIM_SEND_MESSAGES_H
+
+#include "ani_global.h"
+#include "lim_types.h"
+#include "wma_if.h"
+#include "sir_params.h"
+tSirRetStatus lim_send_cf_params(tpAniSirGlobal pMac, uint8_t bssIdx,
+ uint8_t cfpCount, uint8_t cfpPeriod);
+tSirRetStatus lim_send_beacon_params(tpAniSirGlobal pMac,
+ tpUpdateBeaconParams pUpdatedBcnParams,
+ tpPESession psessionEntry);
+/* tSirRetStatus lim_send_beacon_params(tpAniSirGlobal pMac, tpUpdateBeaconParams pUpdatedBcnParams); */
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus lim_send_mode_update(tpAniSirGlobal pMac,
+ tUpdateVHTOpMode *tempParam,
+ tpPESession psessionEntry);
+tSirRetStatus lim_send_rx_nss_update(tpAniSirGlobal pMac,
+ tUpdateRxNss *tempParam,
+ tpPESession psessionEntry);
+
+uint32_t lim_get_center_channel(tpAniSirGlobal pMac,
+ uint8_t primarychanNum,
+ ePhyChanBondState secondaryChanOffset,
+ uint8_t chanWidth);
+
+tSirRetStatus lim_set_membership(tpAniSirGlobal pMac,
+ tUpdateMembership *pTempParam,
+ tpPESession psessionEntry);
+
+tSirRetStatus lim_set_user_pos(tpAniSirGlobal pMac,
+ tUpdateUserPos *pTempParam,
+ tpPESession psessionEntry);
+#endif
+#if defined WLAN_FEATURE_VOWIFI
+tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac,
+ uint8_t chnlNumber,
+ uint8_t ch_center_freq_seg0,
+ uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width,
+ tPowerdBm maxTxPower,
+ uint8_t peSessionId,
+ uint8_t is_restart);
+#else
+tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac,
+ uint8_t chnlNumber,
+ uint8_t ch_center_freq_seg0,
+ uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width,
+ uint8_t localPwrConstraint,
+ uint8_t peSessionId,
+ uint8_t is_restart);
+#endif
+tSirRetStatus lim_send_edca_params(tpAniSirGlobal pMac,
+ tSirMacEdcaParamRecord *pUpdatedEdcaParams,
+ uint16_t bssIdx);
+tSirRetStatus lim_set_link_state(tpAniSirGlobal pMac, tSirLinkState state,
+ tSirMacAddr bssId, tSirMacAddr selfMac,
+ tpSetLinkStateCallback callback,
+ void *callbackArg);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+extern tSirRetStatus lim_set_link_state_ft(tpAniSirGlobal pMac, tSirLinkState
+ state, tSirMacAddr bssId,
+ tSirMacAddr selfMacAddr, int ft,
+ tpPESession psessionEntry);
+#endif
+void lim_set_active_edca_params(tpAniSirGlobal pMac,
+ tSirMacEdcaParamRecord *plocalEdcaParams,
+ tpPESession psessionEntry);
+#define CAPABILITY_FILTER_MASK 0x73CF
+#define ERP_FILTER_MASK 0xF8
+#define EDCA_FILTER_MASK 0xF0
+#define QOS_FILTER_MASK 0xF0
+#define HT_BYTE0_FILTER_MASK 0x0
+#define HT_BYTE2_FILTER_MASK 0xEB
+#define HT_BYTE5_FILTER_MASK 0xFD
+#define DS_PARAM_CHANNEL_MASK 0x0
+#define VHTOP_CHWIDTH_MASK 0xFC
+
+tSirRetStatus lim_send_beacon_filter_info(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+
+#ifdef WLAN_FEATURE_11W
+tSirRetStatus lim_send_exclude_unencrypt_ind(tpAniSirGlobal pMac,
+ bool excludeUnenc,
+ tpPESession psessionEntry);
+#endif
+#endif
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
new file mode 100644
index 0000000..e27113c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -0,0 +1,2370 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_send_sme_rspMessages.cc contains the functions
+ * for sending SME response/notification messages to applications
+ * above MAC software.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "cdf_types.h"
+#include "wni_api.h"
+#include "sir_common.h"
+#include "ani_global.h"
+
+#include "wni_cfg.h"
+#include "sys_def.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_session_utils.h"
+#include "lim_types.h"
+#include "sir_api.h"
+
+static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tSirResultCodes result_code,
+ tpSirSmeJoinRsp sme_join_rsp);
+
+/**
+ * lim_send_sme_rsp() - Send Response to upper layers
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_type: Indicates message type
+ * @result_code: Indicates the result of previously issued
+ * eWNI_SME_msg_type_REQ message
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
+ * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
+ * Software.
+ *
+ * Return: None
+ */
+
+void
+lim_send_sme_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint8_t sme_session_id,
+ uint16_t sme_transaction_id)
+{
+ tSirMsgQ msg;
+ tSirSmeRsp *sme_rsp;
+
+ lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"),
+ lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+ sme_rsp = cdf_mem_malloc(sizeof(tSirSmeRsp));
+ if (NULL == sme_rsp) {
+ /* Buffer not available. Log error */
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGP,
+ FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
+ return;
+ }
+
+ sme_rsp->messageType = msg_type;
+ sme_rsp->length = sizeof(tSirSmeRsp);
+ sme_rsp->statusCode = result_code;
+
+ sme_rsp->sessionId = sme_session_id;
+ sme_rsp->transactionId = sme_transaction_id;
+
+ msg.type = msg_type;
+ msg.bodyptr = sme_rsp;
+ msg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ switch (msg_type) {
+ case eWNI_SME_STOP_BSS_RSP:
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+ NULL, (uint16_t) result_code, 0);
+ break;
+ }
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+
+
+/**
+ * lim_send_sme_roc_rsp() - Send Response to SME
+ * @mac_ctx: Pointer to Global MAC structure
+ * @status: Resume link status
+ * @result_code: Result of the ROC request
+ * @sme_session_id: SME sesson Id
+ * @scan_id: Scan Identifier
+ *
+ * This function is called to send ROC rsp
+ * message to SME.
+ *
+ * Return: None
+ */
+void
+lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint8_t sme_session_id,
+ uint32_t scan_id)
+{
+ tSirMsgQ msg;
+ struct sir_roc_rsp *sme_rsp;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Sending message %s with reasonCode %s scanId %d"),
+ lim_msg_str(msg_type), lim_result_code_str(result_code),
+ scan_id);
+
+ sme_rsp = cdf_mem_malloc(sizeof(struct sir_roc_rsp));
+ if (NULL == sme_rsp) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGP,
+ FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
+ return;
+ }
+
+ sme_rsp->message_type = msg_type;
+ sme_rsp->length = sizeof(struct sir_roc_rsp);
+ sme_rsp->status = result_code;
+
+ sme_rsp->session_id = sme_session_id;
+ sme_rsp->scan_id = scan_id;
+
+ msg.type = msg_type;
+ msg.bodyptr = sme_rsp;
+ msg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type));
+ lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+
+/**
+ * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME
+ * @mac_ctx Pointer to Global MAC structure
+ * @status Resume link status
+ * @ctx context passed while calling resmune link.
+ * (join response to be sent)
+ *
+ * This function is called to send Join/Reassoc rsp
+ * message to SME after the resume link.
+ *
+ * Return: None
+ */
+static void lim_send_sme_join_reassoc_rsp_after_resume(tpAniSirGlobal mac_ctx,
+ CDF_STATUS status, uint32_t *ctx)
+{
+ tSirMsgQ msg;
+ tpSirSmeJoinRsp sme_join_rsp = (tpSirSmeJoinRsp) ctx;
+
+ msg.type = sme_join_rsp->messageType;
+ msg.bodyptr = sme_join_rsp;
+ msg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, NO_SESSION, msg.type));
+ lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+/**
+ * lim_handle_join_rsp_status() - Handle the response.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE Session Info
+ * @result_code: Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ * @sme_join_rsp The received response.
+ *
+ * This function will handle both the success and failure status
+ * of the received response.
+ *
+ * Return: None
+ */
+static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tSirResultCodes result_code,
+ tpSirSmeJoinRsp sme_join_rsp)
+{
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ tSirSmeHTProfile *ht_profile;
+#endif
+ if (result_code == eSIR_SME_SUCCESS) {
+ if (session_entry->beacon != NULL) {
+ sme_join_rsp->beaconLength = session_entry->bcnLen;
+ cdf_mem_copy(sme_join_rsp->frames,
+ session_entry->beacon,
+ sme_join_rsp->beaconLength);
+ cdf_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("Beacon=%d"),
+ session_entry->bcnLen);
+#endif
+ }
+ if (session_entry->assocReq != NULL) {
+ sme_join_rsp->assocReqLength =
+ session_entry->assocReqLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen, session_entry->assocReq,
+ sme_join_rsp->assocReqLength);
+ cdf_mem_free(session_entry->assocReq);
+ session_entry->assocReq = NULL;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx,
+ LOG1, FL("AssocReq=%d"),
+ session_entry->assocReqLen);
+#endif
+ }
+ if (session_entry->assocRsp != NULL) {
+ sme_join_rsp->assocRspLength =
+ session_entry->assocRspLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen +
+ session_entry->assocReqLen,
+ session_entry->assocRsp,
+ sme_join_rsp->assocRspLength);
+ cdf_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (session_entry->ricData != NULL) {
+ sme_join_rsp->parsedRicRspLen =
+ session_entry->RICDataLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen +
+ session_entry->assocReqLen +
+ session_entry->assocRspLen,
+ session_entry->ricData,
+ sme_join_rsp->parsedRicRspLen);
+ cdf_mem_free(session_entry->ricData);
+ session_entry->ricData = NULL;
+ lim_log(mac_ctx, LOG1, FL("RicLength=%d"),
+ sme_join_rsp->parsedRicRspLen);
+ }
+#endif
+#ifdef FEATURE_WLAN_ESE
+ if (session_entry->tspecIes != NULL) {
+ sme_join_rsp->tspecIeLen =
+ session_entry->tspecLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen +
+ session_entry->assocReqLen +
+ session_entry->assocRspLen +
+ session_entry->RICDataLen,
+ session_entry->tspecIes,
+ sme_join_rsp->tspecIeLen);
+ cdf_mem_free(session_entry->tspecIes);
+ session_entry->tspecIes = NULL;
+ lim_log(mac_ctx, LOG1, FL("ESE-TspecLen=%d"),
+ session_entry->tspecLen);
+ }
+#endif
+ sme_join_rsp->aid = session_entry->limAID;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("AssocRsp=%d"),
+ session_entry->assocRspLen);
+#endif
+ sme_join_rsp->vht_channel_width =
+ session_entry->ch_width;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ if (session_entry->cc_switch_mode !=
+ CDF_MCC_TO_SCC_SWITCH_DISABLE) {
+ ht_profile = &sme_join_rsp->HTProfile;
+ ht_profile->htSupportedChannelWidthSet =
+ session_entry->htSupportedChannelWidthSet;
+ ht_profile->htRecommendedTxWidthSet =
+ session_entry->htRecommendedTxWidthSet;
+ ht_profile->htSecondaryChannelOffset =
+ session_entry->htSecondaryChannelOffset;
+ ht_profile->dot11mode = session_entry->dot11mode;
+ ht_profile->htCapability = session_entry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ ht_profile->vhtCapability =
+ session_entry->vhtCapability;
+ ht_profile->vhtTxChannelWidthSet =
+ session_entry->vhtTxChannelWidthSet;
+ ht_profile->apCenterChan = session_entry->ch_center_freq_seg0;
+ ht_profile->apChanWidth = session_entry->ch_width;
+#endif
+ }
+#endif
+ } else {
+ if (session_entry->beacon != NULL) {
+ cdf_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+ }
+ if (session_entry->assocReq != NULL) {
+ cdf_mem_free(session_entry->assocReq);
+ session_entry->assocReq = NULL;
+ }
+ if (session_entry->assocRsp != NULL) {
+ cdf_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (session_entry->ricData != NULL) {
+ cdf_mem_free(session_entry->ricData);
+ session_entry->ricData = NULL;
+ }
+#endif
+#ifdef FEATURE_WLAN_ESE
+ if (session_entry->tspecIes != NULL) {
+ cdf_mem_free(session_entry->tspecIes);
+ session_entry->tspecIes = NULL;
+ }
+#endif
+ }
+}
+/**
+ * lim_send_sme_join_reassoc_rsp() - Send Response to Upper Layers
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_type: Indicates message type
+ * @result_code: Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ * @prot_status_code: Protocol Status Code
+ * @session_entry: PE Session Info
+ * @sme_session_id: SME Session ID
+ * @sme_transaction_id: SME Transaction ID
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications
+ * above MAC Software.
+ *
+ * Return: None
+ */
+
+void
+lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint16_t prot_status_code,
+ tpPESession session_entry, uint8_t sme_session_id,
+ uint16_t sme_transaction_id)
+{
+ tpSirSmeJoinRsp sme_join_rsp;
+ uint32_t rsp_len;
+ tpDphHashNode sta_ds = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ if (msg_type == eWNI_SME_REASSOC_RSP)
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+ session_entry, (uint16_t) result_code, 0);
+ else
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_RSP_EVENT,
+ session_entry, (uint16_t) result_code, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"),
+ lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+ if (session_entry == NULL) {
+ rsp_len = sizeof(tSirSmeJoinRsp);
+ sme_join_rsp = cdf_mem_malloc(rsp_len);
+ if (NULL == sme_join_rsp) {
+ lim_log(mac_ctx, LOGP,
+ FL("Mem Alloc fail - JOIN/REASSOC_RSP"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0);
+ sme_join_rsp->beaconLength = 0;
+ sme_join_rsp->assocReqLength = 0;
+ sme_join_rsp->assocRspLength = 0;
+ } else {
+ rsp_len = session_entry->assocReqLen +
+ session_entry->assocRspLen + session_entry->bcnLen +
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ session_entry->RICDataLen +
+#endif
+#ifdef FEATURE_WLAN_ESE
+ session_entry->tspecLen +
+#endif
+ sizeof(tSirSmeJoinRsp) - sizeof(uint8_t);
+ sme_join_rsp = cdf_mem_malloc(rsp_len);
+ if (NULL == sme_join_rsp) {
+ lim_log(mac_ctx, LOGP,
+ FL("MemAlloc fail - JOIN/REASSOC_RSP"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0);
+ if (result_code == eSIR_SME_SUCCESS) {
+ sta_ds = dph_get_hash_entry(mac_ctx,
+ DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Get Self Sta Entry fail"));
+ } else {
+ /* Pass the peer's staId */
+ sme_join_rsp->staId = sta_ds->staIndex;
+ sme_join_rsp->ucastSig =
+ sta_ds->ucUcastSig;
+ sme_join_rsp->bcastSig =
+ sta_ds->ucBcastSig;
+ sme_join_rsp->timingMeasCap =
+ sta_ds->timingMeasCap;
+#ifdef FEATURE_WLAN_TDLS
+ sme_join_rsp->tdls_prohibited =
+ session_entry->tdls_prohibited;
+ sme_join_rsp->tdls_chan_swit_prohibited =
+ session_entry->tdls_chan_swit_prohibited;
+#endif
+ }
+ }
+ sme_join_rsp->beaconLength = 0;
+ sme_join_rsp->assocReqLength = 0;
+ sme_join_rsp->assocRspLength = 0;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ sme_join_rsp->parsedRicRspLen = 0;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ sme_join_rsp->tspecIeLen = 0;
+#endif
+
+ lim_handle_join_rsp_status(mac_ctx, session_entry, result_code,
+ sme_join_rsp);
+ }
+
+ sme_join_rsp->messageType = msg_type;
+ sme_join_rsp->length = (uint16_t) rsp_len;
+ sme_join_rsp->statusCode = result_code;
+ sme_join_rsp->protStatusCode = prot_status_code;
+
+ sme_join_rsp->sessionId = sme_session_id;
+ sme_join_rsp->transactionId = sme_transaction_id;
+
+ lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, CDF_STATUS_SUCCESS,
+ (uint32_t *)sme_join_rsp);
+}
+
+/**
+ * lim_send_sme_start_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send eWNI_SME_START_BSS_RSP
+ * message to applications above MAC Software.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates message type
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ *
+ * @return None
+ */
+
+void
+lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac,
+ uint16_t msgType, tSirResultCodes resultCode,
+ tpPESession psessionEntry, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+
+ uint16_t size = 0;
+ tSirMsgQ mmhMsg;
+ tSirSmeStartBssRsp *pSirSmeRsp;
+ uint16_t ieLen;
+ uint16_t ieOffset, curLen;
+
+ PELOG1(lim_log(pMac, LOG1, FL("Sending message %s with reasonCode %s"),
+ lim_msg_str(msgType), lim_result_code_str(resultCode));
+ )
+
+ size = sizeof(tSirSmeStartBssRsp);
+
+ if (psessionEntry == NULL) {
+ pSirSmeRsp = cdf_mem_malloc(size);
+ if (NULL == pSirSmeRsp) {
+ /* / Buffer not available. Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) pSirSmeRsp, size, 0);
+
+ } else {
+ /* subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID */
+ ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET;
+ ieLen = psessionEntry->schBeaconOffsetBegin
+ + psessionEntry->schBeaconOffsetEnd - ieOffset;
+ /* calculate the memory size to allocate */
+ size += ieLen;
+
+ pSirSmeRsp = cdf_mem_malloc(size);
+ if (NULL == pSirSmeRsp) {
+ /* / Buffer not available. Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP"));
+
+ return;
+ }
+ cdf_mem_set((uint8_t *) pSirSmeRsp, size, 0);
+ size = sizeof(tSirSmeStartBssRsp);
+ if (resultCode == eSIR_SME_SUCCESS) {
+
+ sir_copy_mac_addr(pSirSmeRsp->bssDescription.bssId,
+ psessionEntry->bssId);
+
+ /* Read beacon interval from session */
+ pSirSmeRsp->bssDescription.beaconInterval =
+ (uint16_t) psessionEntry->beaconParams.
+ beaconInterval;
+ pSirSmeRsp->bssType = psessionEntry->bssType;
+
+ if (cfg_get_capability_info
+ (pMac, &pSirSmeRsp->bssDescription.capabilityInfo,
+ psessionEntry)
+ != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Capabilities value"));
+
+ lim_get_phy_mode(pMac,
+ (uint32_t *) &pSirSmeRsp->bssDescription.
+ nwType, psessionEntry);
+
+ pSirSmeRsp->bssDescription.channelId =
+ psessionEntry->currentOperChannel;
+
+ curLen = psessionEntry->schBeaconOffsetBegin - ieOffset;
+ cdf_mem_copy((uint8_t *) &pSirSmeRsp->bssDescription.
+ ieFields,
+ psessionEntry->pSchBeaconFrameBegin +
+ ieOffset, (uint32_t) curLen);
+
+ cdf_mem_copy(((uint8_t *) &pSirSmeRsp->bssDescription.
+ ieFields) + curLen,
+ psessionEntry->pSchBeaconFrameEnd,
+ (uint32_t) psessionEntry->
+ schBeaconOffsetEnd);
+
+ /* subtracting size of length indicator itself and size of pointer to ieFields */
+ pSirSmeRsp->bssDescription.length =
+ sizeof(tSirBssDescription) - sizeof(uint16_t) -
+ sizeof(uint32_t) + ieLen;
+ /* This is the size of the message, subtracting the size of the pointer to ieFields */
+ size += ieLen - sizeof(uint32_t);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ if (psessionEntry->cc_switch_mode
+ != CDF_MCC_TO_SCC_SWITCH_DISABLE) {
+ pSirSmeRsp->HTProfile.
+ htSupportedChannelWidthSet =
+ psessionEntry->htSupportedChannelWidthSet;
+ pSirSmeRsp->HTProfile.htRecommendedTxWidthSet =
+ psessionEntry->htRecommendedTxWidthSet;
+ pSirSmeRsp->HTProfile.htSecondaryChannelOffset =
+ psessionEntry->htSecondaryChannelOffset;
+ pSirSmeRsp->HTProfile.dot11mode =
+ psessionEntry->dot11mode;
+ pSirSmeRsp->HTProfile.htCapability =
+ psessionEntry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ pSirSmeRsp->HTProfile.vhtCapability =
+ psessionEntry->vhtCapability;
+ pSirSmeRsp->HTProfile.vhtTxChannelWidthSet =
+ psessionEntry->vhtTxChannelWidthSet;
+ pSirSmeRsp->HTProfile.apCenterChan =
+ psessionEntry->ch_center_freq_seg0;
+ pSirSmeRsp->HTProfile.apChanWidth =
+ psessionEntry->ch_width;
+#endif
+ }
+#endif
+ }
+
+ }
+
+ pSirSmeRsp->messageType = msgType;
+ pSirSmeRsp->length = size;
+
+ /* Update SME session Id and transaction Id */
+ pSirSmeRsp->sessionId = smesessionId;
+ pSirSmeRsp->transactionId = smetransactionId;
+ pSirSmeRsp->statusCode = resultCode;
+ if (psessionEntry != NULL)
+ pSirSmeRsp->staId = psessionEntry->staId; /* else it will be always zero smeRsp StaID = 0 */
+
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pSirSmeRsp;
+ mmhMsg.bodyval = 0;
+ if (psessionEntry == NULL) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+ psessionEntry, (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+} /*** end lim_send_sme_start_bss_rsp() ***/
+
+#define LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED 20
+#define LIM_SIZE_OF_EACH_BSS 400 /* this is a rough estimate */
+
+/**
+ * lim_send_sme_scan_rsp() - Send scan response to SME
+ * @pMac: Pointer to Global MAC structure
+ * @length: Indicates length of message
+ * @resultCode: Indicates the result of previously issued
+ * eWNI_SME_SCAN_REQ message
+ * @scan_id: scan identifier
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_SCAN_RSP message to applications above MAC
+ *
+ * return: None
+ */
+
+void
+lim_send_sme_scan_rsp(tpAniSirGlobal pMac, tSirResultCodes resultCode,
+ uint8_t smesessionId, uint16_t smetranscationId,
+ uint32_t scan_id)
+{
+ lim_log(pMac, LOG1,
+ FL("Sending message SME_SCAN_RSP reasonCode %s scanId %d"),
+ lim_result_code_str(resultCode), scan_id);
+ lim_post_sme_scan_rsp_message(pMac, resultCode, smesessionId,
+ smetranscationId, scan_id);
+}
+
+/**
+ * lim_post_sme_scan_rsp_message()
+ *
+ ***FUNCTION:
+ * This function is called by lim_send_sme_scan_rsp() to send
+ * eWNI_SME_SCAN_RSP message with failed result code
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param length Indicates length of message
+ * @param resultCode failed result code
+ *
+ * @return None
+ */
+
+void
+lim_post_sme_scan_rsp_message(tpAniSirGlobal pMac,
+ tSirResultCodes resultCode, uint8_t smesessionId,
+ uint16_t smetransactionId,
+ uint32_t scan_id)
+{
+ tpSirSmeScanRsp pSirSmeScanRsp;
+ tSirMsgQ mmhMsg;
+
+ lim_log(pMac, LOG1, FL("send SME_SCAN_RSP (reasonCode %s)."),
+ lim_result_code_str(resultCode));
+
+ pSirSmeScanRsp = cdf_mem_malloc(sizeof(tSirSmeScanRsp));
+ if (NULL == pSirSmeScanRsp) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_SCAN_RSP"));
+ return;
+ }
+ cdf_mem_set((void *)pSirSmeScanRsp, sizeof(tSirSmeScanRsp), 0);
+
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->statusCode = resultCode;
+
+ /*Update SME session Id and transaction Id */
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetransactionId;
+ pSirSmeScanRsp->scan_id = scan_id;
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL,
+ (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+
+} /*** lim_post_sme_scan_rsp_message ***/
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+/**
+ * lim_send_sme_oem_data_rsp()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_OEM_DATA_RSP message to applications above MAC
+ * Software.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf Indicates the mlm message
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_OEM_DATA_RSP message
+ *
+ * @return None
+ */
+
+void lim_send_sme_oem_data_rsp(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
+ tSirResultCodes resultCode)
+{
+ tSirMsgQ mmhMsg;
+ tSirOemDataRsp *pSirSmeOemDataRsp = NULL;
+ tLimMlmOemDataRsp *pMlmOemDataRsp = NULL;
+ uint16_t msgLength;
+
+ /* get the pointer to the mlm message */
+ pMlmOemDataRsp = (tLimMlmOemDataRsp *) (pMsgBuf);
+
+ msgLength = sizeof(tSirOemDataRsp);
+
+ /* now allocate memory for the char buffer */
+ pSirSmeOemDataRsp = cdf_mem_malloc(msgLength);
+ if (NULL == pSirSmeOemDataRsp) {
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for pSirSmeOemDataRsp"));
+ return;
+ }
+#if defined (ANI_LITTLE_BYTE_ENDIAN)
+ sir_store_u16_n((uint8_t *) &pSirSmeOemDataRsp->length, msgLength);
+ sir_store_u16_n((uint8_t *) &pSirSmeOemDataRsp->messageType,
+ eWNI_SME_OEM_DATA_RSP);
+#else
+ pSirSmeOemDataRsp->length = msgLength;
+ pSirSmeOemDataRsp->messageType = eWNI_SME_OEM_DATA_RSP;
+#endif
+
+ cdf_mem_copy(pSirSmeOemDataRsp->oemDataRsp, pMlmOemDataRsp->oemDataRsp,
+ OEM_DATA_RSP_SIZE);
+
+ /* Now free the memory from MLM Rsp Message */
+ cdf_mem_free(pMlmOemDataRsp);
+
+ mmhMsg.type = eWNI_SME_OEM_DATA_RSP;
+ mmhMsg.bodyptr = pSirSmeOemDataRsp;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+} /*** lim_send_sme_oem_data_rsp ***/
+
+#endif
+
+void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal pMac,
+ CDF_STATUS status, uint32_t *pCtx)
+{
+ tSirMsgQ mmhMsg;
+ tSirMsgQ *pMsg = (tSirMsgQ *) pCtx;
+
+ mmhMsg.type = pMsg->type;
+ mmhMsg.bodyptr = pMsg;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+/**
+ * lim_send_sme_disassoc_ntf()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_DISASSOC_CNF,
+ * or eWNI_SME_DISASSOC_IND to host depending on
+ * disassociation trigger.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * disassociate was initiated
+ * @param reasonCode Indicates the reason for Disassociation
+ * @param disassocTrigger Indicates the trigger for Disassociation
+ * @param aid Indicates the STAID. This parameter is
+ * present only on AP.
+ *
+ * @return None
+ */
+void
+lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirResultCodes reasonCode,
+ uint16_t disassocTrigger,
+ uint16_t aid,
+ uint8_t smesessionId,
+ uint16_t smetransactionId, tpPESession psessionEntry)
+{
+
+ uint8_t *pBuf;
+ tSirSmeDisassocRsp *pSirSmeDisassocRsp;
+ tSirSmeDisassocInd *pSirSmeDisassocInd;
+ uint32_t *pMsg;
+ bool failure = false;
+
+ lim_log(pMac, LOG1, FL("Disassoc Ntf with trigger : %d reasonCode: %d"),
+ disassocTrigger, reasonCode);
+
+ switch (disassocTrigger) {
+ case eLIM_PEER_ENTITY_DISASSOC:
+ if (reasonCode != eSIR_SME_STA_NOT_ASSOCIATED) {
+ failure = true;
+ goto error;
+ }
+
+ case eLIM_HOST_DISASSOC:
+ /**
+ * Disassociation response due to
+ * host triggered disassociation
+ */
+
+ pSirSmeDisassocRsp = cdf_mem_malloc(sizeof(tSirSmeDisassocRsp));
+ if (NULL == pSirSmeDisassocRsp) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("Memory allocation failed"));
+ failure = true;
+ goto error;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with "
+ "retCode: %d for " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP;
+ pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp);
+ /* sessionId */
+ pBuf = (uint8_t *) &pSirSmeDisassocRsp->sessionId;
+ *pBuf = smesessionId;
+ pBuf++;
+
+ /* transactionId */
+ lim_copy_u16(pBuf, smetransactionId);
+ pBuf += sizeof(uint16_t);
+
+ /* statusCode */
+ lim_copy_u32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ /* peerMacAddr */
+ cdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ /* Clear Station Stats */
+ /* for sta, it is always 1, IBSS is handled at halInitSta */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+ psessionEntry, (uint16_t) reasonCode, 0);
+#endif
+ pMsg = (uint32_t *) pSirSmeDisassocRsp;
+ break;
+
+ default:
+ /**
+ * Disassociation indication due to Disassociation
+ * frame reception from peer entity or due to
+ * loss of link with peer entity.
+ */
+ pSirSmeDisassocInd = cdf_mem_malloc(sizeof(tSirSmeDisassocInd));
+ if (NULL == pSirSmeDisassocInd) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("Memory allocation failed"));
+ failure = true;
+ goto error;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_IND with "
+ "retCode: %d for " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+ pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+ /* Update SME session Id and Transaction Id */
+ pSirSmeDisassocInd->sessionId = smesessionId;
+ pSirSmeDisassocInd->transactionId = smetransactionId;
+ pSirSmeDisassocInd->reasonCode = reasonCode;
+ pBuf = (uint8_t *) &pSirSmeDisassocInd->statusCode;
+
+ lim_copy_u32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ cdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ cdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+ psessionEntry, (uint16_t) reasonCode, 0);
+#endif
+ pMsg = (uint32_t *) pSirSmeDisassocInd;
+
+ break;
+ }
+
+error:
+ /* Delete the PE session Created */
+ if ((psessionEntry != NULL) &&
+ (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry))) {
+ pe_delete_session(pMac, psessionEntry);
+ }
+
+ if (false == failure)
+ lim_send_sme_disassoc_deauth_ntf(pMac, CDF_STATUS_SUCCESS,
+ (uint32_t *) pMsg);
+} /*** end lim_send_sme_disassoc_ntf() ***/
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_disassoc_ind() - sends SME_DISASSOC_IND
+
+ After receiving disassociation frame from peer entity, this
+ function sends a eWNI_SME_DISASSOC_IND to SME with a specific
+ reason code.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_disassoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeDisassocInd *pSirSmeDisassocInd;
+
+ pSirSmeDisassocInd = cdf_mem_malloc(sizeof(tSirSmeDisassocInd));
+ if (NULL == pSirSmeDisassocInd) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_DISASSOC_IND"));
+ return;
+ }
+
+ pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+ pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+ pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeDisassocInd->transactionId = psessionEntry->transactionId;
+ pSirSmeDisassocInd->statusCode = pStaDs->mlmStaContext.disassocReason;
+ pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
+
+ cdf_mem_copy(pSirSmeDisassocInd->bssId, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy(pSirSmeDisassocInd->peerMacAddr, pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+
+ pSirSmeDisassocInd->staId = pStaDs->staIndex;
+
+ mmhMsg.type = eWNI_SME_DISASSOC_IND;
+ mmhMsg.bodyptr = pSirSmeDisassocInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry,
+ 0, (uint16_t) pStaDs->mlmStaContext.disassocReason);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+} /*** end lim_send_sme_disassoc_ind() ***/
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_deauth_ind() - sends SME_DEAUTH_IND
+
+ After receiving deauthentication frame from peer entity, this
+ function sends a eWNI_SME_DEAUTH_IND to SME with a specific
+ reason code.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_deauth_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeDeauthInd *pSirSmeDeauthInd;
+
+ pSirSmeDeauthInd = cdf_mem_malloc(sizeof(tSirSmeDeauthInd));
+ if (NULL == pSirSmeDeauthInd) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_DEAUTH_IND "));
+ return;
+ }
+
+ pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+ pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+
+ pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeDeauthInd->transactionId = psessionEntry->transactionId;
+ if (eSIR_INFRA_AP_MODE == psessionEntry->bssType) {
+ pSirSmeDeauthInd->statusCode =
+ (tSirResultCodes) pStaDs->mlmStaContext.cleanupTrigger;
+ } else {
+ /* Need to indicatet he reascon code over the air */
+ pSirSmeDeauthInd->statusCode =
+ (tSirResultCodes) pStaDs->mlmStaContext.disassocReason;
+ }
+ /* BSSID */
+ cdf_mem_copy(pSirSmeDeauthInd->bssId, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ /* peerMacAddr */
+ cdf_mem_copy(pSirSmeDeauthInd->peerMacAddr, pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+ pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
+
+ pSirSmeDeauthInd->staId = pStaDs->staIndex;
+
+ mmhMsg.type = eWNI_SME_DEAUTH_IND;
+ mmhMsg.bodyptr = pSirSmeDeauthInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry,
+ 0, pStaDs->mlmStaContext.cleanupTrigger);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_deauth_ind() ***/
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * lim_send_sme_tdls_del_sta_ind()
+ *
+ ***FUNCTION:
+ * This function is called to send the TDLS STA context deletion to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param pStaDs - Pointer to internal STA Datastructure
+ * @param psessionEntry - Pointer to the session entry
+ * @param reasonCode - Reason for TDLS sta deletion
+ * @return None
+ */
+void
+lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry, uint16_t reasonCode)
+{
+ tSirMsgQ mmhMsg;
+ tSirTdlsDelStaInd *pSirTdlsDelStaInd;
+
+ pSirTdlsDelStaInd = cdf_mem_malloc(sizeof(tSirTdlsDelStaInd));
+ if (NULL == pSirTdlsDelStaInd) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for eWNI_SME_TDLS_DEL_STA_IND "));
+ return;
+ }
+ /* messageType */
+ pSirTdlsDelStaInd->messageType = eWNI_SME_TDLS_DEL_STA_IND;
+ pSirTdlsDelStaInd->length = sizeof(tSirTdlsDelStaInd);
+
+ /* sessionId */
+ pSirTdlsDelStaInd->sessionId = psessionEntry->smeSessionId;
+
+ /* peerMacAddr */
+ cdf_mem_copy(pSirTdlsDelStaInd->peerMac, pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+
+ /* staId */
+ lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->staId),
+ (uint16_t) pStaDs->staIndex);
+
+ /* reasonCode */
+ lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->reasonCode), reasonCode);
+
+ mmhMsg.type = eWNI_SME_TDLS_DEL_STA_IND;
+ mmhMsg.bodyptr = pSirTdlsDelStaInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_tdls_del_sta_ind() ***/
+
+/**
+ * lim_send_sme_tdls_delete_all_peer_ind()
+ *
+ ***FUNCTION:
+ * This function is called to send the eWNI_SME_TDLS_DEL_ALL_PEER_IND
+ * message to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param psessionEntry - Pointer to the session entry
+ * @return None
+ */
+void
+lim_send_sme_tdls_delete_all_peer_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirTdlsDelAllPeerInd *pSirTdlsDelAllPeerInd;
+
+ pSirTdlsDelAllPeerInd = cdf_mem_malloc(sizeof(tSirTdlsDelAllPeerInd));
+ if (NULL == pSirTdlsDelAllPeerInd) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for eWNI_SME_TDLS_DEL_ALL_PEER_IND"));
+ return;
+ }
+ /* messageType */
+ pSirTdlsDelAllPeerInd->messageType = eWNI_SME_TDLS_DEL_ALL_PEER_IND;
+ pSirTdlsDelAllPeerInd->length = sizeof(tSirTdlsDelAllPeerInd);
+
+ /* sessionId */
+ pSirTdlsDelAllPeerInd->sessionId = psessionEntry->smeSessionId;
+
+ mmhMsg.type = eWNI_SME_TDLS_DEL_ALL_PEER_IND;
+ mmhMsg.bodyptr = pSirTdlsDelAllPeerInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
+
+/**
+ * lim_send_sme_mgmt_tx_completion()
+ *
+ ***FUNCTION:
+ * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
+ * message to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param psessionEntry - Pointer to the session entry
+ * @param txCompleteStatus - TX Complete Status of Mgmt Frames
+ * @return None
+ */
+void
+lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, uint32_t txCompleteStatus)
+{
+ tSirMsgQ mmhMsg;
+ tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd;
+
+ pSirMgmtTxCompletionInd =
+ cdf_mem_malloc(sizeof(tSirMgmtTxCompletionInd));
+ if (NULL == pSirMgmtTxCompletionInd) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND"));
+ return;
+ }
+ /* messageType */
+ pSirMgmtTxCompletionInd->messageType =
+ eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+ pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd);
+
+ /* sessionId */
+ pSirMgmtTxCompletionInd->sessionId = psessionEntry->smeSessionId;
+
+ pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus;
+
+ mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+ mmhMsg.bodyptr = pSirMgmtTxCompletionInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
+
+void lim_send_sme_tdls_event_notify(tpAniSirGlobal pMac, uint16_t msgType,
+ void *events)
+{
+ tSirMsgQ mmhMsg;
+
+ switch (msgType) {
+ case SIR_HAL_TDLS_SHOULD_DISCOVER:
+ mmhMsg.type = eWNI_SME_TDLS_SHOULD_DISCOVER;
+ break;
+ case SIR_HAL_TDLS_SHOULD_TEARDOWN:
+ mmhMsg.type = eWNI_SME_TDLS_SHOULD_TEARDOWN;
+ break;
+ case SIR_HAL_TDLS_PEER_DISCONNECTED:
+ mmhMsg.type = eWNI_SME_TDLS_PEER_DISCONNECTED;
+ break;
+ }
+
+ mmhMsg.bodyptr = events;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+#endif /* FEATURE_WLAN_TDLS */
+
+/**
+ * lim_send_sme_deauth_ntf()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_DEAUTH_CNF or
+ * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * deauthentication was initiated
+ * @param reasonCode Indicates the reason for Deauthetication
+ * @param deauthTrigger Indicates the trigger for Deauthetication
+ * @param aid Indicates the STAID. This parameter is present
+ * only on AP.
+ *
+ * @return None
+ */
+void
+lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tSirResultCodes reasonCode, uint16_t deauthTrigger,
+ uint16_t aid, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+ uint8_t *pBuf;
+ tSirSmeDeauthRsp *pSirSmeDeauthRsp;
+ tSirSmeDeauthInd *pSirSmeDeauthInd;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+ uint32_t *pMsg;
+
+ psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
+ switch (deauthTrigger) {
+ case eLIM_PEER_ENTITY_DEAUTH:
+ return;
+
+ case eLIM_HOST_DEAUTH:
+ /**
+ * Deauthentication response to host triggered
+ * deauthentication.
+ */
+ pSirSmeDeauthRsp = cdf_mem_malloc(sizeof(tSirSmeDeauthRsp));
+ if (NULL == pSirSmeDeauthRsp) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP"));
+
+ return;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with "
+ "retCode: %d for" MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP;
+ pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp);
+ pSirSmeDeauthRsp->statusCode = reasonCode;
+ pSirSmeDeauthRsp->sessionId = smesessionId;
+ pSirSmeDeauthRsp->transactionId = smetransactionId;
+
+ pBuf = (uint8_t *) pSirSmeDeauthRsp->peerMacAddr;
+ cdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+ psessionEntry, 0, (uint16_t) reasonCode);
+#endif
+ pMsg = (uint32_t *) pSirSmeDeauthRsp;
+
+ break;
+
+ default:
+ /**
+ * Deauthentication indication due to Deauthentication
+ * frame reception from peer entity or due to
+ * loss of link with peer entity.
+ */
+ pSirSmeDeauthInd = cdf_mem_malloc(sizeof(tSirSmeDeauthInd));
+ if (NULL == pSirSmeDeauthInd) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_DEAUTH_Ind"));
+
+ return;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_IND with "
+ "retCode: %d for " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+ pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+ pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+
+ /* sessionId */
+ pBuf = (uint8_t *) &pSirSmeDeauthInd->sessionId;
+ *pBuf++ = smesessionId;
+
+ /* transaction ID */
+ lim_copy_u16(pBuf, smetransactionId);
+ pBuf += sizeof(uint16_t);
+
+ /* status code */
+ lim_copy_u32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ /* bssId */
+ cdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ /* peerMacAddr */
+ cdf_mem_copy(pSirSmeDeauthInd->peerMacAddr, peerMacAddr,
+ sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+ psessionEntry, 0, (uint16_t) reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ pMsg = (uint32_t *) pSirSmeDeauthInd;
+
+ break;
+ }
+
+ /*Delete the PE session created */
+ if (psessionEntry != NULL) {
+ pe_delete_session(pMac, psessionEntry);
+ }
+
+ lim_send_sme_disassoc_deauth_ntf(pMac, CDF_STATUS_SUCCESS,
+ (uint32_t *) pMsg);
+
+} /*** end lim_send_sme_deauth_ntf() ***/
+
+/**
+ * lim_send_sme_wm_status_change_ntf() - Send Notification
+ * @mac_ctx: Global MAC Context
+ * @status_change_code: Indicates the change in the wireless medium.
+ * @status_change_info: Indicates the information associated with
+ * change in the wireless medium.
+ * @info_len: Indicates the length of status change information
+ * being sent.
+ * @session_id SessionID
+ *
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_WM_STATUS_CHANGE_NTF message to host.
+ *
+ * Return: None
+ */
+void
+lim_send_sme_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
+ tSirSmeStatusChangeCode status_change_code,
+ uint32_t *status_change_info, uint16_t info_len, uint8_t session_id)
+{
+ tSirMsgQ msg;
+ tSirSmeWmStatusChangeNtf *wm_status_change_ntf;
+
+ wm_status_change_ntf = cdf_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf));
+ if (NULL == wm_status_change_ntf) {
+ lim_log(mac_ctx, LOGE,
+ FL("Mem Alloc failed - eWNI_SME_WM_STATUS_CHANGE_NTF"));
+ return;
+ }
+
+ msg.type = eWNI_SME_WM_STATUS_CHANGE_NTF;
+ msg.bodyval = 0;
+ msg.bodyptr = wm_status_change_ntf;
+
+ switch (status_change_code) {
+ case eSIR_SME_RADAR_DETECTED:
+ break;
+ default:
+ wm_status_change_ntf->messageType =
+ eWNI_SME_WM_STATUS_CHANGE_NTF;
+ wm_status_change_ntf->statusChangeCode = status_change_code;
+ wm_status_change_ntf->length = sizeof(tSirSmeWmStatusChangeNtf);
+ wm_status_change_ntf->sessionId = session_id;
+ if (sizeof(wm_status_change_ntf->statusChangeInfo) >=
+ info_len) {
+ cdf_mem_copy(
+ (uint8_t *) &wm_status_change_ntf->statusChangeInfo,
+ (uint8_t *) status_change_info, info_len);
+ }
+ lim_log(mac_ctx, LOGE,
+ FL("**---** StatusChg: code 0x%x, length %d **---**"),
+ status_change_code, info_len);
+ break;
+ }
+
+ MTRACE(mac_trace_msg_tx(mac_ctx, session_id, msg.type));
+ if (eSIR_SUCCESS != lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT)) {
+ cdf_mem_free(wm_status_change_ntf);
+ lim_log(mac_ctx, LOGP,
+ FL("lim_sys_process_mmh_msg_api failed"));
+ }
+
+} /*** end lim_send_sme_wm_status_change_ntf() ***/
+
+/**
+ * lim_send_sme_set_context_rsp()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_SETCONTEXT_RSP message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * setContext was performed
+ * @param aid Indicates the aid corresponding to the peer MAC
+ * address
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_SETCONTEXT_RSP message
+ *
+ * @return None
+ */
+void
+lim_send_sme_set_context_rsp(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr, uint16_t aid,
+ tSirResultCodes resultCode,
+ tpPESession psessionEntry, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+
+ uint8_t *pBuf;
+ tSirMsgQ mmhMsg;
+ tSirSmeSetContextRsp *pSirSmeSetContextRsp;
+
+ pSirSmeSetContextRsp = cdf_mem_malloc(sizeof(tSirSmeSetContextRsp));
+ if (NULL == pSirSmeSetContextRsp) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for SmeSetContextRsp"));
+
+ return;
+ }
+
+ pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP;
+ pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp);
+ pSirSmeSetContextRsp->statusCode = resultCode;
+
+ pBuf = pSirSmeSetContextRsp->peerMacAddr;
+
+ cdf_mem_copy(pBuf, (uint8_t *) peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ /* Update SME session and transaction Id */
+ pSirSmeSetContextRsp->sessionId = smesessionId;
+ pSirSmeSetContextRsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_SETCONTEXT_RSP;
+ mmhMsg.bodyptr = pSirSmeSetContextRsp;
+ mmhMsg.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+ psessionEntry, (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+} /*** end lim_send_sme_set_context_rsp() ***/
+
+/**
+ * lim_send_sme_neighbor_bss_ind()
+ *
+ ***FUNCTION:
+ * This function is called by lim_lookup_nadd_hash_entry() to send
+ * eWNI_SME_NEIGHBOR_BSS_IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to
+ * host upon detecting new BSS during background scanning if CFG
+ * option is enabled for sending such indication
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+lim_send_sme_neighbor_bss_ind(tpAniSirGlobal pMac, tLimScanResultNode *pBssDescr)
+{
+ tSirMsgQ msgQ;
+ uint32_t val;
+ tSirSmeNeighborBssInd *pNewBssInd;
+
+ if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) ||
+ ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) &&
+ pMac->lim.gLimRspReqd)) {
+ /* LIM is not in background scan state OR */
+ /* current scan is initiated by HDD. */
+ /* No need to send new BSS indication to HDD */
+ return;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not get NEIGHBOR_BSS_IND from CFG"));
+
+ return;
+ }
+
+ if (val == 0)
+ return;
+
+ /**
+ * Need to indicate new BSSs found during
+ * background scanning to host.
+ * Allocate buffer for sending indication.
+ * Length of buffer is length of BSS description
+ * and length of header itself
+ */
+ val = pBssDescr->bssDescription.length + sizeof(uint16_t) +
+ sizeof(uint32_t) + sizeof(uint8_t);
+ pNewBssInd = cdf_mem_malloc(val);
+ if (NULL == pNewBssInd) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND"));
+
+ return;
+ }
+
+ pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND;
+ pNewBssInd->length = (uint16_t) val;
+ pNewBssInd->sessionId = 0;
+
+ cdf_mem_copy((uint8_t *) pNewBssInd->bssDescription,
+ (uint8_t *) &pBssDescr->bssDescription,
+ pBssDescr->bssDescription.length + sizeof(uint16_t));
+
+ msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND;
+ msgQ.bodyptr = pNewBssInd;
+ msgQ.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT);
+} /*** end lim_send_sme_neighbor_bss_ind() ***/
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_addts_rsp() - sends SME ADDTS RSP
+ \ This function sends a eWNI_SME_ADDTS_RSP to SME.
+ \ SME only looks at rc and tspec field.
+ \param pMac - global mac structure
+ \param rspReqd - is SmeAddTsRsp required
+ \param status - status code of SME_ADD_TS_RSP
+ \return tspec
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status,
+ tpPESession psessionEntry, tSirMacTspecIE tspec,
+ uint8_t smesessionId, uint16_t smetransactionId)
+{
+ tpSirAddtsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ if (!rspReqd)
+ return;
+
+ rsp = cdf_mem_malloc(sizeof(tSirAddtsRsp));
+ if (NULL == rsp) {
+ lim_log(pMac, LOGP, FL("AllocateMemory failed for ADDTS_RSP"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+ rsp->messageType = eWNI_SME_ADDTS_RSP;
+ rsp->rc = status;
+ rsp->rsp.status = (enum eSirMacStatusCodes)status;
+ rsp->rsp.tspec = tspec;
+ /* Update SME session Id and transcation Id */
+ rsp->sessionId = smesessionId;
+ rsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_ADDTS_RSP;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+void
+lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, uint32_t status,
+ tpPESession psessionEntry, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+ tpSirDeltsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ lim_log(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d",
+ delts->aid,
+ delts->req.tsinfo.traffic.tsid,
+ delts->req.tsinfo.traffic.userPrio, status);
+ if (!delts->rspReqd)
+ return;
+
+ rsp = cdf_mem_malloc(sizeof(tSirDeltsRsp));
+ if (NULL == rsp) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_RSP"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+
+ if (psessionEntry != NULL) {
+
+ rsp->aid = delts->aid;
+ cdf_mem_copy((uint8_t *) &rsp->macAddr[0],
+ (uint8_t *) &delts->macAddr[0], 6);
+ cdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) &delts->req,
+ sizeof(tSirDeltsReqInfo));
+ }
+
+ rsp->messageType = eWNI_SME_DELTS_RSP;
+ rsp->rc = status;
+
+ /* Update SME session Id and transcation Id */
+ rsp->sessionId = smesessionId;
+ rsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_DELTS_RSP;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry,
+ (uint16_t) status, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+void
+lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, uint16_t aid,
+ tpPESession psessionEntry)
+{
+ tpSirDeltsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ lim_log(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)",
+ aid, delts->tsinfo.traffic.tsid, delts->tsinfo.traffic.userPrio);
+
+ rsp = cdf_mem_malloc(sizeof(tSirDeltsRsp));
+ if (NULL == rsp) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_IND"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+
+ rsp->messageType = eWNI_SME_DELTS_IND;
+ rsp->rc = eSIR_SUCCESS;
+ rsp->aid = aid;
+ cdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) delts, sizeof(*delts));
+
+ /* Update SME session Id and SME transaction Id */
+
+ rsp->sessionId = psessionEntry->smeSessionId;
+ rsp->transactionId = psessionEntry->transactionId;
+
+ mmhMsg.type = eWNI_SME_DELTS_IND;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+/**
+ * lim_send_sme_pe_statistics_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send 802.11 statistics response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request for statistics.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param p80211Stats Statistics sent in response
+ * @param resultCode TODO:
+ *
+ *
+ * @return none
+ */
+
+void
+lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgType, void *stats)
+{
+ tSirMsgQ mmhMsg;
+ uint8_t sessionId;
+ tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats;
+ tpPESession pPeSessionEntry;
+
+ /* Get the Session Id based on Sta Id */
+ pPeSessionEntry =
+ pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
+
+ /* Fill the Session Id */
+ if (NULL != pPeSessionEntry) {
+ /* Fill the Session Id */
+ pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+ }
+
+ pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP;
+
+ /* msgType should be WMA_GET_STATISTICS_RSP */
+ mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP;
+
+ mmhMsg.bodyptr = stats;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+
+} /*** end lim_send_sme_pe_statistics_rsp() ***/
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/**
+ * lim_send_sme_pe_ese_tsm_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send tsm stats response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request to get tsm stats.
+ *
+ ***PARAMS:
+ * @param pMac - Pointer to global pMac structure
+ * @param pStats - Pointer to TSM Stats
+ *
+ * @return none
+ */
+
+void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats)
+{
+ tSirMsgQ mmhMsg;
+ uint8_t sessionId;
+ tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats;
+ tpPESession pPeSessionEntry = NULL;
+
+ /* Get the Session Id based on Sta Id */
+ pPeSessionEntry =
+ pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
+
+ /* Fill the Session Id */
+ if (NULL != pPeSessionEntry) {
+ /* Fill the Session Id */
+ pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+ } else {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("Session not found for the Sta id(%d)"),
+ pPeStats->staId);
+ )
+ return;
+ }
+
+ pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP;
+ pPeStats->tsmMetrics.RoamingCount
+ = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount;
+ pPeStats->tsmMetrics.RoamingDly
+ = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly;
+
+ mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP;
+ mmhMsg.bodyptr = pStats;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, sessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+} /*** end lim_send_sme_pe_ese_tsm_rsp() ***/
+
+#endif /* FEATURE_WLAN_ESE) && FEATURE_WLAN_ESE_UPLOAD */
+
+void
+lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ uint16_t staIndex,
+ uint8_t ucastIdx,
+ uint8_t bcastIdx,
+ uint8_t *beacon,
+ uint16_t beaconLen, uint16_t msgType, uint8_t sessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSmeIbssPeerInd *pNewPeerInd;
+
+ pNewPeerInd = cdf_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen);
+ if (NULL == pNewPeerInd) {
+ PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));)
+ return;
+ }
+
+ cdf_mem_set((void *)pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen),
+ 0);
+
+ cdf_mem_copy((uint8_t *) pNewPeerInd->peerAddr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ pNewPeerInd->staId = staIndex;
+ pNewPeerInd->ucastSig = ucastIdx;
+ pNewPeerInd->bcastSig = bcastIdx;
+ pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen;
+ pNewPeerInd->mesgType = msgType;
+ pNewPeerInd->sessionId = sessionId;
+
+ if (beacon != NULL) {
+ cdf_mem_copy((void *)((uint8_t *) pNewPeerInd +
+ sizeof(tSmeIbssPeerInd)), (void *)beacon,
+ beaconLen);
+ }
+
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pNewPeerInd;
+ MTRACE(mac_trace_msg_tx(pMac, sessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+}
+
+/**
+ * lim_handle_csa_offload_msg() - Handle CSA offload message
+ * @mac_ctx: pointer to global adapter context
+ * @msg: Message pointer.
+ *
+ * Return: None
+ */
+void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+ tpPESession session_entry;
+ tSirMsgQ mmh_msg;
+ tpCSAOffloadParams csa_params = (tpCSAOffloadParams) (msg->bodyptr);
+ tpSmeCsaOffloadInd csa_offload_ind;
+ tpDphHashNode sta_ds = NULL;
+ uint8_t session_id;
+ uint16_t aid = 0;
+ tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL;
+
+ if (!csa_params) {
+ lim_log(mac_ctx, LOGE, FL("limMsgQ body ptr is NULL"));
+ return;
+ }
+
+ session_entry =
+ pe_find_session_by_bssid(mac_ctx,
+ csa_params->bssId, &session_id);
+ if (!session_entry) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session does not exist"));
+ goto err;
+ }
+
+ sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid,
+ &session_entry->dph.dphHashTable);
+
+ if (!sta_ds) {
+ lim_log(mac_ctx, LOGE,
+ FL("sta_ds does not exist"));
+ goto err;
+ }
+
+ if (LIM_IS_STA_ROLE(session_entry)) {
+ session_entry->gLimChannelSwitch.switchMode =
+ csa_params->switchmode;
+ /* timer already started by firmware, switch immediately */
+ session_entry->gLimChannelSwitch.switchCount = 0;
+ session_entry->gLimChannelSwitch.primaryChannel =
+ csa_params->channel;
+ session_entry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ;
+
+ if (session_entry->vhtCapability &&
+ session_entry->htSupportedChannelWidthSet) {
+ chnl_switch_info =
+ &session_entry->gLimWiderBWChannelSwitch;
+ if (csa_params->ies_present_flag & lim_wbw_ie_present) {
+ chnl_switch_info->newChanWidth =
+ csa_params->new_ch_width;
+ chnl_switch_info->newCenterChanFreq0 =
+ csa_params->new_ch_freq_seg1;
+ chnl_switch_info->newCenterChanFreq1 =
+ csa_params->new_ch_freq_seg2;
+ session_entry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ session_entry->gLimChannelSwitch.ch_width =
+ csa_params->new_ch_width + 1;
+ }
+ } else if (session_entry->htSupportedChannelWidthSet) {
+ if (csa_params->sec_chan_offset) {
+ session_entry->gLimChannelSwitch.ch_width =
+ CH_WIDTH_40MHZ;
+ session_entry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ } else {
+ session_entry->htSupportedChannelWidthSet =
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ session_entry->htRecommendedTxWidthSet =
+ session_entry->htSupportedChannelWidthSet;
+ }
+ }
+ lim_log(mac_ctx, LOG1, FL("new ch width = %d"),
+ session_entry->gLimChannelSwitch.ch_width);
+
+ lim_prepare_for11h_channel_switch(mac_ctx, session_entry);
+ csa_offload_ind = cdf_mem_malloc(sizeof(tSmeCsaOffloadInd));
+ if (NULL == csa_offload_ind) {
+ lim_log(mac_ctx, LOGE,
+ FL("memalloc fail eWNI_SME_CSA_OFFLOAD_EVENT"));
+ goto err;
+ }
+
+ cdf_mem_set(csa_offload_ind, sizeof(tSmeCsaOffloadInd), 0);
+ csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT;
+ csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd);
+ cdf_mem_copy(csa_offload_ind->bssId, session_entry->bssId,
+ sizeof(tSirMacAddr));
+ mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT;
+ mmh_msg.bodyptr = csa_offload_ind;
+ mmh_msg.bodyval = 0;
+ lim_log(mac_ctx, LOG1,
+ FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME. "));
+ MTRACE(mac_trace_msg_tx
+ (mac_ctx, session_entry->peSessionId, mmh_msg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx,
+ WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT, session_entry,
+ eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+ }
+
+err:
+ cdf_mem_free(csa_params);
+}
+
+/*--------------------------------------------------------------------------
+ \brief pe_delete_session() - Handle the Delete BSS Response from HAL.
+
+ \param pMac - pointer to global adapter context
+ \param sessionId - Message pointer.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ)
+{
+ tpPESession psessionEntry;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) (MsgQ->bodyptr);
+
+ psessionEntry =
+ pe_find_session_by_session_id(pMac, pDelBss->sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session Does not exist for given sessionID %d"),
+ pDelBss->sessionId);
+ return;
+ }
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
+ } else if (LIM_IS_UNKNOWN_ROLE(psessionEntry)) {
+ lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry);
+ }
+
+ else
+ lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry);
+
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_aggr_qos_rsp() - sends SME FT AGGR QOS RSP
+ \ This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME.
+ \ SME only looks at rc and tspec field.
+ \param pMac - global mac structure
+ \param rspReqd - is SmeAddTsRsp required
+ \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP
+ \return tspec
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+ uint8_t smesessionId)
+{
+ tSirMsgQ mmhMsg;
+
+ mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP;
+ mmhMsg.bodyptr = aggrQosRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, smesessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+#endif
+
+void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ uint8_t smesessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSmeMaxAssocInd *pSmeMaxAssocInd;
+
+ pSmeMaxAssocInd = cdf_mem_malloc(sizeof(tSmeMaxAssocInd));
+ if (NULL == pSmeMaxAssocInd) {
+ PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));)
+ return;
+ }
+ cdf_mem_set((void *)pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd), 0);
+ cdf_mem_copy((uint8_t *) pSmeMaxAssocInd->peerMac,
+ (uint8_t *) peerMacAddr, sizeof(tSirMacAddr));
+ pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED;
+ pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd);
+ pSmeMaxAssocInd->sessionId = smesessionId;
+ mmhMsg.type = pSmeMaxAssocInd->mesgType;
+ mmhMsg.bodyptr = pSmeMaxAssocInd;
+ PELOG1(lim_log(pMac, LOG1, FL("msgType %s peerMacAddr " MAC_ADDRESS_STR
+ " sme session id %d"),
+ "eWNI_SME_MAX_ASSOC_EXCEEDED",
+ MAC_ADDR_ARRAY(peerMacAddr));
+ )
+ MTRACE(mac_trace_msg_tx(pMac, smesessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_dfs_event_notify() - sends
+ eWNI_SME_DFS_RADAR_FOUND
+ After receiving WMI_PHYERR_EVENTID indication frame from FW, this
+ function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify
+ that a RADAR is found on current operating channel and SAP-
+ has to move to a new channel.
+ \param pMac - global mac structure
+ \param msgType - message type received from lower layer
+ \param event - event data received from lower layer
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType, void *event)
+{
+ tSirMsgQ mmhMsg;
+ mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND;
+ mmhMsg.bodyptr = event;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+/*--------------------------------------------------------------------------
+ \brief lim_send_dfs_chan_sw_ie_update()
+ This timer handler updates the channel switch IE in beacon template
+
+ \param pMac - pointer to global adapter context
+ \return - channel to scan from valid session else zero.
+ \sa
+ --------------------------------------------------------------------------*/
+static void
+lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ /* Update the beacon template and send to FW */
+ if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("Unable to set CSA IE in beacon"));)
+ return;
+ }
+
+ /* Send update beacon template message */
+ lim_send_beacon_ind(pMac, psessionEntry);
+ PELOG1(lim_log(pMac, LOG1,
+ FL(" Updated CSA IE, IE COUNT = %d"),
+ psessionEntry->gLimChannelSwitch.switchCount);
+ )
+
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_ap_channel_switch_resp() - sends
+ eWNI_SME_CHANNEL_CHANGE_RSP
+ After receiving WMA_SWITCH_CHANNEL_RSP indication this
+ function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify
+ that the Channel change has been done to the specified target
+ channel in the Channel change request
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \param pChnlParams - Channel switch params
+ --------------------------------------------------------------------*/
+void
+lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tpSwitchChannelParams pChnlParams)
+{
+ tSirMsgQ mmhMsg;
+ tpSwitchChannelParams pSmeSwithChnlParams;
+ uint8_t channelId;
+
+ pSmeSwithChnlParams = (tSwitchChannelParams *)
+ cdf_mem_malloc(sizeof(tSwitchChannelParams));
+ if (NULL == pSmeSwithChnlParams) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for pSmeSwithChnlParams\n"));
+ return;
+ }
+
+ cdf_mem_set((void *)pSmeSwithChnlParams,
+ sizeof(tSwitchChannelParams), 0);
+
+ cdf_mem_copy(pSmeSwithChnlParams, pChnlParams,
+ sizeof(tSwitchChannelParams));
+
+ channelId = pSmeSwithChnlParams->channelNumber;
+
+ /*
+ * Pass the sme sessionID to SME instead
+ * PE session ID.
+ */
+ pSmeSwithChnlParams->peSessionId = psessionEntry->smeSessionId;
+
+ mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP;
+ mmhMsg.bodyptr = (void *)pSmeSwithChnlParams;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ /*
+ * We should start beacon transmission only if the new
+ * channel after channel change is Non-DFS. For a DFS
+ * channel, PE will receive an explicit request from
+ * upper layers to start the beacon transmission .
+ */
+
+ if (CHANNEL_STATE_DFS != cds_get_channel_state(channelId)) {
+ if (channelId == psessionEntry->currentOperChannel) {
+ lim_apply_configuration(pMac, psessionEntry);
+ lim_send_beacon_ind(pMac, psessionEntry);
+ } else {
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("Failed to Transmit Beacons on channel = %d"
+ "after AP channel change response"),
+ psessionEntry->bcnLen);
+ )
+ }
+ }
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_process_beacon_tx_success_ind() - This function is used
+ explicitely to handle successful beacon transmission indication
+ from the FW. This is a generic event generated by the FW afer the
+ first beacon is sent out after the beacon template update by the
+ host
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType, void *event)
+{
+ /* Currently, this event is used only for DFS channel switch announcement
+ * IE update in the template. If required to be used for other IE updates
+ * add appropriate code by introducing a state variable
+ */
+ tpPESession psessionEntry;
+ tSirMsgQ mmhMsg;
+ tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse;
+ struct sir_beacon_tx_complete_rsp *beacon_tx_comp_rsp_ptr;
+ uint8_t length = sizeof(tSirSmeCSAIeTxCompleteRsp);
+ tpSirFirstBeaconTxCompleteInd pBcnTxInd =
+ (tSirFirstBeaconTxCompleteInd *) event;
+
+ psessionEntry = pe_find_session_by_bss_idx(pMac, pBcnTxInd->bssIdx);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ true == psessionEntry->dfsIncludeChanSwIe) {
+ /* Send only 5 beacons with CSA IE Set in when a radar is detected */
+ if (psessionEntry->gLimChannelSwitch.switchCount > 0) {
+ /*
+ * Send the next beacon with updated CSA IE count
+ */
+ lim_send_dfs_chan_sw_ie_update(pMac, psessionEntry);
+ /* Decrement the IE count */
+ psessionEntry->gLimChannelSwitch.switchCount--;
+ } else {
+ /* Done with CSA IE update, send response back to SME */
+ psessionEntry->gLimChannelSwitch.switchCount = 0;
+ if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == false)
+ psessionEntry->gLimChannelSwitch.switchMode = 0;
+ psessionEntry->dfsIncludeChanSwIe = false;
+ psessionEntry->dfsIncludeChanWrapperIe = false;
+
+ pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *)
+ cdf_mem_malloc(length);
+
+ if (NULL == pChanSwTxResponse) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp"));
+ return;
+ }
+
+ cdf_mem_set((void *)pChanSwTxResponse, length, 0);
+ pChanSwTxResponse->sessionId =
+ psessionEntry->smeSessionId;
+ pChanSwTxResponse->chanSwIeTxStatus =
+ CDF_STATUS_SUCCESS;
+
+ mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND;
+ mmhMsg.bodyptr = pChanSwTxResponse;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ psessionEntry->gLimOperatingMode.present) {
+ /* Done with nss update, send response back to SME */
+ psessionEntry->gLimOperatingMode.present = 0;
+ beacon_tx_comp_rsp_ptr = (struct sir_beacon_tx_complete_rsp *)
+ cdf_mem_malloc(sizeof(*beacon_tx_comp_rsp_ptr));
+ if (NULL == beacon_tx_comp_rsp_ptr) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for beacon_tx_comp_rsp_ptr"));
+ return;
+ }
+ cdf_mem_set((void *)beacon_tx_comp_rsp_ptr,
+ sizeof(*beacon_tx_comp_rsp_ptr), 0);
+ beacon_tx_comp_rsp_ptr->session_id =
+ psessionEntry->smeSessionId;
+ beacon_tx_comp_rsp_ptr->tx_status = CDF_STATUS_SUCCESS;
+ mmhMsg.type = eWNI_SME_NSS_UPDATE_RSP;
+ mmhMsg.bodyptr = beacon_tx_comp_rsp_ptr;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ }
+ return;
+}
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
new file mode 100644
index 0000000..e707481
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_send_sme_rsp_messages.h contains the definitions for
+ * sending SME response/notification messages to applications above
+ * MAC software.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_SEND_SME_RSP_H
+#define __LIM_SEND_SME_RSP_H
+
+#include "sir_common.h"
+#include "sir_api.h"
+#include "sir_mac_prot_def.h"
+
+/* Functions for sending responses to Host */
+void lim_send_sme_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes, uint8_t,
+ uint16_t);
+void lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint8_t sme_session_id,
+ uint32_t scan_id);
+void lim_send_sme_start_bss_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
+ tpPESession, uint8_t, uint16_t);
+void lim_send_sme_scan_rsp(tpAniSirGlobal, tSirResultCodes, uint8_t,
+ uint16_t, uint32_t scan_id);
+void lim_post_sme_scan_rsp_message(tpAniSirGlobal, tSirResultCodes,
+ uint8_t, uint16_t, uint32_t scan_id);
+
+void lim_send_sme_join_reassoc_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
+ uint16_t, tpPESession, uint8_t, uint16_t);
+void lim_send_sme_disassoc_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes,
+ uint16_t, uint16_t, uint8_t, uint16_t, tpPESession);
+void lim_send_sme_deauth_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, uint16_t,
+ uint16_t, uint8_t, uint16_t);
+void lim_send_sme_disassoc_ind(tpAniSirGlobal, tpDphHashNode, tpPESession);
+void lim_send_sme_deauth_ind(tpAniSirGlobal, tpDphHashNode,
+ tpPESession psessionEntry);
+void lim_send_sme_wm_status_change_ntf(tpAniSirGlobal, tSirSmeStatusChangeCode,
+ uint32_t *, uint16_t, uint8_t);
+void lim_send_sme_set_context_rsp(tpAniSirGlobal, tSirMacAddr, uint16_t,
+ tSirResultCodes, tpPESession, uint8_t, uint16_t);
+void lim_send_sme_neighbor_bss_ind(tpAniSirGlobal, tLimScanResultNode *);
+void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ);
+void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+void
+lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+ uint8_t smesessionId);
+#endif /*WLAN_FEATURE_VOWIFI_11R */
+
+void lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status,
+ tpPESession psessionEntry, tSirMacTspecIE tspec,
+ uint8_t smesessionId, uint16_t smetransactionId);
+void lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts,
+ uint32_t status, tpPESession psessionEntry,
+ uint8_t smessionId, uint16_t smetransactionId);
+void lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts,
+ uint16_t aid, tpPESession);
+void lim_send_sme_stats_rsp(tpAniSirGlobal pMac, uint16_t msgtype, void *stats);
+
+void lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgtype,
+ void *stats);
+#ifdef FEATURE_WLAN_ESE_UPLOAD
+void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats);
+#endif
+
+void lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ uint16_t staIndex, uint8_t ucastIdx,
+ uint8_t bcastIdx, uint8_t *beacon,
+ uint16_t beaconLen, uint16_t msgType,
+ uint8_t sessionId);
+#ifdef FEATURE_OEM_DATA_SUPPORT
+void lim_send_sme_oem_data_rsp(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
+ tSirResultCodes resultCode);
+#endif
+
+void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ uint8_t smesessionId);
+#ifdef FEATURE_WLAN_TDLS
+void lim_send_sme_tdls_link_establish_req_rsp(tpAniSirGlobal pMac, uint8_t sessionId,
+ tSirMacAddr peerMac,
+ tDphHashNode *pStaDs, uint8_t status);
+void lim_send_sme_tdls_event_notify(tpAniSirGlobal pMac, uint16_t msgType,
+ void *events);
+#endif
+
+void lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType,
+ void *event);
+void lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tpSwitchChannelParams pChnlParams);
+void
+lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType,
+ void *event);
+
+typedef enum {
+ lim_csa_ie_present = 0x00000001,
+ lim_xcsa_ie_present = 0x00000002,
+ lim_wbw_ie_present = 0x00000004,
+ lim_cswarp_ie_present = 0x00000008,
+} lim_csa_event_ies_present_flag;
+
+#endif /* __LIM_SEND_SME_RSP_H */
diff --git a/core/mac/src/pe/lim/lim_ser_des_utils.c b/core/mac/src/pe/lim/lim_ser_des_utils.c
new file mode 100644
index 0000000..bd778f5
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ser_des_utils.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_ser_des_utils.cc contains the serializer/deserializer
+ * utility functions LIM uses while communicating with upper layer
+ * software entities
+ * Author: Chandra Modumudi
+ * Date: 10/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "ani_system_defs.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_ser_des_utils.h"
+
+/**---------------------------------------------------------------
+ \fn lim_get_session_info
+ \brief This function returns the sessionId and transactionId
+ \ of a message. This assumes that the message structure
+ \ is of format:
+ \ uint16_t messageType
+ \ uint16_t messageLength
+ \ uint8_t sessionId
+ \ uint16_t transactionId
+ \param pMac - pMac global structure
+ \param *pBuf - pointer to the message buffer
+ \param sessionId - returned session id value
+ \param transactionId - returned transaction ID value
+ \return None
+ ------------------------------------------------------------------*/
+void
+lim_get_session_info(tpAniSirGlobal pMac, uint8_t *pBuf, uint8_t *sessionId,
+ uint16_t *transactionId)
+{
+ if (!pBuf) {
+ lim_log(pMac, LOGE, FL("NULL ptr received. "));
+ return;
+ }
+
+ pBuf += sizeof(uint16_t); /* skip message type */
+ pBuf += sizeof(uint16_t); /* skip message length */
+
+ *sessionId = *pBuf; /* get sessionId */
+ pBuf++;
+ *transactionId = lim_get_u16(pBuf); /* get transactionId */
+
+ return;
+}
diff --git a/core/mac/src/pe/lim/lim_ser_des_utils.h b/core/mac/src/pe/lim/lim_ser_des_utils.h
new file mode 100644
index 0000000..f05f4dd
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_ser_des_utils.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_ser_des_utils.h contains the utility definitions
+ * LIM uses while processing messages from upper layer software
+ * modules
+ * Author: Chandra Modumudi
+ * Date: 10/20/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SERDES_UTILS_H
+#define __LIM_SERDES_UTILS_H
+
+#include "sir_api.h"
+#include "ani_system_defs.h"
+#include "sir_mac_prot_def.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_prop_exts_utils.h"
+
+void lim_get_session_info(tpAniSirGlobal pMac, uint8_t *,
+ uint8_t *, uint16_t *);
+
+/* Byte String <--> uint16_t/uint32_t copy functions */
+static inline void lim_copy_u16(uint8_t *ptr, uint16_t u16Val)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ *ptr++ = (uint8_t) (u16Val & 0xff);
+ *ptr = (uint8_t) ((u16Val >> 8) & 0xff);
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+static inline uint16_t lim_get_u16(uint8_t *ptr)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ return ((uint16_t) (*(ptr + 1) << 8)) | ((uint16_t) (*ptr));
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+static inline void lim_copy_u32(uint8_t *ptr, uint32_t u32Val)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ *ptr++ = (uint8_t) (u32Val & 0xff);
+ *ptr++ = (uint8_t) ((u32Val >> 8) & 0xff);
+ *ptr++ = (uint8_t) ((u32Val >> 16) & 0xff);
+ *ptr = (uint8_t) ((u32Val >> 24) & 0xff);
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+static inline uint32_t lim_get_u32(uint8_t *ptr)
+{
+#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \
+ (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN)))
+ return ((*(ptr + 3) << 24) |
+ (*(ptr + 2) << 16) | (*(ptr + 1) << 8) | (*(ptr)));
+#else
+#error "Unknown combination of OS Type and endianess"
+#endif
+}
+
+#endif /* __LIM_SERDES_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c
new file mode 100644
index 0000000..6c73b4c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_session.c
@@ -0,0 +1,767 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file lim_session.c
+
+ \brief implementation for lim Session related APIs
+
+ \author Sunit Bhatia
+
+ ========================================================================*/
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include "ani_global.h"
+#include "lim_debug.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#include "lim_ft.h"
+#endif
+#include "lim_session.h"
+#include "lim_utils.h"
+
+#include "sch_api.h"
+#include "lim_send_messages.h"
+
+/*--------------------------------------------------------------------------
+
+ \brief pe_init_beacon_params() - Initialize the beaconParams structure
+
+ \param tpPESession - pointer to the session context or NULL if session can not be created.
+ \return void
+ \sa
+
+ --------------------------------------------------------------------------*/
+
+void pe_init_beacon_params(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ psessionEntry->beaconParams.beaconInterval = 0;
+ psessionEntry->beaconParams.fShortPreamble = 0;
+ psessionEntry->beaconParams.llaCoexist = 0;
+ psessionEntry->beaconParams.llbCoexist = 0;
+ psessionEntry->beaconParams.llgCoexist = 0;
+ psessionEntry->beaconParams.ht20Coexist = 0;
+ psessionEntry->beaconParams.llnNonGFCoexist = 0;
+ psessionEntry->beaconParams.fRIFSMode = 0;
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
+ psessionEntry->beaconParams.gHTObssMode = 0;
+
+ /* Number of legacy STAs associated */
+ cdf_mem_set((void *)&psessionEntry->gLim11bParams,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set((void *)&psessionEntry->gLim11aParams,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set((void *)&psessionEntry->gLim11gParams,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set((void *)&psessionEntry->gLimNonGfParams,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set((void *)&psessionEntry->gLimHt20Params,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set((void *)&psessionEntry->gLimLsigTxopParams,
+ sizeof(tLimProtStaParams), 0);
+ cdf_mem_set((void *)&psessionEntry->gLimOlbcParams,
+ sizeof(tLimProtStaParams), 0);
+}
+
+/*
+ * pe_reset_protection_callback() - resets protection structs so that when an AP
+ * causing use of protection goes away, corresponding protection bit can be
+ * reset
+ * @ptr: pointer to pSessionEntry
+ *
+ * This function resets protection structs so that when an AP causing use of
+ * protection goes away, corresponding protection bit can be reset. This allowes
+ * protection bits to be reset once legacy overlapping APs are gone.
+ *
+ * Return: void
+ */
+void pe_reset_protection_callback(void *ptr)
+{
+ tpPESession pe_session_entry = (tpPESession)ptr;
+ tpAniSirGlobal mac_ctx = (tpAniSirGlobal)pe_session_entry->mac_ctx;
+ int8_t i = 0;
+ tUpdateBeaconParams beacon_params;
+ uint16_t current_protection_state = 0;
+ tpDphHashNode station_hash_node = NULL;
+ tSirMacHTOperatingMode old_op_mode;
+ bool bcn_prms_changed = false;
+
+ if (pe_session_entry->valid == false) {
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_ERROR,
+ FL("session already deleted. exiting timer callback"));
+ return;
+ }
+
+ current_protection_state |=
+ pe_session_entry->gLimOverlap11gParams.protectionEnabled |
+ pe_session_entry->gLimOverlap11aParams.protectionEnabled << 1 |
+ pe_session_entry->gLimOverlapHt20Params.protectionEnabled << 2 |
+ pe_session_entry->gLimOverlapNonGfParams.protectionEnabled << 3 |
+ pe_session_entry->gLimOlbcParams.protectionEnabled << 4;
+
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_INFO,
+ FL("old protection state: 0x%04X, new protection state: 0x%04X\n"),
+ pe_session_entry->old_protection_state,
+ current_protection_state);
+
+ cdf_mem_zero(&pe_session_entry->gLimOverlap11gParams,
+ sizeof(pe_session_entry->gLimOverlap11gParams));
+ cdf_mem_zero(&pe_session_entry->gLimOverlap11aParams,
+ sizeof(pe_session_entry->gLimOverlap11aParams));
+ cdf_mem_zero(&pe_session_entry->gLimOverlapHt20Params,
+ sizeof(pe_session_entry->gLimOverlapHt20Params));
+ cdf_mem_zero(&pe_session_entry->gLimOverlapNonGfParams,
+ sizeof(pe_session_entry->gLimOverlapNonGfParams));
+
+ cdf_mem_zero(&pe_session_entry->gLimOlbcParams,
+ sizeof(pe_session_entry->gLimOlbcParams));
+
+ cdf_mem_zero(&pe_session_entry->beaconParams,
+ sizeof(pe_session_entry->beaconParams));
+
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlap11gParams,
+ sizeof(mac_ctx->lim.gLimOverlap11gParams));
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlap11aParams,
+ sizeof(mac_ctx->lim.gLimOverlap11aParams));
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlapHt20Params,
+ sizeof(mac_ctx->lim.gLimOverlapHt20Params));
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlapNonGfParams,
+ sizeof(mac_ctx->lim.gLimOverlapNonGfParams));
+
+ old_op_mode = pe_session_entry->htOperMode;
+ pe_session_entry->htOperMode = eSIR_HT_OP_MODE_PURE;
+
+ cdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+ /* index 0, is self node, peers start from 1 */
+ for (i = 1 ; i <= mac_ctx->lim.gLimAssocStaLimit ; i++)
+ {
+ station_hash_node = dph_get_hash_entry(mac_ctx, i,
+ &pe_session_entry->dph.dphHashTable);
+ if (NULL == station_hash_node)
+ continue;
+ lim_decide_ap_protection(mac_ctx, station_hash_node->staAddr,
+ &beacon_params, pe_session_entry);
+ }
+
+ if (pe_session_entry->htOperMode != old_op_mode)
+ bcn_prms_changed = true;
+
+ if ((current_protection_state !=
+ pe_session_entry->old_protection_state) &&
+ (false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_ERROR,
+ FL("protection changed, update beacon template\n"));
+ /* update beacon fix params and send update to FW */
+ cdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
+ beacon_params.bssIdx = pe_session_entry->bssIdx;
+ beacon_params.fShortPreamble =
+ pe_session_entry->beaconParams.fShortPreamble;
+ beacon_params.beaconInterval =
+ pe_session_entry->beaconParams.beaconInterval;
+ beacon_params.llaCoexist =
+ pe_session_entry->beaconParams.llaCoexist;
+ beacon_params.llbCoexist =
+ pe_session_entry->beaconParams.llbCoexist;
+ beacon_params.llgCoexist =
+ pe_session_entry->beaconParams.llgCoexist;
+ beacon_params.ht20MhzCoexist =
+ pe_session_entry->beaconParams.ht20Coexist;
+ beacon_params.llnNonGFCoexist =
+ pe_session_entry->beaconParams.llnNonGFCoexist;
+ beacon_params.fLsigTXOPProtectionFullSupport =
+ pe_session_entry->beaconParams.
+ fLsigTXOPProtectionFullSupport;
+ beacon_params.fRIFSMode =
+ pe_session_entry->beaconParams.fRIFSMode;
+ beacon_params.smeSessionId =
+ pe_session_entry->smeSessionId;
+ bcn_prms_changed = true;
+ }
+
+ if (bcn_prms_changed) {
+ sch_set_fixed_beacon_fields(mac_ctx, pe_session_entry);
+ lim_send_beacon_params(mac_ctx, &beacon_params, pe_session_entry);
+ }
+
+ pe_session_entry->old_protection_state = current_protection_state;
+ if (cdf_mc_timer_start(&pe_session_entry->
+ protection_fields_reset_timer,
+ SCH_PROTECTION_RESET_TIME)
+ != CDF_STATUS_SUCCESS) {
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_ERROR,
+ FL("cannot create or start protectionFieldsResetTimer\n"));
+ }
+}
+
+/**
+ * pe_create_session() creates a new PE session given the BSSID
+ * @param pMac: pointer to global adapter context
+ * @param bssid: BSSID of the new session
+ * @param sessionId: session ID is returned here, if session is created.
+ * @param bssType: station or a
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the passed BSSID is found in the PE session table.
+ *
+ * Return: tpPESession: pointer to the session context or NULL if session
+ * can not be created.
+ */
+
+tpPESession
+pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId,
+ uint16_t numSta, tSirBssType bssType)
+{
+ CDF_STATUS status;
+ uint8_t i;
+ tpPESession session_ptr;
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ /* Find first free room in session table */
+ if (pMac->lim.gpSession[i].valid == true)
+ continue;
+ break;
+ }
+
+ if (i == pMac->lim.maxBssId) {
+ lim_log(pMac, LOGE,
+ FL("Session can't be created. Reached max sessions\n"));
+ return NULL;
+ }
+
+ session_ptr = &pMac->lim.gpSession[i];
+ cdf_mem_set((void *)session_ptr, sizeof(tPESession), 0);
+ /* Allocate space for Station Table for this session. */
+ session_ptr->dph.dphHashTable.pHashTable =
+ cdf_mem_malloc(sizeof(tpDphHashNode) * (numSta + 1));
+ if (NULL == session_ptr->dph.dphHashTable.pHashTable) {
+ lim_log(pMac, LOGE, FL("memory allocate failed!"));
+ return NULL;
+ }
+
+ session_ptr->dph.dphHashTable.pDphNodeArray =
+ cdf_mem_malloc(sizeof(tDphHashNode) * (numSta + 1));
+ if (NULL == session_ptr->dph.dphHashTable.pDphNodeArray) {
+ lim_log(pMac, LOGE, FL("memory allocate failed!"));
+ cdf_mem_free(session_ptr->dph.dphHashTable.pHashTable);
+ session_ptr->dph.dphHashTable.
+ pHashTable = NULL;
+ return NULL;
+ }
+
+ session_ptr->dph.dphHashTable.size = numSta + 1;
+ dph_hash_table_class_init(pMac, &session_ptr->dph.dphHashTable);
+ session_ptr->gpLimPeerIdxpool = cdf_mem_malloc(
+ sizeof(*(session_ptr->gpLimPeerIdxpool)) * (numSta + 1));
+ if (NULL == session_ptr->gpLimPeerIdxpool) {
+ lim_log(pMac, LOGE, FL("memory allocate failed!"));
+ cdf_mem_free(session_ptr->dph.dphHashTable.pHashTable);
+ cdf_mem_free(session_ptr->dph.dphHashTable.pDphNodeArray);
+ session_ptr->dph.dphHashTable.pHashTable = NULL;
+ session_ptr->dph.dphHashTable.pDphNodeArray = NULL;
+ return NULL;
+ }
+ cdf_mem_set(session_ptr->gpLimPeerIdxpool,
+ sizeof(*session_ptr->gpLimPeerIdxpool) * (numSta + 1),
+ 0);
+ session_ptr->freePeerIdxHead = 0;
+ session_ptr->freePeerIdxTail = 0;
+ session_ptr->gLimNumOfCurrentSTAs = 0;
+ /* Copy the BSSID to the session table */
+ sir_copy_mac_addr(session_ptr->bssId, bssid);
+ session_ptr->valid = true;
+ /* Intialize the SME and MLM states to IDLE */
+ session_ptr->limMlmState = eLIM_MLM_IDLE_STATE;
+ session_ptr->limSmeState = eLIM_SME_IDLE_STATE;
+ session_ptr->limCurrentAuthType = eSIR_OPEN_SYSTEM;
+ pe_init_beacon_params(pMac, &pMac->lim.gpSession[i]);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ session_ptr->is11Rconnection = false;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ session_ptr->isESEconnection = false;
+#endif
+#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
+ session_ptr->isFastTransitionEnabled = false;
+#endif
+#ifdef FEATURE_WLAN_LFR
+ session_ptr->isFastRoamIniFeatureEnabled = false;
+#endif
+ *sessionId = i;
+ session_ptr->gLimPhyMode = WNI_CFG_PHY_MODE_11G;
+ /* Initialize CB mode variables when session is created */
+ session_ptr->htSupportedChannelWidthSet = 0;
+ session_ptr->htRecommendedTxWidthSet = 0;
+ session_ptr->htSecondaryChannelOffset = 0;
+#ifdef FEATURE_WLAN_TDLS
+ cdf_mem_set(session_ptr->peerAIDBitmap,
+ sizeof(session_ptr->peerAIDBitmap), 0);
+ session_ptr->tdls_prohibited = false;
+ session_ptr->tdls_chan_swit_prohibited = false;
+#endif
+ session_ptr->fWaitForProbeRsp = 0;
+ session_ptr->fIgnoreCapsChange = 0;
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ FL("Create a new PE session(%d), BSSID: "MAC_ADDRESS_STR" Max No. of STA %d"),
+ session_ptr->peSessionId, MAC_ADDR_ARRAY(bssid), numSta);
+
+ if (eSIR_INFRA_AP_MODE == bssType
+ || eSIR_IBSS_MODE == bssType
+ || eSIR_BTAMP_AP_MODE == bssType) {
+ session_ptr->pSchProbeRspTemplate =
+ cdf_mem_malloc(SCH_MAX_PROBE_RESP_SIZE);
+ session_ptr->pSchBeaconFrameBegin =
+ cdf_mem_malloc(SCH_MAX_BEACON_SIZE);
+ session_ptr->pSchBeaconFrameEnd =
+ cdf_mem_malloc(SCH_MAX_BEACON_SIZE);
+ if ((NULL == session_ptr->pSchProbeRspTemplate)
+ || (NULL == session_ptr->pSchBeaconFrameBegin)
+ || (NULL == session_ptr->pSchBeaconFrameEnd)) {
+ lim_log(pMac, LOGE, FL("memory allocate failed!"));
+ cdf_mem_free(session_ptr->dph.dphHashTable.pHashTable);
+ cdf_mem_free(session_ptr->dph.dphHashTable.pDphNodeArray);
+ cdf_mem_free(session_ptr->gpLimPeerIdxpool);
+ cdf_mem_free(session_ptr->pSchProbeRspTemplate);
+ cdf_mem_free(session_ptr->pSchBeaconFrameBegin);
+ cdf_mem_free(session_ptr->pSchBeaconFrameEnd);
+
+ session_ptr->dph.dphHashTable.pHashTable = NULL;
+ session_ptr->dph.dphHashTable.pDphNodeArray = NULL;
+ session_ptr->gpLimPeerIdxpool = NULL;
+ session_ptr->pSchProbeRspTemplate = NULL;
+ session_ptr->pSchBeaconFrameBegin = NULL;
+ session_ptr->pSchBeaconFrameEnd = NULL;
+ return NULL;
+ }
+ }
+#if defined WLAN_FEATURE_VOWIFI_11R
+ if (eSIR_INFRASTRUCTURE_MODE == bssType)
+ lim_ft_open(pMac, &pMac->lim.gpSession[i]);
+#endif
+ if (eSIR_INFRA_AP_MODE == bssType) {
+ session_ptr->old_protection_state = 0;
+ session_ptr->mac_ctx = (void *)pMac;
+ status = cdf_mc_timer_init(
+ &session_ptr->protection_fields_reset_timer,
+ CDF_TIMER_TYPE_SW, pe_reset_protection_callback,
+ (void *)&pMac->lim.gpSession[i]);
+ if (status == CDF_STATUS_SUCCESS) {
+ status = cdf_mc_timer_start(
+ &session_ptr->protection_fields_reset_timer,
+ SCH_PROTECTION_RESET_TIME);
+ }
+ if (status != CDF_STATUS_SUCCESS)
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ FL("cannot create or start protectionFieldsResetTimer\n"));
+ }
+ return &pMac->lim.gpSession[i];
+}
+
+/*--------------------------------------------------------------------------
+ \brief pe_find_session_by_bssid() - looks up the PE session given the BSSID.
+
+ This function returns the session context and the session ID if the session
+ corresponding to the given BSSID is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param bssid - BSSID of the session
+ \param sessionId -session ID is returned here, if session is found.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+tpPESession pe_find_session_by_bssid(tpAniSirGlobal pMac, uint8_t *bssid,
+ uint8_t *sessionId)
+{
+ uint8_t i;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ /* If BSSID matches return corresponding tables address */
+ if ((pMac->lim.gpSession[i].valid)
+ && (sir_compare_mac_addr(pMac->lim.gpSession[i].bssId, bssid)))
+ {
+ *sessionId = i;
+ return (&pMac->lim.gpSession[i]);
+ }
+ }
+
+ lim_log(pMac, LOG4, FL("Session lookup fails for BSSID: \n "));
+ lim_print_mac_addr(pMac, bssid, LOG4);
+ return (NULL);
+
+}
+
+/*--------------------------------------------------------------------------
+ \brief pe_find_session_by_bss_idx() - looks up the PE session given the bssIdx.
+
+ This function returns the session context if the session
+ corresponding to the given bssIdx is found in the PE session table.
+ \param pMac - pointer to global adapter context
+ \param bssIdx - bss index of the session
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+ \sa
+ --------------------------------------------------------------------------*/
+tpPESession pe_find_session_by_bss_idx(tpAniSirGlobal pMac, uint8_t bssIdx)
+{
+ uint8_t i;
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ /* If BSSID matches return corresponding tables address */
+ if ((pMac->lim.gpSession[i].valid)
+ && (pMac->lim.gpSession[i].bssIdx == bssIdx)) {
+ return &pMac->lim.gpSession[i];
+ }
+ }
+ lim_log(pMac, LOG4, FL("Session lookup fails for bssIdx: %d"), bssIdx);
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------
+ \brief pe_find_session_by_session_id() - looks up the PE session given the session ID.
+
+ This function returns the session context if the session
+ corresponding to the given session ID is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param sessionId -session ID for which session context needs to be looked up.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+tpPESession pe_find_session_by_session_id(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+ if (sessionId >= pMac->lim.maxBssId) {
+ lim_log(pMac, LOGE, FL("Invalid sessionId: %d \n "), sessionId);
+ return (NULL);
+ }
+ if ((pMac->lim.gpSession[sessionId].valid == true)) {
+ return (&pMac->lim.gpSession[sessionId]);
+ }
+ return (NULL);
+
+}
+
+/**
+ * pe_find_session_by_sta_id() - looks up the PE session given staid.
+ * @mac_ctx: pointer to global adapter context
+ * @staid: StaId of the session
+ * @session_id: session ID is returned here, if session is found.
+ *
+ * This function returns the session context and the session ID if the session
+ * corresponding to the given StaId is found in the PE session table.
+ *
+ * Return: session pointer
+ */
+tpPESession
+pe_find_session_by_sta_id(tpAniSirGlobal mac_ctx,
+ uint8_t staid,
+ uint8_t *session_id)
+{
+ uint8_t i, j;
+ tpPESession session_ptr;
+ dphHashTableClass *dph_ptr;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ if (!mac_ctx->lim.gpSession[i].valid)
+ continue;
+ session_ptr = &mac_ctx->lim.gpSession[i];
+ dph_ptr = &session_ptr->dph.dphHashTable;
+ for (j = 0; j < dph_ptr->size; j++) {
+ if (dph_ptr->pDphNodeArray[j].valid
+ && dph_ptr->pDphNodeArray[j].added
+ && staid == dph_ptr->pDphNodeArray[j].staIndex) {
+ *session_id = i;
+ return session_ptr;
+ }
+ }
+ }
+
+ lim_log(mac_ctx, LOG4,
+ FL("Session lookup fails for StaId: %d\n "), staid);
+ return NULL;
+}
+
+/**
+ * pe_delete_session() - deletes the PE session given the session ID.
+ * @mac_ctx: pointer to global adapter context
+ * @session: session to be deleted.
+ *
+ * Deletes the given PE session
+ *
+ * Return: void
+ */
+void pe_delete_session(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+ uint16_t i = 0;
+ uint16_t n;
+ TX_TIMER *timer_ptr;
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_DEBUG,
+ FL("Trying to delete PE session %d Opmode %d BssIdx %d BSSID: "MAC_ADDRESS_STR),
+ session->peSessionId, session->operMode,
+ session->bssIdx,
+ MAC_ADDR_ARRAY(session->bssId));
+ for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
+ timer_ptr = &mac_ctx->lim.limTimers.gpLimCnfWaitTimer[n];
+ if (session->peSessionId == timer_ptr->sessionId)
+ if (true == tx_timer_running(timer_ptr))
+ tx_timer_deactivate(timer_ptr);
+ }
+
+#if defined (WLAN_FEATURE_VOWIFI_11R)
+ /* Delete FT related information */
+ lim_ft_cleanup(mac_ctx, session);
+#endif
+ if (session->pLimStartBssReq != NULL) {
+ cdf_mem_free(session->pLimStartBssReq);
+ session->pLimStartBssReq = NULL;
+ }
+
+ if (session->pLimJoinReq != NULL) {
+ cdf_mem_free(session->pLimJoinReq);
+ session->pLimJoinReq = NULL;
+ }
+
+ if (session->pLimReAssocReq != NULL) {
+ cdf_mem_free(session->pLimReAssocReq);
+ session->pLimReAssocReq = NULL;
+ }
+
+ if (session->pLimMlmJoinReq != NULL) {
+ cdf_mem_free(session->pLimMlmJoinReq);
+ session->pLimMlmJoinReq = NULL;
+ }
+
+ if (session->dph.dphHashTable.pHashTable != NULL) {
+ cdf_mem_free(session->dph.dphHashTable.pHashTable);
+ session->dph.dphHashTable.pHashTable = NULL;
+ }
+
+ if (session->dph.dphHashTable.pDphNodeArray != NULL) {
+ cdf_mem_free(session->dph.dphHashTable.pDphNodeArray);
+ session->dph.dphHashTable.pDphNodeArray = NULL;
+ }
+
+ if (session->gpLimPeerIdxpool != NULL) {
+ cdf_mem_free(session->gpLimPeerIdxpool);
+ session->gpLimPeerIdxpool = NULL;
+ }
+
+ if (session->beacon != NULL) {
+ cdf_mem_free(session->beacon);
+ session->beacon = NULL;
+ }
+
+ if (session->assocReq != NULL) {
+ cdf_mem_free(session->assocReq);
+ session->assocReq = NULL;
+ }
+
+ if (session->assocRsp != NULL) {
+ cdf_mem_free(session->assocRsp);
+ session->assocRsp = NULL;
+ }
+
+ if (session->parsedAssocReq != NULL) {
+ tpSirAssocReq tmp_ptr = NULL;
+ /* Cleanup the individual allocation first */
+ for (i = 0; i < session->dph.dphHashTable.size; i++) {
+ if (session->parsedAssocReq[i] == NULL)
+ continue;
+ tmp_ptr = ((tpSirAssocReq)
+ (session->parsedAssocReq[i]));
+ if (tmp_ptr->assocReqFrame) {
+ cdf_mem_free(tmp_ptr->assocReqFrame);
+ tmp_ptr->assocReqFrame = NULL;
+ tmp_ptr->assocReqFrameLength = 0;
+ }
+ cdf_mem_free(session->parsedAssocReq[i]);
+ session->parsedAssocReq[i] = NULL;
+ }
+ /* Cleanup the whole block */
+ cdf_mem_free(session->parsedAssocReq);
+ session->parsedAssocReq = NULL;
+ }
+ if (NULL != session->limAssocResponseData) {
+ cdf_mem_free(session->limAssocResponseData);
+ session->limAssocResponseData = NULL;
+ }
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ if (NULL != session->pLimMlmReassocRetryReq) {
+ cdf_mem_free(session->pLimMlmReassocRetryReq);
+ session->pLimMlmReassocRetryReq = NULL;
+ }
+#endif
+ if (NULL != session->pLimMlmReassocReq) {
+ cdf_mem_free(session->pLimMlmReassocReq);
+ session->pLimMlmReassocReq = NULL;
+ }
+
+ if (NULL != session->pSchProbeRspTemplate) {
+ cdf_mem_free(session->pSchProbeRspTemplate);
+ session->pSchProbeRspTemplate = NULL;
+ }
+
+ if (NULL != session->pSchBeaconFrameBegin) {
+ cdf_mem_free(session->pSchBeaconFrameBegin);
+ session->pSchBeaconFrameBegin = NULL;
+ }
+
+ if (NULL != session->pSchBeaconFrameEnd) {
+ cdf_mem_free(session->pSchBeaconFrameEnd);
+ session->pSchBeaconFrameEnd = NULL;
+ }
+
+ /* Must free the buffer before peSession invalid */
+ if (NULL != session->addIeParams.probeRespData_buff) {
+ cdf_mem_free(session->addIeParams.probeRespData_buff);
+ session->addIeParams.probeRespData_buff = NULL;
+ session->addIeParams.probeRespDataLen = 0;
+ }
+ if (NULL != session->addIeParams.assocRespData_buff) {
+ cdf_mem_free(session->addIeParams.assocRespData_buff);
+ session->addIeParams.assocRespData_buff = NULL;
+ session->addIeParams.assocRespDataLen = 0;
+ }
+ if (NULL != session->addIeParams.probeRespBCNData_buff) {
+ cdf_mem_free(session->addIeParams.probeRespBCNData_buff);
+ session->addIeParams.probeRespBCNData_buff = NULL;
+ session->addIeParams.probeRespBCNDataLen = 0;
+ }
+#ifdef WLAN_FEATURE_11W
+ /* if PMF connection */
+ if (session->limRmfEnabled)
+ cdf_mc_timer_destroy(&session->pmfComebackTimer);
+#endif
+
+ if (LIM_IS_AP_ROLE(session)) {
+ cdf_mc_timer_stop(&session->protection_fields_reset_timer);
+ cdf_mc_timer_destroy(&session->protection_fields_reset_timer);
+ }
+
+ session->valid = false;
+
+ if (LIM_IS_AP_ROLE(session))
+ lim_check_and_reset_protection_params(mac_ctx);
+
+ return;
+}
+
+/*--------------------------------------------------------------------------
+ \brief pe_find_session_by_peer_sta() - looks up the PE session given the Station Address.
+
+ This function returns the session context and the session ID if the session
+ corresponding to the given station address is found in the PE session table.
+
+ \param pMac - pointer to global adapter context
+ \param sa - Peer STA Address of the session
+ \param sessionId -session ID is returned here, if session is found.
+
+ \return tpPESession - pointer to the session context or NULL if session is not found.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+tpPESession pe_find_session_by_peer_sta(tpAniSirGlobal pMac, uint8_t *sa,
+ uint8_t *sessionId)
+{
+ uint8_t i;
+ tpDphHashNode pSta;
+ uint16_t aid;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if ((pMac->lim.gpSession[i].valid)) {
+ pSta =
+ dph_lookup_hash_entry(pMac, sa, &aid,
+ &pMac->lim.gpSession[i].dph.
+ dphHashTable);
+ if (pSta != NULL) {
+ *sessionId = i;
+ return &pMac->lim.gpSession[i];
+ }
+ }
+ }
+
+ lim_log(pMac, LOG1, FL("Session lookup fails for Peer StaId: \n "));
+ lim_print_mac_addr(pMac, sa, LOG1);
+ return NULL;
+}
+
+/**
+ * pe_find_session_by_sme_session_id() - looks up the PE session for given sme
+ * session id
+ * @mac_ctx: pointer to global adapter context
+ * @sme_session_id: sme session id
+ *
+ * looks up the PE session for given sme session id
+ *
+ * Return: pe session entry for given sme session if found else NULL
+ */
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+ uint8_t sme_session_id)
+{
+ uint8_t i;
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ if ((mac_ctx->lim.gpSession[i].valid) &&
+ (mac_ctx->lim.gpSession[i].smeSessionId ==
+ sme_session_id)) {
+ return &mac_ctx->lim.gpSession[i];
+ }
+ }
+ lim_log(mac_ctx, LOG4,
+ FL("Session lookup fails for smeSessionID: %d"),
+ sme_session_id);
+ return NULL;
+}
+
+/**
+ * pe_get_active_session_count() - function to return active pe session count
+ *
+ * @mac_ctx: pointer to global mac structure
+ *
+ * returns number of active pe session count
+ *
+ * Return: 0 if there are no active sessions else return number of active
+ * sessions
+ */
+uint8_t pe_get_active_session_count(tpAniSirGlobal mac_ctx)
+{
+ uint8_t i, active_session_count = 0;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++)
+ if (mac_ctx->lim.gpSession[i].valid)
+ active_session_count++;
+
+ return active_session_count;
+}
diff --git a/core/mac/src/pe/lim/lim_session_utils.c b/core/mac/src/pe/lim/lim_session_utils.c
new file mode 100644
index 0000000..49b37a1
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_session_utils.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file lim_session_utils.c
+ \brief implementation for lim Session Utility APIs
+ \author Sunit Bhatia
+ ========================================================================*/
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include "ani_global.h"
+#include "lim_debug.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "lim_session_utils.h"
+#include "lim_utils.h"
+
+/**
+ * is_lim_session_off_channel() - checks if any other off channel session exists
+ * @mac_ctx: Global MAC context.
+ * @sessionId: PE session ID.
+ *
+ * Return: This function returns true if the session Id passed needs to be on
+ * a different channel than atleast one session already active.
+ **/
+uint8_t is_lim_session_off_channel(tpAniSirGlobal mac_ctx, uint8_t session_id)
+{
+ uint8_t i;
+
+ if (session_id >= mac_ctx->lim.maxBssId) {
+ lim_log(mac_ctx, LOGE, FL("Invalid session_id:%d"), session_id);
+ return false;
+ }
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ /* Skip the session_id that is to be joined. */
+ if (i == session_id)
+ continue;
+ /*
+ * if another session is valid and it is on different channel
+ * then it is an off channel operation.
+ */
+ if ((mac_ctx->lim.gpSession[i].valid) &&
+ (mac_ctx->lim.gpSession[i].currentOperChannel !=
+ mac_ctx->lim.gpSession[session_id].currentOperChannel))
+ return true;
+ }
+ return false;
+
+}
+
+/**
+ * lim_is_chan_switch_running() - check if channel switch is happening
+ * @mac_ctx: Global MAC context.
+ *
+ * Return: 1 - if channel switch is happening on any session.
+ * 0 - if channel switch is not happening.
+ **/
+uint8_t lim_is_chan_switch_running(tpAniSirGlobal mac_ctx)
+{
+ uint8_t i;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++)
+ if (mac_ctx->lim.gpSession[i].valid &&
+ mac_ctx->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState
+ == eLIM_11H_CHANSW_RUNNING)
+ return 1;
+ return 0;
+}
+
+/**
+ * lim_is_in_mcc() - check if device is in MCC
+ * @mac_ctx: Global MAC context.
+ *
+ * Return: true - if in MCC.
+ * false - Not in MCC
+ **/
+uint8_t lim_is_in_mcc(tpAniSirGlobal mac_ctx)
+{
+ uint8_t i;
+ uint8_t chan = 0;
+ uint8_t curr_oper_channel = 0;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ /*
+ * if another session is valid and it is on different channel
+ * it is an off channel operation.
+ */
+ if ((mac_ctx->lim.gpSession[i].valid)) {
+ curr_oper_channel =
+ mac_ctx->lim.gpSession[i].currentOperChannel;
+ if (chan == 0)
+ chan = curr_oper_channel;
+ else if (chan != curr_oper_channel)
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * pe_get_current_stas_count() - Total stations associated on all sessions.
+ * @mac_ctx: Global MAC context.
+ *
+ * Return: true - Number of stations active on all sessions.
+ **/
+uint8_t pe_get_current_stas_count(tpAniSirGlobal mac_ctx)
+{
+ uint8_t i;
+ uint8_t stacount = 0;
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++)
+ if (mac_ctx->lim.gpSession[i].valid == true)
+ stacount +=
+ mac_ctx->lim.gpSession[i].gLimNumOfCurrentSTAs;
+ return stacount;
+}
diff --git a/core/mac/src/pe/lim/lim_session_utils.h b/core/mac/src/pe/lim/lim_session_utils.h
new file mode 100644
index 0000000..d1dd7d1
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_session_utils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if !defined(__LIM_SESSION_UTILS_H)
+#define __LIM_SESSION_UTILS_H
+
+uint8_t is_lim_session_off_channel(tpAniSirGlobal pMac, uint8_t sessionId);
+uint8_t lim_is_chan_switch_running(tpAniSirGlobal pMac);
+uint8_t lim_is_in_mcc(tpAniSirGlobal pMac);
+uint8_t pe_get_current_stas_count(tpAniSirGlobal pMac);
+
+#endif /* #if !defined( __LIM_SESSION_UTILS_H ) */
diff --git a/core/mac/src/pe/lim/lim_sme_req_utils.c b/core/mac/src/pe/lim/lim_sme_req_utils.c
new file mode 100644
index 0000000..550231f
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sme_req_utils.c
@@ -0,0 +1,925 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_sme_req_utils.cc contains the utility functions
+ * for processing SME request messages.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ * 05/26/10 js WPA handling in (Re)Assoc frames
+ *
+ */
+
+#include "wni_api.h"
+#include "wni_cfg.h"
+#include "cfg_api.h"
+#include "sir_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+
+/**
+ * lim_is_rs_nie_valid_in_sme_req_message()
+ *
+ * @mac_ctx Pointer to Global MAC structure
+ * @rsn_ie Pointer to received RSN IE
+ *
+ * This function is called to verify if the RSN IE received in various SME_REQ
+ * messages is valid or not
+ *
+ * Return: true when RSN IE is valid, false otherwise
+ *
+ */
+
+static uint8_t
+lim_is_rsn_ie_valid_in_sme_req_message(tpAniSirGlobal mac_ctx, tpSirRSNie rsn_ie)
+{
+ uint8_t start = 0;
+ uint32_t privacy, val;
+ int len;
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_PRIVACY_ENABLED,
+ &privacy) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP, FL("Unable to retrieve POI from CFG"));
+ }
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_RSN_ENABLED, &val)
+ != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGP,
+ FL("Unable to retrieve RSN_ENABLED from CFG"));
+ }
+
+ if (rsn_ie->length && (!privacy || !val)) {
+ /* Privacy & RSN not enabled in CFG.
+ * In order to allow mixed mode for Guest access
+ * allow BSS creation/join with no Privacy capability
+ * yet advertising WPA IE
+ */
+ PELOG1(lim_log(mac_ctx, LOG1,
+ FL("RSN ie len %d PRIVACY %d RSN %d"),
+ rsn_ie->length, privacy, val);)
+ }
+
+ if (!rsn_ie->length)
+ return true;
+
+ if ((rsn_ie->rsnIEdata[0] != DOT11F_EID_RSN)
+#ifdef FEATURE_WLAN_WAPI
+ && (rsn_ie->rsnIEdata[0] != DOT11F_EID_WAPI)
+#endif
+ && (rsn_ie->rsnIEdata[0] != DOT11F_EID_WPA)) {
+ lim_log(mac_ctx, LOGE, FL("RSN/WPA/WAPI EID %d not [%d || %d]"),
+ rsn_ie->rsnIEdata[0], DOT11F_EID_RSN,
+ DOT11F_EID_WPA);
+ return false;
+ }
+
+ len = rsn_ie->length;
+ start = 0;
+ while (len > 0) {
+ switch (rsn_ie->rsnIEdata[start]) {
+ case DOT11F_EID_RSN:
+ /* Check validity of RSN IE */
+ if ((rsn_ie->rsnIEdata[start + 1] >
+ DOT11F_IE_RSN_MAX_LEN)
+ || (rsn_ie->rsnIEdata[start + 1] <
+ DOT11F_IE_RSN_MIN_LEN)) {
+ lim_log(mac_ctx, LOGE,
+ FL("RSN IE len %d not [%d,%d]"),
+ rsn_ie->rsnIEdata[start + 1],
+ DOT11F_IE_RSN_MIN_LEN,
+ DOT11F_IE_RSN_MAX_LEN);
+ return false;
+ }
+ break;
+ case DOT11F_EID_WPA:
+ /* Check validity of WPA IE */
+ if (SIR_MAC_MAX_IE_LENGTH <= start)
+ break;
+
+ if (start <= (SIR_MAC_MAX_IE_LENGTH - sizeof(uint32_t)))
+ val = sir_read_u32((uint8_t *) &
+ rsn_ie->rsnIEdata[start + 2]);
+
+ if ((rsn_ie->rsnIEdata[start + 1] <
+ DOT11F_IE_WPA_MIN_LEN)
+ || (rsn_ie->rsnIEdata[start + 1] >
+ DOT11F_IE_WPA_MAX_LEN)
+ || (SIR_MAC_WPA_OUI != val)) {
+ lim_log(mac_ctx, LOGE,
+ FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"),
+ rsn_ie->rsnIEdata[start + 1],
+ DOT11F_IE_WPA_MIN_LEN,
+ DOT11F_IE_WPA_MAX_LEN,
+ val, SIR_MAC_WPA_OUI);
+ return false;
+ }
+ break;
+#ifdef FEATURE_WLAN_WAPI
+ case DOT11F_EID_WAPI:
+ if ((rsn_ie->rsnIEdata[start + 1] >
+ DOT11F_IE_WAPI_MAX_LEN)
+ || (rsn_ie->rsnIEdata[start + 1] <
+ DOT11F_IE_WAPI_MIN_LEN)) {
+ lim_log(mac_ctx, LOGE,
+ FL("WAPI IE len %d not [%d,%d]"),
+ rsn_ie->rsnIEdata[start + 1],
+ DOT11F_IE_WAPI_MIN_LEN,
+ DOT11F_IE_WAPI_MAX_LEN);
+ return false;
+ }
+ break;
+#endif
+ default:
+ /* we will never be here, simply for completeness */
+ return false;
+ } /* end of switch */
+ /* EID + length field + length */
+ start += 2 + rsn_ie->rsnIEdata[start + 1];
+ len -= start;
+ } /* end while loop */
+ return true;
+} /*** end lim_is_rs_nie_valid_in_sme_req_message() ***/
+
+/**
+ * lim_is_addie_valid_in_sme_req_message()
+ *
+ ***FUNCTION:
+ * This function is called to verify if the Add IE
+ * received in various SME_REQ messages is valid or not
+ *
+ ***LOGIC:
+ * Add IE validity checks are performed on only length
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pWSCie Pointer to received WSC IE
+ * @return true when WSC IE is valid, false otherwise
+ */
+
+static uint8_t
+lim_is_addie_valid_in_sme_req_message(tpAniSirGlobal pMac, tpSirAddie pAddie)
+{
+ int left = pAddie->length;
+ uint8_t *ptr = pAddie->addIEdata;
+ uint8_t elem_id, elem_len;
+
+ if (left == 0)
+ return true;
+
+ while (left >= 2) {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if (elem_len > left) {
+ lim_log(pMac, LOGE,
+ FL
+ ("****Invalid Add IEs eid = %d elem_len=%d left=%d*****"),
+ elem_id, elem_len, left);
+ return false;
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ /* there shouldn't be any left byte */
+
+ return true;
+} /*** end lim_is_addie_valid_in_sme_req_message() ***/
+
+/**
+ * lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message() - to set rsnie/wpaie
+ *
+ * @mac_ctx : Pointer to Global MAC structure
+ * @rsn_ie : Pointer to received RSN IE
+ * @session : Pointer to pe session
+ *
+ * This function is called to verify if the RSN IE received in various
+ * SME_REQ messages is valid or not. RSN IE validity checks are performed in
+ * this function
+ *
+ * Return: true when RSN IE is valid, false otherwise
+ */
+uint8_t
+lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(tpAniSirGlobal mac_ctx,
+ tpSirRSNie rsn_ie,
+ tpPESession session)
+{
+ uint8_t wpa_idx = 0;
+ uint32_t privacy, val;
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_PRIVACY_ENABLED,
+ &privacy) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP, FL("Unable to retrieve POI from CFG"));
+
+ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_RSN_ENABLED,
+ &val) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Unable to retrieve RSN_ENABLED from CFG"));
+
+ if (rsn_ie->length && (!privacy || !val)) {
+ /*
+ * Privacy & RSN not enabled in CFG.
+ * In order to allow mixed mode for Guest access
+ * allow BSS creation/join with no Privacy capability
+ * yet advertising WPA IE
+ */
+ lim_log(mac_ctx, LOG1,
+ FL("RSN ie len %d but PRIVACY %d RSN %d"),
+ rsn_ie->length, privacy, val);
+ }
+
+ if (!rsn_ie->length)
+ return true;
+
+ if ((rsn_ie->rsnIEdata[0] != SIR_MAC_RSN_EID) &&
+ (rsn_ie->rsnIEdata[0] != SIR_MAC_WPA_EID)) {
+ lim_log(mac_ctx, LOGE, FL("RSN/WPA EID %d not [%d || %d]"),
+ rsn_ie->rsnIEdata[0], SIR_MAC_RSN_EID,
+ SIR_MAC_WPA_EID);
+ return false;
+ }
+ /* Check validity of RSN IE */
+ if ((rsn_ie->rsnIEdata[0] == SIR_MAC_RSN_EID) &&
+ (rsn_ie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH)) {
+ lim_log(mac_ctx, LOGE, FL("RSN IE len %d not [%d,%d]"),
+ rsn_ie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
+ SIR_MAC_RSN_IE_MAX_LENGTH);
+ return false;
+ }
+
+ if (rsn_ie->length > rsn_ie->rsnIEdata[1] + 2) {
+ if (rsn_ie->rsnIEdata[0] != SIR_MAC_RSN_EID) {
+ lim_log(mac_ctx, LOGE,
+ FL("First byte[%d] in rsnIEdata isn't RSN_EID"),
+ rsn_ie->rsnIEdata[1]);
+ return false;
+ }
+ lim_log(mac_ctx, LOG1,
+ FL("WPA IE is present along with WPA2 IE"));
+ wpa_idx = 2 + rsn_ie->rsnIEdata[1];
+ } else if ((rsn_ie->length == rsn_ie->rsnIEdata[1] + 2) &&
+ (rsn_ie->rsnIEdata[0] == SIR_MAC_RSN_EID)) {
+ lim_log(mac_ctx, LOG1, FL("Only RSN IE is present"));
+ dot11f_unpack_ie_rsn(mac_ctx, &rsn_ie->rsnIEdata[2],
+ (uint8_t) rsn_ie->length,
+ &session->gStartBssRSNIe);
+ } else if ((rsn_ie->length == rsn_ie->rsnIEdata[1] + 2)
+ && (rsn_ie->rsnIEdata[0] == SIR_MAC_WPA_EID)) {
+ lim_log(mac_ctx, LOG1, FL("Only WPA IE is present"));
+ dot11f_unpack_ie_wpa(mac_ctx, &rsn_ie->rsnIEdata[6],
+ (uint8_t) rsn_ie->length - 4,
+ &session->gStartBssWPAIe);
+ }
+ /* Check validity of WPA IE */
+ if (wpa_idx + 6 >= SIR_MAC_MAX_IE_LENGTH)
+ return false;
+
+ val = sir_read_u32((uint8_t *)&rsn_ie->rsnIEdata[wpa_idx + 2]);
+ if ((rsn_ie->rsnIEdata[wpa_idx] == SIR_MAC_WPA_EID)
+ && ((rsn_ie->rsnIEdata[wpa_idx + 1] < SIR_MAC_WPA_IE_MIN_LENGTH)
+ || (SIR_MAC_WPA_OUI != val))) {
+ lim_log(mac_ctx, LOGE,
+ FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"),
+ rsn_ie->rsnIEdata[1],
+ SIR_MAC_RSN_IE_MIN_LENGTH,
+ SIR_MAC_RSN_IE_MAX_LENGTH, val,
+ SIR_MAC_WPA_OUI);
+ return false;
+ } else {
+ /* Both RSN and WPA IEs are present */
+ dot11f_unpack_ie_rsn(mac_ctx, &rsn_ie->rsnIEdata[2],
+ (uint8_t) rsn_ie->length,
+ &session->gStartBssRSNIe);
+ dot11f_unpack_ie_wpa(mac_ctx, &rsn_ie->rsnIEdata[wpa_idx + 6],
+ rsn_ie->rsnIEdata[wpa_idx + 1] - 4,
+ &session->gStartBssWPAIe);
+ }
+ return true;
+}
+
+/**
+ * lim_is_bss_descr_valid_in_sme_req_message()
+ *
+ ***FUNCTION:
+ * This function is called to verify if the BSS Descr
+ * received in various SME_REQ messages is valid or not
+ *
+ ***LOGIC:
+ * BSS Descritipion validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pBssDescr Pointer to received Bss Descritipion
+ * @return true when BSS description is valid, false otherwise
+ */
+
+static uint8_t
+lim_is_bss_descr_valid_in_sme_req_message(tpAniSirGlobal pMac,
+ tpSirBssDescription pBssDescr)
+{
+ uint8_t valid = true;
+
+ if (lim_is_addr_bc(pBssDescr->bssId) || !pBssDescr->channelId) {
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end lim_is_bss_descr_valid_in_sme_req_message() ***/
+
+/**
+ * lim_is_sme_start_bss_req_valid() - To validate sme start bss request
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @start_bss_req: Pointer to received SME_START_BSS_REQ message
+ *
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_START_BSS_REQ message from application.
+ *
+ * Return: true when received SME_START_BSS_REQ is formatted correctly false
+ * otherwise
+ */
+
+uint8_t
+lim_is_sme_start_bss_req_valid(tpAniSirGlobal mac_ctx,
+ tpSirSmeStartBssReq start_bss_req)
+{
+ uint8_t i = 0;
+ tSirMacRateSet *opr_rates = &start_bss_req->operationalRateSet;
+
+ PELOG1(lim_log(mac_ctx, LOG1,
+ FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d, SSID len=%d, rsnIE len=%d, nwType=%d, rateset len=%d"),
+ start_bss_req->bssType, start_bss_req->channelId,
+ start_bss_req->ssId.length, start_bss_req->rsnIE.length,
+ start_bss_req->nwType, opr_rates->numRates);)
+
+ switch (start_bss_req->bssType) {
+ case eSIR_INFRASTRUCTURE_MODE:
+ /**
+ * Should not have received start BSS req with bssType
+ * Infrastructure on STA.
+ */
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"),
+ start_bss_req->bssType);
+ return false;
+ break;
+ case eSIR_IBSS_MODE:
+ break;
+ case eSIR_BTAMP_STA_MODE:
+ break;
+ case eSIR_BTAMP_AP_MODE:
+ break;
+ case eSIR_INFRA_AP_MODE:
+ break;
+ default:
+ /**
+ * Should not have received start BSS req with bssType
+ * other than Infrastructure/IBSS.
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"),
+ start_bss_req->bssType);
+ return false;
+ }
+
+ if (start_bss_req->bssType == eSIR_IBSS_MODE
+ && (!start_bss_req->ssId.length
+ || start_bss_req->ssId.length > SIR_MAC_MAX_SSID_LENGTH)) {
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid SSID length in eWNI_SME_START_BSS_REQ"));
+ return false;
+ }
+
+ if (!lim_is_rsn_ie_valid_in_sme_req_message(mac_ctx,
+ &start_bss_req->rsnIE))
+ return false;
+
+ if (start_bss_req->nwType != eSIR_11A_NW_TYPE
+ && start_bss_req->nwType != eSIR_11B_NW_TYPE
+ && start_bss_req->nwType != eSIR_11G_NW_TYPE)
+ return false;
+
+ if (start_bss_req->nwType == eSIR_11A_NW_TYPE) {
+ for (i = 0; i < opr_rates->numRates; i++) {
+ if (sirIsArate(opr_rates->rate[i] & 0x7F))
+ continue;
+
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid operational 11A rates"));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
+ opr_rates->rate, opr_rates->numRates);
+ return false;
+ }
+ return true;
+ }
+ /* check if all the rates in the opr rate set are legal 11G rates */
+ if (start_bss_req->nwType == eSIR_11G_NW_TYPE) {
+ for (i = 0; i < opr_rates->numRates; i++) {
+ if (sirIsGrate(opr_rates->rate[i] & 0x7F))
+ continue;
+
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid operational 11G rates"));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
+ opr_rates->rate, opr_rates->numRates);
+ return false;
+ }
+ return true;
+ }
+
+ for (i = 0; i < opr_rates->numRates; i++) {
+ if (sirIsBrate(opr_rates->rate[i] & 0x7F))
+ continue;
+
+ lim_log(mac_ctx, LOGW,
+ FL("Invalid operational 11B rates"));
+ sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
+ opr_rates->rate, opr_rates->numRates);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * lim_is_sme_join_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_JOIN_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pJoinReq Pointer to received SME_JOIN_REQ message
+ * @return true when received SME_JOIN_REQ is formatted correctly
+ * false otherwise
+ */
+
+uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
+{
+ uint8_t valid = true;
+
+ if (!lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
+ lim_log(pMac, LOGE,
+ FL("received SME_JOIN_REQ with invalid RSNIE"));
+ valid = false;
+ goto end;
+ }
+
+ if (!lim_is_addie_valid_in_sme_req_message(pMac, &pJoinReq->addIEScan)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("received SME_JOIN_REQ with invalid additional IE for scan"));
+ valid = false;
+ goto end;
+ }
+
+ if (!lim_is_addie_valid_in_sme_req_message(pMac, &pJoinReq->addIEAssoc)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("received SME_JOIN_REQ with invalid additional IE for assoc"));
+ valid = false;
+ goto end;
+ }
+
+ if (!lim_is_bss_descr_valid_in_sme_req_message(pMac, &pJoinReq->bssDescription)) {
+ /* / Received eWNI_SME_JOIN_REQ with invalid BSS Info */
+ /* Log the event */
+ lim_log(pMac, LOGE,
+ FL("received SME_JOIN_REQ with invalid bssInfo"));
+
+ valid = false;
+ goto end;
+ }
+
+ /*
+ Reject Join Req if the Self Mac Address and
+ the Ap's Mac Address is same
+ */
+ if (cdf_mem_compare((uint8_t *) pJoinReq->selfMacAddr,
+ (uint8_t *) pJoinReq->bssDescription.bssId,
+ (uint8_t) (sizeof(tSirMacAddr)))) {
+ /* Log the event */
+ lim_log(pMac, LOGE,
+ FL
+ ("received SME_JOIN_REQ with Self Mac and BSSID Same"));
+
+ valid = false;
+ goto end;
+ }
+
+end:
+ return valid;
+} /*** end lim_is_sme_join_req_valid() ***/
+
+/**
+ * lim_is_sme_disassoc_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_DISASSOC_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pDisassocReq Pointer to received SME_DISASSOC_REQ message
+ * @return true When received SME_DISASSOC_REQ is formatted
+ * correctly
+ * false otherwise
+ */
+
+uint8_t
+lim_is_sme_disassoc_req_valid(tpAniSirGlobal pMac,
+ tpSirSmeDisassocReq pDisassocReq,
+ tpPESession psessionEntry)
+{
+ if (lim_is_group_addr(pDisassocReq->peerMacAddr) &&
+ !lim_is_addr_bc(pDisassocReq->peerMacAddr))
+ return false;
+
+ return true;
+} /*** end lim_is_sme_disassoc_req_valid() ***/
+
+/**
+ * lim_is_sme_disassoc_cnf_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_DISASSOC_CNF message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pDisassocCnf Pointer to received SME_DISASSOC_REQ message
+ * @return true When received SME_DISASSOC_CNF is formatted
+ * correctly
+ * false otherwise
+ */
+
+uint8_t
+lim_is_sme_disassoc_cnf_valid(tpAniSirGlobal pMac,
+ tpSirSmeDisassocCnf pDisassocCnf,
+ tpPESession psessionEntry)
+{
+ if (lim_is_group_addr(pDisassocCnf->peerMacAddr))
+ return false;
+
+ return true;
+} /*** end lim_is_sme_disassoc_cnf_valid() ***/
+
+/**
+ * lim_is_sme_deauth_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_DEAUTH_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pDeauthReq Pointer to received SME_DEAUTH_REQ message
+ * @return true When received SME_DEAUTH_REQ is formatted correctly
+ * false otherwise
+ */
+
+uint8_t
+lim_is_sme_deauth_req_valid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq,
+ tpPESession psessionEntry)
+{
+ if (lim_is_group_addr(pDeauthReq->peerMacAddr) &&
+ !lim_is_addr_bc(pDeauthReq->peerMacAddr))
+ return false;
+
+ return true;
+} /*** end lim_is_sme_deauth_req_valid() ***/
+
+/**
+ * lim_is_sme_scan_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_SCAN_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pScanReq Pointer to received SME_SCAN_REQ message
+ * @return true when received SME_SCAN_REQ is formatted correctly
+ * false otherwise
+ */
+
+uint8_t lim_is_sme_scan_req_valid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq)
+{
+ uint8_t valid = true;
+ uint8_t i = 0;
+
+ if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) {
+ valid = false;
+ lim_log(pMac, LOGE,
+ FL("Number of SSIDs > SIR_SCAN_MAX_NUM_SSID"));
+ goto end;
+ }
+
+ for (i = 0; i < pScanReq->numSsid; i++) {
+ if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Requested SSID length > SIR_MAC_MAX_SSID_LENGTH"));
+ valid = false;
+ goto end;
+ }
+ }
+ if ((pScanReq->bssType < 0) || (pScanReq->bssType > eSIR_AUTO_MODE)) {
+ lim_log(pMac, LOGE, FL("Invalid BSS Type"));
+ valid = false;
+ }
+ if (lim_is_group_addr(pScanReq->bssId) && !lim_is_addr_bc(pScanReq->bssId)) {
+ valid = false;
+ lim_log(pMac, LOGE,
+ FL("BSSID is group addr and is not Broadcast Addr"));
+ }
+ if (!
+ (pScanReq->scanType == eSIR_PASSIVE_SCAN
+ || pScanReq->scanType == eSIR_ACTIVE_SCAN)) {
+ valid = false;
+ lim_log(pMac, LOGE, FL("Invalid Scan Type"));
+ }
+ if (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS) {
+ valid = false;
+ lim_log(pMac, LOGE,
+ FL("Number of Channels > SIR_MAX_NUM_CHANNELS"));
+ }
+
+ /*
+ ** check min/max channelTime range
+ **/
+ if (valid) {
+ if ((pScanReq->scanType == eSIR_ACTIVE_SCAN) &&
+ (pScanReq->maxChannelTime < pScanReq->minChannelTime)) {
+ lim_log(pMac, LOGE,
+ FL("Max Channel Time < Min Channel Time"));
+ valid = false;
+ goto end;
+ }
+ }
+
+end:
+ return valid;
+} /*** end lim_is_sme_scan_req_valid() ***/
+
+/**
+ * lim_is_sme_set_context_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_SET_CONTEXT_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMsg - Pointer to received SME_SET_CONTEXT_REQ message
+ * @return true when received SME_SET_CONTEXT_REQ is formatted correctly
+ * false otherwise
+ */
+
+uint8_t
+lim_is_sme_set_context_req_valid(tpAniSirGlobal pMac,
+ tpSirSmeSetContextReq pSetContextReq)
+{
+ uint8_t i = 0;
+ uint8_t valid = true;
+ tpSirKeys pKey = pSetContextReq->keyMaterial.key;
+
+ if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) &&
+ (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) &&
+ (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) &&
+#ifdef FEATURE_WLAN_WAPI
+ (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) &&
+#endif
+ !pSetContextReq->keyMaterial.numKeys) {
+ /**
+ * No keys present in case of TKIP or CCMP
+ * Log error.
+ */
+ lim_log(pMac, LOGW,
+ FL
+ ("No keys present in SME_SETCONTEXT_REQ for edType=%d"),
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+
+ if (pSetContextReq->keyMaterial.numKeys &&
+ (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE)) {
+ /**
+ * Keys present in case of no ED policy
+ * Log error.
+ */
+ lim_log(pMac, LOGW,
+ FL("Keys present in SME_SETCONTEXT_REQ for edType=%d"),
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+
+ if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED) {
+ /**
+ * Invalid edType in the message
+ * Log error.
+ */
+ lim_log(pMac, LOGW,
+ FL("Invalid edType=%d in SME_SETCONTEXT_REQ"),
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ } else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE) {
+ uint32_t poi;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED,
+ &poi) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to retrieve POI from CFG"));
+ }
+
+ if (!poi) {
+ /**
+ * Privacy is not enabled
+ * In order to allow mixed mode for Guest access
+ * allow BSS creation/join with no Privacy capability
+ * yet advertising WPA IE
+ */
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("Privacy is not enabled, yet non-None EDtype=%d in SME_SETCONTEXT_REQ"),
+ pSetContextReq->keyMaterial.edType);
+ )
+ }
+ }
+
+ for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++) {
+ if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) &&
+ (pKey->keyLength != 5)) ||
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) &&
+ (pKey->keyLength != 13)) ||
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) &&
+ (pKey->keyLength != 32)) ||
+#ifdef FEATURE_WLAN_WAPI
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) &&
+ (pKey->keyLength != 32)) ||
+#endif
+ ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) &&
+ (pKey->keyLength != 16))) {
+ /**
+ * Invalid key length for a given ED type
+ * Log error.
+ */
+ lim_log(pMac, LOGW,
+ FL
+ ("Invalid keyLength =%d for edType=%d in SME_SETCONTEXT_REQ"),
+ pKey->keyLength,
+ pSetContextReq->keyMaterial.edType);
+
+ valid = false;
+ goto end;
+ }
+ pKey++;
+ }
+
+end:
+ return valid;
+} /*** end lim_is_sme_set_context_req_valid() ***/
+
+/**
+ * lim_is_sme_stop_bss_req_valid()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() upon
+ * receiving SME_STOP_BSS_REQ message from application.
+ *
+ ***LOGIC:
+ * Message validity checks are performed in this function
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMsg - Pointer to received SME_STOP_BSS_REQ message
+ * @return true when received SME_STOP_BSS_REQ is formatted correctly
+ * false otherwise
+ */
+
+uint8_t lim_is_sme_stop_bss_req_valid(uint32_t *pMsg)
+{
+ uint8_t valid = true;
+
+ return valid;
+} /*** end lim_is_sme_stop_bss_req_valid() ***/
+
+/**
+ * lim_get_bss_id_from_sme_join_req_msg()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get BSSID
+ * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/
+ * SME_REASSOC_REQ message.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pBuf - Pointer to received SME_JOIN/SME_REASSOC_REQ
+ * message
+ * @return pBssId - Pointer to BSSID
+ */
+
+uint8_t *lim_get_bss_id_from_sme_join_req_msg(uint8_t *pBuf)
+{
+ if (!pBuf)
+ return NULL;
+
+ pBuf += sizeof(uint32_t); /* skip message header */
+
+ pBuf += lim_get_u16(pBuf) + sizeof(uint16_t); /* skip RSN IE */
+
+ pBuf += sizeof(uint16_t); /* skip length of BSS description */
+
+ return (pBuf);
+} /*** end lim_get_bss_id_from_sme_join_req_msg() ***/
diff --git a/core/mac/src/pe/lim/lim_sme_req_utils.h b/core/mac/src/pe/lim/lim_sme_req_utils.h
new file mode 100644
index 0000000..7e89373
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sme_req_utils.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011-2012,2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_sme_req_utils.h contains the utility definitions
+ * LIM uses while processing SME request messsages.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_SME_REQ_UTILS_H
+#define __LIM_SME_REQ_UTILS_H
+
+#include "sir_api.h"
+#include "lim_types.h"
+
+/* LIM SME request messages related utility functions */
+uint8_t lim_is_sme_start_bss_req_valid(tpAniSirGlobal, tpSirSmeStartBssReq);
+uint8_t lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(tpAniSirGlobal,
+ tpSirRSNie, tpPESession);
+uint8_t lim_is_sme_scan_req_valid(tpAniSirGlobal, tpSirSmeScanReq);
+uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal, tpSirSmeJoinReq);
+uint8_t lim_is_sme_disassoc_req_valid(tpAniSirGlobal, tpSirSmeDisassocReq,
+ tpPESession);
+uint8_t lim_is_sme_deauth_req_valid(tpAniSirGlobal, tpSirSmeDeauthReq, tpPESession);
+uint8_t lim_is_sme_set_context_req_valid(tpAniSirGlobal, tpSirSmeSetContextReq);
+uint8_t lim_is_sme_stop_bss_req_valid(uint32_t *);
+uint8_t *lim_get_bss_id_from_sme_join_req_msg(uint8_t *);
+uint8_t lim_is_sme_disassoc_cnf_valid(tpAniSirGlobal, tpSirSmeDisassocCnf,
+ tpPESession);
+
+#endif /* __LIM_SME_REQ_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_sta_hash_api.c b/core/mac/src/pe/lim/lim_sta_hash_api.c
new file mode 100644
index 0000000..794ebaa
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sta_hash_api.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * lim_sta_hash_api.c: Provides access functions to get/set values of station hash entry fields.
+ * Author: Sunit Bhatia
+ * Date: 09/19/2006
+ * History:-
+ * Date Modified by Modification Information
+ *
+ * --------------------------------------------------------------------------
+ *
+ */
+
+#include "lim_sta_hash_api.h"
+
+/**
+ * lim_get_sta_hash_bssidx()
+ *
+ ***FUNCTION:
+ * This function is called to Get the Bss Index of the currently associated Station.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac pointer to Global Mac structure.
+ * @param assocId AssocID of the Station.
+ * @param bssidx pointer to the bss index, which will be returned by the function.
+ *
+ * @return success if GET operation is ok, else Failure.
+ */
+
+tSirRetStatus lim_get_sta_hash_bssidx(tpAniSirGlobal pMac, uint16_t assocId,
+ uint8_t *bssidx, tpPESession psessionEntry)
+{
+ tpDphHashNode pSta =
+ dph_get_hash_entry(pMac, assocId, &psessionEntry->dph.dphHashTable);
+
+ if (pSta == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("invalid STA %d"), assocId);)
+ return eSIR_LIM_INVALID_STA;
+ }
+
+ *bssidx = (uint8_t) pSta->bssId;
+ return eSIR_SUCCESS;
+}
diff --git a/core/mac/src/pe/lim/lim_sta_hash_api.h b/core/mac/src/pe/lim/lim_sta_hash_api.h
new file mode 100644
index 0000000..9a34091
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_sta_hash_api.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_sta_hash_api.h contains the
+ * function prototypes for accessing station hash entry fields.
+ *
+ * Author: Sunit Bhatia
+ * Date: 09/19/2006
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __LIM_STA_HASH_API_H__
+#define __LIM_STA_HASH_API_H__
+
+#include "ani_global.h"
+#include "lim_types.h"
+
+tSirRetStatus lim_get_sta_hash_bssidx(tpAniSirGlobal pMac, uint16_t assocId,
+ uint8_t *bssidx, tpPESession psessionEntry);
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_timer_utils.c b/core/mac/src/pe/lim/lim_timer_utils.c
new file mode 100644
index 0000000..f68f7b0
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_timer_utils.c
@@ -0,0 +1,1357 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_timer_utils.cc contains the utility functions
+ * LIM uses for handling various timers.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_assoc_utils.h"
+#include "lim_security_utils.h"
+
+/* channel Switch Timer in ticks */
+#define LIM_CHANNEL_SWITCH_TIMER_TICKS 1
+/* Lim Quite timer in ticks */
+#define LIM_QUIET_TIMER_TICKS 100
+/* Lim Quite BSS timer interval in ticks */
+#define LIM_QUIET_BSS_TIMER_TICK 100
+/* Lim KeepAlive timer default (3000)ms */
+#define LIM_KEEPALIVE_TIMER_MS 3000
+/* Lim JoinProbeRequest Retry timer default (200)ms */
+#define LIM_JOIN_PROBE_REQ_TIMER_MS 200
+
+/* This timer is a periodic timer which expires at every 1 sec to
+ convert ACTIVE DFS channel to DFS channels */
+#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT 1000
+
+static bool
+lim_create_non_ap_timers(tpAniSirGlobal pMac)
+{
+ uint32_t cfgValue;
+ /* Create Channel Switch Timer */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimChannelSwitchTimer,
+ "CHANNEL SWITCH TIMER",
+ lim_channel_switch_timer_handler, 0,
+ LIM_CHANNEL_SWITCH_TIMER_TICKS,
+ 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("failed to create Ch Switch timer"));
+ return false;
+ }
+ /* Create Quiet Timer
+ * This is used on the STA to go and shut-off Tx/Rx "after" the
+ * specified quiteInterval
+ */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimQuietTimer,
+ "QUIET TIMER", lim_quiet_timer_handler,
+ SIR_LIM_QUIET_TIMEOUT, LIM_QUIET_TIMER_TICKS,
+ 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("failed to create Quiet Begin Timer"));
+ return false;
+ }
+ /* Create Quiet BSS Timer
+ * After the specified quiteInterval, determined by gLimQuietTimer, this
+ * timer, gLimQuietBssTimer, trigger and put the STA to sleep for the
+ * specified gLimQuietDuration
+ */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimQuietBssTimer,
+ "QUIET BSS TIMER", lim_quiet_bss_timer_handler,
+ SIR_LIM_QUIET_BSS_TIMEOUT, LIM_QUIET_BSS_TIMER_TICK,
+ 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("failed to create Quiet Bss Timer"));
+ return false;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve JoinFailureTimeout value"));
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ /* Create Join failure timer and activate it later */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimJoinFailureTimer,
+ "JOIN FAILURE TIMEOUT",
+ lim_timer_handler, SIR_LIM_JOIN_FAIL_TIMEOUT,
+ cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS) {
+ /* / Could not create Join failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("could not create Join failure timer"));
+ return false;
+ }
+ /* Send unicast probe req frame every 200 ms */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer,
+ "Periodic Join Probe Request Timer",
+ lim_timer_handler,
+ SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT,
+ SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS), 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not create Periodic Join Probe Request tmr"));
+ return false;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve AssocFailureTimeout value"));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ /* Create Association failure timer and activate it later */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimAssocFailureTimer,
+ "ASSOC FAILURE TIMEOUT",
+ lim_assoc_failure_timer_handler, LIM_ASSOC,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not create Association failure timer"));
+ return false;
+ }
+ if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve ReassocFailureTimeout value"));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ /* Create Association failure timer and activate it later */
+ if (tx_timer_create
+ (&pMac->lim.limTimers.gLimReassocFailureTimer,
+ "REASSOC FAILURE TIMEOUT", lim_assoc_failure_timer_handler,
+ LIM_REASSOC, cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not create Reassociation failure timer"));
+ return false;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &cfgValue)
+ != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("Fail to get WNI_CFG_ADDTS_RSP_TIMEOUT "));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+
+ /* Create Addts response timer and activate it later */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimAddtsRspTimer,
+ "ADDTS RSP TIMEOUT",
+ lim_addts_response_timer_handler,
+ SIR_LIM_ADDTS_RSP_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not create Addts response timer"));
+ return false;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve AuthFailureTimeout value"));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ /* Create Auth failure timer and activate it later */
+ if (tx_timer_create(&pMac->lim.limTimers.gLimAuthFailureTimer,
+ "AUTH FAILURE TIMEOUT",
+ lim_timer_handler,
+ SIR_LIM_AUTH_FAIL_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not create Auth failure timer"));
+ return false;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value"));
+
+ /* Change timer to reactivate it in future */
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
+ "Probe after Heartbeat TIMEOUT",
+ lim_timer_handler,
+ SIR_LIM_PROBE_HB_FAILURE_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("unable to create ProbeAfterHBTimer"));
+ return false;
+ }
+
+ return true;
+}
+/**
+ * lim_create_timers()
+ *
+ * @pMac : Pointer to Global MAC structure
+ *
+ * This function is called upon receiving
+ * 1. SME_START_REQ for STA in ESS role
+ * 2. SME_START_BSS_REQ for AP role & STA in IBSS role
+ *
+ * @return : status of operation
+ */
+
+uint32_t lim_create_timers(tpAniSirGlobal pMac)
+{
+ uint32_t cfgValue, i = 0;
+ uint32_t cfgValue1;
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL("Creating Timers used by LIM module in Role %d"),
+ pMac->lim.gLimSystemRole);)
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME,
+ &cfgValue) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not retrieve MinChannelTimeout value"));
+ }
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ /* Periodic probe request timer value is half of the Min channel
+ * timer. Probe request sends periodically till min/max channel
+ * timer expires
+ */
+ cfgValue1 = cfgValue / 2;
+ /* Create periodic probe request timer and activate them later */
+ if (cfgValue1 >= 1
+ && (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer,
+ "Periodic Probe Request Timer", lim_timer_handler,
+ SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT, cfgValue1, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS)) {
+ lim_log(pMac, LOGP,
+ FL("could not create periodic probe timer"));
+ goto err_timer;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve MAXChannelTimeout value"));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ /* Limiting max numm of probe req for each channel scan */
+ pMac->lim.maxProbe = (cfgValue / cfgValue1);
+
+ if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE)
+ if (false == lim_create_non_ap_timers(pMac))
+ goto err_timer;
+
+ cfgValue = SYS_MS_TO_TICKS(LIM_HASH_MISS_TIMER_MS);
+
+ if (tx_timer_create(
+ &pMac->lim.limTimers.gLimSendDisassocFrameThresholdTimer,
+ "Disassoc throttle TIMEOUT",
+ lim_send_disassoc_frame_threshold_handler,
+ SIR_LIM_HASH_MISS_THRES_TIMEOUT, cfgValue, cfgValue,
+ TX_AUTO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("create Disassociate throttle timer failed"));
+ goto err_timer;
+ }
+ PELOG1(lim_log(pMac, LOG1, FL("Created Disassociate throttle timer "));)
+
+ /* Create all CNF_WAIT Timers upfront */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WT_CNF_TIMEOUT, &cfgValue)
+ != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not retrieve CNF timeout value"));
+ }
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ for (i = 0; i < (pMac->lim.maxStation + 1); i++) {
+ if (tx_timer_create(&pMac->lim.limTimers.gpLimCnfWaitTimer[i],
+ "CNF_MISS_TIMEOUT",
+ lim_cnf_wait_tmer_handler,
+ (uint32_t) i, cfgValue,
+ 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("Cannot create CNF wait timer"));
+ goto err_timer;
+ }
+ }
+
+ /* Alloc and init table for the preAuth timer list */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_NUM_PRE_AUTH,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, FL("could not retrieve mac preauth value"));
+ pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue;
+ pMac->lim.gLimPreAuthTimerTable.pTable =
+ cdf_mem_malloc(cfgValue * sizeof(tLimPreAuthNode));
+
+ if (pMac->lim.gLimPreAuthTimerTable.pTable == NULL) {
+ lim_log(pMac, LOGP, FL("AllocateMemory failed!"));
+ goto err_timer;
+ }
+
+ lim_init_pre_auth_timer_table(pMac, &pMac->lim.gLimPreAuthTimerTable);
+ PELOG1(lim_log(pMac, LOG1,
+ FL("alloc and init table for preAuth timers"));)
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_OLBC_DETECT_TIMEOUT,
+ &cfgValue) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL("could not retrieve OLBD detect timeout value"));
+
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer,
+ "OLBC UPDATE CACHE TIMEOUT",
+ lim_update_olbc_cache_timer_handler,
+ SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT, cfgValue,
+ cfgValue, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("Cannot create update OLBC cache tmr"));
+ goto err_timer;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ /* In future we need to use the auth timer, cause the pre auth session
+ * will be introduced before sending Auth frame. We need to go off
+ * channel and come back to home channel
+ */
+ cfgValue = 1000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimFTPreAuthRspTimer,
+ "FT PREAUTH RSP TIMEOUT",
+ lim_timer_handler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not create Join failure timer"));
+ goto err_timer;
+ }
+#endif
+ cfgValue = 1000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimRemainOnChannelTimer,
+ "FT PREAUTH RSP TIMEOUT",
+ lim_timer_handler, SIR_LIM_REMAIN_CHN_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not create Join failure timer"));
+ goto err_timer;
+ }
+
+ cfgValue = 1000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimDisassocAckTimer,
+ "DISASSOC ACK TIMEOUT",
+ lim_timer_handler, SIR_LIM_DISASSOC_ACK_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not DISASSOC ACK TIMEOUT timer"));
+ goto err_timer;
+ }
+
+ cfgValue = 1000;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(&pMac->lim.limTimers.gLimDeauthAckTimer,
+ "DISASSOC ACK TIMEOUT",
+ lim_timer_handler, SIR_LIM_DEAUTH_ACK_TIMEOUT,
+ cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not create DEAUTH ACK TIMEOUT timer"));
+ goto err_timer;
+ }
+
+ /* (> no of BI* no of TUs per BI * 1TU in msec +
+ * p2p start time offset*1 TU in msec = 2*100*1.024 + 5*1.024
+ * = 204.8 + 5.12 = 209.20)
+ */
+ cfgValue = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(
+ &pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer,
+ "Single Shot NOA Insert timeout", lim_timer_handler,
+ SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT, cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Can't create Single Shot NOA Insert Timeout tmr"));
+ goto err_timer;
+ }
+
+ cfgValue = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT;
+ cfgValue = SYS_MS_TO_TICKS(cfgValue);
+ if (tx_timer_create(
+ &pMac->lim.limTimers.gLimActiveToPassiveChannelTimer,
+ "ACTIVE TO PASSIVE CHANNEL", lim_timer_handler,
+ SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE, cfgValue, 0,
+ TX_NO_ACTIVATE) != TX_SUCCESS) {
+ lim_log(pMac, LOGW,
+ FL("could not create timer for passive channel to active channel"));
+ goto err_timer;
+ }
+
+ return TX_SUCCESS;
+
+err_timer:
+ tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimRemainOnChannelTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer);
+ while (((int32_t)-- i) >= 0) {
+ tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[i]);
+ }
+ tx_timer_delete(&pMac->lim.limTimers.
+ gLimSendDisassocFrameThresholdTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer);
+ tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer);
+
+ if (NULL != pMac->lim.gLimPreAuthTimerTable.pTable) {
+ cdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
+ pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
+ }
+ return TX_TIMER_ERROR;
+} /****** end lim_create_timers() ******/
+
+/**
+ * lim_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon
+ * 1. MIN_CHANNEL, MAX_CHANNEL timer expiration during scanning
+ * 2. JOIN_FAILURE timer expiration while joining a BSS
+ * 3. AUTH_FAILURE timer expiration while authenticating with a peer
+ * 4. Heartbeat timer expiration on STA
+ * 5. Background scan timer expiration on STA
+ * 6. AID release, Pre-auth cleanup and Link monitoring timer
+ * expiration on AP
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param param - Message corresponding to the timer that expired
+ *
+ * @return None
+ */
+
+void lim_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ uint32_t statusCode;
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ /* Prepare and post message to LIM Message Queue */
+
+ msg.type = (uint16_t) param;
+ msg.bodyptr = NULL;
+ msg.bodyval = 0;
+
+ if ((statusCode = lim_post_msg_api(pMac, &msg)) != eSIR_SUCCESS)
+ lim_log(pMac, LOGE,
+ FL("posting message %X to LIM failed, reason=%d"),
+ msg.type, statusCode);
+} /****** end lim_timer_handler() ******/
+
+/**
+ * lim_addts_response_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon Addts response timer expiration on sta
+ *
+ ***LOGIC:
+ * Message SIR_LIM_ADDTS_RSP_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param param - pointer to pre-auth node
+ *
+ * @return None
+ */
+
+void lim_addts_response_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ /* Prepare and post message to LIM Message Queue */
+
+ msg.type = SIR_LIM_ADDTS_RSP_TIMEOUT;
+ msg.bodyval = param;
+ msg.bodyptr = NULL;
+
+ lim_post_msg_api(pMac, &msg);
+} /****** end lim_auth_response_timer_handler() ******/
+
+/**
+ * lim_auth_response_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon Auth response timer expiration on AP
+ *
+ ***LOGIC:
+ * Message SIR_LIM_AUTH_RSP_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param param - pointer to pre-auth node
+ *
+ * @return None
+ */
+
+void lim_auth_response_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ /* Prepare and post message to LIM Message Queue */
+
+ msg.type = SIR_LIM_AUTH_RSP_TIMEOUT;
+ msg.bodyptr = NULL;
+ msg.bodyval = (uint32_t) param;
+
+ lim_post_msg_api(pMac, &msg);
+} /****** end lim_auth_response_timer_handler() ******/
+
+/**
+ * lim_assoc_failure_timer_handler()
+ *
+ * @mac_global : Pointer to Global MAC structure
+ * @param : Indicates whether this is assoc or reassoc failure timeout
+ *
+ * This function is called upon Re/Assoc failure timer expiration on STA.
+ * Message SIR_LIM_ASSOC_FAIL_TIMEOUT is posted to gSirLimMsgQ when this
+ * function is executed.
+ *
+ * Return void
+ */
+void lim_assoc_failure_timer_handler(void *mac_global, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal mac_ctx = (tpAniSirGlobal) mac_global;
+ tpPESession session = NULL;
+
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+ session = mac_ctx->lim.pSessionEntry;
+ if (LIM_REASSOC == param && NULL != session
+ && session->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE) {
+ lim_log(mac_ctx, LOGE, FL("Reassoc timeout happened"));
+ if (mac_ctx->lim.reAssocRetryAttempt <
+ LIM_MAX_REASSOC_RETRY_LIMIT) {
+ lim_send_retry_reassoc_req_frame(mac_ctx,
+ session->pLimMlmReassocRetryReq, session);
+ mac_ctx->lim.reAssocRetryAttempt++;
+ lim_log(mac_ctx, LOGW,
+ FL("Reassoc request retry is sent %d times"),
+ mac_ctx->lim.reAssocRetryAttempt);
+ return;
+ } else {
+ lim_log(mac_ctx, LOGW,
+ FL("Reassoc request retry MAX(%d) reached"),
+ LIM_MAX_REASSOC_RETRY_LIMIT);
+ if (NULL != session->pLimMlmReassocRetryReq) {
+ cdf_mem_free(session->pLimMlmReassocRetryReq);
+ session->pLimMlmReassocRetryReq = NULL;
+ }
+ }
+ }
+#endif
+ /* Prepare and post message to LIM Message Queue */
+ msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT;
+ msg.bodyval = (uint32_t) param;
+ msg.bodyptr = NULL;
+ lim_post_msg_api(mac_ctx, &msg);
+} /****** end lim_assoc_failure_timer_handler() ******/
+
+/**
+ * lim_update_olbc_cache_timer_handler()
+ *
+ ***FUNCTION:
+ * This function is called upon update olbc cache timer expiration
+ * on STA
+ *
+ ***LOGIC:
+ * Message SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT is posted to gSirLimMsgQ
+ * when this function is executed.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+void lim_update_olbc_cache_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ /* Prepare and post message to LIM Message Queue */
+
+ msg.type = SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT;
+ msg.bodyval = 0;
+ msg.bodyptr = NULL;
+
+ lim_post_msg_api(pMac, &msg);
+} /****** end lim_update_olbc_cache_timer_handler() ******/
+
+/**
+ * lim_deactivate_and_change_timer()
+ *
+ ***FUNCTION:
+ * This function is called to deactivate and change a timer
+ * for future re-activation
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param timerId - enum of timer to be deactivated and changed
+ * This enum is defined in lim_utils.h file
+ *
+ * @return None
+ */
+
+void lim_deactivate_and_change_timer(tpAniSirGlobal pMac, uint32_t timerId)
+{
+ uint32_t val = 0;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, timerId));
+
+ switch (timerId) {
+ case eLIM_ADDTS_RSP_TIMER:
+ pMac->lim.gLimAddtsRspTimerCount++;
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer)
+ != TX_SUCCESS) {
+ /* Could not deactivate AddtsRsp Timer */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate AddtsRsp timer"));
+ }
+ break;
+
+ case eLIM_PERIODIC_PROBE_REQ_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimPeriodicProbeReqTimer)
+ != TX_SUCCESS) {
+ /* Could not deactivate min channel timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate periodic timer"));
+ }
+
+ val =
+ SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime) /
+ 2;
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimPeriodicProbeReqTimer, val,
+ 0) != TX_SUCCESS) {
+ /* Could not change min channel timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("Unable to change periodic timer"));
+ }
+
+ break;
+
+ case eLIM_JOIN_FAIL_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimJoinFailureTimer)
+ != TX_SUCCESS) {
+ /**
+ * Could not deactivate Join Failure
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate Join Failure timer"));
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get JoinFailureTimeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve JoinFailureTimeout value"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimJoinFailureTimer,
+ val, 0) != TX_SUCCESS) {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL("Unable to change Join Failure timer"));
+ }
+
+ break;
+
+ case eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer)
+ != TX_SUCCESS) {
+ /* Could not deactivate periodic join req Times. */
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to deactivate periodic join request timer"));
+ }
+
+ val = SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS);
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, val,
+ 0) != TX_SUCCESS) {
+ /* Could not change periodic join req times. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to change periodic join request timer"));
+ }
+
+ break;
+
+ case eLIM_AUTH_FAIL_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimAuthFailureTimer)
+ != TX_SUCCESS) {
+ /* Could not deactivate Auth failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate auth failure timer"));
+ }
+ /* Change timer to reactivate it in future */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get AuthFailureTimeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve AuthFailureTimeout value"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimAuthFailureTimer,
+ val, 0) != TX_SUCCESS) {
+ /* Could not change Authentication failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("unable to change Auth failure timer"));
+ }
+
+ break;
+
+ case eLIM_ASSOC_FAIL_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimAssocFailureTimer) !=
+ TX_SUCCESS) {
+ /* Could not deactivate Association failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("unable to deactivate Association failure timer"));
+ }
+ /* Change timer to reactivate it in future */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get AssocFailureTimeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve AssocFailureTimeout value"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimAssocFailureTimer,
+ val, 0) != TX_SUCCESS) {
+ /* Could not change Association failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("unable to change Assoc failure timer"));
+ }
+
+ break;
+
+ case eLIM_REASSOC_FAIL_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimReassocFailureTimer) !=
+ TX_SUCCESS) {
+ /* Could not deactivate Reassociation failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("unable to deactivate Reassoc failure timer"));
+ }
+ /* Change timer to reactivate it in future */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get ReassocFailureTimeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve ReassocFailureTimeout value"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimReassocFailureTimer, val,
+ 0) != TX_SUCCESS) {
+ /* Could not change Reassociation failure timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("unable to change Reassociation failure timer"));
+ }
+
+ break;
+
+ case eLIM_PROBE_AFTER_HB_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimProbeAfterHBTimer) !=
+ TX_SUCCESS) {
+ /* Could not deactivate Heartbeat timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("unable to deactivate probeAfterHBTimer"));
+ } else {
+ lim_log(pMac, LOG1,
+ FL("Deactivated probe after hb timer"));
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get PROBE_AFTER_HB_FAILURE
+ * value from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value"));
+ }
+ /* Change timer to reactivate it in future */
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pMac->lim.limTimers.gLimProbeAfterHBTimer,
+ val, 0) != TX_SUCCESS) {
+ /* Could not change HeartBeat timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("unable to change ProbeAfterHBTimer"));
+ } else {
+ lim_log(pMac, LOGW,
+ FL("Probe after HB timer value is changed = %u"),
+ val);
+ }
+
+ break;
+
+ case eLIM_LEARN_DURATION_TIMER:
+ break;
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case eLIM_FT_PREAUTH_RSP_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimFTPreAuthRspTimer) !=
+ TX_SUCCESS) {
+ /**
+ ** Could not deactivate Join Failure
+ ** timer. Log error.
+ **/
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to deactivate Preauth response Failure timer"));
+ return;
+ }
+ val = 1000;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimFTPreAuthRspTimer,
+ val, 0) != TX_SUCCESS) {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL("Unable to change Join Failure timer"));
+ return;
+ }
+ break;
+#endif
+ case eLIM_REMAIN_CHN_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimRemainOnChannelTimer) !=
+ TX_SUCCESS) {
+ /**
+ ** Could not deactivate Join Failure
+ ** timer. Log error.
+ **/
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate Remain on Chn timer"));
+ return;
+ }
+ val = 1000;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimRemainOnChannelTimer, val,
+ 0) != TX_SUCCESS) {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP, FL("Unable to change timer"));
+ return;
+ }
+ break;
+
+ case eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) !=
+ TX_SUCCESS) {
+ /**
+ ** Could not deactivate Active to passive channel timer.
+ ** Log error.
+ **/
+ lim_log(pMac, LOGP, FL("Unable to Deactivate "
+ "Active to passive channel timer"));
+ return;
+ }
+ val = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, val,
+ 0) != TX_SUCCESS) {
+ /**
+ * Could not change timer to check scan type for passive channel.
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP, FL("Unable to change timer"));
+ return;
+ }
+ break;
+
+ case eLIM_DISASSOC_ACK_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimDisassocAckTimer) != TX_SUCCESS) {
+ /**
+ ** Could not deactivate Join Failure
+ ** timer. Log error.
+ **/
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate Disassoc ack timer"));
+ return;
+ }
+ val = 1000;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimDisassocAckTimer,
+ val, 0) != TX_SUCCESS) {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP, FL("Unable to change timer"));
+ return;
+ }
+ break;
+
+ case eLIM_DEAUTH_ACK_TIMER:
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer)
+ != TX_SUCCESS) {
+ /**
+ ** Could not deactivate Join Failure
+ ** timer. Log error.
+ **/
+ lim_log(pMac, LOGP,
+ FL("Unable to deactivate Deauth ack timer"));
+ return;
+ }
+ val = 1000;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change(&pMac->lim.limTimers.gLimDeauthAckTimer,
+ val, 0) != TX_SUCCESS) {
+ /**
+ * Could not change Join Failure
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP, FL("Unable to change timer"));
+ return;
+ }
+ break;
+
+ case eLIM_INSERT_SINGLESHOT_NOA_TIMER:
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer) !=
+ TX_SUCCESS) {
+ /**
+ ** Could not deactivate SingleShot NOA Insert
+ ** timer. Log error.
+ **/
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to deactivate SingleShot NOA Insert timer"));
+ return;
+ }
+ val = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE;
+ val = SYS_MS_TO_TICKS(val);
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer, val,
+ 0) != TX_SUCCESS) {
+ /**
+ * Could not change Single Shot NOA Insert
+ * timer. Log error.
+ */
+ lim_log(pMac, LOGP, FL("Unable to change timer"));
+ return;
+ }
+ break;
+
+ default:
+ /* Invalid timerId. Log error */
+ break;
+ }
+} /****** end lim_deactivate_and_change_timer() ******/
+
+/**
+ * lim_deactivate_and_change_per_sta_id_timer()
+ *
+ *
+ * @brief: This function is called to deactivate and change a per STA timer
+ * for future re-activation
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index.
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param timerId - enum of timer to be deactivated and changed
+ * This enum is defined in lim_utils.h file
+ * @param staId - staId
+ *
+ * @return None
+ */
+
+void
+lim_deactivate_and_change_per_sta_id_timer(tpAniSirGlobal pMac, uint32_t timerId,
+ uint16_t staId)
+{
+ uint32_t val;
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, timerId));
+
+ switch (timerId) {
+ case eLIM_CNF_WAIT_TIMER:
+
+ if (tx_timer_deactivate
+ (&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("unable to deactivate CNF wait timer"));
+
+ }
+ /* Change timer to reactivate it in future */
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WT_CNF_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get cnf timeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL("could not retrieve cnf timeout value"));
+ }
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change
+ (&pMac->lim.limTimers.gpLimCnfWaitTimer[staId], val,
+ val) != TX_SUCCESS) {
+ /* Could not change cnf timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("unable to change cnf wait timer"));
+ }
+
+ break;
+
+ case eLIM_AUTH_RSP_TIMER:
+ {
+ tLimPreAuthNode *pAuthNode;
+
+ pAuthNode =
+ lim_get_pre_auth_node_from_index(pMac,
+ &pMac->lim.
+ gLimPreAuthTimerTable,
+ staId);
+
+ if (pAuthNode == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Invalid Pre Auth Index passed :%d"),
+ staId);
+ break;
+ }
+
+ if (tx_timer_deactivate(&pAuthNode->timer) !=
+ TX_SUCCESS) {
+ /* Could not deactivate auth response timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("unable to deactivate auth response timer"));
+ }
+ /* Change timer to reactivate it in future */
+
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
+ &val) != eSIR_SUCCESS) {
+ /**
+ * Could not get auth rsp timeout value
+ * from CFG. Log error.
+ */
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve auth response timeout value"));
+ }
+
+ val = SYS_MS_TO_TICKS(val);
+
+ if (tx_timer_change(&pAuthNode->timer, val, 0) !=
+ TX_SUCCESS) {
+ /* Could not change auth rsp timer. */
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL("unable to change auth rsp timer"));
+ }
+ }
+ break;
+
+ default:
+ /* Invalid timerId. Log error */
+ break;
+
+ }
+}
+
+/**
+ * lim_activate_cnf_timer()
+ *
+ ***FUNCTION:
+ * This function is called to activate a per STA timer
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param StaId - staId
+ *
+ * @return None
+ */
+
+void lim_activate_cnf_timer(tpAniSirGlobal pMac, uint16_t staId,
+ tpPESession psessionEntry)
+{
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
+ eLIM_CNF_WAIT_TIMER));
+ pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId =
+ psessionEntry->peSessionId;
+ if (tx_timer_activate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId])
+ != TX_SUCCESS) {
+ lim_log(pMac, LOGP, FL("could not activate cnf wait timer"));
+ }
+}
+
+/**
+ * lim_activate_auth_rsp_timer()
+ *
+ ***FUNCTION:
+ * This function is called to activate a per STA timer
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param id - id
+ *
+ * @return None
+ */
+
+void lim_activate_auth_rsp_timer(tpAniSirGlobal pMac, tLimPreAuthNode *pAuthNode)
+{
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION,
+ eLIM_AUTH_RESP_TIMER));
+ if (tx_timer_activate(&pAuthNode->timer) != TX_SUCCESS) {
+ /* / Could not activate auth rsp timer. */
+ /* Log error */
+ lim_log(pMac, LOGP, FL("could not activate auth rsp timer"));
+ }
+}
+
+/**
+ * lim_send_disassoc_frame_threshold_handler()
+ *
+ ***FUNCTION:
+ * This function reloads the credit to the send disassociate frame bucket
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+
+void lim_send_disassoc_frame_threshold_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ uint32_t statusCode;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ msg.type = SIR_LIM_HASH_MISS_THRES_TIMEOUT;
+ msg.bodyval = 0;
+ msg.bodyptr = NULL;
+
+ if ((statusCode = lim_post_msg_api(pMac, &msg)) != eSIR_SUCCESS)
+ lim_log(pMac, LOGE,
+ FL("posting to LIM failed, reason=%d"), statusCode);
+
+}
+
+/**
+ * limAssocCnfWaitTmerHandler()
+ *
+ ***FUNCTION:
+ * This function post a message to send a disassociate frame out.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param
+ *
+ * @return None
+ */
+
+void lim_cnf_wait_tmer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ uint32_t statusCode;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ msg.type = SIR_LIM_CNF_WAIT_TIMEOUT;
+ msg.bodyval = (uint32_t) param;
+ msg.bodyptr = NULL;
+
+ if ((statusCode = lim_post_msg_api(pMac, &msg)) != eSIR_SUCCESS)
+ lim_log(pMac, LOGE,
+ FL("posting to LIM failed, reason=%d"), statusCode);
+
+}
+
+void lim_channel_switch_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL("ChannelSwitch Timer expired. Posting msg to LIM "));
+ )
+
+ msg.type = SIR_LIM_CHANNEL_SWITCH_TIMEOUT;
+ msg.bodyval = (uint32_t) param;
+ msg.bodyptr = NULL;
+
+ lim_post_msg_api(pMac, &msg);
+}
+
+void lim_quiet_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ msg.type = SIR_LIM_QUIET_TIMEOUT;
+ msg.bodyval = (uint32_t) param;
+ msg.bodyptr = NULL;
+
+ PELOG1(lim_log(pMac, LOG1, FL("Post SIR_LIM_QUIET_TIMEOUT msg. "));)
+ lim_post_msg_api(pMac, &msg);
+}
+
+void lim_quiet_bss_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tSirMsgQ msg;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+
+ msg.type = SIR_LIM_QUIET_BSS_TIMEOUT;
+ msg.bodyval = (uint32_t) param;
+ msg.bodyptr = NULL;
+ PELOG1(lim_log(pMac, LOG1, FL("Post SIR_LIM_QUIET_BSS_TIMEOUT msg. "));)
+ lim_post_msg_api(pMac, &msg);
+}
+
diff --git a/core/mac/src/pe/lim/lim_timer_utils.h b/core/mac/src/pe/lim/lim_timer_utils.h
new file mode 100644
index 0000000..b133d71
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_timer_utils.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file lim_timer_utils.h contains the utility definitions
+ * LIM uses for timer handling.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_TIMER_UTILS_H
+#define __LIM_TIMER_UTILS_H
+
+#include "lim_types.h"
+
+/* Timer related functions */
+enum {
+ eLIM_MIN_CHANNEL_TIMER,
+ eLIM_MAX_CHANNEL_TIMER,
+ eLIM_JOIN_FAIL_TIMER,
+ eLIM_AUTH_FAIL_TIMER,
+ eLIM_AUTH_RESP_TIMER,
+ eLIM_ASSOC_FAIL_TIMER,
+ eLIM_REASSOC_FAIL_TIMER,
+ eLIM_PRE_AUTH_CLEANUP_TIMER,
+ eLIM_CNF_WAIT_TIMER,
+ eLIM_AUTH_RSP_TIMER,
+ eLIM_UPDATE_OLBC_CACHE_TIMER,
+ eLIM_PROBE_AFTER_HB_TIMER,
+ eLIM_ADDTS_RSP_TIMER,
+ eLIM_CHANNEL_SWITCH_TIMER,
+ eLIM_LEARN_DURATION_TIMER,
+ eLIM_QUIET_TIMER,
+ eLIM_QUIET_BSS_TIMER,
+ eLIM_WPS_OVERLAP_TIMER,
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ eLIM_FT_PREAUTH_RSP_TIMER,
+#endif
+ eLIM_REMAIN_CHN_TIMER,
+ eLIM_PERIODIC_PROBE_REQ_TIMER,
+#ifdef FEATURE_WLAN_ESE
+ eLIM_TSM_TIMER,
+#endif
+ eLIM_DISASSOC_ACK_TIMER,
+ eLIM_DEAUTH_ACK_TIMER,
+ eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER,
+ eLIM_INSERT_SINGLESHOT_NOA_TIMER,
+ eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE
+};
+
+#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500
+#define LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE 500
+
+/* Timer Handler functions */
+uint32_t lim_create_timers(tpAniSirGlobal);
+void lim_timer_handler(void *, uint32_t);
+void lim_auth_response_timer_handler(void *, uint32_t);
+void lim_assoc_failure_timer_handler(void *, uint32_t);
+void limReassocFailureTimerHandler(void *, uint32_t);
+
+void lim_deactivate_and_change_timer(tpAniSirGlobal, uint32_t);
+void limDummyPktExpTimerHandler(void *, uint32_t);
+void lim_send_disassoc_frame_threshold_handler(void *, uint32_t);
+void lim_cnf_wait_tmer_handler(void *, uint32_t);
+void lim_deactivate_and_change_per_sta_id_timer(tpAniSirGlobal, uint32_t, uint16_t);
+void lim_activate_cnf_timer(tpAniSirGlobal, uint16_t, tpPESession);
+void lim_activate_auth_rsp_timer(tpAniSirGlobal, tLimPreAuthNode *);
+void lim_update_olbc_cache_timer_handler(void *, uint32_t);
+void lim_addts_response_timer_handler(void *, uint32_t);
+void lim_channel_switch_timer_handler(void *, uint32_t);
+void lim_quiet_timer_handler(void *, uint32_t);
+void lim_quiet_bss_timer_handler(void *, uint32_t);
+void limCBScanIntervalTimerHandler(void *, uint32_t);
+void limCBScanDurationTimerHandler(void *, uint32_t);
+#endif /* __LIM_TIMER_UTILS_H */
diff --git a/core/mac/src/pe/lim/lim_trace.c b/core/mac/src/pe/lim/lim_trace.c
new file mode 100644
index 0000000..3847127
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_trace.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file lim_trace.c
+
+ \brief implementation for trace related APIs
+
+ \author Sunit Bhatia
+
+ ========================================================================*/
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+
+#include "ani_global.h" /* for tpAniSirGlobal */
+
+#include "lim_trace.h"
+#include "lim_timer_utils.h"
+#include "cdf_trace.h"
+
+#ifdef LIM_TRACE_RECORD
+uint32_t g_mgmt_frame_stats[14];
+
+#define LIM_TRACE_MAX_SUBTYPES 14
+
+static uint8_t *__lim_trace_get_timer_string(uint16_t timerId)
+{
+ switch (timerId) {
+ CASE_RETURN_STRING(eLIM_MIN_CHANNEL_TIMER);
+ CASE_RETURN_STRING(eLIM_MAX_CHANNEL_TIMER);
+ CASE_RETURN_STRING(eLIM_JOIN_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_AUTH_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_AUTH_RESP_TIMER);
+ CASE_RETURN_STRING(eLIM_ASSOC_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_REASSOC_FAIL_TIMER);
+ CASE_RETURN_STRING(eLIM_PRE_AUTH_CLEANUP_TIMER);
+ CASE_RETURN_STRING(eLIM_CNF_WAIT_TIMER);
+ CASE_RETURN_STRING(eLIM_AUTH_RSP_TIMER);
+ CASE_RETURN_STRING(eLIM_UPDATE_OLBC_CACHE_TIMER);
+ CASE_RETURN_STRING(eLIM_PROBE_AFTER_HB_TIMER);
+ CASE_RETURN_STRING(eLIM_ADDTS_RSP_TIMER);
+ CASE_RETURN_STRING(eLIM_CHANNEL_SWITCH_TIMER);
+ CASE_RETURN_STRING(eLIM_LEARN_DURATION_TIMER);
+ CASE_RETURN_STRING(eLIM_QUIET_TIMER);
+ CASE_RETURN_STRING(eLIM_QUIET_BSS_TIMER);
+ CASE_RETURN_STRING(eLIM_WPS_OVERLAP_TIMER);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ CASE_RETURN_STRING(eLIM_FT_PREAUTH_RSP_TIMER);
+#endif
+ CASE_RETURN_STRING(eLIM_REMAIN_CHN_TIMER);
+ CASE_RETURN_STRING(eLIM_PERIODIC_PROBE_REQ_TIMER);
+#ifdef FEATURE_WLAN_ESE
+ CASE_RETURN_STRING(eLIM_TSM_TIMER);
+#endif
+ CASE_RETURN_STRING(eLIM_DISASSOC_ACK_TIMER);
+ CASE_RETURN_STRING(eLIM_DEAUTH_ACK_TIMER);
+ CASE_RETURN_STRING(eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
+ CASE_RETURN_STRING(eLIM_INSERT_SINGLESHOT_NOA_TIMER);
+ CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
+ default:
+ return ("UNKNOWN");
+ break;
+ }
+}
+
+static uint8_t *__lim_trace_get_mgmt_drop_reason_string(uint16_t dropReason)
+{
+
+ switch (dropReason) {
+ CASE_RETURN_STRING(eMGMT_DROP_INFRA_BCN_IN_IBSS);
+ CASE_RETURN_STRING(eMGMT_DROP_INVALID_SIZE);
+ CASE_RETURN_STRING(eMGMT_DROP_NON_SCAN_MODE_FRAME);
+ CASE_RETURN_STRING(eMGMT_DROP_NOT_LAST_IBSS_BCN);
+ CASE_RETURN_STRING(eMGMT_DROP_NO_DROP);
+ CASE_RETURN_STRING(eMGMT_DROP_SCAN_MODE_FRAME);
+
+ default:
+ return ("UNKNOWN");
+ break;
+ }
+}
+
+void lim_trace_init(tpAniSirGlobal pMac)
+{
+ cdf_trace_register(CDF_MODULE_ID_PE, (tp_cdf_trace_cb) & lim_trace_dump);
+}
+
+void lim_trace_dump(tpAniSirGlobal pMac, tp_cdf_trace_record pRecord,
+ uint16_t recIndex)
+{
+
+ static char *frameSubtypeStr[LIM_TRACE_MAX_SUBTYPES] = {
+ "Association request",
+ "Association response",
+ "Reassociation request",
+ "Reassociation response",
+ "Probe request",
+ "Probe response",
+ NULL,
+ NULL,
+ "Beacon",
+ "ATIM",
+ "Disassociation",
+ "Authentication",
+ "Deauthentication",
+ "Action"
+ };
+
+ switch (pRecord->code) {
+ case TRACE_CODE_MLM_STATE:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "MLM State:",
+ lim_trace_get_mlm_state_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_SME_STATE:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "SME State:",
+ lim_trace_get_sme_state_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_TX_MGMT:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "TX Mgmt:",
+ frameSubtypeStr[pRecord->data], pRecord->data);
+ break;
+
+ case TRACE_CODE_RX_MGMT:
+ if (LIM_TRACE_MAX_SUBTYPES <=
+ LIM_TRACE_GET_SUBTYPE(pRecord->data)) {
+ lim_log(pMac, LOGE, "Wrong Subtype - %d",
+ LIM_TRACE_GET_SUBTYPE(pRecord->data));
+ } else {
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(%d) SN: %d ",
+ recIndex, pRecord->time, pRecord->session,
+ "RX Mgmt:",
+ frameSubtypeStr[LIM_TRACE_GET_SUBTYPE
+ (pRecord->data)],
+ LIM_TRACE_GET_SUBTYPE(pRecord->data),
+ LIM_TRACE_GET_SSN(pRecord->data));
+ }
+ break;
+ case TRACE_CODE_RX_MGMT_DROP:
+ lim_log(pMac, LOGE, "%04d %012llu S%d %-14s %-30s(%d) ",
+ recIndex, pRecord->time, pRecord->session,
+ "Drop RX Mgmt:",
+ __lim_trace_get_mgmt_drop_reason_string((uint16_t) pRecord->
+ data), pRecord->data);
+ break;
+
+ case TRACE_CODE_RX_MGMT_TSF:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s0x%x(%d) ",
+ recIndex, pRecord->time, pRecord->session,
+ "RX Mgmt TSF:", " ", pRecord->data, pRecord->data);
+ break;
+
+ case TRACE_CODE_TX_COMPLETE:
+ lim_log(pMac, LOGE, "%04d %012llu S%d %-14s %d ", recIndex,
+ pRecord->time, pRecord->session, "TX Complete",
+ pRecord->data);
+ break;
+
+ case TRACE_CODE_TX_SME_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "TX SME Msg:",
+ mac_trace_get_sme_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_RX_SME_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->
+ data) ? "Def/Drp LIM Msg:"
+ : "RX Sme Msg:",
+ mac_trace_get_sme_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+
+ case TRACE_CODE_TX_WMA_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "TX WMA Msg:",
+ mac_trace_get_wma_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+
+ case TRACE_CODE_RX_WMA_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->
+ data) ? "Def/Drp LIM Msg:"
+ : "RX WMA Msg:",
+ mac_trace_get_wma_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+
+ case TRACE_CODE_TX_LIM_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "TX LIM Msg:",
+ mac_trace_get_lim_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_RX_LIM_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->
+ data) ? "Def/Drp LIM Msg:"
+ : "RX LIM Msg",
+ mac_trace_get_lim_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_TX_CFG_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "TX CFG Msg:",
+ mac_trace_get_cfg_msg_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_RX_CFG_MSG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session,
+ LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->
+ data) ? "Def/Drp LIM Msg:"
+ : "RX CFG Msg:",
+ mac_trace_get_cfg_msg_string((uint16_t)
+ MAC_TRACE_GET_MSG_ID(pRecord->
+ data)),
+ pRecord->data);
+ break;
+
+ case TRACE_CODE_TIMER_ACTIVATE:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "Timer Actvtd",
+ __lim_trace_get_timer_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ case TRACE_CODE_TIMER_DEACTIVATE:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) ", recIndex,
+ pRecord->time, pRecord->session, "Timer DeActvtd",
+ __lim_trace_get_timer_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+
+ case TRACE_CODE_INFO_LOG:
+ lim_log(pMac, LOGE,
+ "%04d %012llu S%d %-14s %-30s(0x%x) \n",
+ recIndex, pRecord->time, pRecord->session,
+ "INFORMATION_LOG",
+ mac_trace_get_info_log_string((uint16_t) pRecord->data),
+ pRecord->data);
+ break;
+ default:
+ lim_log(pMac, LOGE, "%04d %012llu S%d %-14s(%d) (0x%x) ",
+ recIndex, pRecord->time, pRecord->session,
+ "Unknown Code", pRecord->code, pRecord->data);
+ break;
+ }
+}
+
+void mac_trace_msg_tx(tpAniSirGlobal pMac, uint8_t session, uint32_t data)
+{
+
+ uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+ uint8_t moduleId = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+ switch (moduleId) {
+ case SIR_LIM_MODULE_ID:
+ if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ mac_trace(pMac, TRACE_CODE_TX_LIM_MSG, session, data);
+ else
+ mac_trace(pMac, TRACE_CODE_TX_SME_MSG, session, data);
+ break;
+ case SIR_WMA_MODULE_ID:
+ mac_trace(pMac, TRACE_CODE_TX_WMA_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ mac_trace(pMac, TRACE_CODE_TX_CFG_MSG, session, data);
+ break;
+ default:
+ mac_trace(pMac, moduleId, session, data);
+ break;
+ }
+}
+
+void mac_trace_msg_tx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+ uint32_t data)
+{
+ uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+ uint8_t moduleId = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+ switch (moduleId) {
+ case SIR_LIM_MODULE_ID:
+ if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ mac_trace_new(pMac, module, TRACE_CODE_TX_LIM_MSG,
+ session, data);
+ else
+ mac_trace_new(pMac, module, TRACE_CODE_TX_SME_MSG,
+ session, data);
+ break;
+ case SIR_WMA_MODULE_ID:
+ mac_trace_new(pMac, module, TRACE_CODE_TX_WMA_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ mac_trace_new(pMac, module, TRACE_CODE_TX_CFG_MSG, session, data);
+ break;
+ default:
+ mac_trace(pMac, moduleId, session, data);
+ break;
+ }
+}
+
+/*
+ * bit31: Rx message defferred or not
+ * bit 0-15: message ID:
+ */
+void mac_trace_msg_rx(tpAniSirGlobal pMac, uint8_t session, uint32_t data)
+{
+ uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+ uint8_t moduleId = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+ switch (moduleId) {
+ case SIR_LIM_MODULE_ID:
+ if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ mac_trace(pMac, TRACE_CODE_RX_LIM_MSG, session, data);
+ else
+ mac_trace(pMac, TRACE_CODE_RX_SME_MSG, session, data);
+ break;
+ case SIR_WMA_MODULE_ID:
+ mac_trace(pMac, TRACE_CODE_RX_WMA_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ mac_trace(pMac, TRACE_CODE_RX_CFG_MSG, session, data);
+ break;
+ default:
+ mac_trace(pMac, moduleId, session, data);
+ break;
+ }
+}
+
+/*
+ * bit31: Rx message defferred or not
+ * bit 0-15: message ID:
+ */
+void mac_trace_msg_rx_new(tpAniSirGlobal pMac, uint8_t module, uint8_t session,
+ uint32_t data)
+{
+ uint16_t msgId = (uint16_t) MAC_TRACE_GET_MSG_ID(data);
+ uint8_t moduleId = (uint8_t) MAC_TRACE_GET_MODULE_ID(data);
+
+ switch (moduleId) {
+ case SIR_LIM_MODULE_ID:
+ if (msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN)
+ mac_trace_new(pMac, module, TRACE_CODE_RX_LIM_MSG,
+ session, data);
+ else
+ mac_trace_new(pMac, module, TRACE_CODE_RX_SME_MSG,
+ session, data);
+ break;
+ case SIR_WMA_MODULE_ID:
+ mac_trace_new(pMac, module, TRACE_CODE_RX_WMA_MSG, session, data);
+ break;
+ case SIR_CFG_MODULE_ID:
+ mac_trace_new(pMac, module, TRACE_CODE_RX_CFG_MSG, session, data);
+ break;
+ default:
+ mac_trace(pMac, moduleId, session, data);
+ break;
+ }
+}
+
+uint8_t *lim_trace_get_mlm_state_string(uint32_t mlmState)
+{
+ switch (mlmState) {
+ CASE_RETURN_STRING(eLIM_MLM_OFFLINE_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_IDLE_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_PROBE_RESP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_PASSIVE_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_JOIN_BEACON_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_JOINED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_BSS_STARTED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME2_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME3_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME4_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_AUTH_RSP_TIMEOUT_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_AUTHENTICATED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_REASSOC_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_ASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_REASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_LINK_ESTABLISHED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_CNF_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_LEARN_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_DEL_BSS_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_STA_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_DEL_STA_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_SET_BSS_KEY_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_SET_STA_KEY_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_SET_STA_BCASTKEY_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_SET_MIMOPS_STATE);
+ default:
+ return ("UNKNOWN");
+ break;
+ }
+}
+
+uint8_t *lim_trace_get_sme_state_string(uint32_t smeState)
+{
+ switch (smeState) {
+
+ CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_IDLE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE);
+ CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE);
+ CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE);
+ CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE);
+ CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE);
+ default:
+ return ("UNKNOWN");
+ break;
+ }
+}
+
+#endif
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
new file mode 100644
index 0000000..715e775
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_types.h contains the definitions used by all
+ * all LIM modules.
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __LIM_TYPES_H
+#define __LIM_TYPES_H
+
+#include "wni_api.h"
+#include "sir_api.h"
+#include "sir_common.h"
+#include "sir_mac_prot_def.h"
+#include "utils_api.h"
+
+#include "lim_api.h"
+#include "lim_debug.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "sys_global.h"
+#include "dph_global.h"
+#include "parser_api.h"
+#include "wma_if.h"
+
+#define LINK_TEST_DEFER 1
+
+#define TRACE_EVENT_CNF_TIMER_DEACT 0x6600
+#define TRACE_EVENT_CNF_TIMER_ACT 0x6601
+#define TRACE_EVENT_AUTH_RSP_TIMER_DEACT 0x6602
+#define TRACE_EVENT_AUTH_RSP_TIMER_ACT 0x6603
+
+/* MLM message types */
+#define LIM_MLM_MSG_START 1000
+#define LIM_MLM_SCAN_REQ LIM_MLM_MSG_START
+#define LIM_MLM_SCAN_CNF (LIM_MLM_MSG_START + 1)
+#define LIM_MLM_START_REQ (LIM_MLM_MSG_START + 2)
+#define LIM_MLM_START_CNF (LIM_MLM_MSG_START + 3)
+#define LIM_MLM_JOIN_REQ (LIM_MLM_MSG_START + 4)
+#define LIM_MLM_JOIN_CNF (LIM_MLM_MSG_START + 5)
+#define LIM_MLM_AUTH_REQ (LIM_MLM_MSG_START + 6)
+#define LIM_MLM_AUTH_CNF (LIM_MLM_MSG_START + 7)
+#define LIM_MLM_AUTH_IND (LIM_MLM_MSG_START + 8)
+#define LIM_MLM_ASSOC_REQ (LIM_MLM_MSG_START + 9)
+#define LIM_MLM_ASSOC_CNF (LIM_MLM_MSG_START + 10)
+#define LIM_MLM_ASSOC_IND (LIM_MLM_MSG_START + 11)
+#define LIM_MLM_DISASSOC_REQ (LIM_MLM_MSG_START + 12)
+#define LIM_MLM_DISASSOC_CNF (LIM_MLM_MSG_START + 13)
+#define LIM_MLM_DISASSOC_IND (LIM_MLM_MSG_START + 14)
+#define LIM_MLM_REASSOC_REQ (LIM_MLM_MSG_START + 15)
+#define LIM_MLM_REASSOC_CNF (LIM_MLM_MSG_START + 16)
+#define LIM_MLM_REASSOC_IND (LIM_MLM_MSG_START + 17)
+#define LIM_MLM_DEAUTH_REQ (LIM_MLM_MSG_START + 18)
+#define LIM_MLM_DEAUTH_CNF (LIM_MLM_MSG_START + 19)
+#define LIM_MLM_DEAUTH_IND (LIM_MLM_MSG_START + 20)
+#define LIM_MLM_TSPEC_REQ (LIM_MLM_MSG_START + 21)
+#define LIM_MLM_TSPEC_CNF (LIM_MLM_MSG_START + 22)
+#define LIM_MLM_TSPEC_IND (LIM_MLM_MSG_START + 23)
+#define LIM_MLM_SETKEYS_REQ (LIM_MLM_MSG_START + 24)
+#define LIM_MLM_SETKEYS_CNF (LIM_MLM_MSG_START + 25)
+#define LIM_MLM_LINK_TEST_STOP_REQ (LIM_MLM_MSG_START + 30)
+#define LIM_MLM_PURGE_STA_IND (LIM_MLM_MSG_START + 31)
+/*
+ * Values (LIM_MLM_MSG_START + 32) through
+ * (LIM_MLM_MSG_START + 40) are unused.
+ */
+#ifdef FEATURE_OEM_DATA_SUPPORT
+#define LIM_MLM_OEM_DATA_REQ (LIM_MLM_MSG_START + 41)
+#define LIM_MLM_OEM_DATA_CNF (LIM_MLM_MSG_START + 42)
+#endif
+
+#define LIM_HASH_ADD 0
+#define LIM_HASH_UPDATE 1
+
+#define LIM_WEP_IN_FC 1
+#define LIM_NO_WEP_IN_FC 0
+
+#define LIM_DECRYPT_ICV_FAIL 1
+
+/* / Definitions to distinquish between Association/Reassociaton */
+#define LIM_ASSOC 0
+#define LIM_REASSOC 1
+
+/* / Minimum Memory blocks require for different scenario */
+#define LIM_MIN_MEM_ASSOC 4
+
+/* / Verifies whether given mac addr matches the CURRENT Bssid */
+#define IS_CURRENT_BSSID(pMac, addr, psessionEntry) (cdf_mem_compare(addr, \
+ psessionEntry->bssId, \
+ sizeof(psessionEntry->bssId)))
+/* / Verifies whether given addr matches the REASSOC Bssid */
+#define IS_REASSOC_BSSID(pMac, addr, psessionEntry) (cdf_mem_compare(addr, \
+ psessionEntry->limReAssocbssId, \
+ sizeof(psessionEntry->limReAssocbssId)))
+
+#define REQ_TYPE_REGISTRAR (0x2)
+#define REQ_TYPE_WLAN_MANAGER_REGISTRAR (0x3)
+
+#define RESP_TYPE_REGISTRAR (0x2)
+#define RESP_TYPE_ENROLLEE_INFO_ONLY (0x0)
+#define RESP_TYPE_ENROLLEE_OPEN_8021X (0x1)
+#define RESP_TYPE_AP (0x3)
+#define LIM_TX_FRAMES_THRESHOLD_ON_CHIP 300
+
+
+#define HAL_TXCOMP_REQUESTED_MASK 0x1 /* bit 0 for TxComp intr requested. */
+#define HAL_USE_SELF_STA_REQUESTED_MASK 0x2 /* bit 1 for STA overwrite with selfSta Requested. */
+#define HAL_TX_NO_ENCRYPTION_MASK 0x4 /* bit 2. If set, the frame is not to be encrypted */
+#if defined(LIBRA_WAPI_SUPPORT)
+#define HAL_WAPI_STA_MASK 0x8 /* bit 3. If set, this frame is for WAPI station */
+#endif
+
+#define HAL_TRIGGER_ENABLED_AC_MASK 0x10 /* bit 4 for data frames belonging to trigger enabled AC */
+#define HAL_USE_NO_ACK_REQUESTED_MASK 0x20
+
+#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 /* Bit 6 will be used to control BD rate for Management frames */
+#define HAL_USE_PEER_STA_REQUESTED_MASK 0x80 /* bit 7 will be used to control frames for p2p interface */
+
+#ifdef FEATURE_WLAN_TDLS
+#define HAL_TDLS_PEER_STA_MASK 0x80 /* bit 7 set for TDLS peer station */
+#endif
+
+
+/* enums used by LIM are as follows */
+
+enum eLimDisassocTrigger {
+ eLIM_HOST_DISASSOC,
+ eLIM_PEER_ENTITY_DISASSOC,
+ eLIM_LINK_MONITORING_DISASSOC,
+ eLIM_PROMISCUOUS_MODE_DISASSOC,
+ eLIM_HOST_DEAUTH,
+ eLIM_PEER_ENTITY_DEAUTH,
+ eLIM_LINK_MONITORING_DEAUTH,
+ eLIM_JOIN_FAILURE,
+ eLIM_REASSOC_REJECT
+};
+
+/* Reason code to determine the channel change context while sending
+ * WMA_CHNL_SWITCH_REQ message to HAL
+ */
+enum eChannelChangeReasonCodes {
+ LIM_SWITCH_CHANNEL_REASSOC,
+ LIM_SWITCH_CHANNEL_JOIN,
+ LIM_SWITCH_CHANNEL_OPERATION, /* Generic change channel */
+ LIM_SWITCH_CHANNEL_SAP_DFS, /* DFS channel change */
+};
+
+typedef struct sLimAuthRspTimeout {
+ tSirMacAddr peerMacAddr;
+} tLimAuthRspTimeout;
+
+typedef struct sLimMlmStartReq {
+ tSirMacSSid ssId;
+ tSirBssType bssType;
+ tSirMacAddr bssId;
+ tSirMacBeaconInterval beaconPeriod;
+ uint8_t dtimPeriod;
+ tSirMacCfParamSet cfParamSet;
+ tSirMacChanNum channelNumber;
+ ePhyChanBondState cbMode;
+ uint16_t atimWindow;
+ tSirMacRateSet rateSet;
+ uint8_t sessionId; /* Added For BT-AMP Support */
+
+ /* Parameters reqd for new HAL (message) interface */
+ tSirNwType nwType;
+ uint8_t htCapable;
+ tSirMacHTOperatingMode htOperMode;
+ uint8_t dualCTSProtection;
+ uint8_t txChannelWidthSet;
+ uint8_t ssidHidden;
+ uint8_t wps_state;
+ uint8_t obssProtEnabled;
+} tLimMlmStartReq, *tpLimMlmStartReq;
+
+typedef struct sLimMlmStartCnf {
+ tSirResultCodes resultCode;
+ uint8_t sessionId;
+} tLimMlmStartCnf, *tpLimMlmStartCnf;
+
+typedef struct sLimMlmScanCnf {
+ tSirResultCodes resultCode;
+ uint16_t scanResultLength;
+ tSirBssDescription bssDescription[1];
+ uint8_t sessionId;
+} tLimMlmScanCnf, *tpLimMlmScanCnf;
+
+typedef struct sLimScanResult {
+ uint16_t numBssDescriptions;
+ tSirBssDescription bssDescription[1];
+} tLimScanResult;
+
+typedef struct sLimMlmJoinCnf {
+ tSirResultCodes resultCode;
+ uint16_t protStatusCode;
+ uint8_t sessionId;
+} tLimMlmJoinCnf, *tpLimMlmJoinCnf;
+
+typedef struct sLimMlmAssocReq {
+ tSirMacAddr peerMacAddr;
+ uint32_t assocFailureTimeout;
+ uint16_t capabilityInfo;
+ tSirMacListenInterval listenInterval;
+ uint8_t sessionId;
+} tLimMlmAssocReq, *tpLimMlmAssocReq;
+
+typedef struct sLimMlmAssocCnf {
+ tSirResultCodes resultCode; /* Internal status code. */
+ uint16_t protStatusCode; /* Protocol Status code. */
+ uint8_t sessionId;
+} tLimMlmAssocCnf, *tpLimMlmAssocCnf;
+
+typedef struct sLimMlmAssocInd {
+ tSirMacAddr peerMacAddr;
+ uint16_t aid;
+ tAniAuthType authType;
+ tAniSSID ssId;
+ tSirRSNie rsnIE;
+ tSirWAPIie wapiIE;
+ tSirAddie addIE; /* additional IE received from the peer, which possibly includes WSC IE and/or P2P IE. */
+ tSirMacCapabilityInfo capabilityInfo;
+ tAniBool spectrumMgtIndicator;
+ tSirMacPowerCapInfo powerCap;
+ tSirSupChnl supportedChannels;
+ uint8_t sessionId;
+
+ tAniBool WmmStaInfoPresent;
+
+ /* Required for indicating the frames to upper layer */
+ uint32_t beaconLength;
+ uint8_t *beaconPtr;
+ uint32_t assocReqLength;
+ uint8_t *assocReqPtr;
+ tSirSmeChanInfo chan_info;
+} tLimMlmAssocInd, *tpLimMlmAssocInd;
+
+typedef struct sLimMlmReassocReq {
+ tSirMacAddr peerMacAddr;
+ uint32_t reassocFailureTimeout;
+ uint16_t capabilityInfo;
+ tSirMacListenInterval listenInterval;
+ uint8_t sessionId;
+} tLimMlmReassocReq, *tpLimMlmReassocReq;
+
+typedef struct sLimMlmReassocCnf {
+ tSirResultCodes resultCode;
+ uint16_t protStatusCode; /* Protocol Status code. */
+ uint8_t sessionId;
+} tLimMlmReassocCnf, *tpLimMlmReassocCnf;
+
+typedef struct sLimMlmReassocInd {
+ tSirMacAddr peerMacAddr;
+ tSirMacAddr currentApAddr;
+ uint16_t aid;
+ tAniAuthType authType;
+ tAniSSID ssId;
+ tSirRSNie rsnIE;
+ tSirWAPIie wapiIE;
+ tSirAddie addIE; /* additional IE received from the peer, which can be WSC IE and/or P2P IE. */
+ tSirMacCapabilityInfo capabilityInfo;
+ tAniBool spectrumMgtIndicator;
+ tSirMacPowerCapInfo powerCap;
+ tSirSupChnl supportedChannels;
+
+ tAniBool WmmStaInfoPresent;
+
+ /* Required for indicating the frames to upper layer */
+ uint32_t beaconLength;
+ uint8_t *beaconPtr;
+ uint32_t assocReqLength;
+ uint8_t *assocReqPtr;
+} tLimMlmReassocInd, *tpLimMlmReassocInd;
+
+typedef struct sLimMlmAuthCnf {
+ tSirMacAddr peerMacAddr;
+ tAniAuthType authType;
+ tSirResultCodes resultCode;
+ uint16_t protStatusCode;
+ uint8_t sessionId;
+} tLimMlmAuthCnf, *tpLimMlmAuthCnf;
+
+typedef struct sLimMlmDeauthReq {
+ tSirMacAddr peerMacAddr;
+ uint16_t reasonCode;
+ uint16_t deauthTrigger;
+ uint16_t aid;
+ uint8_t sessionId; /* Added for BT-AMP SUPPORT */
+
+} tLimMlmDeauthReq, *tpLimMlmDeauthReq;
+
+typedef struct sLimMlmDeauthCnf {
+ tSirMacAddr peerMacAddr;
+ tSirResultCodes resultCode;
+ uint16_t deauthTrigger;
+ uint16_t aid;
+ uint8_t sessionId;
+} tLimMlmDeauthCnf, *tpLimMLmDeauthCnf;
+
+typedef struct sLimMlmDeauthInd {
+ tSirMacAddr peerMacAddr;
+ uint16_t reasonCode;
+ uint16_t deauthTrigger;
+ uint16_t aid;
+} tLimMlmDeauthInd, *tpLimMlmDeauthInd;
+
+typedef struct sLimMlmDisassocReq {
+ tSirMacAddr peerMacAddr;
+ uint16_t reasonCode;
+ uint16_t disassocTrigger;
+ uint16_t aid;
+ uint8_t sessionId;
+} tLimMlmDisassocReq, *tpLimMlmDisassocReq;
+
+typedef struct sLimMlmDisassocCnf {
+ tSirMacAddr peerMacAddr;
+ tSirResultCodes resultCode;
+ uint16_t disassocTrigger;
+ uint16_t aid;
+ uint8_t sessionId;
+} tLimMlmDisassocCnf, *tpLimMlmDisassocCnf;
+
+typedef struct sLimMlmDisassocInd {
+ tSirMacAddr peerMacAddr;
+ uint16_t reasonCode;
+ uint16_t disassocTrigger;
+ uint16_t aid;
+ uint8_t sessionId;
+} tLimMlmDisassocInd, *tpLimMlmDisassocInd;
+
+typedef struct sLimMlmPurgeStaReq {
+ tSirMacAddr peerMacAddr;
+ uint16_t aid;
+ uint8_t sessionId; /* Added For BT-AMP Support */
+} tLimMlmPurgeStaReq, *tpLimMlmPurgeStaReq;
+
+typedef struct sLimMlmPurgeStaInd {
+ tSirMacAddr peerMacAddr;
+ uint16_t reasonCode;
+ uint16_t purgeTrigger;
+ uint16_t aid;
+ uint8_t sessionId;
+} tLimMlmPurgeStaInd, *tpLimMlmPurgeStaInd;
+
+typedef struct sLimMlmSetKeysCnf {
+ tSirMacAddr peerMacAddr;
+ uint16_t resultCode;
+ uint16_t aid;
+ uint8_t sessionId;
+} tLimMlmSetKeysCnf, *tpLimMlmSetKeysCnf;
+
+typedef struct sLimMlmResetReq {
+ tSirMacAddr macAddr;
+ uint8_t performCleanup;
+ uint8_t sessionId;
+} tLimMlmResetReq, *tpLimMlmResetReq;
+
+typedef struct sLimMlmResetCnf {
+ tSirMacAddr macAddr;
+ tSirResultCodes resultCode;
+ uint8_t sessionId;
+} tLimMlmResetCnf, *tpLimMlmResetCnf;
+
+typedef struct sLimMlmLinkTestStopReq {
+ tSirMacAddr peerMacAddr;
+ uint8_t sessionId;
+} tLimMlmLinkTestStopReq, *tpLimMlmLinkTestStopReq;
+
+/* Function templates */
+
+bool lim_process_sme_req_messages(tpAniSirGlobal, tpSirMsgQ);
+void lim_process_mlm_req_messages(tpAniSirGlobal, tpSirMsgQ);
+void lim_process_mlm_rsp_messages(tpAniSirGlobal, uint32_t, uint32_t *);
+void lim_process_sme_del_bss_rsp(tpAniSirGlobal, uint32_t, tpPESession);
+
+void lim_get_random_bssid(tpAniSirGlobal pMac, uint8_t *data);
+
+/* Function to handle HT and HT IE CFG parameter intializations */
+void handle_ht_capabilityand_ht_info(struct sAniSirGlobal *pMac,
+ tpPESession psessionEntry);
+
+/* Function to handle CFG parameter updates */
+void lim_handle_cf_gparam_update(tpAniSirGlobal, uint32_t);
+
+void lim_handle_param_update(tpAniSirGlobal pMac, eUpdateIEsType cfgId);
+
+/* Function to apply CFG parameters before join/reassoc/start BSS */
+void lim_apply_configuration(tpAniSirGlobal, tpPESession);
+
+void lim_set_cfg_protection(tpAniSirGlobal pMac, tpPESession pesessionEntry);
+
+/* Function to Initialize MLM state machine on STA */
+void lim_init_mlm(tpAniSirGlobal);
+
+/* Function to cleanup MLM state machine */
+void lim_cleanup_mlm(tpAniSirGlobal);
+
+/* Function to cleanup LMM state machine */
+void lim_cleanup_lmm(tpAniSirGlobal);
+
+/* Management frame handling functions */
+void lim_process_beacon_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_beacon_frame_no_session(tpAniSirGlobal, uint8_t *);
+void lim_process_probe_req_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_probe_rsp_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_probe_rsp_frame_no_session(tpAniSirGlobal, uint8_t *);
+void lim_process_probe_req_frame_multiple_bss(tpAniSirGlobal, uint8_t *,
+ tpPESession);
+
+/* Process Auth frame when we have a session in progress. */
+void lim_process_auth_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+tSirRetStatus lim_process_auth_frame_no_session(tpAniSirGlobal pMac, uint8_t *,
+ void *body);
+#endif
+
+void lim_process_assoc_req_frame(tpAniSirGlobal, uint8_t *, uint8_t, tpPESession);
+void lim_send_mlm_assoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry);
+
+void lim_process_assoc_rsp_frame(tpAniSirGlobal, uint8_t *, uint8_t, tpPESession);
+void lim_process_disassoc_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_deauth_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_action_frame(tpAniSirGlobal, uint8_t *, tpPESession);
+void lim_process_action_frame_no_session(tpAniSirGlobal pMac, uint8_t *pRxMetaInfo);
+
+void lim_populate_p2p_mac_header(tpAniSirGlobal, uint8_t *);
+void lim_populate_mac_header(tpAniSirGlobal, uint8_t *, uint8_t, uint8_t,
+ tSirMacAddr, tSirMacAddr);
+tSirRetStatus lim_send_probe_req_mgmt_frame(tpAniSirGlobal, tSirMacSSid *,
+ tSirMacAddr, uint8_t, tSirMacAddr,
+ uint32_t, uint32_t, uint8_t *);
+void lim_send_probe_rsp_mgmt_frame(tpAniSirGlobal, tSirMacAddr, tpAniSSID, short,
+ uint8_t, tpPESession, uint8_t);
+void lim_send_auth_mgmt_frame(tpAniSirGlobal, tSirMacAuthFrameBody *, tSirMacAddr,
+ uint8_t, tpPESession);
+void lim_send_assoc_req_mgmt_frame(tpAniSirGlobal, tLimMlmAssocReq *, tpPESession);
+void lim_send_reassoc_req_mgmt_frame(tpAniSirGlobal, tLimMlmReassocReq *,
+ tpPESession);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+void lim_send_reassoc_req_with_ft_ies_mgmt_frame(tpAniSirGlobal pMac,
+ tLimMlmReassocReq *pMlmReassocReq,
+ tpPESession psessionEntry);
+#endif
+void lim_send_delts_req_action_frame(tpAniSirGlobal pMac, tSirMacAddr peer,
+ uint8_t wmmTspecPresent,
+ tSirMacTSInfo *pTsinfo,
+ tSirMacTspecIE *pTspecIe,
+ tpPESession psessionEntry);
+void lim_send_addts_req_action_frame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tSirAddtsReqInfo *addts, tpPESession);
+void lim_send_addts_rsp_action_frame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ uint16_t statusCode, tSirAddtsReqInfo *addts,
+ tSirMacScheduleIE *pSchedule, tpPESession);
+
+void lim_send_assoc_rsp_mgmt_frame(tpAniSirGlobal, uint16_t, uint16_t, tSirMacAddr,
+ uint8_t, tpDphHashNode pSta, tpPESession);
+
+void lim_send_disassoc_mgmt_frame(tpAniSirGlobal, uint16_t, tSirMacAddr,
+ tpPESession, bool waitForAck);
+void lim_send_deauth_mgmt_frame(tpAniSirGlobal, uint16_t, tSirMacAddr, tpPESession,
+ bool waitForAck);
+
+tSirResultCodes lim_mlm_add_bss(tpAniSirGlobal, tLimMlmStartReq *,
+ tpPESession psessionEntry);
+
+tSirRetStatus lim_send_channel_switch_mgmt_frame(tpAniSirGlobal, tSirMacAddr,
+ uint8_t, uint8_t, uint8_t,
+ tpPESession);
+
+#ifdef WLAN_FEATURE_11AC
+tSirRetStatus lim_send_vht_opmode_notification_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer, uint8_t nMode,
+ tpPESession psessionEntry);
+tSirRetStatus lim_send_vht_channel_switch_mgmt_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ uint8_t nChanWidth,
+ uint8_t nNewChannel,
+ uint8_t ncbMode,
+ tpPESession psessionEntry);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+tSirRetStatus lim_send_neighbor_report_request_frame(tpAniSirGlobal,
+ tpSirMacNeighborReportReq,
+ tSirMacAddr, tpPESession);
+tSirRetStatus lim_send_link_report_action_frame(tpAniSirGlobal, tpSirMacLinkReport,
+ tSirMacAddr, tpPESession);
+tSirRetStatus lim_send_radio_measure_report_action_frame(tpAniSirGlobal, uint8_t,
+ uint8_t,
+ tpSirMacRadioMeasureReport,
+ tSirMacAddr, tpPESession);
+#endif
+
+
+#ifdef FEATURE_WLAN_TDLS
+void lim_init_tdls_data(tpAniSirGlobal, tpPESession);
+tSirRetStatus lim_process_sme_tdls_mgmt_send_req(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf);
+tSirRetStatus lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf);
+tSirRetStatus lim_process_sme_tdls_link_establish_req(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf);
+tSirRetStatus lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
+ uint32_t *pMsgBuf);
+void lim_send_sme_tdls_delete_all_peer_ind(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+void lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint32_t txCompleteStatus);
+tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+CDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg, tpPESession);
+tSirRetStatus lim_send_tdls_teardown_frame(tpAniSirGlobal pMac,
+ tSirMacAddr peerMac, uint16_t reason,
+ uint8_t responder,
+ tpPESession psessionEntry,
+ uint8_t *addIe, uint16_t addIeLen);
+#endif
+
+/* Algorithms & Link Monitoring related functions */
+/* / Function that handles heartbeat failure */
+void lim_handle_heart_beat_failure(tpAniSirGlobal, tpPESession);
+
+/* / Function that triggers link tear down with AP upon HB failure */
+void lim_tear_down_link_with_ap(tpAniSirGlobal, uint8_t, tSirMacReasonCodes);
+
+/* / Function that processes Max retries interrupt from TFP */
+void limHandleMaxRetriesInterrupt(uint32_t);
+
+/* / Function that processes messages deferred during Learn mode */
+void lim_process_deferred_message_queue(tpAniSirGlobal);
+
+/* / Function that defers the messages received */
+uint32_t lim_defer_msg(tpAniSirGlobal, tSirMsgQ *);
+
+/* / Function that Switches the Channel and sets the CB Mode */
+void lim_set_channel(tpAniSirGlobal pMac, uint8_t channel,
+ uint8_t ch_center_freq_seg0, uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width, tPowerdBm maxTxPower,
+ uint8_t peSessionId);
+
+
+/* / Function that completes channel scan */
+void lim_complete_mlm_scan(tpAniSirGlobal, tSirResultCodes);
+
+#ifdef ANI_SUPPORT_11H
+/* / Function that sends Measurement Report action frame */
+tSirRetStatus lim_send_meas_report_frame(tpAniSirGlobal, tpSirMacMeasReqActionFrame,
+ tSirMacAddr, tpPESession psessionEntry);
+
+/* / Function that sends TPC Report action frame */
+tSirRetStatus lim_send_tpc_report_frame(tpAniSirGlobal, tpSirMacTpcReqActionFrame,
+ tSirMacAddr, tpPESession psessionEntry);
+#endif
+
+/* / Function that sends TPC Request action frame */
+void lim_send_tpc_request_frame(tpAniSirGlobal, tSirMacAddr,
+ tpPESession psessionEntry);
+
+/* Function(s) to handle responses received from HAL */
+void lim_process_mlm_add_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ);
+void lim_process_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQt,
+ tpPESession psessionEntry);
+void lim_process_mlm_del_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ);
+void lim_process_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession);
+void lim_process_sta_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+void lim_process_sta_mlm_del_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+void lim_process_sta_mlm_del_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+void lim_process_mlm_set_sta_key_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ);
+void lim_process_mlm_set_bss_key_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ);
+
+/* Function to process WMA_SWITCH_CHANNEL_RSP message */
+void lim_process_switch_channel_rsp(tpAniSirGlobal pMac, void *);
+
+void lim_covert_channel_scan_type(tpAniSirGlobal pMac, uint8_t channelNum,
+ bool passiveToActive);
+void lim_set_dfs_channel_list(tpAniSirGlobal pMac, uint8_t channelNum,
+ tSirDFSChannelList *dfsChannelList);
+void limContinueChannelLearn(tpAniSirGlobal);
+/* WLAN_SUSPEND_LINK Related */
+uint8_t lim_is_link_suspended(tpAniSirGlobal pMac);
+/* end WLAN_SUSPEND_LINK Related */
+
+#ifdef WLAN_FEATURE_11W
+/* 11w send SA query request action frame */
+tSirRetStatus lim_send_sa_query_request_frame(tpAniSirGlobal pMac, uint8_t *transId,
+ tSirMacAddr peer,
+ tpPESession psessionEntry);
+/* 11w SA query request action frame handler */
+tSirRetStatus lim_send_sa_query_response_frame(tpAniSirGlobal pMac,
+ uint8_t *transId, tSirMacAddr peer,
+ tpPESession psessionEntry);
+#endif
+
+/* Inline functions */
+
+/**
+ * lim_post_sme_message()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessMlmMessages(). In this
+ * function MLM sub-module invokes MLM ind/cnf primitives.
+ *
+ ***LOGIC:
+ * Initially MLM makes an SME function call to invoke MLM ind/cnf
+ * primitive. In future this can be enhanced to 'post' messages to SME.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM primitive message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+static inline void
+lim_post_sme_message(tpAniSirGlobal pMac, uint32_t msgType, uint32_t *pMsgBuf)
+{
+ tSirMsgQ msg;
+
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+
+ msg.type = (uint16_t) msgType;
+ msg.bodyptr = pMsgBuf;
+ msg.bodyval = 0;
+ if (msgType > eWNI_SME_MSG_TYPES_BEGIN)
+ lim_process_sme_req_messages(pMac, &msg);
+ else
+ lim_process_mlm_rsp_messages(pMac, msgType, pMsgBuf);
+} /*** end lim_post_sme_message() ***/
+
+/**
+ * lim_post_mlm_message()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages(). In this
+ * function SME invokes MLME primitives.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ * Initially SME makes an MLM function call to invoke MLM primitive.
+ * In future this can be enhanced to 'post' messages to MLM.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates the MLM primitive message type
+ * @param *pMsgBuf A pointer to the MLM message buffer
+ *
+ * @return None
+ */
+static inline void
+lim_post_mlm_message(tpAniSirGlobal pMac, uint32_t msgType, uint32_t *pMsgBuf)
+{
+
+ tSirMsgQ msg;
+ if (pMsgBuf == NULL) {
+ lim_log(pMac, LOGE, FL("Buffer is Pointing to NULL"));
+ return;
+ }
+ msg.type = (uint16_t) msgType;
+ msg.bodyptr = pMsgBuf;
+ msg.bodyval = 0;
+ lim_process_mlm_req_messages(pMac, &msg);
+} /*** end lim_post_mlm_message() ***/
+
+/**
+ * lim_get_current_scan_channel()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get current channel
+ * number being scanned.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return Channel number
+ */
+static inline uint8_t lim_get_current_scan_channel(tpAniSirGlobal pMac)
+{
+ uint8_t *pChanNum =
+ pMac->lim.gpLimMlmScanReq->channelList.channelNumber;
+
+ return *(pChanNum + pMac->lim.gLimCurrentScanChannelId);
+} /*** end lim_get_current_scan_channel() ***/
+
+/**
+ * lim_get_ielen_from_bss_description()
+ *
+ ***FUNCTION:
+ * This function is called in various places to get IE length
+ * from tSirBssDescription structure
+ * number being scanned.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pBssDescr
+ * @return Total IE length
+ */
+
+static inline uint16_t
+lim_get_ielen_from_bss_description(tpSirBssDescription pBssDescr)
+{
+ uint16_t ielen;
+
+ if (!pBssDescr)
+ return 0;
+
+ /*
+ * Length of BSS desription is without length of
+ * length itself and length of pointer
+ * that holds ieFields
+ *
+ * <------------sizeof(tSirBssDescription)-------------------->
+ * +--------+---------------------------------+---------------+
+ * | length | other fields | pointer to IEs|
+ * +--------+---------------------------------+---------------+
+ * ^
+ * ieFields
+ */
+
+ ielen = (uint16_t)(pBssDescr->length + sizeof(pBssDescr->length) -
+ GET_FIELD_OFFSET(tSirBssDescription, ieFields));
+
+ return ielen;
+} /*** end lim_get_ielen_from_bss_description() ***/
+
+/**
+ * lim_send_beacon_ind()
+ *
+ ***FUNCTION:
+ * This function is called to send the beacon indication
+ * number being scanned.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ */
+
+void lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry);
+
+void
+lim_send_vdev_restart(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint8_t sessionId);
+
+void lim_get_wpspbc_sessions(tpAniSirGlobal pMac, uint8_t *addr, uint8_t *uuid_e,
+ eWPSPBCOverlap *overlap, tpPESession psessionEntry);
+void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_wpspbc_close(tpAniSirGlobal pMac, tpPESession psessionEntry);
+void lim_remove_pbc_sessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,
+ tpPESession psessionEntry);
+
+#define LIM_WPS_OVERLAP_TIMER_MS 10000
+void
+lim_change_channel_with_callback(tpAniSirGlobal pMac, uint8_t newChannel,
+ CHANGE_CHANNEL_CALLBACK callback,
+ uint32_t *cbdata, tpPESession psessionEntry);
+
+void lim_send_sme_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
+ uint8_t *frame, uint32_t frameLen,
+ uint16_t sessionId, uint32_t rxChan,
+ tpPESession psessionEntry, int8_t rxRssi);
+void lim_process_remain_on_chn_timeout(tpAniSirGlobal pMac);
+void lim_process_insert_single_shot_noa_timeout(tpAniSirGlobal pMac);
+void lim_convert_active_channel_to_passive_channel(tpAniSirGlobal pMac);
+void lim_send_p2p_action_frame(tpAniSirGlobal pMac, tpSirMsgQ pMsg);
+void lim_abort_remain_on_chan(tpAniSirGlobal pMac, uint8_t sessionId,
+ uint32_t scan_id);
+tSirRetStatus __lim_process_sme_no_a_update(tpAniSirGlobal pMac, uint32_t *pMsgBuf);
+void lim_process_regd_defd_sme_req_after_noa_start(tpAniSirGlobal pMac);
+
+void lim_process_disassoc_ack_timeout(tpAniSirGlobal pMac);
+void lim_process_deauth_ack_timeout(tpAniSirGlobal pMac);
+CDF_STATUS lim_send_disassoc_cnf(tpAniSirGlobal pMac);
+CDF_STATUS lim_send_deauth_cnf(tpAniSirGlobal pMac);
+CDF_STATUS lim_disassoc_tx_complete_cnf(tpAniSirGlobal pMac,
+ uint32_t txCompleteSuccess);
+CDF_STATUS lim_deauth_tx_complete_cnf(tpAniSirGlobal pMac,
+ uint32_t txCompleteSuccess);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+typedef struct sSetLinkCbackParams {
+ void *cbackDataPtr;
+} tSetLinkCbackParams;
+#endif
+
+void lim_process_rx_scan_event(tpAniSirGlobal mac, void *buf);
+
+int lim_process_remain_on_chnl_req(tpAniSirGlobal pMac, uint32_t *pMsg);
+void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, CDF_STATUS status, uint32_t *data);
+
+/* / Bit value data structure */
+typedef enum sHalBitVal /* For Bit operations */
+{
+ eHAL_CLEAR,
+ eHAL_SET
+} tHalBitVal;
+
+enum {
+ eHI_PRI,
+ ePROT,
+ eDBG
+};
+
+#endif /* __LIM_TYPES_H */
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
new file mode 100644
index 0000000..d34c2a3
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -0,0 +1,7145 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_utils.cc contains the utility functions
+ * LIM uses.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "sch_api.h"
+#include "lim_utils.h"
+#include "lim_types.h"
+#include "lim_security_utils.h"
+#include "lim_prop_exts_utils.h"
+#include "lim_send_messages.h"
+#include "lim_ser_des_utils.h"
+#include "lim_admit_control.h"
+#include "lim_sta_hash_api.h"
+#include "dot11f.h"
+#include "dot11fdefs.h"
+#include "wmm_apsd.h"
+#include "lim_trace.h"
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+#include "host_diag_core_event.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_session_utils.h"
+#ifdef WLAN_FEATURE_VOWIFI_11R
+#include "lim_ft_defs.h"
+#endif
+#include "lim_session.h"
+#include "cds_reg_service.h"
+
+#ifdef WLAN_FEATURE_11W
+#include "wni_cfg.h"
+#endif
+#define ASCII_SPACE_CHARACTER 0x20
+
+#define SUCCESS 1
+
+#define MAX_BA_WINDOW_SIZE_FOR_CISCO 25
+
+/** -------------------------------------------------------------
+ \fn lim_delete_dialogue_token_list
+ \brief deletes the complete lim dialogue token linked list.
+ \param tpAniSirGlobal pMac
+ \return None
+ -------------------------------------------------------------*/
+void lim_delete_dialogue_token_list(tpAniSirGlobal pMac)
+{
+ tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead;
+
+ while (NULL != pMac->lim.pDialogueTokenHead) {
+ pCurrNode = pMac->lim.pDialogueTokenHead;
+ pMac->lim.pDialogueTokenHead =
+ pMac->lim.pDialogueTokenHead->next;
+ cdf_mem_free(pCurrNode);
+ pCurrNode = NULL;
+ }
+ pMac->lim.pDialogueTokenTail = NULL;
+}
+
+char *lim_dot11_reason_str(uint16_t reasonCode)
+{
+ switch (reasonCode) {
+ case 0:
+ return " ";
+ CASE_RETURN_STRING(eSIR_MAC_UNSPEC_FAILURE_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_PREV_AUTH_NOT_VALID_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON);
+ CASE_RETURN_STRING
+ (eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON);
+ CASE_RETURN_STRING
+ (eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_DISASSOC_LEAVING_BSS_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_PWR_CAPABILITY_BAD_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_SPRTD_CHANNELS_BAD_REASON);
+
+ CASE_RETURN_STRING(eSIR_MAC_INVALID_IE_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_MIC_FAILURE_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_RSN_IE_MISMATCH_REASON);
+
+ CASE_RETURN_STRING(eSIR_MAC_INVALID_MC_CIPHER_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_INVALID_UC_CIPHER_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_INVALID_AKMP_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_1X_AUTH_FAILURE_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_CIPHER_SUITE_REJECTED_REASON);
+#ifdef FEATURE_WLAN_TDLS
+ CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE);
+ CASE_RETURN_STRING(eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
+#endif
+ /* Reserved 27 - 30 */
+#ifdef WLAN_FEATURE_11W
+ CASE_RETURN_STRING
+ (eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION);
+#endif
+ CASE_RETURN_STRING(eSIR_MAC_QOS_UNSPECIFIED_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_QAP_NO_BANDWIDTH_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_XS_UNACKED_FRAMES_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_BAD_TXOP_USE_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_PEER_REJECT_MECHANISIM_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_MECHANISM_NOT_SETUP_REASON);
+
+ CASE_RETURN_STRING(eSIR_MAC_PEER_TIMEDOUT_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON);
+ CASE_RETURN_STRING(eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON);
+ /* Reserved 47 - 65535 */
+ default:
+ return "Unknown";
+ }
+}
+
+char *lim_mlm_state_str(tLimMlmStates state)
+{
+ switch (state) {
+ case eLIM_MLM_OFFLINE_STATE:
+ return "eLIM_MLM_OFFLINE_STATE";
+ case eLIM_MLM_IDLE_STATE:
+ return "eLIM_MLM_IDLE_STATE";
+ case eLIM_MLM_WT_PROBE_RESP_STATE:
+ return "eLIM_MLM_WT_PROBE_RESP_STATE";
+ case eLIM_MLM_PASSIVE_SCAN_STATE:
+ return "eLIM_MLM_PASSIVE_SCAN_STATE";
+ case eLIM_MLM_WT_JOIN_BEACON_STATE:
+ return "eLIM_MLM_WT_JOIN_BEACON_STATE";
+ case eLIM_MLM_JOINED_STATE:
+ return "eLIM_MLM_JOINED_STATE";
+ case eLIM_MLM_BSS_STARTED_STATE:
+ return "eLIM_MLM_BSS_STARTED_STATE";
+ case eLIM_MLM_WT_AUTH_FRAME2_STATE:
+ return "eLIM_MLM_WT_AUTH_FRAME2_STATE";
+ case eLIM_MLM_WT_AUTH_FRAME3_STATE:
+ return "eLIM_MLM_WT_AUTH_FRAME3_STATE";
+ case eLIM_MLM_WT_AUTH_FRAME4_STATE:
+ return "eLIM_MLM_WT_AUTH_FRAME4_STATE";
+ case eLIM_MLM_AUTH_RSP_TIMEOUT_STATE:
+ return "eLIM_MLM_AUTH_RSP_TIMEOUT_STATE";
+ case eLIM_MLM_AUTHENTICATED_STATE:
+ return "eLIM_MLM_AUTHENTICATED_STATE";
+ case eLIM_MLM_WT_ASSOC_RSP_STATE:
+ return "eLIM_MLM_WT_ASSOC_RSP_STATE";
+ case eLIM_MLM_WT_REASSOC_RSP_STATE:
+ return "eLIM_MLM_WT_REASSOC_RSP_STATE";
+ case eLIM_MLM_WT_FT_REASSOC_RSP_STATE:
+ return "eLIM_MLM_WT_FT_REASSOC_RSP_STATE";
+ case eLIM_MLM_WT_DEL_STA_RSP_STATE:
+ return "eLIM_MLM_WT_DEL_STA_RSP_STATE";
+ case eLIM_MLM_WT_DEL_BSS_RSP_STATE:
+ return "eLIM_MLM_WT_DEL_BSS_RSP_STATE";
+ case eLIM_MLM_WT_ADD_STA_RSP_STATE:
+ return "eLIM_MLM_WT_ADD_STA_RSP_STATE";
+ case eLIM_MLM_WT_ADD_BSS_RSP_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_STATE";
+ case eLIM_MLM_REASSOCIATED_STATE:
+ return "eLIM_MLM_REASSOCIATED_STATE";
+ case eLIM_MLM_LINK_ESTABLISHED_STATE:
+ return "eLIM_MLM_LINK_ESTABLISHED_STATE";
+ case eLIM_MLM_WT_ASSOC_CNF_STATE:
+ return "eLIM_MLM_WT_ASSOC_CNF_STATE";
+ case eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE";
+ case eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE";
+ case eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE:
+ return "eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE";
+ case eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE:
+ return "eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE";
+ case eLIM_MLM_WT_SET_BSS_KEY_STATE:
+ return "eLIM_MLM_WT_SET_BSS_KEY_STATE";
+ case eLIM_MLM_WT_SET_STA_KEY_STATE:
+ return "eLIM_MLM_WT_SET_STA_KEY_STATE";
+ default:
+ return "INVALID MLM state";
+ }
+}
+
+void
+lim_print_mlm_state(tpAniSirGlobal pMac, uint16_t logLevel, tLimMlmStates state)
+{
+ lim_log(pMac, logLevel, lim_mlm_state_str(state));
+}
+
+char *lim_sme_state_str(tLimSmeStates state)
+{
+ switch (state) {
+ case eLIM_SME_OFFLINE_STATE:
+ return "eLIM_SME_OFFLINE_STATE";
+ case eLIM_SME_IDLE_STATE:
+ return "eLIM_SME_OFFLINE_STATE";
+ case eLIM_SME_SUSPEND_STATE:
+ return "eLIM_SME_SUSPEND_STATE";
+ case eLIM_SME_WT_SCAN_STATE:
+ return "eLIM_SME_WT_SCAN_STATE";
+ case eLIM_SME_WT_JOIN_STATE:
+ return "eLIM_SME_WT_JOIN_STATE";
+ case eLIM_SME_WT_AUTH_STATE:
+ return "eLIM_SME_WT_AUTH_STATE";
+ case eLIM_SME_WT_ASSOC_STATE:
+ return "eLIM_SME_WT_ASSOC_STATE";
+ case eLIM_SME_WT_REASSOC_STATE:
+ return "eLIM_SME_WT_REASSOC_STATE";
+ case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE:
+ return "eLIM_SME_WT_REASSOC_LINK_FAIL_STATE";
+ case eLIM_SME_JOIN_FAILURE_STATE:
+ return "eLIM_SME_JOIN_FAILURE_STATE";
+ case eLIM_SME_ASSOCIATED_STATE:
+ return "eLIM_SME_ASSOCIATED_STATE";
+ case eLIM_SME_REASSOCIATED_STATE:
+ return "eLIM_SME_REASSOCIATED_STATE";
+ case eLIM_SME_LINK_EST_STATE:
+ return "eLIM_SME_LINK_EST_STATE";
+ case eLIM_SME_LINK_EST_WT_SCAN_STATE:
+ return "eLIM_SME_LINK_EST_WT_SCAN_STATE";
+ case eLIM_SME_WT_PRE_AUTH_STATE:
+ return "eLIM_SME_WT_PRE_AUTH_STATE";
+ case eLIM_SME_WT_DISASSOC_STATE:
+ return "eLIM_SME_WT_DISASSOC_STATE";
+ case eLIM_SME_WT_DEAUTH_STATE:
+ return "eLIM_SME_WT_DEAUTH_STATE";
+ case eLIM_SME_WT_START_BSS_STATE:
+ return "eLIM_SME_WT_START_BSS_STATE";
+ case eLIM_SME_WT_STOP_BSS_STATE:
+ return "eLIM_SME_WT_STOP_BSS_STATE";
+ case eLIM_SME_NORMAL_STATE:
+ return "eLIM_SME_NORMAL_STATE";
+ case eLIM_SME_CHANNEL_SCAN_STATE:
+ return "eLIM_SME_CHANNEL_SCAN_STATE";
+ case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE:
+ return "eLIM_SME_NORMAL_CHANNEL_SCAN_STATE";
+ default:
+ return "INVALID SME STATE";
+ }
+}
+
+void
+lim_print_sme_state(tpAniSirGlobal pMac, uint16_t logLevel, tLimSmeStates state)
+{
+ lim_log(pMac, logLevel, lim_sme_state_str(state));
+}
+
+char *lim_msg_str(uint32_t msgType)
+{
+#ifdef FIXME_GEN6
+ switch (msgType) {
+ case eWNI_SME_SYS_READY_IND:
+ return "eWNI_SME_SYS_READY_IND";
+ case eWNI_SME_SCAN_REQ:
+ return "eWNI_SME_SCAN_REQ";
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ case eWNI_SME_OEM_DATA_REQ:
+ return "eWNI_SME_OEM_DATA_REQ";
+ case eWNI_SME_OEM_DATA_RSP:
+ return "eWNI_SME_OEM_DATA_RSP";
+#endif
+ case eWNI_SME_SCAN_RSP:
+ return "eWNI_SME_SCAN_RSP";
+ case eWNI_SME_JOIN_REQ:
+ return "eWNI_SME_JOIN_REQ";
+ case eWNI_SME_JOIN_RSP:
+ return "eWNI_SME_JOIN_RSP";
+ case eWNI_SME_SETCONTEXT_REQ:
+ return "eWNI_SME_SETCONTEXT_REQ";
+ case eWNI_SME_SETCONTEXT_RSP:
+ return "eWNI_SME_SETCONTEXT_RSP";
+ case eWNI_SME_REASSOC_REQ:
+ return "eWNI_SME_REASSOC_REQ";
+ case eWNI_SME_REASSOC_RSP:
+ return "eWNI_SME_REASSOC_RSP";
+ case eWNI_SME_DISASSOC_REQ:
+ return "eWNI_SME_DISASSOC_REQ";
+ case eWNI_SME_DISASSOC_RSP:
+ return "eWNI_SME_DISASSOC_RSP";
+ case eWNI_SME_DISASSOC_IND:
+ return "eWNI_SME_DISASSOC_IND";
+ case eWNI_SME_DISASSOC_CNF:
+ return "eWNI_SME_DISASSOC_CNF";
+ case eWNI_SME_DEAUTH_REQ:
+ return "eWNI_SME_DEAUTH_REQ";
+ case eWNI_SME_DEAUTH_RSP:
+ return "eWNI_SME_DEAUTH_RSP";
+ case eWNI_SME_DEAUTH_IND:
+ return "eWNI_SME_DEAUTH_IND";
+ case eWNI_SME_WM_STATUS_CHANGE_NTF:
+ return "eWNI_SME_WM_STATUS_CHANGE_NTF";
+ case eWNI_SME_START_BSS_REQ:
+ return "eWNI_SME_START_BSS_REQ";
+ case eWNI_SME_START_BSS_RSP:
+ return "eWNI_SME_START_BSS_RSP";
+ case eWNI_SME_ASSOC_IND:
+ return "eWNI_SME_ASSOC_IND";
+ case eWNI_SME_ASSOC_CNF:
+ return "eWNI_SME_ASSOC_CNF";
+ case eWNI_SME_SWITCH_CHL_IND:
+ return "eWNI_SME_SWITCH_CHL_IND";
+ case eWNI_SME_STOP_BSS_REQ:
+ return "eWNI_SME_STOP_BSS_REQ";
+ case eWNI_SME_STOP_BSS_RSP:
+ return "eWNI_SME_STOP_BSS_RSP";
+ case eWNI_SME_NEIGHBOR_BSS_IND:
+ return "eWNI_SME_NEIGHBOR_BSS_IND";
+ case eWNI_SME_DEAUTH_CNF:
+ return "eWNI_SME_DEAUTH_CNF";
+ case eWNI_SME_ADDTS_REQ:
+ return "eWNI_SME_ADDTS_REQ";
+ case eWNI_SME_ADDTS_RSP:
+ return "eWNI_SME_ADDTS_RSP";
+ case eWNI_SME_DELTS_REQ:
+ return "eWNI_SME_DELTS_REQ";
+ case eWNI_SME_DELTS_RSP:
+ return "eWNI_SME_DELTS_RSP";
+ case eWNI_SME_DELTS_IND:
+ return "eWNI_SME_DELTS_IND";
+ case WMA_SUSPEND_ACTIVITY_RSP:
+ return "WMA_SUSPEND_ACTIVITY_RSP";
+ case SIR_LIM_RETRY_INTERRUPT_MSG:
+ return "SIR_LIM_RETRY_INTERRUPT_MSG";
+ case SIR_BB_XPORT_MGMT_MSG:
+ return "SIR_BB_XPORT_MGMT_MSG";
+ case SIR_LIM_INV_KEY_INTERRUPT_MSG:
+ return "SIR_LIM_INV_KEY_INTERRUPT_MSG";
+ case SIR_LIM_KEY_ID_INTERRUPT_MSG:
+ return "SIR_LIM_KEY_ID_INTERRUPT_MSG";
+ case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG:
+ return "SIR_LIM_REPLAY_THRES_INTERRUPT_MSG";
+ case SIR_LIM_JOIN_FAIL_TIMEOUT:
+ return "SIR_LIM_JOIN_FAIL_TIMEOUT";
+ case SIR_LIM_AUTH_FAIL_TIMEOUT:
+ return "SIR_LIM_AUTH_FAIL_TIMEOUT";
+ case SIR_LIM_AUTH_RSP_TIMEOUT:
+ return "SIR_LIM_AUTH_RSP_TIMEOUT";
+ case SIR_LIM_ASSOC_FAIL_TIMEOUT:
+ return "SIR_LIM_ASSOC_FAIL_TIMEOUT";
+ case SIR_LIM_REASSOC_FAIL_TIMEOUT:
+ return "SIR_LIM_REASSOC_FAIL_TIMEOUT";
+ case SIR_LIM_HEART_BEAT_TIMEOUT:
+ return "SIR_LIM_HEART_BEAT_TIMEOUT";
+ case SIR_LIM_ADDTS_RSP_TIMEOUT:
+ return "SIR_LIM_ADDTS_RSP_TIMEOUT";
+ case SIR_LIM_LINK_TEST_DURATION_TIMEOUT:
+ return "SIR_LIM_LINK_TEST_DURATION_TIMEOUT";
+ case SIR_LIM_HASH_MISS_THRES_TIMEOUT:
+ return "SIR_LIM_HASH_MISS_THRES_TIMEOUT";
+ case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT:
+ return "SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT";
+ case SIR_LIM_CNF_WAIT_TIMEOUT:
+ return "SIR_LIM_CNF_WAIT_TIMEOUT";
+ case SIR_LIM_RADAR_DETECT_IND:
+ return "SIR_LIM_RADAR_DETECT_IND";
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:
+ return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT";
+#endif
+
+ case WNI_CFG_PARAM_UPDATE_IND:
+ return "WNI_CFG_PARAM_UPDATE_IND";
+ case WNI_CFG_DNLD_REQ:
+ return "WNI_CFG_DNLD_REQ";
+ case WNI_CFG_DNLD_CNF:
+ return "WNI_CFG_DNLD_CNF";
+ case WNI_CFG_GET_RSP:
+ return "WNI_CFG_GET_RSP";
+ case WNI_CFG_SET_CNF:
+ return "WNI_CFG_SET_CNF";
+ case WNI_CFG_GET_ATTRIB_RSP:
+ return "WNI_CFG_GET_ATTRIB_RSP";
+ case WNI_CFG_ADD_GRP_ADDR_CNF:
+ return "WNI_CFG_ADD_GRP_ADDR_CNF";
+ case WNI_CFG_DEL_GRP_ADDR_CNF:
+ return "WNI_CFG_DEL_GRP_ADDR_CNF";
+ case ANI_CFG_GET_RADIO_STAT_RSP:
+ return "ANI_CFG_GET_RADIO_STAT_RSP";
+ case ANI_CFG_GET_PER_STA_STAT_RSP:
+ return "ANI_CFG_GET_PER_STA_STAT_RSP";
+ case ANI_CFG_GET_AGG_STA_STAT_RSP:
+ return "ANI_CFG_GET_AGG_STA_STAT_RSP";
+ case ANI_CFG_CLEAR_STAT_RSP:
+ return "ANI_CFG_CLEAR_STAT_RSP";
+ case WNI_CFG_DNLD_RSP:
+ return "WNI_CFG_DNLD_RSP";
+ case WNI_CFG_GET_REQ:
+ return "WNI_CFG_GET_REQ";
+ case WNI_CFG_SET_REQ:
+ return "WNI_CFG_SET_REQ";
+ case WNI_CFG_SET_REQ_NO_RSP:
+ return "WNI_CFG_SET_REQ_NO_RSP";
+ case eWNI_PMC_ENTER_IMPS_RSP:
+ return "eWNI_PMC_ENTER_IMPS_RSP";
+ case eWNI_PMC_EXIT_IMPS_RSP:
+ return "eWNI_PMC_EXIT_IMPS_RSP";
+ case eWNI_PMC_ENTER_BMPS_RSP:
+ return "eWNI_PMC_ENTER_BMPS_RSP";
+ case eWNI_PMC_EXIT_BMPS_RSP:
+ return "eWNI_PMC_EXIT_BMPS_RSP";
+ case eWNI_PMC_EXIT_BMPS_IND:
+ return "eWNI_PMC_EXIT_BMPS_IND";
+ case eWNI_SME_SET_BCN_FILTER_REQ:
+ return "eWNI_SME_SET_BCN_FILTER_REQ";
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+ case eWNI_SME_GET_TSM_STATS_REQ:
+ return "eWNI_SME_GET_TSM_STATS_REQ";
+ case eWNI_SME_GET_TSM_STATS_RSP:
+ return "eWNI_SME_GET_TSM_STATS_RSP";
+#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
+ case eWNI_SME_CSA_OFFLOAD_EVENT:
+ return "eWNI_SME_CSA_OFFLOAD_EVENT";
+ case eWNI_SME_SET_HW_MODE_REQ:
+ return "eWNI_SME_SET_HW_MODE_REQ";
+ case eWNI_SME_SET_HW_MODE_RESP:
+ return "eWNI_SME_SET_HW_MODE_RESP";
+ case eWNI_SME_HW_MODE_TRANS_IND:
+ return "eWNI_SME_HW_MODE_TRANS_IND";
+ default:
+ return "INVALID SME message";
+ }
+#endif
+ return "";
+}
+
+char *lim_result_code_str(tSirResultCodes resultCode)
+{
+ switch (resultCode) {
+ case eSIR_SME_SUCCESS:
+ return "eSIR_SME_SUCCESS";
+ case eSIR_LOGP_EXCEPTION:
+ return "eSIR_LOGP_EXCEPTION";
+ case eSIR_SME_INVALID_PARAMETERS:
+ return "eSIR_SME_INVALID_PARAMETERS";
+ case eSIR_SME_UNEXPECTED_REQ_RESULT_CODE:
+ return "eSIR_SME_UNEXPECTED_REQ_RESULT_CODE";
+ case eSIR_SME_RESOURCES_UNAVAILABLE:
+ return "eSIR_SME_RESOURCES_UNAVAILABLE";
+ case eSIR_SME_SCAN_FAILED:
+ return "eSIR_SME_SCAN_FAILED";
+ case eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED:
+ return "eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED";
+ case eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE:
+ return "eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE";
+ case eSIR_SME_REFUSED:
+ return "eSIR_SME_REFUSED";
+ case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_JOIN_TIMEOUT_RESULT_CODE";
+ case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_AUTH_TIMEOUT_RESULT_CODE";
+ case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE";
+ case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE:
+ return "eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE";
+ case eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED:
+ return "eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED";
+ case eSIR_SME_AUTH_REFUSED:
+ return "eSIR_SME_AUTH_REFUSED";
+ case eSIR_SME_INVALID_WEP_DEFAULT_KEY:
+ return "eSIR_SME_INVALID_WEP_DEFAULT_KEY";
+ case eSIR_SME_ASSOC_REFUSED:
+ return "eSIR_SME_ASSOC_REFUSED";
+ case eSIR_SME_REASSOC_REFUSED:
+ return "eSIR_SME_REASSOC_REFUSED";
+ case eSIR_SME_STA_NOT_AUTHENTICATED:
+ return "eSIR_SME_STA_NOT_AUTHENTICATED";
+ case eSIR_SME_STA_NOT_ASSOCIATED:
+ return "eSIR_SME_STA_NOT_ASSOCIATED";
+ case eSIR_SME_ALREADY_JOINED_A_BSS:
+ return "eSIR_SME_ALREADY_JOINED_A_BSS";
+ case eSIR_SME_MORE_SCAN_RESULTS_FOLLOW:
+ return "eSIR_SME_MORE_SCAN_RESULTS_FOLLOW";
+ case eSIR_SME_INVALID_ASSOC_RSP_RXED:
+ return "eSIR_SME_INVALID_ASSOC_RSP_RXED";
+ case eSIR_SME_MIC_COUNTER_MEASURES:
+ return "eSIR_SME_MIC_COUNTER_MEASURES";
+ case eSIR_SME_ADDTS_RSP_TIMEOUT:
+ return "eSIR_SME_ADDTS_RSP_TIMEOUT";
+ case eSIR_SME_CHANNEL_SWITCH_FAIL:
+ return "eSIR_SME_CHANNEL_SWITCH_FAIL";
+ case eSIR_SME_HAL_SCAN_INIT_FAILED:
+ return "eSIR_SME_HAL_SCAN_INIT_FAILED";
+ case eSIR_SME_HAL_SCAN_END_FAILED:
+ return "eSIR_SME_HAL_SCAN_END_FAILED";
+ case eSIR_SME_HAL_SCAN_FINISH_FAILED:
+ return "eSIR_SME_HAL_SCAN_FINISH_FAILED";
+ case eSIR_SME_HAL_SEND_MESSAGE_FAIL:
+ return "eSIR_SME_HAL_SEND_MESSAGE_FAIL";
+
+ default:
+ return "INVALID resultCode";
+ }
+}
+
+void lim_print_msg_name(tpAniSirGlobal pMac, uint16_t logLevel, uint32_t msgType)
+{
+ lim_log(pMac, logLevel, lim_msg_str(msgType));
+}
+
+/**
+ * lim_init_mlm()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to
+ * initialize MLM state machine on STA
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+void lim_init_mlm(tpAniSirGlobal pMac)
+{
+ uint32_t retVal;
+
+ pMac->lim.gLimTimersCreated = 0;
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
+ pMac->lim.gLimMlmState));
+
+
+ /* / Initialize number of pre-auth contexts */
+ pMac->lim.gLimNumPreAuthContexts = 0;
+
+ /* / Initialize MAC based Authentication STA list */
+ lim_init_pre_auth_list(pMac);
+
+ /* Create timers used by LIM */
+ retVal = lim_create_timers(pMac);
+ if (retVal == TX_SUCCESS) {
+ pMac->lim.gLimTimersCreated = 1;
+ } else {
+ lim_log(pMac, LOGP,
+ FL(" lim_create_timers Failed to create lim timers "));
+ }
+} /*** end lim_init_mlm() ***/
+
+/**
+ * lim_deactivate_del_sta() - This function deactivate/delete associates STA
+ * @mac_ctx: pointer to Global Mac Structure
+ * @bss_entry: index for bss_entry
+ * @psession_entry: pointer to session entry
+ * @sta_ds: pointer to tpDphHashNode
+ *
+ * Function deactivate/delete associates STA
+ *
+ * Return: none
+ */
+static void lim_deactivate_del_sta(tpAniSirGlobal mac_ctx, uint32_t bss_entry,
+ tpPESession psession_entry, tpDphHashNode sta_ds)
+{
+ uint32_t sta_entry;
+
+ for (sta_entry = 1; sta_entry < mac_ctx->lim.gLimAssocStaLimit;
+ sta_entry++) {
+ psession_entry = &mac_ctx->lim.gpSession[bss_entry];
+ sta_ds = dph_get_hash_entry(mac_ctx, sta_entry,
+ &psession_entry->dph.dphHashTable);
+ if (NULL == sta_ds)
+ continue;
+
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ FL("Deleting pmfSaQueryTimer for staid[%d]"),
+ sta_ds->staIndex);
+ tx_timer_deactivate(&sta_ds->pmfSaQueryTimer);
+ tx_timer_delete(&sta_ds->pmfSaQueryTimer);
+ }
+}
+
+/**
+ * lim_cleanup_mlm() - This function is called to cleanup
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * Function is called to cleanup any resources allocated by the MLM
+ * state machine.
+ *
+ * Return: none
+ */
+void lim_cleanup_mlm(tpAniSirGlobal mac_ctx)
+{
+ uint32_t n;
+ tLimPreAuthNode *pAuthNode;
+#ifdef WLAN_FEATURE_11W
+ uint32_t bss_entry;
+ tpDphHashNode sta_ds = NULL;
+ tpPESession psession_entry = NULL;
+#endif
+ tLimTimers *lim_timer = NULL;
+
+ if (mac_ctx->lim.gLimTimersCreated == 1) {
+ lim_timer = &mac_ctx->lim.limTimers;
+
+ /* Deactivate and delete Periodic Probe channel timers. */
+ tx_timer_deactivate(&lim_timer->gLimPeriodicProbeReqTimer);
+ tx_timer_delete(&lim_timer->gLimPeriodicProbeReqTimer);
+
+ /* Deactivate and delete channel switch timer. */
+ tx_timer_deactivate(&lim_timer->gLimChannelSwitchTimer);
+ tx_timer_delete(&lim_timer->gLimChannelSwitchTimer);
+
+ /* Deactivate and delete addts response timer. */
+ tx_timer_deactivate(&lim_timer->gLimAddtsRspTimer);
+ tx_timer_delete(&lim_timer->gLimAddtsRspTimer);
+
+ /* Deactivate and delete Join failure timer. */
+ tx_timer_deactivate(&lim_timer->gLimJoinFailureTimer);
+ tx_timer_delete(&lim_timer->gLimJoinFailureTimer);
+
+ /* Deactivate and delete Periodic Join Probe Request timer. */
+ tx_timer_deactivate(&lim_timer->gLimPeriodicJoinProbeReqTimer);
+ tx_timer_delete(&lim_timer->gLimPeriodicJoinProbeReqTimer);
+
+ /* Deactivate and delete Association failure timer. */
+ tx_timer_deactivate(&lim_timer->gLimAssocFailureTimer);
+ tx_timer_delete(&lim_timer->gLimAssocFailureTimer);
+
+ /* Deactivate and delete Reassociation failure timer. */
+ tx_timer_deactivate(&lim_timer->gLimReassocFailureTimer);
+ tx_timer_delete(&lim_timer->gLimReassocFailureTimer);
+
+ /* Deactivate and delete Authentication failure timer. */
+ tx_timer_deactivate(&lim_timer->gLimAuthFailureTimer);
+ tx_timer_delete(&lim_timer->gLimAuthFailureTimer);
+
+ /* Deactivate and delete wait-for-probe-after-Heartbeat timer. */
+ tx_timer_deactivate(&lim_timer->gLimProbeAfterHBTimer);
+ tx_timer_delete(&lim_timer->gLimProbeAfterHBTimer);
+
+ /* Deactivate and delete Quiet timer. */
+ tx_timer_deactivate(&lim_timer->gLimQuietTimer);
+ tx_timer_delete(&lim_timer->gLimQuietTimer);
+
+ /* Deactivate and delete Quiet BSS timer. */
+ tx_timer_deactivate(&lim_timer->gLimQuietBssTimer);
+ tx_timer_delete(&lim_timer->gLimQuietBssTimer);
+
+ /* Deactivate and delete cnf wait timer */
+ for (n = 0; n < (mac_ctx->lim.maxStation + 1); n++) {
+ tx_timer_deactivate(&lim_timer->gpLimCnfWaitTimer[n]);
+ tx_timer_delete(&lim_timer->gpLimCnfWaitTimer[n]);
+ }
+
+ pAuthNode = mac_ctx->lim.gLimPreAuthTimerTable.pTable;
+
+ /* Deactivate any Authentication response timers */
+ lim_delete_pre_auth_list(mac_ctx);
+
+ for (n = 0; n < mac_ctx->lim.gLimPreAuthTimerTable.numEntry;
+ n++, pAuthNode++) {
+ /*
+ * Delete any Authentication response
+ * timers, which might have been started.
+ */
+ tx_timer_delete(&pAuthNode->timer);
+ }
+
+ /* Deactivate and delete Hash Miss throttle timer */
+ tx_timer_deactivate(&lim_timer->
+ gLimSendDisassocFrameThresholdTimer);
+ tx_timer_delete(&lim_timer->
+ gLimSendDisassocFrameThresholdTimer);
+
+ tx_timer_deactivate(&lim_timer->gLimUpdateOlbcCacheTimer);
+ tx_timer_delete(&lim_timer->gLimUpdateOlbcCacheTimer);
+ tx_timer_deactivate(&lim_timer->gLimPreAuthClnupTimer);
+ tx_timer_delete(&lim_timer->gLimPreAuthClnupTimer);
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ /* Deactivate and delete FT Preauth response timer */
+ tx_timer_deactivate(&lim_timer->gLimFTPreAuthRspTimer);
+ tx_timer_delete(&lim_timer->gLimFTPreAuthRspTimer);
+#endif
+
+ /* Deactivate and delete remain on channel timer */
+ tx_timer_deactivate(&lim_timer->gLimRemainOnChannelTimer);
+ tx_timer_delete(&lim_timer->gLimRemainOnChannelTimer);
+
+
+ tx_timer_deactivate(&lim_timer->gLimDisassocAckTimer);
+ tx_timer_delete(&lim_timer->gLimDisassocAckTimer);
+
+ tx_timer_deactivate(&lim_timer->gLimDeauthAckTimer);
+ tx_timer_delete(&lim_timer->gLimDeauthAckTimer);
+
+ tx_timer_deactivate(&lim_timer->
+ gLimP2pSingleShotNoaInsertTimer);
+ tx_timer_delete(&lim_timer->
+ gLimP2pSingleShotNoaInsertTimer);
+
+ tx_timer_deactivate(&lim_timer->
+ gLimActiveToPassiveChannelTimer);
+ tx_timer_delete(&lim_timer->
+ gLimActiveToPassiveChannelTimer);
+
+ mac_ctx->lim.gLimTimersCreated = 0;
+ }
+#ifdef WLAN_FEATURE_11W
+ /*
+ * When SSR is triggered, we need to loop through
+ * each STA associated per BSSId and deactivate/delete
+ * the pmfSaQueryTimer for it
+ */
+ if (cds_is_logp_in_progress()) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_ERROR,
+ FL("SSR is detected, proceed to clean up pmfSaQueryTimer"));
+ for (bss_entry = 0; bss_entry < mac_ctx->lim.maxBssId;
+ bss_entry++) {
+ if (!mac_ctx->lim.gpSession[bss_entry].valid)
+ continue;
+ lim_deactivate_del_sta(mac_ctx, bss_entry,
+ psession_entry, sta_ds);
+ }
+ }
+#endif
+
+} /*** end lim_cleanup_mlm() ***/
+
+/**
+ * lim_cleanup_lmm()
+ *
+ ***FUNCTION:
+ * This function is called to cleanup any resources
+ * allocated by LMM sub-module.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @return None
+ */
+
+void lim_cleanup_lmm(tpAniSirGlobal pMac)
+{
+} /*** end lim_cleanup_lmm() ***/
+
+/**
+ * lim_is_addr_bc()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed MAC address is a broadcast or not
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param macAddr Indicates MAC address that need to be determined
+ * whether it is Broadcast address or not
+ *
+ * @return true if passed address is Broadcast address else false
+ */
+
+uint8_t lim_is_addr_bc(tSirMacAddr macAddr)
+{
+ int i;
+ for (i = 0; i < 6; i++) {
+ if ((macAddr[i] & 0xFF) != 0xFF)
+ return false;
+ }
+
+ return true;
+} /****** end lim_is_addr_bc() ******/
+
+/**
+ * lim_is_group_addr()
+ *
+ ***FUNCTION:
+ * This function is called in various places within LIM code
+ * to determine whether passed MAC address is a group address or not
+ *
+ ***LOGIC:
+ * If least significant bit of first octet of the MAC address is
+ * set to 1, it is a Group address.
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param macAddr Indicates MAC address that need to be determined
+ * whether it is Group address or not
+ *
+ * @return true if passed address is Group address else false
+ */
+
+uint8_t lim_is_group_addr(tSirMacAddr macAddr)
+{
+ if ((macAddr[0] & 0x01) == 0x01)
+ return true;
+ else
+ return false;
+} /****** end lim_is_group_addr() ******/
+
+/**
+ * lim_print_mac_addr()
+ *
+ ***FUNCTION:
+ * This function is called to print passed MAC address
+ * in : format.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * @param macAddr - MacAddr to be printed
+ * @param logLevel - Loglevel to be used
+ *
+ * @return None.
+ */
+
+void lim_print_mac_addr(tpAniSirGlobal pMac, tSirMacAddr macAddr, uint8_t logLevel)
+{
+ lim_log(pMac, logLevel, FL(MAC_ADDRESS_STR), MAC_ADDR_ARRAY(macAddr));
+} /****** end lim_print_mac_addr() ******/
+
+/*
+ * lim_reset_deferred_msg_q()
+ *
+ ***FUNCTION:
+ * This function resets the deferred message queue parameters.
+ *
+ ***PARAMS:
+ * @param pMac - Pointer to Global MAC structure
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ ***RETURNS:
+ * None
+ */
+
+void lim_reset_deferred_msg_q(tpAniSirGlobal pMac)
+{
+ pMac->lim.gLimDeferredMsgQ.size =
+ pMac->lim.gLimDeferredMsgQ.write =
+ pMac->lim.gLimDeferredMsgQ.read = 0;
+
+}
+
+#define LIM_DEFERRED_Q_CHECK_THRESHOLD (MAX_DEFERRED_QUEUE_LEN/2)
+#define LIM_MAX_NUM_MGMT_FRAME_DEFERRED (MAX_DEFERRED_QUEUE_LEN/2)
+
+/**
+ * lim_write_deferred_msg_q() - This function queues up a deferred message
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ * @lim_msg: a LIM message
+ *
+ * Function queues up a deferred message for later processing on the
+ * STA side.
+ *
+ * Return: none
+ */
+
+uint8_t lim_write_deferred_msg_q(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg)
+{
+ lim_log(mac_ctx, LOG1,
+ FL("Queue a deferred message (size %d, write %d) - type 0x%x "),
+ mac_ctx->lim.gLimDeferredMsgQ.size,
+ mac_ctx->lim.gLimDeferredMsgQ.write,
+ lim_msg->type);
+
+ /* check if the deferred message queue is full */
+ if (mac_ctx->lim.gLimDeferredMsgQ.size >= MAX_DEFERRED_QUEUE_LEN) {
+ if (!(mac_ctx->lim.deferredMsgCnt & 0xF)) {
+ lim_log(mac_ctx, LOGE,
+ FL("queue->MsgQ full Msg:%d Msgs Failed:%d"),
+ lim_msg->type,
+ ++mac_ctx->lim.deferredMsgCnt);
+ } else {
+ mac_ctx->lim.deferredMsgCnt++;
+ }
+ return TX_QUEUE_FULL;
+ }
+
+ /*
+ * In the application, there should not be more than 1 message get
+ * queued up. If happens, flags a warning. In the future, this can
+ * happen.
+ */
+ if (mac_ctx->lim.gLimDeferredMsgQ.size > 0)
+ lim_log(mac_ctx, LOGW,
+ FL("%d Deferred Msg (type 0x%x, scan %d, global sme %d, global mlme %d, addts %d)"),
+ mac_ctx->lim.gLimDeferredMsgQ.size,
+ lim_msg->type,
+ lim_is_system_in_scan_state(mac_ctx),
+ mac_ctx->lim.gLimSmeState,
+ mac_ctx->lim.gLimMlmState,
+ mac_ctx->lim.gLimAddtsSent);
+
+ /*
+ * To prevent the deferred Q is full of management frames, only give
+ * them certain space
+ */
+ if ((SIR_BB_XPORT_MGMT_MSG == lim_msg->type) &&
+ (LIM_DEFERRED_Q_CHECK_THRESHOLD <
+ mac_ctx->lim.gLimDeferredMsgQ.size)) {
+ uint16_t idx, count = 0;
+ for (idx = 0; idx < mac_ctx->lim.gLimDeferredMsgQ.size;
+ idx++) {
+ if (SIR_BB_XPORT_MGMT_MSG ==
+ mac_ctx->lim.gLimDeferredMsgQ.
+ deferredQueue[idx].type) {
+ count++;
+ }
+ }
+ if (LIM_MAX_NUM_MGMT_FRAME_DEFERRED < count) {
+ /*
+ * We reach the quota for management frames,
+ * drop this one
+ */
+ lim_log(mac_ctx, LOGW,
+ FL("Too many queue->MsgQ Msg: %d (count=%d)"),
+ lim_msg->type, count);
+ /* Return error, caller knows what to do */
+ return TX_QUEUE_FULL;
+ }
+ }
+
+ ++mac_ctx->lim.gLimDeferredMsgQ.size;
+
+ /* reset the count here since we are able to defer the message */
+ if (mac_ctx->lim.deferredMsgCnt != 0)
+ mac_ctx->lim.deferredMsgCnt = 0;
+
+ /* if the write pointer hits the end of the queue, rewind it */
+ if (mac_ctx->lim.gLimDeferredMsgQ.write >= MAX_DEFERRED_QUEUE_LEN)
+ mac_ctx->lim.gLimDeferredMsgQ.write = 0;
+
+ /* save the message to the queue and advanced the write pointer */
+ cdf_mem_copy((uint8_t *) &mac_ctx->lim.gLimDeferredMsgQ.
+ deferredQueue[mac_ctx->lim.gLimDeferredMsgQ.write++],
+ (uint8_t *) lim_msg, sizeof(tSirMsgQ));
+ return TX_SUCCESS;
+
+}
+
+/*
+ * lim_read_deferred_msg_q()
+ *
+ ***FUNCTION:
+ * This function dequeues a deferred message for processing on the
+ * STA side.
+ *
+ ***PARAMS:
+ * @param pMac - Pointer to Global MAC structure
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ *
+ ***RETURNS:
+ * Returns the message at the head of the deferred message queue
+ */
+
+tSirMsgQ *lim_read_deferred_msg_q(tpAniSirGlobal pMac)
+{
+ tSirMsgQ *msg;
+
+ /*
+ ** check any messages left. If no, return
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.size <= 0)
+ return NULL;
+
+ /*
+ ** decrement the queue size
+ **/
+ pMac->lim.gLimDeferredMsgQ.size--;
+
+ /*
+ ** retrieve the message from the head of the queue
+ **/
+ msg =
+ &pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.
+ gLimDeferredMsgQ.read];
+
+ /*
+ ** advance the read pointer
+ **/
+ pMac->lim.gLimDeferredMsgQ.read++;
+
+ /*
+ ** if the read pointer hits the end of the queue, rewind it
+ **/
+ if (pMac->lim.gLimDeferredMsgQ.read >= MAX_DEFERRED_QUEUE_LEN)
+ pMac->lim.gLimDeferredMsgQ.read = 0;
+
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("** DeQueue a deferred message (size %d read %d) - type 0x%x **"),
+ pMac->lim.gLimDeferredMsgQ.size,
+ pMac->lim.gLimDeferredMsgQ.read, msg->type);
+ )
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("DQ msg -- scan %d, global sme %d, global mlme %d, addts %d"),
+ lim_is_system_in_scan_state(pMac), pMac->lim.gLimSmeState,
+ pMac->lim.gLimMlmState, pMac->lim.gLimAddtsSent);
+ )
+
+ return msg;
+}
+
+tSirRetStatus
+lim_sys_process_mmh_msg_api(tpAniSirGlobal pMac, tSirMsgQ *pMsg, uint8_t qType)
+{
+ /* FIXME */
+ sys_process_mmh_msg(pMac, pMsg);
+ return eSIR_SUCCESS;
+}
+
+/*
+ * lim_handle_update_olbc_cache() - This function update olbc cache
+ *
+ * @mac_ctx: Pointer to Global MAC structure
+ *
+ * Function updates olbc cache
+ *
+ * Return: none
+ */
+void lim_handle_update_olbc_cache(tpAniSirGlobal mac_ctx)
+{
+ int i;
+ static int enable;
+ tUpdateBeaconParams beaconParams;
+
+ tpPESession psessionEntry = lim_is_ap_session_active(mac_ctx);
+
+ if (psessionEntry == NULL) {
+ lim_log(mac_ctx, LOGE, FL(" Session not found"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
+ beaconParams.bssIdx = psessionEntry->bssIdx;
+
+ beaconParams.paramChangeBitmap = 0;
+ /*
+ * This is doing a 2 pass check. The first pass is to invalidate
+ * all the cache entries. The second pass is to decide whether to
+ * disable protection.
+ */
+ if (!enable) {
+ lim_log(mac_ctx, LOG2, FL("Resetting OLBC cache"));
+ psessionEntry->gLimOlbcParams.numSta = 0;
+ psessionEntry->gLimOverlap11gParams.numSta = 0;
+ psessionEntry->gLimOverlapHt20Params.numSta = 0;
+ psessionEntry->gLimNonGfParams.numSta = 0;
+ psessionEntry->gLimLsigTxopParams.numSta = 0;
+
+ for (i = 0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++)
+ mac_ctx->lim.protStaOverlapCache[i].active = false;
+
+ enable = 1;
+ } else {
+ if ((!psessionEntry->gLimOlbcParams.numSta) &&
+ (psessionEntry->gLimOlbcParams.protectionEnabled) &&
+ (!psessionEntry->gLim11bParams.protectionEnabled)) {
+ lim_log(mac_ctx, LOG1,
+ FL("Overlap cache clear and no 11B STA set"));
+ lim_enable11g_protection(mac_ctx, false, true,
+ &beaconParams,
+ psessionEntry);
+ }
+
+ if ((!psessionEntry->gLimOverlap11gParams.numSta) &&
+ (psessionEntry->gLimOverlap11gParams.protectionEnabled)
+ && (!psessionEntry->gLim11gParams.protectionEnabled)) {
+ lim_log(mac_ctx, LOG1,
+ FL("Overlap cache clear and no 11G STA set"));
+ lim_enable_ht_protection_from11g(mac_ctx, false, true,
+ &beaconParams,
+ psessionEntry);
+ }
+
+ if ((!psessionEntry->gLimOverlapHt20Params.numSta) &&
+ (psessionEntry->gLimOverlapHt20Params.protectionEnabled)
+ && (!psessionEntry->gLimHt20Params.protectionEnabled)) {
+ lim_log(mac_ctx, LOG1,
+ FL("Overlap cache clear and no HT20 STA set"));
+ lim_enable11g_protection(mac_ctx, false, true,
+ &beaconParams,
+ psessionEntry);
+ }
+
+ enable = 0;
+ }
+
+ if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+ && beaconParams.paramChangeBitmap) {
+ sch_set_fixed_beacon_fields(mac_ctx, psessionEntry);
+ lim_send_beacon_params(mac_ctx, &beaconParams, psessionEntry);
+ }
+ /* Start OLBC timer */
+ if (tx_timer_activate(&mac_ctx->lim.limTimers.gLimUpdateOlbcCacheTimer)
+ != TX_SUCCESS)
+ lim_log(mac_ctx, LOGE, FL("tx_timer_activate failed"));
+}
+
+/**
+ * lim_is_null_ssid() - This function checks if ssid supplied is Null SSID
+ * @ssid: pointer to tSirMacSSid
+ *
+ * Function checks if ssid supplied is Null SSID
+ *
+ * Return: none
+ */
+
+uint8_t lim_is_null_ssid(tSirMacSSid *ssid)
+{
+ uint8_t fnull_ssid = false;
+ uint32_t ssid_len;
+ uint8_t *ssid_str;
+
+ if (0 == ssid->length) {
+ fnull_ssid = true;
+ return fnull_ssid;
+ }
+ /* If the first charactes is space, then check if all
+ * characters in SSID are spaces to consider it as NULL SSID
+ */
+ if ((ASCII_SPACE_CHARACTER == ssid->ssId[0]) &&
+ (ssid->length == 1)){
+ fnull_ssid = true;
+ return fnull_ssid;
+ } else {
+ /* check if all the charactes in SSID are NULL */
+ ssid_len = ssid->length;
+ ssid_str = ssid->ssId;
+
+ while (ssid_len) {
+ if (*ssid_str)
+ return fnull_ssid;
+
+ ssid_str++;
+ ssid_len--;
+ }
+
+ if (0 == ssid_len) {
+ fnull_ssid = true;
+ return fnull_ssid;
+ }
+ }
+
+ return fnull_ssid;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_update_prot_sta_params
+ \brief updates protection related counters.
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr peerMacAddr
+ \param tLimProtStaCacheType protStaCacheType
+ \param tHalBitVal gfSupported
+ \param tHalBitVal lsigTxopSupported
+ \return None
+ -------------------------------------------------------------*/
+void
+lim_update_prot_sta_params(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tLimProtStaCacheType protStaCacheType,
+ tHalBitVal gfSupported, tHalBitVal lsigTxopSupported,
+ tpPESession psessionEntry)
+{
+ uint32_t i;
+
+ PELOG1(lim_log(pMac, LOG1, FL("A STA is associated:"));
+ lim_log(pMac, LOG1, FL("Addr : "));
+ lim_print_mac_addr(pMac, peerMacAddr, LOG1);
+ )
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (psessionEntry->protStaCache[i].active) {
+ PELOG1(lim_log(pMac, LOG1, FL("Addr: "));)
+ PELOG1(lim_print_mac_addr
+ (pMac, psessionEntry->protStaCache[i].addr,
+ LOG1);
+ )
+
+ if (cdf_mem_compare
+ (psessionEntry->protStaCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr))) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("matching cache entry at %d already active."),
+ i);
+ )
+ return;
+ }
+ }
+ }
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (!psessionEntry->protStaCache[i].active)
+ break;
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE) {
+ PELOGE(lim_log(pMac, LOGE, FL("No space in ProtStaCache"));)
+ return;
+ }
+
+ cdf_mem_copy(psessionEntry->protStaCache[i].addr,
+ peerMacAddr, sizeof(tSirMacAddr));
+
+ psessionEntry->protStaCache[i].protStaCacheType = protStaCacheType;
+ psessionEntry->protStaCache[i].active = true;
+ if (eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) {
+ psessionEntry->gLim11bParams.numSta++;
+ lim_log(pMac, LOG1, FL("11B, "));
+ } else if (eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) {
+ psessionEntry->gLim11gParams.numSta++;
+ lim_log(pMac, LOG1, FL("11G, "));
+ } else if (eLIM_PROT_STA_CACHE_TYPE_HT20 == protStaCacheType) {
+ psessionEntry->gLimHt20Params.numSta++;
+ lim_log(pMac, LOG1, FL("HT20, "));
+ }
+
+ if (!gfSupported) {
+ psessionEntry->gLimNonGfParams.numSta++;
+ lim_log(pMac, LOG1, FL("NonGf, "));
+ }
+ if (!lsigTxopSupported) {
+ psessionEntry->gLimLsigTxopParams.numSta++;
+ lim_log(pMac, LOG1, FL("!lsigTxopSupported"));
+ }
+} /* --------------------------------------------------------------------- */
+
+/** -------------------------------------------------------------
+ \fn lim_decide_ap_protection
+ \brief Decides all the protection related staiton coexistence and also sets
+ \ short preamble and short slot appropriately. This function will be called
+ \ when AP is ready to send assocRsp tp the station joining right now.
+ \param tpAniSirGlobal pMac
+ \param tSirMacAddr peerMacAddr
+ \return None
+ -------------------------------------------------------------*/
+void
+lim_decide_ap_protection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ uint16_t tmpAid;
+ tpDphHashNode pStaDs;
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ uint32_t phyMode;
+ tLimProtStaCacheType protStaCacheType =
+ eLIM_PROT_STA_CACHE_TYPE_INVALID;
+ tHalBitVal gfSupported = eHAL_SET, lsigTxopSupported = eHAL_SET;
+
+ pBeaconParams->paramChangeBitmap = 0;
+ /* check whether to enable protection or not */
+ pStaDs =
+ dph_lookup_hash_entry(pMac, peerMacAddr, &tmpAid,
+ &psessionEntry->dph.dphHashTable);
+ if (NULL == pStaDs) {
+ PELOG1(lim_log(pMac, LOG1, FL("pStaDs is NULL"));)
+ return;
+ }
+ lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+ /* if we are in 5 GHZ band */
+ if (SIR_BAND_5_GHZ == rfBand) {
+ /* We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ. */
+ /* HT20 case is common between both the bands and handled down as common code. */
+ if (true == psessionEntry->htCapability) {
+ /* we are 11N and 11A station is joining. */
+ /* protection from 11A required. */
+ if (false == pStaDs->mlmStaContext.htCapability) {
+ lim_update_11a_protection(pMac, true, false,
+ pBeaconParams,
+ psessionEntry);
+ return;
+ }
+ }
+ } else if (SIR_BAND_2_4_GHZ == rfBand) {
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ /* We are 11G. Check if we need protection from 11b Stations. */
+ if ((phyMode == WNI_CFG_PHY_MODE_11G) &&
+ (false == psessionEntry->htCapability)) {
+
+ if (pStaDs->erpEnabled == eHAL_CLEAR) {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+ /* enable protection */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("Enabling protection from 11B"));
+ )
+ lim_enable11g_protection(pMac, true, false,
+ pBeaconParams,
+ psessionEntry);
+ }
+ }
+ /* HT station. */
+ if (true == psessionEntry->htCapability) {
+ /* check if we need protection from 11b station */
+ if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
+ (!pStaDs->mlmStaContext.htCapability)) {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
+ /* enable protection */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("Enabling protection from 11B"));
+ )
+ lim_enable11g_protection(pMac, true, false,
+ pBeaconParams,
+ psessionEntry);
+ }
+ /* station being joined is non-11b and non-ht ==> 11g device */
+ else if (!pStaDs->mlmStaContext.htCapability) {
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llG;
+ /* enable protection */
+ lim_enable_ht_protection_from11g(pMac, true, false,
+ pBeaconParams,
+ psessionEntry);
+ }
+ /* ERP mode is enabled for the latest station joined */
+ /* latest station joined is HT capable */
+ /* This case is being handled in common code (commn between both the bands) below. */
+ }
+ }
+ /* we are HT and HT station is joining. This code is common for both the bands. */
+ if ((true == psessionEntry->htCapability) &&
+ (true == pStaDs->mlmStaContext.htCapability)) {
+ if (!pStaDs->htGreenfield) {
+ lim_enable_ht_non_gf_protection(pMac, true, false,
+ pBeaconParams,
+ psessionEntry);
+ gfSupported = eHAL_CLEAR;
+ }
+ /* Station joining is HT 20Mhz */
+ if ((eHT_CHANNEL_WIDTH_20MHZ ==
+ pStaDs->htSupportedChannelWidthSet) &&
+ (eHT_CHANNEL_WIDTH_20MHZ !=
+ psessionEntry->htSupportedChannelWidthSet)){
+ protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_HT20;
+ lim_enable_ht20_protection(pMac, true, false,
+ pBeaconParams, psessionEntry);
+ }
+ /* Station joining does not support LSIG TXOP Protection */
+ if (!pStaDs->htLsigTXOPProtection) {
+ lim_enable_ht_lsig_txop_protection(pMac, false, false,
+ pBeaconParams,
+ psessionEntry);
+ lsigTxopSupported = eHAL_CLEAR;
+ }
+ }
+
+ lim_update_prot_sta_params(pMac, peerMacAddr, protStaCacheType,
+ gfSupported, lsigTxopSupported, psessionEntry);
+
+ return;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_enable_overlap11g_protection
+ \brief wrapper function for setting overlap 11g protection.
+ \param tpAniSirGlobal pMac
+ \param tpUpdateBeaconParams pBeaconParams
+ \param tpSirMacMgmtHdr pMh
+ \return None
+ -------------------------------------------------------------*/
+void
+lim_enable_overlap11g_protection(tpAniSirGlobal pMac,
+ tpUpdateBeaconParams pBeaconParams,
+ tpSirMacMgmtHdr pMh, tpPESession psessionEntry)
+{
+ lim_update_overlap_sta_param(pMac, pMh->bssId,
+ &(psessionEntry->gLimOlbcParams));
+
+ if (psessionEntry->gLimOlbcParams.numSta &&
+ !psessionEntry->gLimOlbcParams.protectionEnabled) {
+ /* enable protection */
+ PELOG1(lim_log(pMac, LOG1, FL("OLBC happens!!!"));)
+ lim_enable11g_protection(pMac, true, true, pBeaconParams,
+ psessionEntry);
+ }
+}
+
+/**
+ * lim_update_short_preamble() - This function Updates short preamble
+ * @mac_ctx: pointer to Global MAC structure
+ * @peer_mac_addr: pointer to tSirMacAddr
+ * @pbeaconparams: pointer to tpUpdateBeaconParams
+ * @psession_entry: pointer to tpPESession
+ *
+ * Function Updates short preamble if needed when a new station joins
+ *
+ * Return: none
+ */
+void
+lim_update_short_preamble(tpAniSirGlobal mac_ctx, tSirMacAddr peer_mac_addr,
+ tpUpdateBeaconParams beaconparams,
+ tpPESession psession_entry)
+{
+ uint16_t aid;
+ tpDphHashNode sta_ds;
+ uint32_t phy_mode;
+ uint16_t i;
+
+ /* check whether to enable protection or not */
+ sta_ds =
+ dph_lookup_hash_entry(mac_ctx, peer_mac_addr, &aid,
+ &psession_entry->dph.dphHashTable);
+
+ lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry);
+
+ if (sta_ds == NULL || phy_mode != WNI_CFG_PHY_MODE_11G)
+ return;
+
+ if (sta_ds->shortPreambleEnabled != eHAL_CLEAR)
+ return;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Short Preamble is not enabled in Assoc Req from "));
+
+ lim_print_mac_addr(mac_ctx, peer_mac_addr, LOG1);
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (LIM_IS_AP_ROLE(psession_entry) &&
+ (psession_entry->gLimNoShortParams.
+ staNoShortCache[i].active) &&
+ (cdf_mem_compare
+ (psession_entry->gLimNoShortParams.
+ staNoShortCache[i].addr,
+ peer_mac_addr, sizeof(tSirMacAddr))))
+ return;
+ else if (!LIM_IS_AP_ROLE(psession_entry) &&
+ (mac_ctx->lim.gLimNoShortParams.
+ staNoShortCache[i].active) &&
+ (cdf_mem_compare(mac_ctx->lim.gLimNoShortParams.
+ staNoShortCache[i].addr,
+ peer_mac_addr,
+ sizeof(tSirMacAddr))))
+ return;
+ }
+
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (LIM_IS_AP_ROLE(psession_entry) &&
+ !psession_entry->gLimNoShortParams.
+ staNoShortCache[i].active)
+ break;
+ else if (!mac_ctx->lim.gLimNoShortParams.
+ staNoShortCache[i].active)
+ break;
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE) {
+ tLimNoShortParams *lim_params =
+ &psession_entry->gLimNoShortParams;
+ if (LIM_IS_AP_ROLE(psession_entry)) {
+ lim_log(mac_ctx, LOGE,
+ FL("No space in Short cache (#active %d, #sta %d) for sta "),
+ i,
+ lim_params->numNonShortPreambleSta);
+ lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
+ return;
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("No space in Short cache (#active %d, #sta %d) for sta "),
+ i,
+ lim_params->numNonShortPreambleSta);
+ lim_print_mac_addr(mac_ctx, peer_mac_addr, LOGE);
+ return;
+ }
+
+ }
+
+ if (LIM_IS_AP_ROLE(psession_entry)) {
+ cdf_mem_copy(psession_entry->gLimNoShortParams.
+ staNoShortCache[i].addr,
+ peer_mac_addr, sizeof(tSirMacAddr));
+ psession_entry->gLimNoShortParams.staNoShortCache[i].
+ active = true;
+ psession_entry->gLimNoShortParams.numNonShortPreambleSta++;
+ } else {
+ cdf_mem_copy(mac_ctx->lim.gLimNoShortParams.
+ staNoShortCache[i].addr,
+ peer_mac_addr, sizeof(tSirMacAddr));
+ mac_ctx->lim.gLimNoShortParams.staNoShortCache[i].active = true;
+ mac_ctx->lim.gLimNoShortParams.numNonShortPreambleSta++;
+ }
+
+ /* enable long preamble */
+ lim_log(mac_ctx, LOG1, FL("Disabling short preamble"));
+
+ if (lim_enable_short_preamble(mac_ctx, false, beaconparams,
+ psession_entry) != eSIR_SUCCESS)
+ lim_log(mac_ctx, LOGE, FL("Cannot enable long preamble"));
+}
+
+/**
+ * lim_update_short_slot_time() - This function Updates short slot time
+ * @mac_ctx: pointer to Global MAC structure
+ * @peer_mac_addr: pointer to tSirMacAddr
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @psession_entry: pointer to tpPESession
+ *
+ * Function Updates short slot time if needed when a new station joins
+ *
+ * Return: None
+ */
+void
+lim_update_short_slot_time(tpAniSirGlobal mac_ctx, tSirMacAddr peer_mac_addr,
+ tpUpdateBeaconParams beaconparams,
+ tpPESession session_entry)
+{
+ uint16_t aid;
+ tpDphHashNode sta_ds;
+ uint32_t phy_mode;
+ uint32_t val;
+ uint16_t i;
+
+ /* check whether to enable protection or not */
+ sta_ds =
+ dph_lookup_hash_entry(mac_ctx, peer_mac_addr, &aid,
+ &session_entry->dph.dphHashTable);
+ lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
+
+ if (sta_ds == NULL || phy_mode != WNI_CFG_PHY_MODE_11G)
+ return;
+
+ /*
+ * Only in case of softap in 11g mode, slot time might change
+ * depending on the STA being added. In 11a case, it should
+ * be always 1 and in 11b case, it should be always 0.
+ * Only when the new STA has short slot time disabled, we need to
+ * change softap's overall slot time settings else the default for
+ * softap is always short slot enabled. When the last long slot STA
+ * leaves softAP, we take care of it in lim_decide_short_slot
+ */
+ if (sta_ds->shortSlotTimeEnabled == eHAL_CLEAR) {
+ lim_log(mac_ctx, LOG1,
+ FL("Short Slot Time is not enabled in Assoc Req from "));
+ lim_print_mac_addr(mac_ctx, peer_mac_addr, LOG1);
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (LIM_IS_AP_ROLE(session_entry) &&
+ session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active) {
+ if (cdf_mem_compare(
+ session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].addr,
+ peer_mac_addr, sizeof(tSirMacAddr)))
+ return;
+ } else if (!LIM_IS_AP_ROLE(session_entry)) {
+ if (mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active) {
+ if (cdf_mem_compare(mac_ctx->lim.
+ gLimNoShortSlotParams.
+ staNoShortSlotCache[i].
+ addr, peer_mac_addr,
+ sizeof(tSirMacAddr)))
+ return;
+ }
+ }
+ }
+ for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
+ if (LIM_IS_AP_ROLE(session_entry) &&
+ !session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active)
+ break;
+ else {
+ if (!mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active)
+ break;
+ }
+ }
+
+ if (i >= LIM_PROT_STA_CACHE_SIZE) {
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOGE,
+ FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "),
+ i,
+ session_entry->gLimNoShortSlotParams.
+ numNonShortSlotSta);
+ lim_print_mac_addr(mac_ctx, peer_mac_addr,
+ LOGE);
+ return;
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "),
+ i,
+ mac_ctx->lim.gLimNoShortSlotParams.
+ numNonShortSlotSta);
+ lim_print_mac_addr(mac_ctx, peer_mac_addr,
+ LOGE);
+ return;
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ cdf_mem_copy(session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].addr,
+ peer_mac_addr, sizeof(tSirMacAddr));
+ session_entry->gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active = true;
+ session_entry->gLimNoShortSlotParams.
+ numNonShortSlotSta++;
+ } else {
+ cdf_mem_copy(mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].addr,
+ peer_mac_addr, sizeof(tSirMacAddr));
+ mac_ctx->lim.gLimNoShortSlotParams.
+ staNoShortSlotCache[i].active = true;
+ mac_ctx->lim.gLimNoShortSlotParams.
+ numNonShortSlotSta++;
+ }
+ wlan_cfg_get_int(mac_ctx,
+ WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
+ &val);
+ /*
+ * Here we check if we are AP role and short slot enabled
+ * (both admin and oper modes) but we have atleast one STA
+ * connected with only long slot enabled, we need to change
+ * our beacon/pb rsp to broadcast short slot disabled
+ */
+ if ((LIM_IS_AP_ROLE(session_entry)) && (val &&
+ session_entry->gLimNoShortSlotParams.numNonShortSlotSta
+ && session_entry->shortSlotTimeSupported)) {
+ /* enable long slot time */
+ beaconparams->fShortSlotTime = false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_SHORT_SLOT_TIME_CHANGED;
+ lim_log(mac_ctx, LOG1,
+ FL("Disable short slot time. Enable long slot time."));
+ session_entry->shortSlotTimeSupported = false;
+ } else if (!LIM_IS_AP_ROLE(session_entry) &&
+ (val && mac_ctx->lim.gLimNoShortSlotParams.
+ numNonShortSlotSta &&
+ session_entry->shortSlotTimeSupported)) {
+ /* enable long slot time */
+ beaconparams->fShortSlotTime = false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_SHORT_SLOT_TIME_CHANGED;
+ lim_log(mac_ctx, LOG1,
+ FL("Disable short slot time. Enable long slot time."));
+ session_entry->shortSlotTimeSupported =
+ false;
+ }
+ }
+}
+
+/** -------------------------------------------------------------
+ \fn lim_decide_sta_protection_on_assoc
+ \brief Decide protection related settings on Sta while association.
+ \param tpAniSirGlobal pMac
+ \param tpSchBeaconStruct pBeaconStruct
+ \return None
+ -------------------------------------------------------------*/
+void
+lim_decide_sta_protection_on_assoc(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeaconStruct,
+ tpPESession psessionEntry)
+{
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+ uint32_t phyMode = WNI_CFG_PHY_MODE_NONE;
+
+ lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ if (SIR_BAND_5_GHZ == rfBand) {
+ if ((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ pBeaconStruct->HTInfo.opMode)) {
+ if (pMac->lim.cfgProtection.fromlla)
+ psessionEntry->beaconParams.llaCoexist = true;
+ } else if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+ pBeaconStruct->HTInfo.opMode) {
+ if (pMac->lim.cfgProtection.ht20)
+ psessionEntry->beaconParams.ht20Coexist = true;
+ }
+
+ } else if (SIR_BAND_2_4_GHZ == rfBand) {
+ /* spec 7.3.2.13 */
+ /* UseProtection will be set when nonERP STA is associated. */
+ /* NonERPPresent bit will be set when: */
+ /* --nonERP Sta is associated OR */
+ /* --nonERP Sta exists in overlapping BSS */
+ /* when useProtection is not set then protection from nonERP stations is optional. */
+
+ /* CFG protection from 11b is enabled and */
+ /* 11B device in the BSS */
+ /* TODO, This is not sessionized */
+ if (phyMode != WNI_CFG_PHY_MODE_11B) {
+ if (pMac->lim.cfgProtection.fromllb &&
+ pBeaconStruct->erpPresent &&
+ (pBeaconStruct->erpIEInfo.useProtection ||
+ pBeaconStruct->erpIEInfo.nonErpPresent)) {
+ psessionEntry->beaconParams.llbCoexist = true;
+ }
+ /* AP has no 11b station associated. */
+ else {
+ psessionEntry->beaconParams.llbCoexist = false;
+ }
+ }
+ /* following code block is only for HT station. */
+ if ((psessionEntry->htCapability) &&
+ (pBeaconStruct->HTInfo.present)) {
+ tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+
+ /* Obss Non HT STA present mode */
+ psessionEntry->beaconParams.gHTObssMode =
+ (uint8_t) htInfo.obssNonHTStaPresent;
+
+ /* CFG protection from 11G is enabled and */
+ /* our AP has at least one 11G station associated. */
+ if (pMac->lim.cfgProtection.fromllg &&
+ ((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))
+ && (!psessionEntry->beaconParams.llbCoexist)) {
+ if (pMac->lim.cfgProtection.fromllg)
+ psessionEntry->beaconParams.llgCoexist =
+ true;
+ }
+ /* AP has only HT stations associated and at least one station is HT 20 */
+ /* disable protection from any non-HT devices. */
+ /* decision for disabling protection from 11b has already been taken above. */
+ if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) {
+ /* Disable protection from 11G station. */
+ psessionEntry->beaconParams.llgCoexist = false;
+ /* CFG protection from HT 20 is enabled. */
+ if (pMac->lim.cfgProtection.ht20)
+ psessionEntry->beaconParams.
+ ht20Coexist = true;
+ }
+ /* Disable protection from non-HT and HT20 devices. */
+ /* decision for disabling protection from 11b has already been taken above. */
+ if (eSIR_HT_OP_MODE_PURE == htInfo.opMode) {
+ psessionEntry->beaconParams.llgCoexist = false;
+ psessionEntry->beaconParams.ht20Coexist = false;
+ }
+
+ }
+ }
+ /* protection related factors other than HT operating mode. Applies to 2.4 GHZ as well as 5 GHZ. */
+ if ((psessionEntry->htCapability) && (pBeaconStruct->HTInfo.present)) {
+ tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo;
+ psessionEntry->beaconParams.fRIFSMode =
+ (uint8_t) htInfo.rifsMode;
+ psessionEntry->beaconParams.llnNonGFCoexist =
+ (uint8_t) htInfo.nonGFDevicesPresent;
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+ (uint8_t) htInfo.lsigTXOPProtectionFullSupport;
+ }
+}
+
+
+/**
+ * lim_decide_sta_11bg_protection() - decides protection related settings on sta
+ * @mac_ctx: pointer to global mac structure
+ * @beacon_struct: pointer to tpschbeaconstruct
+ * @beaconparams: pointer to tpupdatebeaconparams
+ * @psession_entry: pointer to tppesession
+ * @phy_mode: phy mode index
+ *
+ * decides 11bg protection related settings on sta while processing beacon
+ *
+ * Return: none
+ */
+static void
+lim_decide_sta_11bg_protection(tpAniSirGlobal mac_ctx,
+ tpSchBeaconStruct beacon_struct,
+ tpUpdateBeaconParams beaconparams,
+ tpPESession psession_entry,
+ uint32_t phy_mode)
+{
+
+ tDot11fIEHTInfo htInfo;
+
+ /*
+ * spec 7.3.2.13
+ * UseProtection will be set when nonERP STA is associated.
+ * NonERPPresent bit will be set when:
+ * --nonERP Sta is associated OR
+ * --nonERP Sta exists in overlapping BSS
+ * when useProtection is not set then protection from
+ * nonERP stations is optional.
+ */
+ if (phy_mode != WNI_CFG_PHY_MODE_11B) {
+ if (beacon_struct->erpPresent &&
+ (beacon_struct->erpIEInfo.useProtection ||
+ beacon_struct->erpIEInfo.nonErpPresent)) {
+ lim_enable11g_protection(mac_ctx, true, false,
+ beaconparams,
+ psession_entry);
+ }
+ /* AP has no 11b station associated. */
+ else {
+ /* disable protection from 11b station */
+ lim_enable11g_protection(mac_ctx, false, false,
+ beaconparams,
+ psession_entry);
+ }
+ }
+
+ if (!(psession_entry->htCapability) ||
+ !(beacon_struct->HTInfo.present))
+ return;
+
+ /* following code is only for HT station. */
+
+ htInfo = beacon_struct->HTInfo;
+ /* AP has at least one 11G station associated. */
+ if (((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode)) &&
+ (!psession_entry->beaconParams.llbCoexist)) {
+ lim_enable_ht_protection_from11g(mac_ctx, true, false,
+ beaconparams, psession_entry);
+
+ }
+ /*
+ * no HT operating mode change ==> no change in
+ * protection settings except for MIXED_MODE/Legacy
+ * Mode.
+ */
+ /*
+ * in Mixed mode/legacy Mode even if there is no
+ * change in HT operating mode, there might be
+ * change in 11bCoexist or 11gCoexist. Hence this
+ * check is being done after mixed/legacy mode
+ * check.
+ */
+ if (mac_ctx->lim.gHTOperMode !=
+ (tSirMacHTOperatingMode)htInfo.opMode) {
+ mac_ctx->lim.gHTOperMode =
+ (tSirMacHTOperatingMode) htInfo.opMode;
+ /*
+ * AP has only HT stations associated and
+ * at least one station is HT 20
+ */
+
+ /* disable protection from any non-HT devices. */
+
+ /*
+ * decision for disabling protection from
+ * 11b has already been taken above.
+ */
+ if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+ htInfo.opMode) {
+ /* Disable protection from 11G station. */
+ lim_enable_ht_protection_from11g(mac_ctx, false,
+ false, beaconparams,
+ psession_entry);
+
+ lim_enable_ht20_protection(mac_ctx, true, false,
+ beaconparams,
+ psession_entry);
+ }
+ /*
+ * Disable protection from non-HT and
+ * HT20 devices.
+ */
+ /*
+ * decision for disabling protection from
+ * 11b has already been taken above.
+ */
+ else if (eSIR_HT_OP_MODE_PURE == htInfo.opMode) {
+ lim_enable_ht_protection_from11g(mac_ctx, false,
+ false, beaconparams,
+ psession_entry);
+
+ lim_enable_ht20_protection(mac_ctx, false,
+ false, beaconparams,
+ psession_entry);
+
+ }
+ }
+
+}
+
+/**
+ * lim_decide_sta_protection() - decides protection related settings on sta
+ * @mac_ctx: pointer to global mac structure
+ * @beacon_struct: pointer to tpschbeaconstruct
+ * @beaconparams: pointer to tpupdatebeaconparams
+ * @psession_entry: pointer to tppesession
+ *
+ * decides protection related settings on sta while processing beacon
+ *
+ * Return: none
+ */
+void
+lim_decide_sta_protection(tpAniSirGlobal mac_ctx,
+ tpSchBeaconStruct beacon_struct,
+ tpUpdateBeaconParams beaconparams,
+ tpPESession psession_entry)
+{
+
+ tSirRFBand rfband = SIR_BAND_UNKNOWN;
+ uint32_t phy_mode = WNI_CFG_PHY_MODE_NONE;
+
+ lim_get_rf_band_new(mac_ctx, &rfband, psession_entry);
+ lim_get_phy_mode(mac_ctx, &phy_mode, psession_entry);
+
+ if ((SIR_BAND_5_GHZ == rfband) &&
+ /* we are HT capable. */
+ (true == psession_entry->htCapability) &&
+ (beacon_struct->HTInfo.present)) {
+ /*
+ * we are HT capable, AP's HT OPMode is
+ * mixed / overlap legacy ==> need protection
+ * from 11A.
+ */
+ if ((eSIR_HT_OP_MODE_MIXED ==
+ beacon_struct->HTInfo.opMode) ||
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ beacon_struct->HTInfo.opMode)) {
+ lim_update_11a_protection(mac_ctx, true, false,
+ beaconparams, psession_entry);
+ }
+ /*
+ * we are HT capable, AP's HT OPMode is
+ * HT20 ==> disable protection from 11A if
+ * enabled.
+ */
+ /* protection from HT20 if needed. */
+ else if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+ beacon_struct->HTInfo.opMode) {
+ lim_update_11a_protection(mac_ctx, false, false,
+ beaconparams, psession_entry);
+ lim_enable_ht20_protection(mac_ctx, true, false,
+ beaconparams, psession_entry);
+ } else if (eSIR_HT_OP_MODE_PURE ==
+ beacon_struct->HTInfo.opMode) {
+ lim_update_11a_protection(mac_ctx, false, false,
+ beaconparams, psession_entry);
+ lim_enable_ht20_protection(mac_ctx, false,
+ false, beaconparams,
+ psession_entry);
+ }
+ } else if (SIR_BAND_2_4_GHZ == rfband) {
+ lim_decide_sta_11bg_protection(mac_ctx, beacon_struct,
+ beaconparams, psession_entry, phy_mode);
+ }
+ /*
+ * following code block is only for HT station.
+ * (2.4 GHZ as well as 5 GHZ)
+ */
+ if ((psession_entry->htCapability) && (beacon_struct->HTInfo.present)) {
+ tDot11fIEHTInfo htInfo = beacon_struct->HTInfo;
+ /*
+ * Check for changes in protection related factors other
+ * than HT operating mode.
+ */
+ /*
+ * Check for changes in RIFS mode, nonGFDevicesPresent,
+ * lsigTXOPProtectionFullSupport.
+ */
+ if (psession_entry->beaconParams.fRIFSMode !=
+ (uint8_t) htInfo.rifsMode) {
+ beaconparams->fRIFSMode =
+ psession_entry->beaconParams.fRIFSMode =
+ (uint8_t) htInfo.rifsMode;
+ beaconparams->paramChangeBitmap |=
+ PARAM_RIFS_MODE_CHANGED;
+ }
+
+ if (psession_entry->beaconParams.llnNonGFCoexist !=
+ htInfo.nonGFDevicesPresent) {
+ beaconparams->llnNonGFCoexist =
+ psession_entry->beaconParams.llnNonGFCoexist =
+ (uint8_t) htInfo.nonGFDevicesPresent;
+ beaconparams->paramChangeBitmap |=
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+
+ if (psession_entry->beaconParams.
+ fLsigTXOPProtectionFullSupport !=
+ (uint8_t) htInfo.lsigTXOPProtectionFullSupport) {
+ beaconparams->fLsigTXOPProtectionFullSupport =
+ psession_entry->beaconParams.
+ fLsigTXOPProtectionFullSupport =
+ (uint8_t) htInfo.
+ lsigTXOPProtectionFullSupport;
+ beaconparams->paramChangeBitmap |=
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ /*
+ * For Station just update the global lim variable,
+ * no need to send message to HAL since Station already
+ * taking care of HT OPR Mode=01,
+ * meaning AP is seeing legacy
+ */
+ /* stations in overlapping BSS. */
+ if (psession_entry->beaconParams.gHTObssMode !=
+ (uint8_t) htInfo.obssNonHTStaPresent)
+ psession_entry->beaconParams.gHTObssMode =
+ (uint8_t) htInfo.obssNonHTStaPresent;
+
+ }
+}
+
+/**
+ * lim_process_channel_switch_timeout()
+ *
+ ***FUNCTION:
+ * This function is invoked when Channel Switch Timer expires at
+ * the STA. Now, STA must stop traffic, and then change/disable
+ * primary or secondary channel.
+ *
+ *
+ ***NOTE:
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+void lim_process_channel_switch_timeout(tpAniSirGlobal pMac)
+{
+ tpPESession psessionEntry = NULL;
+ uint8_t channel; /* This is received and stored from channelSwitch Action frame */
+
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ if (!LIM_IS_STA_ROLE(psessionEntry)) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ "Channel switch can be done only in STA role, Current Role = %d",
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+ )
+ return;
+ }
+
+ channel = psessionEntry->gLimChannelSwitch.primaryChannel;
+ /* Restore Channel Switch parameters to default */
+ psessionEntry->gLimChannelSwitch.switchTimeoutValue = 0;
+
+ /* Channel-switch timeout has occurred. reset the state */
+ psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_END;
+
+ /* Check if the AP is switching to a channel that we support.
+ * Else, just don't bother to switch. Indicate HDD to look for a
+ * better AP to associate
+ */
+ if (!lim_is_channel_valid_for_channel_switch(pMac, channel)) {
+ /* We need to restore pre-channelSwitch state on the STA */
+ if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Could not restore pre-channelSwitch (11h) state, resetting the system"));
+ return;
+ }
+
+ /* If the channel-list that AP is asking us to switch is invalid,
+ * then we cannot switch the channel. Just disassociate from AP.
+ * We will find a better AP !!!
+ */
+ lim_tear_down_link_with_ap(pMac,
+ pMac->lim.limTimers.
+ gLimChannelSwitchTimer.sessionId,
+ eSIR_MAC_UNSPEC_FAILURE_REASON);
+ return;
+ }
+ lim_covert_channel_scan_type(pMac, psessionEntry->currentOperChannel,
+ false);
+ pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] =
+ 0;
+ switch (psessionEntry->gLimChannelSwitch.state) {
+ case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY:
+ PELOGW(lim_log(pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_ONLY "));)
+ lim_switch_primary_channel(pMac,
+ psessionEntry->gLimChannelSwitch.
+ primaryChannel, psessionEntry);
+ psessionEntry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_IDLE;
+ break;
+ case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY:
+ PELOGW(lim_log
+ (pMac, LOGW, FL("CHANNEL_SWITCH_PRIMARY_AND_SECONDARY"));
+ )
+ lim_switch_primary_secondary_channel(pMac, psessionEntry,
+ psessionEntry->gLimChannelSwitch.primaryChannel,
+ psessionEntry->gLimChannelSwitch.ch_center_freq_seg0,
+ psessionEntry->gLimChannelSwitch.ch_center_freq_seg1,
+ psessionEntry->gLimChannelSwitch.ch_width);
+ psessionEntry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_IDLE;
+ break;
+
+ case eLIM_CHANNEL_SWITCH_IDLE:
+ default:
+ PELOGE(lim_log(pMac, LOGE, FL("incorrect state "));)
+ if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Could not restore pre-channelSwitch (11h) state, resetting the system"));
+ }
+ return; /* Please note, this is 'return' and not 'break' */
+ }
+}
+
+/**
+ * lim_update_channel_switch() - This Function updates channel switch
+ * @mac_ctx: pointer to Global MAC structure
+ * @beacon: pointer to tpSirProbeRespBeacon
+ * @psessionentry: pointer to tpPESession
+ *
+ * This function is invoked whenever Station receives
+ * either 802.11h channel switch IE or airgo proprietary
+ * channel switch IE.
+ *
+ * Return: none
+ */
+void
+lim_update_channel_switch(struct sAniSirGlobal *mac_ctx,
+ tpSirProbeRespBeacon beacon,
+ tpPESession psession_entry)
+{
+ uint16_t beacon_period;
+ tDot11fIEChanSwitchAnn *chnl_switch;
+ tLimChannelSwitchInfo *ch_switch_params;
+#ifdef WLAN_FEATURE_11AC
+ tDot11fIEWiderBWChanSwitchAnn *widerchnl_switch;
+#endif
+
+ beacon_period = psession_entry->beaconParams.beaconInterval;
+
+ /* 802.11h standard channel switch IE */
+ chnl_switch = &(beacon->channelSwitchIE);
+ ch_switch_params = &psession_entry->gLimChannelSwitch;
+ ch_switch_params->primaryChannel =
+ chnl_switch->newChannel;
+ ch_switch_params->switchCount = chnl_switch->switchCount;
+ ch_switch_params->switchTimeoutValue =
+ SYS_MS_TO_TICKS(beacon_period) * (chnl_switch->switchCount);
+ ch_switch_params->switchMode = chnl_switch->switchMode;
+#ifdef WLAN_FEATURE_11AC
+ widerchnl_switch = &(beacon->WiderBWChanSwitchAnn);
+ if (beacon->WiderBWChanSwitchAnnPresent) {
+ psession_entry->gLimWiderBWChannelSwitch.newChanWidth =
+ widerchnl_switch->newChanWidth;
+ psession_entry->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
+ widerchnl_switch->newCenterChanFreq0;
+ psession_entry->gLimWiderBWChannelSwitch.newCenterChanFreq1 =
+ widerchnl_switch->newCenterChanFreq1;
+ }
+#endif
+
+ /* Only primary channel switch element is present */
+ ch_switch_params->state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ ch_switch_params->ch_width = CH_WIDTH_20MHZ;
+
+ /*
+ * Do not bother to look and operate on extended channel switch element
+ * if our own channel-bonding state is not enabled
+ */
+ if (psession_entry->htSupportedChannelWidthSet &&
+ beacon->sec_chan_offset_present) {
+ if (beacon->sec_chan_offset.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
+ ch_switch_params->state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+ ch_switch_params->ch_center_freq_seg0 =
+ ch_switch_params->primaryChannel + 2;
+ } else if (beacon->sec_chan_offset.secondaryChannelOffset ==
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
+ ch_switch_params->state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ ch_switch_params->ch_width = CH_WIDTH_40MHZ;
+ ch_switch_params->ch_center_freq_seg0 =
+ ch_switch_params->primaryChannel - 2;
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (psession_entry->vhtCapability &&
+ beacon->WiderBWChanSwitchAnnPresent) {
+ ch_switch_params->ch_width =
+ widerchnl_switch->newChanWidth + 1;
+ ch_switch_params->ch_center_freq_seg0 =
+ psession_entry->gLimWiderBWChannelSwitch.
+ newCenterChanFreq0;
+ ch_switch_params->ch_center_freq_seg1 =
+ psession_entry->gLimWiderBWChannelSwitch.
+ newCenterChanFreq1;
+#endif
+ }
+ }
+ if (eSIR_SUCCESS != lim_start_channel_switch(mac_ctx, psession_entry))
+ lim_log(mac_ctx, LOGW, FL("Could not start Channel Switch"));
+
+ lim_log(mac_ctx, LOGW,
+ FL("session %d primary chl %d, ch_width %d, count %d (%d ticks)"),
+ psession_entry->peSessionId,
+ psession_entry->gLimChannelSwitch.primaryChannel,
+ psession_entry->gLimChannelSwitch.ch_width,
+ psession_entry->gLimChannelSwitch.switchCount,
+ psession_entry->gLimChannelSwitch.switchTimeoutValue);
+ return;
+}
+
+/**
+ * lim_cancel_dot11h_channel_switch
+ *
+ ***FUNCTION:
+ * This function is called when STA does not send updated channel-swith IE
+ * after indicating channel-switch start. This will cancel the channel-swith
+ * timer which is already running.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+ if (!LIM_IS_STA_ROLE(psessionEntry))
+ return;
+
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Received a beacon without channel switch IE"));
+ )
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER));
+
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("tx_timer_deactivate failed!"));)
+ }
+
+ /* We need to restore pre-channelSwitch state on the STA */
+ if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL
+ ("LIM: Could not restore pre-channelSwitch (11h) state, resetting the system"));
+ )
+
+ }
+}
+
+/**
+ * lim_cancel_dot11h_quiet()
+ *
+ * @mac_ctx: pointer to global mac structure
+ * @psession_entry: pointer to tppesession
+ *
+ * Cancel the quieting on Station if latest beacon
+ * doesn't contain quiet IE in it.
+ *
+ * Return: none
+ */
+void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ if (!LIM_IS_STA_ROLE(psessionEntry))
+ return;
+
+ if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ psessionEntry->peSessionId, eLIM_QUIET_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) !=
+ TX_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("tx_timer_deactivate failed"));
+ )
+ }
+ } else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) {
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_DEACTIVATE,
+ psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER));
+ if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)
+ != TX_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("tx_timer_deactivate failed"));
+ )
+ }
+ /**
+ * If the channel switch is already running in silent mode, dont resume the
+ * transmission. Channel switch timer when timeout, transmission will be resumed.
+ */
+ if (!
+ ((psessionEntry->gLimSpecMgmt.dot11hChanSwState ==
+ eLIM_11H_CHANSW_RUNNING)
+ && (psessionEntry->gLimChannelSwitch.switchMode ==
+ eSIR_CHANSW_MODE_SILENT))) {
+ lim_frame_transmission_control(pMac, eLIM_TX_ALL,
+ eLIM_RESUME_TX);
+ lim_restore_pre_quiet_state(pMac, psessionEntry);
+ }
+ }
+ psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+}
+
+/**
+ * lim_process_quiet_timeout
+ *
+ * FUNCTION:
+ * This function is active only on the STA.
+ * Handles SIR_LIM_QUIET_TIMEOUT
+ *
+ * LOGIC:
+ * This timeout can occur under only one circumstance:
+ *
+ * 1) When gLimQuietState = eLIM_QUIET_BEGIN
+ * This indicates that the timeout "interval" has
+ * expired. This is a trigger for the STA to now
+ * shut-off Tx/Rx for the specified gLimQuietDuration
+ * -> The TIMER object gLimQuietBssTimer is
+ * activated
+ * -> With timeout = gLimQuietDuration
+ * -> gLimQuietState is set to eLIM_QUIET_RUNNING
+ *
+ * ASSUMPTIONS:
+ * Using two TIMER objects -
+ * gLimQuietTimer & gLimQuietBssTimer
+ *
+ * NOTE:
+ *
+ * @param pMac - Pointer to Global MAC structure
+ *
+ * @return None
+ */
+void lim_process_quiet_timeout(tpAniSirGlobal pMac)
+{
+ tpPESession psessionEntry;
+
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pMac->lim.limTimers.gLimQuietTimer.sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ PELOG1(lim_log
+ (pMac, LOG1, FL("quietState = %d"),
+ psessionEntry->gLimSpecMgmt.quietState);
+ )
+ switch (psessionEntry->gLimSpecMgmt.quietState) {
+ case eLIM_QUIET_BEGIN:
+ /* Time to Stop data traffic for quietDuration */
+ /* lim_deactivate_and_change_timer(pMac, eLIM_QUIET_BSS_TIMER); */
+ if (TX_SUCCESS != tx_timer_deactivate(
+ &pMac->lim.limTimers.gLimQuietBssTimer)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway..."));
+ }
+ /* gLimQuietDuration appears to be in units of ticks */
+ /* Use it as is */
+ if (TX_SUCCESS !=
+ tx_timer_change(&pMac->lim.limTimers.gLimQuietBssTimer,
+ psessionEntry->gLimSpecMgmt.quietDuration,
+ 0)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway..."));
+ }
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE,
+ pMac->lim.limTimers.gLimQuietTimer.sessionId,
+ eLIM_QUIET_BSS_TIMER));
+ if (TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.gLimQuietBssTimer)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("Unable to activate gLimQuietBssTimer! The STA will be unable to honor Quiet BSS..."));
+ } else {
+ /* Transition to eLIM_QUIET_RUNNING */
+ psessionEntry->gLimSpecMgmt.quietState =
+ eLIM_QUIET_RUNNING;
+ /* Shut-off Tx/Rx for gLimSpecMgmt.quietDuration */
+ /* freeze the transmission */
+ lim_frame_transmission_control(pMac, eLIM_TX_ALL,
+ eLIM_STOP_TX);
+
+ lim_log(pMac, LOG2,
+ FL("Quiet BSS: STA shutting down for %d ticks"),
+ psessionEntry->gLimSpecMgmt.quietDuration);
+ }
+ break;
+
+ case eLIM_QUIET_RUNNING:
+ case eLIM_QUIET_INIT:
+ case eLIM_QUIET_END:
+ default:
+ /* */
+ /* As of now, nothing to be done */
+ /* */
+ break;
+ }
+}
+
+/**
+ * lim_process_quiet_bss_timeout() - Handles SIR_LIM_QUIET_BSS_TIMEOUT
+ * @mac_ctx: pointer to Globale Mac Structure
+ *
+ * This function is active on the AP and STA.
+ * Handles SIR_LIM_QUIET_BSS_TIMEOUT
+ *
+ * On the AP -
+ * When the SIR_LIM_QUIET_BSS_TIMEOUT is triggered, it is
+ * an indication for the AP to START sending out the
+ * Quiet BSS IE.
+ * If 802.11H is enabled, the Quiet BSS IE is sent as per
+ * the 11H spec
+ * If 802.11H is not enabled, the Quiet BSS IE is sent as
+ * a Proprietary IE. This will be understood by all the
+ * TITAN STA's
+ * Transitioning gLimQuietState to eLIM_QUIET_BEGIN will
+ * initiate the SCH to include the Quiet BSS IE in all
+ * its subsequent Beacons/PR's.
+ * The Quiet BSS IE will be included in all the Beacons
+ * & PR's until the next DTIM period
+ *
+ * On the STA -
+ * When gLimQuietState = eLIM_QUIET_RUNNING
+ * This indicates that the STA was successfully shut-off
+ * for the specified gLimQuietDuration. This is a trigger
+ * for the STA to now resume data traffic.
+ * -> gLimQuietState is set to eLIM_QUIET_INIT
+ *
+ *
+ * Return: none
+ */
+void lim_process_quiet_bss_timeout(tpAniSirGlobal mac_ctx)
+{
+ tpPESession psession_entry = NULL;
+ tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
+
+ psession_entry = pe_find_session_by_session_id(mac_ctx,
+ lim_timer->gLimQuietBssTimer.sessionId);
+
+ if (psession_entry == NULL) {
+ lim_log(mac_ctx, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ lim_log(mac_ctx, LOG1, FL("quietState = %d"),
+ psession_entry->gLimSpecMgmt.quietState);
+
+ if (LIM_IS_AP_ROLE(psession_entry))
+ return;
+
+ /* eLIM_STA_ROLE */
+ switch (psession_entry->gLimSpecMgmt.quietState) {
+ case eLIM_QUIET_RUNNING:
+ /* Transition to eLIM_QUIET_INIT */
+ psession_entry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+ /*
+ * Resume data traffic only if channel switch is
+ * not running in silent mode.
+ */
+ if (!((psession_entry->gLimSpecMgmt.dot11hChanSwState ==
+ eLIM_11H_CHANSW_RUNNING) &&
+ (psession_entry->gLimChannelSwitch.switchMode ==
+ eSIR_CHANSW_MODE_SILENT))) {
+ lim_frame_transmission_control(mac_ctx, eLIM_TX_ALL,
+ eLIM_RESUME_TX);
+ lim_restore_pre_quiet_state(mac_ctx, psession_entry);
+ }
+ lim_log(mac_ctx, LOG2, FL("Quiet BSS: Resuming traffic..."));
+ break;
+
+ case eLIM_QUIET_INIT:
+ case eLIM_QUIET_BEGIN:
+ case eLIM_QUIET_END:
+ lim_log(mac_ctx, LOG2, FL("Quiet state not in RUNNING"));
+ /*
+ * If the quiet period has ended, then resume the
+ * frame transmission
+ */
+ lim_frame_transmission_control(mac_ctx, eLIM_TX_ALL,
+ eLIM_RESUME_TX);
+ lim_restore_pre_quiet_state(mac_ctx, psession_entry);
+ psession_entry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ break;
+
+ default:
+ /* As of now, nothing to be done */
+ break;
+ }
+}
+
+/**----------------------------------------------
+ \fn lim_start_quiet_timer
+ \brief Starts the quiet timer.
+
+ \param pMac
+ \return NONE
+ -----------------------------------------------*/
+void lim_start_quiet_timer(tpAniSirGlobal pMac, uint8_t sessionId)
+{
+ tpPESession psessionEntry;
+ psessionEntry = pe_find_session_by_session_id(pMac, sessionId);
+
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ if (!LIM_IS_STA_ROLE(psessionEntry))
+ return;
+ /* First, de-activate Timer, if its already active */
+ lim_cancel_dot11h_quiet(pMac, psessionEntry);
+
+ MTRACE(mac_trace
+ (pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_QUIET_TIMER));
+ if (TX_SUCCESS !=
+ tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway..."));
+ }
+ /* Set the NEW timeout value, in ticks */
+ if (TX_SUCCESS != tx_timer_change(&pMac->lim.limTimers.gLimQuietTimer,
+ SYS_MS_TO_TICKS(psessionEntry->
+ gLimSpecMgmt.
+ quietTimeoutValue),
+ 0)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to change gLimQuietTimer! Will still attempt to re-activate anyway..."));
+ }
+
+ pMac->lim.limTimers.gLimQuietTimer.sessionId = sessionId;
+ if (TX_SUCCESS !=
+ tx_timer_activate(&pMac->lim.limTimers.gLimQuietTimer)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Unable to activate gLimQuietTimer! STA cannot honor Quiet BSS!"));
+ lim_restore_pre_quiet_state(pMac, psessionEntry);
+
+ psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+ return;
+ }
+}
+
+/** ------------------------------------------------------------------------ **/
+/**
+ * keep track of the number of ANI peers associated in the BSS
+ * For the first and last ANI peer, we have to update EDCA params as needed
+ *
+ * When the first ANI peer joins the BSS, we notify SCH
+ * When the last ANI peer leaves the BSS, we notfiy SCH
+ */
+void
+lim_util_count_sta_add(tpAniSirGlobal pMac,
+ tpDphHashNode pSta, tpPESession psessionEntry)
+{
+
+ if ((!pSta) || (!pSta->valid) || (pSta->fAniCount))
+ return;
+
+ pSta->fAniCount = 1;
+
+ if (pMac->lim.gLimNumOfAniSTAs++ != 0)
+ return;
+
+ /* get here only if this is the first ANI peer in the BSS */
+ sch_edca_profile_update(pMac, psessionEntry);
+}
+
+void
+lim_util_count_sta_del(tpAniSirGlobal pMac,
+ tpDphHashNode pSta, tpPESession psessionEntry)
+{
+
+ if ((pSta == NULL) || (!pSta->fAniCount))
+ return;
+
+ /* Only if sta is invalid and the validInDummyState bit is set to 1,
+ * then go ahead and update the count and profiles. This ensures
+ * that the "number of ani station" count is properly incremented/decremented.
+ */
+ if (pSta->valid == 1)
+ return;
+
+ pSta->fAniCount = 0;
+
+ if (pMac->lim.gLimNumOfAniSTAs <= 0) {
+ lim_log(pMac, LOGE,
+ FL
+ ("CountStaDel: ignoring Delete Req when AniPeer count is %d"),
+ pMac->lim.gLimNumOfAniSTAs);
+ return;
+ }
+
+ pMac->lim.gLimNumOfAniSTAs--;
+
+ if (pMac->lim.gLimNumOfAniSTAs != 0)
+ return;
+
+ /* get here only if this is the last ANI peer in the BSS */
+ sch_edca_profile_update(pMac, psessionEntry);
+}
+
+/**
+ * lim_switch_channel_cback()
+ *
+ ***FUNCTION:
+ * This is the callback function registered while requesting to switch channel
+ * after AP indicates a channel switch for spectrum management (11h).
+ *
+ ***NOTE:
+ * @param pMac Pointer to Global MAC structure
+ * @param status Status of channel switch request
+ * @param data User data
+ * @param psessionEntry Session information
+ * @return NONE
+ */
+void lim_switch_channel_cback(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg = { 0 };
+ tSirSmeSwitchChannelInd *pSirSmeSwitchChInd;
+
+ psessionEntry->currentOperChannel = psessionEntry->currentReqChannel;
+
+ /* We need to restore pre-channelSwitch state on the STA */
+ if (lim_restore_pre_channel_switch_state(pMac, psessionEntry) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Could not restore pre-channelSwitch (11h) state, resetting the system"));
+ return;
+ }
+
+ mmhMsg.type = eWNI_SME_SWITCH_CHL_IND;
+ pSirSmeSwitchChInd = cdf_mem_malloc(sizeof(tSirSmeSwitchChannelInd));
+ if (NULL == pSirSmeSwitchChInd) {
+ lim_log(pMac, LOGP,
+ FL("Failed to allocate buffer for buffer descriptor"));
+ return;
+ }
+
+ pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_IND;
+ pSirSmeSwitchChInd->length = sizeof(tSirSmeSwitchChannelInd);
+ pSirSmeSwitchChInd->newChannelId =
+ psessionEntry->gLimChannelSwitch.primaryChannel;
+ pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId;
+ cdf_mem_copy(pSirSmeSwitchChInd->bssId, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ mmhMsg.bodyptr = pSirSmeSwitchChInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+
+ sys_process_mmh_msg(pMac, &mmhMsg);
+}
+
+/**
+ * lim_switch_primary_channel()
+ *
+ ***FUNCTION:
+ * This function changes the current operating channel
+ * and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL.
+ *
+ ***NOTE:
+ * @param pMac Pointer to Global MAC structure
+ * @param newChannel new chnannel ID
+ * @return NONE
+ */
+void lim_switch_primary_channel(tpAniSirGlobal pMac, uint8_t newChannel,
+ tpPESession psessionEntry)
+{
+#if !defined WLAN_FEATURE_VOWIFI
+ uint32_t localPwrConstraint;
+#endif
+
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("lim_switch_primary_channel: old chnl %d --> new chnl %d "),
+ psessionEntry->currentOperChannel, newChannel);
+ )
+ psessionEntry->currentReqChannel = newChannel;
+ psessionEntry->limRFBand = lim_get_rf_band(newChannel);
+
+ psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
+
+ pMac->lim.gpchangeChannelCallback = lim_switch_channel_cback;
+ pMac->lim.gpchangeChannelData = NULL;
+
+#if defined WLAN_FEATURE_VOWIFI
+ lim_send_switch_chnl_params(pMac, newChannel, 0, 0, CH_WIDTH_20MHZ,
+ psessionEntry->maxTxPower,
+ psessionEntry->peSessionId, false);
+#else
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ &localPwrConstraint) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to read Local Power Constraint from cfg"));
+ return;
+ }
+ lim_send_switch_chnl_params(pMac, newChannel, 0, 0, CH_WIDTH_20MHZ,
+ (tPowerdBm) localPwrConstraint,
+ psessionEntry->peSessionId, false);
+#endif
+ return;
+}
+
+/**
+ * lim_switch_primary_secondary_channel()
+ *
+ ***FUNCTION:
+ * This function changes the primary and secondary channel.
+ * If 11h is enabled and user provides a "new channel ID"
+ * that is different from the current operating channel,
+ * then we must set this new channel in WNI_CFG_CURRENT_CHANNEL,
+ * assign notify LIM of such change.
+ *
+ ***NOTE:
+ * @param pMac Pointer to Global MAC structure
+ * @param newChannel New chnannel ID (or current channel ID)
+ * @param subband CB secondary info:
+ * - eANI_CB_SECONDARY_NONE
+ * - eANI_CB_SECONDARY_UP
+ * - eANI_CB_SECONDARY_DOWN
+ * @return NONE
+ */
+void lim_switch_primary_secondary_channel(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint8_t newChannel,
+ uint8_t ch_center_freq_seg0,
+ uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width)
+{
+#if !defined WLAN_FEATURE_VOWIFI
+ uint32_t localPwrConstraint;
+#endif
+ uint8_t subband = 0;
+#if !defined WLAN_FEATURE_VOWIFI
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ &localPwrConstraint) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to get Local Power Constraint from cfg"));
+ return;
+ }
+#endif
+ /* Assign the callback to resume TX once channel is changed. */
+ psessionEntry->currentReqChannel = newChannel;
+ psessionEntry->limRFBand = lim_get_rf_band(newChannel);
+ psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_OPERATION;
+ pMac->lim.gpchangeChannelCallback = lim_switch_channel_cback;
+ pMac->lim.gpchangeChannelData = NULL;
+
+#if defined WLAN_FEATURE_VOWIFI
+ lim_send_switch_chnl_params(pMac, newChannel, ch_center_freq_seg0,
+ ch_center_freq_seg1, ch_width,
+ psessionEntry->maxTxPower,
+ psessionEntry->peSessionId,
+ false);
+#else
+ lim_send_switch_chnl_params(pMac, newChannel, ch_center_freq_seg0,
+ ch_center_freq_seg1, ch_width,
+ psessionEntry->peSessionId,
+ false);
+#endif
+
+ /* Store the new primary and secondary channel in session entries if different */
+ if (psessionEntry->currentOperChannel != newChannel) {
+ lim_log(pMac, LOGW,
+ FL("switch old chnl %d --> new chnl %d "),
+ psessionEntry->currentOperChannel, newChannel);
+ psessionEntry->currentOperChannel = newChannel;
+ }
+ if (psessionEntry->htSecondaryChannelOffset != subband) {
+ lim_log(pMac, LOGW,
+ FL("switch old sec chnl %d --> new sec chnl %d "),
+ psessionEntry->htSecondaryChannelOffset, subband);
+ psessionEntry->htSecondaryChannelOffset = subband;
+ if (psessionEntry->htSecondaryChannelOffset ==
+ PHY_SINGLE_CHANNEL_CENTERED) {
+ psessionEntry->htSupportedChannelWidthSet =
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ } else {
+ psessionEntry->htSupportedChannelWidthSet =
+ WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
+ }
+ psessionEntry->htRecommendedTxWidthSet =
+ psessionEntry->htSupportedChannelWidthSet;
+ }
+
+ return;
+}
+
+/**
+ * lim_active_scan_allowed()
+ *
+ ***FUNCTION:
+ * Checks if active scans are permitted on the given channel
+ *
+ ***LOGIC:
+ * The config variable SCAN_CONTROL_LIST contains pairs of (channelNum, activeScanAllowed)
+ * Need to check if the channelNum matches, then depending on the corresponding
+ * scan flag, return true (for activeScanAllowed==1) or false (otherwise).
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param channelNum channel number
+ * @return None
+ */
+
+uint8_t lim_active_scan_allowed(tpAniSirGlobal pMac, uint8_t channelNum)
+{
+ uint32_t i;
+ uint8_t channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN];
+ uint32_t len = WNI_CFG_SCAN_CONTROL_LIST_LEN;
+ if (wlan_cfg_get_str(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len)
+ != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("Unable to get scan control list"));
+ )
+ return false;
+ }
+
+ if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) {
+ lim_log(pMac, LOGE, FL("Invalid scan control list length:%d"),
+ len);
+ return false;
+ }
+
+ for (i = 0; (i + 1) < len; i += 2) {
+ if (channelPair[i] == channelNum)
+ return ((channelPair[i + 1] ==
+ eSIR_ACTIVE_SCAN) ? true : false);
+ }
+ return false;
+}
+
+/**
+ * lim_get_ht_capability()
+ *
+ ***FUNCTION:
+ * A utility function that returns the "current HT capability state" for the HT
+ * capability of interest (as requested in the API)
+ *
+ ***LOGIC:
+ * This routine will return with the "current" setting of a requested HT
+ * capability. This state info could be retrieved from -
+ * a) CFG (for static entries)
+ * b) Run time info
+ * - Dynamic state maintained by LIM
+ * - Configured at radio init time by SME
+ *
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param htCap The HT capability being queried
+ * @return uint8_t The current state of the requested HT capability is returned in a
+ * uint8_t variable
+ */
+
+uint8_t lim_get_ht_capability(tpAniSirGlobal pMac,
+ uint32_t htCap, tpPESession psessionEntry)
+{
+ uint8_t retVal = 0;
+ uint8_t *ptr;
+ uint32_t cfgValue;
+ tSirMacHTCapabilityInfo macHTCapabilityInfo = { 0 };
+ tSirMacExtendedHTCapabilityInfo macExtHTCapabilityInfo = { 0 };
+ tSirMacTxBFCapabilityInfo macTxBFCapabilityInfo = { 0 };
+ tSirMacASCapabilityInfo macASCapabilityInfo = { 0 };
+
+ /* */
+ /* Determine which CFG to read from. Not ALL of the HT */
+ /* related CFG's need to be read each time this API is */
+ /* accessed */
+ /* */
+ if (htCap >= eHT_ANTENNA_SELECTION && htCap < eHT_SI_GRANULARITY) {
+ /* Get Antenna Seletion HT Capabilities */
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac, WNI_CFG_AS_CAP, &cfgValue))
+ cfgValue = 0;
+ ptr = (uint8_t *) &macASCapabilityInfo;
+ *((uint8_t *) ptr) = (uint8_t) (cfgValue & 0xff);
+ } else {
+ if (htCap >= eHT_TX_BEAMFORMING &&
+ htCap < eHT_ANTENNA_SELECTION) {
+ /* Get Transmit Beam Forming HT Capabilities */
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac, WNI_CFG_TX_BF_CAP, &cfgValue))
+ cfgValue = 0;
+ ptr = (uint8_t *) &macTxBFCapabilityInfo;
+ *((uint32_t *) ptr) = (uint32_t) (cfgValue);
+ } else {
+ if (htCap >= eHT_PCO && htCap < eHT_TX_BEAMFORMING) {
+ /* Get Extended HT Capabilities */
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac,
+ WNI_CFG_EXT_HT_CAP_INFO,
+ &cfgValue))
+ cfgValue = 0;
+ ptr = (uint8_t *) &macExtHTCapabilityInfo;
+ *((uint16_t *) ptr) =
+ (uint16_t) (cfgValue & 0xffff);
+ } else {
+ if (htCap < eHT_MAX_RX_AMPDU_FACTOR) {
+ /* Get HT Capabilities */
+ if (eSIR_SUCCESS !=
+ wlan_cfg_get_int(pMac,
+ WNI_CFG_HT_CAP_INFO,
+ &cfgValue))
+ cfgValue = 0;
+ ptr = (uint8_t *) &macHTCapabilityInfo;
+ /* CR 265282 MDM SoftAP 2.4PL: SoftAP boot up crash in 2.4 PL builds while same WLAN SU is working on 2.1 PL */
+ *ptr++ = cfgValue & 0xff;
+ *ptr = (cfgValue >> 8) & 0xff;
+ }
+ }
+ }
+ }
+
+ switch (htCap) {
+ case eHT_LSIG_TXOP_PROTECTION:
+ retVal = pMac->lim.gHTLsigTXOPProtection;
+ break;
+
+ case eHT_STBC_CONTROL_FRAME:
+ retVal = (uint8_t) macHTCapabilityInfo.stbcControlFrame;
+ break;
+
+ case eHT_PSMP:
+ retVal = pMac->lim.gHTPSMPSupport;
+ break;
+
+ case eHT_DSSS_CCK_MODE_40MHZ:
+ retVal = pMac->lim.gHTDsssCckRate40MHzSupport;
+ break;
+
+ case eHT_MAX_AMSDU_LENGTH:
+ retVal = (uint8_t) macHTCapabilityInfo.maximalAMSDUsize;
+ break;
+
+ case eHT_RX_STBC:
+ retVal = (uint8_t) psessionEntry->htConfig.ht_rx_stbc;
+ break;
+
+ case eHT_TX_STBC:
+ retVal = (uint8_t) psessionEntry->htConfig.ht_tx_stbc;
+ break;
+
+ case eHT_SHORT_GI_40MHZ:
+ retVal = (uint8_t)
+ (psessionEntry->htConfig.ht_sgi) ? macHTCapabilityInfo.
+ shortGI40MHz : 0;
+ break;
+
+ case eHT_SHORT_GI_20MHZ:
+ retVal = (uint8_t)
+ (psessionEntry->htConfig.ht_sgi) ? macHTCapabilityInfo.
+ shortGI20MHz : 0;
+ break;
+
+ case eHT_GREENFIELD:
+ retVal = (uint8_t) macHTCapabilityInfo.greenField;
+ break;
+
+ case eHT_MIMO_POWER_SAVE:
+ retVal = (uint8_t) pMac->lim.gHTMIMOPSState;
+ break;
+
+ case eHT_SUPPORTED_CHANNEL_WIDTH_SET:
+ retVal = (uint8_t) psessionEntry->htSupportedChannelWidthSet;
+ break;
+
+ case eHT_ADVANCED_CODING:
+ retVal = (uint8_t) psessionEntry->htConfig.ht_rx_ldpc;
+ break;
+
+ case eHT_MAX_RX_AMPDU_FACTOR:
+ retVal = pMac->lim.gHTMaxRxAMpduFactor;
+ break;
+
+ case eHT_MPDU_DENSITY:
+ retVal = pMac->lim.gHTAMpduDensity;
+ break;
+
+ case eHT_PCO:
+ retVal = (uint8_t) macExtHTCapabilityInfo.pco;
+ break;
+
+ case eHT_TRANSITION_TIME:
+ retVal = (uint8_t) macExtHTCapabilityInfo.transitionTime;
+ break;
+
+ case eHT_MCS_FEEDBACK:
+ retVal = (uint8_t) macExtHTCapabilityInfo.mcsFeedback;
+ break;
+
+ case eHT_TX_BEAMFORMING:
+ retVal = (uint8_t) macTxBFCapabilityInfo.txBF;
+ break;
+
+ case eHT_ANTENNA_SELECTION:
+ retVal = (uint8_t) macASCapabilityInfo.antennaSelection;
+ break;
+
+ case eHT_SI_GRANULARITY:
+ retVal = pMac->lim.gHTServiceIntervalGranularity;
+ break;
+
+ case eHT_CONTROLLED_ACCESS:
+ retVal = pMac->lim.gHTControlledAccessOnly;
+ break;
+
+ case eHT_RIFS_MODE:
+ retVal = psessionEntry->beaconParams.fRIFSMode;
+ break;
+
+ case eHT_RECOMMENDED_TX_WIDTH_SET:
+ retVal = psessionEntry->htRecommendedTxWidthSet;
+ break;
+
+ case eHT_EXTENSION_CHANNEL_OFFSET:
+ retVal = psessionEntry->htSecondaryChannelOffset;
+ break;
+
+ case eHT_OP_MODE:
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ retVal = psessionEntry->htOperMode;
+ else
+ retVal = pMac->lim.gHTOperMode;
+ break;
+
+ case eHT_BASIC_STBC_MCS:
+ retVal = pMac->lim.gHTSTBCBasicMCS;
+ break;
+
+ case eHT_DUAL_CTS_PROTECTION:
+ retVal = pMac->lim.gHTDualCTSProtection;
+ break;
+
+ case eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT:
+ retVal =
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport;
+ break;
+
+ case eHT_PCO_ACTIVE:
+ retVal = pMac->lim.gHTPCOActive;
+ break;
+
+ case eHT_PCO_PHASE:
+ retVal = pMac->lim.gHTPCOPhase;
+ break;
+
+ default:
+ break;
+ }
+
+ return retVal;
+}
+
+/**
+ * lim_enable_11a_protection() - updates protection params for enable 11a
+ * protection request
+ * @mac_ctx: pointer to Global MAC structure
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @bcn_prms: beacon parameters
+ * @pe_session: pe session entry
+ *
+ * This fucntion updates protection params for enable 11a protection request
+ *
+ * @Return: void
+ */
+static void
+lim_enable_11a_protection(tpAniSirGlobal mac_ctx,
+ uint8_t overlap,
+ tpUpdateBeaconParams bcn_prms,
+ tpPESession pe_session)
+{
+ /*
+ * If we are AP and HT capable, we need to set the HT OP mode
+ * appropriately.
+ */
+ if ((LIM_IS_AP_ROLE(pe_session) || LIM_IS_BT_AMP_AP_ROLE(pe_session))
+ && (true == pe_session->htCapability)) {
+ if (overlap) {
+ mac_ctx->lim.gLimOverlap11aParams.protectionEnabled =
+ true;
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ mac_ctx->lim.gHTOperMode)
+ && (eSIR_HT_OP_MODE_MIXED !=
+ mac_ctx->lim.gHTOperMode)) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ pe_session->htOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, bcn_prms, pe_session);
+ lim_enable_ht_obss_protection(mac_ctx, true,
+ overlap, bcn_prms, pe_session);
+ }
+ } else {
+ pe_session->gLim11aParams.protectionEnabled = true;
+ if (eSIR_HT_OP_MODE_MIXED != pe_session->htOperMode) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_MIXED;
+ pe_session->htOperMode = eSIR_HT_OP_MODE_MIXED;
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, bcn_prms, pe_session);
+ lim_enable_ht_obss_protection(mac_ctx, true,
+ overlap, bcn_prms, pe_session);
+ }
+ }
+ }
+ /* This part is common for station as well. */
+ if (false == pe_session->beaconParams.llaCoexist) {
+ lim_log(mac_ctx, LOGW,
+ FL(" => protection from 11A Enabled"));
+ bcn_prms->llaCoexist = true;
+ pe_session->beaconParams.llaCoexist = true;
+ bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+ }
+}
+
+/**
+ * lim_disable_11a_protection() - updates protection params for disable 11a
+ * protection request
+ * @mac_ctx: pointer to Global MAC structure
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @bcn_prms: beacon parameters
+ * @pe_session: pe session entry
+ *
+ * This fucntion updates protection params for disable 11a protection request
+ *
+ * @Return: void
+ */
+static void
+lim_disable_11a_protection(tpAniSirGlobal mac_ctx,
+ uint8_t overlap,
+ tpUpdateBeaconParams bcn_prms,
+ tpPESession pe_session)
+{
+ if (false == pe_session->beaconParams.llaCoexist)
+ return;
+
+ /* for station role */
+ if (!LIM_IS_AP_ROLE(pe_session)) {
+ lim_log(mac_ctx, LOGW,
+ FL("===> Protection from 11A Disabled"));
+ bcn_prms->llaCoexist = false;
+ pe_session->beaconParams.llaCoexist = false;
+ bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+ return;
+ }
+ /*
+ * for AP role.
+ * we need to take care of HT OP mode change if needed.
+ * We need to take care of Overlap cases.
+ */
+ if (overlap) {
+ /* Overlap Legacy protection disabled. */
+ mac_ctx->lim.gLimOverlap11aParams.protectionEnabled = false;
+
+ /*
+ * We need to take care of HT OP mode iff we are HT AP.
+ * OR no HT op-mode change is needed if any of the overlap
+ * protection enabled.
+ */
+ if (!pe_session->htCapability ||
+ (mac_ctx->lim.gLimOverlap11aParams.protectionEnabled
+ || mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled
+ || mac_ctx->lim.gLimOverlapNonGfParams.protectionEnabled))
+ goto disable_11a_end;
+
+ /* Check if there is a need to change HT OP mode. */
+ if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ mac_ctx->lim.gHTOperMode) {
+ lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
+ bcn_prms, pe_session);
+ lim_enable_ht_obss_protection(mac_ctx, false, overlap,
+ bcn_prms, pe_session);
+
+ if (pe_session->gLimHt20Params.protectionEnabled)
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ else
+ mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ } else {
+ /* Disable protection from 11A stations. */
+ pe_session->gLim11aParams.protectionEnabled = false;
+ lim_enable_ht_obss_protection(mac_ctx, false, overlap,
+ bcn_prms, pe_session);
+
+ /*
+ * Check if any other non-HT protection enabled. Right now we
+ * are in HT OP Mixed mode. Change HT op mode appropriately.
+ */
+
+ /* Change HT OP mode to 01 if any overlap protection enabled */
+ if (mac_ctx->lim.gLimOverlap11aParams.protectionEnabled
+ || mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled
+ || mac_ctx->lim.gLimOverlapNonGfParams.protectionEnabled) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ pe_session->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(mac_ctx, true, overlap,
+ bcn_prms, pe_session);
+ } else if (pe_session->gLimHt20Params.protectionEnabled) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ pe_session->htOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
+ bcn_prms, pe_session);
+ } else {
+ mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ pe_session->htOperMode = eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(mac_ctx, false, overlap,
+ bcn_prms, pe_session);
+ }
+ }
+
+disable_11a_end:
+ if (!mac_ctx->lim.gLimOverlap11aParams.protectionEnabled &&
+ !pe_session->gLim11aParams.protectionEnabled) {
+ lim_log(mac_ctx, LOGW,
+ FL("===> Protection from 11A Disabled"));
+ bcn_prms->llaCoexist = false;
+ pe_session->beaconParams.llaCoexist = false;
+ bcn_prms->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED;
+ }
+}
+
+/**
+ * lim_update_11a_protection() - based on config setting enables\disables 11a
+ * protection.
+ * @mac_ctx: pointer to Global MAC structure
+ * @enable: 1=> enable protection, 0=> disable protection.
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @bcn_prms: beacon parameters
+ * @session: pe session entry
+ *
+ * This based on config setting enables\disables 11a protection.
+ *
+ * @Return: success of failure of operation
+ */
+tSirRetStatus
+lim_update_11a_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
+ uint8_t overlap, tpUpdateBeaconParams bcn_prms,
+ tpPESession session)
+{
+ if (NULL == session) {
+ lim_log(mac_ctx, LOGW, FL("session is NULL"));
+ return eSIR_FAILURE;
+ }
+ /* overlapping protection configuration check. */
+ if (!overlap) {
+ /* normal protection config check */
+ if ((LIM_IS_AP_ROLE(session)) &&
+ (!session->cfgProtection.fromlla)) {
+ /* protection disabled. */
+ lim_log(mac_ctx, LOGW,
+ FL("protection from 11a is disabled"));
+ return eSIR_SUCCESS;
+ }
+ }
+
+ if (enable)
+ lim_enable_11a_protection(mac_ctx, overlap, bcn_prms, session);
+ else
+ lim_disable_11a_protection(mac_ctx, overlap, bcn_prms, session);
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_handle_enable11g_protection_enabled() - handle 11g protection enabled
+ * @mac_ctx: pointer to Globale Mac structure
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @session_entry: pointer to tpPESession
+ *
+ * Function handles 11g protection enaled case
+ *
+ * Return: none
+ */
+static void
+lim_handle_enable11g_protection_enabled(tpAniSirGlobal mac_ctx,
+ tpUpdateBeaconParams beaconparams,
+ uint8_t overlap, tpPESession session_entry)
+{
+ /*
+ * If we are AP and HT capable, we need to set the HT OP mode
+ * appropriately.
+ */
+ if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+ session_entry->gLimOlbcParams.protectionEnabled = true;
+
+ lim_log(mac_ctx, LOG1, FL("protection from olbc is enabled"));
+
+ if (true == session_entry->htCapability) {
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ session_entry->htOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED !=
+ session_entry->htOperMode)) {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ }
+ /*
+ * CR-263021: OBSS bit is not switching back to 0 after
+ * disabling the overlapping legacy BSS
+ */
+ /*
+ * This fixes issue of OBSS bit not set after 11b, 11g
+ * station leaves
+ */
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, beaconparams, session_entry);
+ /*
+ * Not processing OBSS bit from other APs, as we are
+ * already taking care of Protection from overlapping
+ * BSS based on erp IE or useProtection bit
+ */
+ lim_enable_ht_obss_protection(mac_ctx, true,
+ overlap, beaconparams, session_entry);
+ }
+ } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+ session_entry->gLim11bParams.protectionEnabled = true;
+ lim_log(mac_ctx, LOG1, FL("protection from 11b is enabled"));
+ if (true == session_entry->htCapability) {
+ if (eSIR_HT_OP_MODE_MIXED !=
+ session_entry->htOperMode) {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_MIXED;
+ lim_enable_ht_rifs_protection(mac_ctx,
+ true, overlap, beaconparams,
+ session_entry);
+ lim_enable_ht_obss_protection(mac_ctx,
+ true, overlap, beaconparams,
+ session_entry);
+ }
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(session_entry) &&
+ (true == session_entry->htCapability) && overlap) {
+ session_entry->gLimOlbcParams.protectionEnabled = true;
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ mac_ctx->lim.gHTOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED !=
+ mac_ctx->lim.gHTOperMode)) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ }
+ /*
+ * CR-263021: OBSS bit is not switching back to 0 after
+ * disabling the overlapping legacy BSS
+ */
+ /*
+ * This fixes issue of OBSS bit not set after 11b, 11g station
+ * leaves
+ */
+ lim_enable_ht_rifs_protection(mac_ctx, true, overlap,
+ beaconparams, session_entry);
+ /*
+ * Not processing OBSS bit from other APs, as we are already
+ * taking care of Protection from overlapping BSS based on erp
+ * IE or useProtection bit
+ */
+ lim_enable_ht_obss_protection(mac_ctx, true, overlap,
+ beaconparams, session_entry);
+ } else if (LIM_IS_BT_AMP_AP_ROLE(session_entry) &&
+ (true == session_entry->htCapability) && !overlap) {
+ session_entry->gLim11bParams.protectionEnabled = true;
+ if (eSIR_HT_OP_MODE_MIXED !=
+ mac_ctx->lim.gHTOperMode) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_MIXED;
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, true,
+ overlap, beaconparams, session_entry);
+ }
+ }
+ /* This part is common for staiton as well. */
+ if (false == session_entry->beaconParams.llbCoexist) {
+ lim_log(mac_ctx, LOG1, FL("=> 11G Protection Enabled"));
+ beaconparams->llbCoexist =
+ session_entry->beaconParams.llbCoexist = true;
+ beaconparams->paramChangeBitmap |=
+ PARAM_llBCOEXIST_CHANGED;
+ }
+}
+
+/**
+ * lim_handle_11g_protection_for_11bcoexist() - 11g protection for 11b co-ex
+ * @mac_ctx: pointer to Globale Mac structure
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @session_entry: pointer to tpPESession
+ *
+ * Function handles 11g protection for 11b co-exist
+ *
+ * Return: none
+ */
+static void
+lim_handle_11g_protection_for_11bcoexist(tpAniSirGlobal mac_ctx,
+ tpUpdateBeaconParams beaconparams,
+ uint8_t overlap, tpPESession session_entry)
+{
+ /*
+ * For AP role:
+ * we need to take care of HT OP mode change if needed.
+ * We need to take care of Overlap cases.
+ */
+ if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+ /* Overlap Legacy protection disabled. */
+ session_entry->gLimOlbcParams.protectionEnabled = false;
+
+ /* We need to take care of HT OP mode if we are HT AP. */
+ if (session_entry->htCapability) {
+ /*
+ * no HT op mode change if any of the overlap
+ * protection enabled.
+ */
+ if (!(session_entry->gLimOverlap11gParams.
+ protectionEnabled ||
+ session_entry->gLimOverlapHt20Params.
+ protectionEnabled ||
+ session_entry->gLimOverlapNonGfParams.
+ protectionEnabled) &&
+ /*
+ * Check if there is a need to change HT
+ * OP mode.
+ */
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ session_entry->htOperMode)) {
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ if (session_entry->gLimHt20Params.
+ protectionEnabled) {
+ if(eHT_CHANNEL_WIDTH_20MHZ ==
+ session_entry->htSupportedChannelWidthSet)
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ else
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ } else
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+ /* Disable protection from 11B stations. */
+ session_entry->gLim11bParams.protectionEnabled = false;
+ lim_log(mac_ctx, LOG1, FL("===> 11B Protection Disabled"));
+ /* Check if any other non-HT protection enabled. */
+ if (!session_entry->gLim11gParams.protectionEnabled) {
+ /* Right now we are in HT OP Mixed mode. */
+ /* Change HT op mode appropriately. */
+ lim_enable_ht_obss_protection(mac_ctx, false, overlap,
+ beaconparams, session_entry);
+ /*
+ * Change HT OP mode to 01 if any overlap protection
+ * enabled
+ */
+ if (session_entry->gLimOlbcParams.protectionEnabled ||
+ session_entry->gLimOverlap11gParams.
+ protectionEnabled ||
+ session_entry->gLimOverlapHt20Params.
+ protectionEnabled ||
+ session_entry->gLimOverlapNonGfParams.
+ protectionEnabled) {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_log(mac_ctx, LOG1,
+ FL("===> 11G Protection Disabled"));
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, beaconparams,
+ session_entry);
+ } else if (session_entry->gLimHt20Params.
+ protectionEnabled) {
+ /* Commenting because of CR 258588 WFA cert */
+ /* session_entry->htOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; */
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_log(mac_ctx, LOG1,
+ FL("===> 11G Protection Disabled"));
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams,
+ session_entry);
+ } else {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams,
+ session_entry);
+ }
+ }
+ }
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ if (!session_entry->gLimOlbcParams.protectionEnabled &&
+ !session_entry->gLim11bParams.protectionEnabled) {
+ lim_log(mac_ctx, LOG1,
+ FL("===> 11G Protection Disabled"));
+ beaconparams->llbCoexist =
+ session_entry->beaconParams.llbCoexist =
+ false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_llBCOEXIST_CHANGED;
+ }
+ }
+ if (LIM_IS_BT_AMP_AP_ROLE(session_entry) && overlap) {
+ /* Overlap Legacy protection disabled. */
+ session_entry->gLimOlbcParams.protectionEnabled = false;
+
+ /* We need to take care of HT OP mode iff we are HT AP. */
+ if (session_entry->htCapability) {
+ /*
+ * no HT op mode change if any of the overlap protection
+ * enabled.
+ */
+ if (!(mac_ctx->lim.gLimOverlap11gParams.
+ protectionEnabled ||
+ mac_ctx->lim.gLimOverlapHt20Params.
+ protectionEnabled ||
+ mac_ctx->lim.gLimOverlapNonGfParams.
+ protectionEnabled) &&
+ /*
+ * Check if there is a need to change HT
+ * OP mode.
+ */
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ mac_ctx->lim.gHTOperMode)) {
+ lim_enable_ht_rifs_protection(mac_ctx,
+ false, overlap, beaconparams,
+ session_entry);
+ lim_enable_ht_obss_protection(mac_ctx,
+ false, overlap, beaconparams,
+ session_entry);
+ if (session_entry->gLimHt20Params.
+ protectionEnabled)
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ else
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(session_entry) && !overlap) {
+ /* Disable protection from 11B stations. */
+ session_entry->gLim11bParams.protectionEnabled = false;
+ /* Check if any other non-HT protection enabled. */
+ if (!session_entry->gLim11gParams.protectionEnabled) {
+ /* Right now we are in HT OP Mixed mode. */
+ /* Change HT op mode appropriately. */
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ /*
+ * Change HT OP mode to 01 if any overlap protection
+ * enabled
+ */
+ if (session_entry->gLimOlbcParams.protectionEnabled ||
+ mac_ctx->lim.gLimOverlap11gParams.
+ protectionEnabled ||
+ mac_ctx->lim.gLimOverlapHt20Params.
+ protectionEnabled ||
+ mac_ctx->lim.gLimOverlapNonGfParams.
+ protectionEnabled) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(mac_ctx,
+ true, overlap, beaconparams,
+ session_entry);
+ } else if (session_entry->gLimHt20Params.
+ protectionEnabled) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ lim_enable_ht_rifs_protection(mac_ctx,
+ false, overlap, beaconparams,
+ session_entry);
+ } else {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(mac_ctx,
+ false, overlap, beaconparams,
+ session_entry);
+ }
+ }
+ }
+ if (LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ if (!session_entry->gLimOlbcParams.protectionEnabled &&
+ !session_entry->gLim11bParams.protectionEnabled) {
+ lim_log(mac_ctx, LOG1,
+ FL("===> 11G Protection Disabled"));
+ beaconparams->llbCoexist =
+ session_entry->beaconParams.llbCoexist =
+ false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_llBCOEXIST_CHANGED;
+ }
+ }
+ /* For station role */
+ if (!LIM_IS_AP_ROLE(session_entry) &&
+ !LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOG1, FL("===> 11G Protection Disabled"));
+ beaconparams->llbCoexist =
+ session_entry->beaconParams.llbCoexist = false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_llBCOEXIST_CHANGED;
+ }
+}
+
+/**
+ * lim_enable11g_protection() - Function to enable 11g protection
+ * @mac_ctx: pointer to Global Mac structure
+ * @enable: 1=> enable protection, 0=> disable protection.
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ *
+ * based on config setting enables\disables 11g protection.
+ *
+ * Return: Success - eSIR_SUCCESS - Success, Error number - Failure
+ */
+tSirRetStatus
+lim_enable11g_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
+ uint8_t overlap, tpUpdateBeaconParams beaconparams,
+ tpPESession session_entry)
+{
+
+ /* overlapping protection configuration check. */
+ if (!overlap) {
+ /* normal protection config check */
+ if ((LIM_IS_AP_ROLE(session_entry)) &&
+ !session_entry->cfgProtection.fromllb) {
+ /* protection disabled. */
+ lim_log(mac_ctx, LOG1,
+ FL("protection from 11b is disabled"));
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(session_entry)) {
+ if (!mac_ctx->lim.cfgProtection.fromllb) {
+ /* protection disabled. */
+ lim_log(mac_ctx, LOG1,
+ FL("protection from 11b is disabled"));
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (enable) {
+ lim_handle_enable11g_protection_enabled(mac_ctx, beaconparams,
+ overlap, session_entry);
+ } else if (true == session_entry->beaconParams.llbCoexist) {
+ lim_handle_11g_protection_for_11bcoexist(mac_ctx, beaconparams,
+ overlap, session_entry);
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_enable_ht_protection_from11g
+ \brief based on cofig enables\disables protection from 11g.
+ \param uint8_t enable : 1=> enable protection, 0=> disable protection.
+ \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+lim_enable_ht_protection_from11g(tpAniSirGlobal pMac, uint8_t enable,
+ uint8_t overlap,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ if (!psessionEntry->htCapability)
+ return eSIR_SUCCESS; /* protection from 11g is only for HT stations. */
+
+ /* overlapping protection configuration check. */
+ if (overlap) {
+ if ((LIM_IS_AP_ROLE(psessionEntry))
+ && (!psessionEntry->cfgProtection.overlapFromllg)) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("overlap protection from 11g is disabled"));
+ );
+ return eSIR_SUCCESS;
+ } else if (LIM_IS_BT_AMP_AP_ROLE(psessionEntry) &&
+ (!pMac->lim.cfgProtection.overlapFromllg)) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("overlap protection from 11g is disabled"));
+ );
+ return eSIR_SUCCESS;
+ }
+ } else {
+ /* normal protection config check */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ !psessionEntry->cfgProtection.fromllg) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("protection from 11g is disabled"));
+ )
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+ if (!pMac->lim.cfgProtection.fromllg) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("protection from 11g is disabled"));
+ )
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+ if (enable) {
+ /* If we are AP and HT capable, we need to set the HT OP mode */
+ /* appropriately. */
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if (overlap) {
+ psessionEntry->gLimOverlap11gParams.
+ protectionEnabled = true;
+ /* 11g exists in overlap BSS. */
+ /* need not to change the operating mode to overlap_legacy */
+ /* if higher or same protection operating mode is enabled right now. */
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ psessionEntry->htOperMode)
+ && (eSIR_HT_OP_MODE_MIXED !=
+ psessionEntry->htOperMode)) {
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ }
+ lim_enable_ht_rifs_protection(pMac, true, overlap,
+ pBeaconParams,
+ psessionEntry);
+ lim_enable_ht_obss_protection(pMac, true, overlap,
+ pBeaconParams,
+ psessionEntry);
+ } else {
+ /* 11g is associated to an AP operating in 11n mode. */
+ /* Change the HT operating mode to 'mixed mode'. */
+ psessionEntry->gLim11gParams.protectionEnabled =
+ true;
+ if (eSIR_HT_OP_MODE_MIXED !=
+ psessionEntry->htOperMode) {
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_MIXED;
+ lim_enable_ht_rifs_protection(pMac, true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ lim_enable_ht_obss_protection(pMac, true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ }
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ if (overlap) {
+ pMac->lim.gLimOverlap11gParams.
+ protectionEnabled = true;
+ /* 11g exists in overlap BSS. */
+ /* need not to change the operating mode to overlap_legacy */
+ /* if higher or same protection operating mode is enabled right now. */
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ pMac->lim.gHTOperMode)
+ && (eSIR_HT_OP_MODE_MIXED !=
+ pMac->lim.gHTOperMode)) {
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(pMac, true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ }
+ } else {
+ /* 11g is associated to an AP operating in 11n mode. */
+ /* Change the HT operating mode to 'mixed mode'. */
+ psessionEntry->gLim11gParams.protectionEnabled =
+ true;
+ if (eSIR_HT_OP_MODE_MIXED !=
+ pMac->lim.gHTOperMode) {
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_MIXED;
+ lim_enable_ht_rifs_protection(pMac, true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ lim_enable_ht_obss_protection(pMac, true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ }
+ }
+ }
+ /* This part is common for staiton as well. */
+ if (false == psessionEntry->beaconParams.llgCoexist) {
+ pBeaconParams->llgCoexist =
+ psessionEntry->beaconParams.llgCoexist = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_llGCOEXIST_CHANGED;
+ } else if (true ==
+ psessionEntry->gLimOverlap11gParams.
+ protectionEnabled) {
+ /* As operating mode changed after G station assoc some way to update beacon */
+ /* This addresses the issue of mode not changing to - 11 in beacon when OBSS overlap is enabled */
+ /* pMac->sch.schObject.fBeaconChanged = 1; */
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_llGCOEXIST_CHANGED;
+ }
+ } else if (true == psessionEntry->beaconParams.llgCoexist) {
+ /* for AP role. */
+ /* we need to take care of HT OP mode change if needed. */
+ /* We need to take care of Overlap cases. */
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if (overlap) {
+ /* Overlap Legacy protection disabled. */
+ if (psessionEntry->gLim11gParams.numSta == 0)
+ psessionEntry->gLimOverlap11gParams.
+ protectionEnabled = false;
+
+ /* no HT op mode change if any of the overlap protection enabled. */
+ if (!
+ (psessionEntry->gLimOlbcParams.
+ protectionEnabled
+ || psessionEntry->gLimOverlapHt20Params.
+ protectionEnabled
+ || psessionEntry->gLimOverlapNonGfParams.
+ protectionEnabled)) {
+ /* Check if there is a need to change HT OP mode. */
+ if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ psessionEntry->htOperMode) {
+ lim_enable_ht_rifs_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ lim_enable_ht_obss_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+
+ if (psessionEntry->gLimHt20Params.protectionEnabled) {
+ if(eHT_CHANNEL_WIDTH_20MHZ ==
+ psessionEntry->htSupportedChannelWidthSet)
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ else
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ } else
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ } else {
+ /* Disable protection from 11G stations. */
+ psessionEntry->gLim11gParams.protectionEnabled =
+ false;
+ /* Check if any other non-HT protection enabled. */
+ if (!psessionEntry->gLim11bParams.
+ protectionEnabled) {
+
+ /* Right now we are in HT OP Mixed mode. */
+ /* Change HT op mode appropriately. */
+ lim_enable_ht_obss_protection(pMac, false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+
+ /* Change HT OP mode to 01 if any overlap protection enabled */
+ if (psessionEntry->gLimOlbcParams.
+ protectionEnabled
+ || psessionEntry->
+ gLimOverlap11gParams.
+ protectionEnabled
+ || psessionEntry->
+ gLimOverlapHt20Params.
+ protectionEnabled
+ || psessionEntry->
+ gLimOverlapNonGfParams.
+ protectionEnabled) {
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(pMac,
+ true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ } else if (psessionEntry->
+ gLimHt20Params.
+ protectionEnabled) {
+ /* Commenting because of CR 258588 WFA cert */
+ /* psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; */
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ } else {
+ psessionEntry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ }
+ }
+ }
+ if (!psessionEntry->gLimOverlap11gParams.
+ protectionEnabled
+ && !psessionEntry->gLim11gParams.
+ protectionEnabled) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("===> Protection from 11G Disabled"));
+ )
+ pBeaconParams->llgCoexist =
+ psessionEntry->beaconParams.llgCoexist =
+ false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_llGCOEXIST_CHANGED;
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+ if (overlap) {
+ /* Overlap Legacy protection disabled. */
+ pMac->lim.gLimOverlap11gParams.
+ protectionEnabled = false;
+
+ /* no HT op mode change if any of the overlap protection enabled. */
+ if (!
+ (psessionEntry->gLimOlbcParams.
+ protectionEnabled
+ || psessionEntry->gLimOverlapHt20Params.
+ protectionEnabled
+ || psessionEntry->gLimOverlapNonGfParams.
+ protectionEnabled)) {
+ /* Check if there is a need to change HT OP mode. */
+ if (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ pMac->lim.gHTOperMode) {
+ lim_enable_ht_rifs_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ lim_enable_ht_obss_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+
+ if (psessionEntry->
+ gLimHt20Params.
+ protectionEnabled)
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ else
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ } else {
+ /* Disable protection from 11G stations. */
+ psessionEntry->gLim11gParams.protectionEnabled =
+ false;
+ /* Check if any other non-HT protection enabled. */
+ if (!psessionEntry->gLim11bParams.
+ protectionEnabled) {
+
+ /* Right now we are in HT OP Mixed mode. */
+ /* Change HT op mode appropriately. */
+ lim_enable_ht_obss_protection(pMac, false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+
+ /* Change HT OP mode to 01 if any overlap protection enabled */
+ if (psessionEntry->gLimOlbcParams.
+ protectionEnabled
+ || pMac->lim.gLimOverlap11gParams.
+ protectionEnabled
+ || pMac->lim.gLimOverlapHt20Params.
+ protectionEnabled
+ || pMac->lim.gLimOverlapNonGfParams.
+ protectionEnabled) {
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(pMac,
+ true,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ } else if (psessionEntry->
+ gLimHt20Params.
+ protectionEnabled) {
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ lim_enable_ht_rifs_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ } else {
+ pMac->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(pMac,
+ false,
+ overlap,
+ pBeaconParams,
+ psessionEntry);
+ }
+ }
+ }
+ if (!pMac->lim.gLimOverlap11gParams.protectionEnabled &&
+ !psessionEntry->gLim11gParams.protectionEnabled) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("===> Protection from 11G Disabled"));
+ )
+ pBeaconParams->llgCoexist =
+ psessionEntry->beaconParams.llgCoexist =
+ false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_llGCOEXIST_CHANGED;
+ }
+ }
+ /* for station role */
+ else {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> Protection from 11G Disabled"));
+ )
+ pBeaconParams->llgCoexist =
+ psessionEntry->beaconParams.llgCoexist = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_llGCOEXIST_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/* FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. */
+/* This check will be done at the caller. */
+
+/** -------------------------------------------------------------
+ \fn limEnableHtObssProtection
+ \brief based on cofig enables\disables obss protection.
+ \param uint8_t enable : 1=> enable protection, 0=> disable protection.
+ \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+lim_enable_ht_obss_protection(tpAniSirGlobal pMac, uint8_t enable,
+ uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+
+ if (!psessionEntry->htCapability)
+ return eSIR_SUCCESS; /* this protection is only for HT stations. */
+
+ /* overlapping protection configuration check. */
+ if (overlap) {
+ /* overlapping protection configuration check. */
+ } else {
+ /* normal protection config check */
+ if ((LIM_IS_AP_ROLE(psessionEntry)) &&
+ !psessionEntry->cfgProtection.obss) { /* ToDo Update this field */
+ /* protection disabled. */
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("protection from Obss is disabled"));
+ )
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+ if (!pMac->lim.cfgProtection.obss) { /* ToDo Update this field */
+ /* protection disabled. */
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("protection from Obss is disabled"));
+ )
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if ((enable)
+ && (false == psessionEntry->beaconParams.gHTObssMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("=>obss protection enabled"));
+ )
+ psessionEntry->beaconParams.gHTObssMode = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; /* UPDATE AN ENUM FOR OBSS MODE <todo> */
+
+ } else if (!enable
+ && (true ==
+ psessionEntry->beaconParams.gHTObssMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> obss Protection disabled"));
+ )
+ psessionEntry->beaconParams.gHTObssMode = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_OBSS_MODE_CHANGED;
+
+ }
+/* CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS */
+ if (!enable && !overlap) {
+ psessionEntry->gLimOverlap11gParams.protectionEnabled =
+ false;
+ }
+ } else {
+ if ((enable)
+ && (false == psessionEntry->beaconParams.gHTObssMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("=>obss protection enabled"));
+ )
+ psessionEntry->beaconParams.gHTObssMode = true;
+ pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; /* UPDATE AN ENUM FOR OBSS MODE <todo> */
+
+ } else if (!enable
+ && (true ==
+ psessionEntry->beaconParams.gHTObssMode)) {
+
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> obss Protection disabled"));
+ )
+ psessionEntry->beaconParams.gHTObssMode = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_OBSS_MODE_CHANGED;
+
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_handle_ht20protection_enabled() - Handle ht20 protection enabled
+ * @mac_ctx: pointer to Gloal Mac Structure
+ * @overlap: variable for overlap detection
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ *
+ * Function handles ht20 protection enabled
+ *
+ * Return: none
+ */
+static void lim_handle_ht20protection_enabled(tpAniSirGlobal mac_ctx,
+ uint8_t overlap, tpUpdateBeaconParams beaconparams,
+ tpPESession session_entry)
+{
+ /*
+ * If we are AP and HT capable, we need to set the HT OP mode
+ * appropriately.
+ */
+ if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+ session_entry->gLimOverlapHt20Params.protectionEnabled = true;
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ session_entry->htOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED !=
+ session_entry->htOperMode)) {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, beaconparams, session_entry);
+ }
+ } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+ session_entry->gLimHt20Params.protectionEnabled = true;
+ if (eSIR_HT_OP_MODE_PURE == session_entry->htOperMode) {
+ if (session_entry->htSupportedChannelWidthSet !=
+ eHT_CHANNEL_WIDTH_20MHZ)
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(session_entry) && overlap) {
+ mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled =
+ true;
+ if ((eSIR_HT_OP_MODE_OVERLAP_LEGACY !=
+ mac_ctx->lim.gHTOperMode) &&
+ (eSIR_HT_OP_MODE_MIXED !=
+ mac_ctx->lim.gHTOperMode)) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_OVERLAP_LEGACY;
+ lim_enable_ht_rifs_protection(mac_ctx, true,
+ overlap, beaconparams, session_entry);
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(session_entry) && !overlap) {
+ session_entry->gLimHt20Params.protectionEnabled = true;
+ if (eSIR_HT_OP_MODE_PURE == mac_ctx->lim.gHTOperMode) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ }
+ }
+ /* This part is common for staiton as well. */
+ if (false == session_entry->beaconParams.ht20Coexist) {
+ lim_log(mac_ctx, LOG1,
+ FL("=> Protection from HT20 Enabled"));
+ beaconparams->ht20MhzCoexist =
+ session_entry->beaconParams.ht20Coexist = true;
+ beaconparams->paramChangeBitmap |=
+ PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+}
+
+/**
+ * lim_handle_ht20coexist_ht20protection() - ht20 protection for ht20 coexist
+ * @mac_ctx: pointer to Gloal Mac Structure
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ * @overlap: variable for overlap detection
+ *
+ * Function handles ht20 protection for ht20 coexist
+ *
+ * Return: none
+ */
+static void lim_handle_ht20coexist_ht20protection(tpAniSirGlobal mac_ctx,
+ tpUpdateBeaconParams beaconparams,
+ tpPESession session_entry, uint8_t overlap)
+{
+ /*
+ * For AP role:
+ * we need to take care of HT OP mode change if needed.
+ * We need to take care of Overlap cases.
+ */
+ if (LIM_IS_AP_ROLE(session_entry) && overlap) {
+ /* Overlap Legacy protection disabled. */
+ session_entry->gLimOverlapHt20Params.protectionEnabled =
+ false;
+ /*
+ * no HT op mode change if any of the overlap
+ * protection enabled.
+ */
+ if (!(session_entry->gLimOlbcParams.protectionEnabled ||
+ session_entry->gLimOverlap11gParams.protectionEnabled ||
+ session_entry->gLimOverlapHt20Params.protectionEnabled
+ || session_entry->gLimOverlapNonGfParams.
+ protectionEnabled) &&
+ /*
+ * Check if there is a need to change HT
+ * OP mode.
+ */
+ (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ session_entry->htOperMode)) {
+ if (session_entry->gLimHt20Params.
+ protectionEnabled) {
+ if(eHT_CHANNEL_WIDTH_20MHZ ==
+ session_entry->htSupportedChannelWidthSet)
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ else
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+
+ lim_enable_ht_rifs_protection(mac_ctx,
+ false, overlap, beaconparams,
+ session_entry);
+ lim_enable_ht_obss_protection(mac_ctx,
+ false, overlap, beaconparams,
+ session_entry);
+ } else {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ } else if (LIM_IS_AP_ROLE(session_entry) && !overlap) {
+ /* Disable protection from 11G stations. */
+ session_entry->gLimHt20Params.protectionEnabled = false;
+ /* Change HT op mode appropriately. */
+ if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+ session_entry->htOperMode) {
+ session_entry->htOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ }
+ }
+ if (LIM_IS_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOG1,
+ FL("===> Protection from HT 20 Disabled"));
+ beaconparams->ht20MhzCoexist =
+ session_entry->beaconParams.ht20Coexist = false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+ if (LIM_IS_BT_AMP_AP_ROLE(session_entry) && overlap) {
+ /* Overlap Legacy protection disabled. */
+ mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled = false;
+ /*
+ * no HT op mode change if any of the overlap
+ * protection enabled.
+ */
+ if (!(session_entry->gLimOlbcParams.protectionEnabled ||
+ mac_ctx->lim.gLimOverlap11gParams.protectionEnabled ||
+ mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled ||
+ mac_ctx->lim.gLimOverlapNonGfParams.protectionEnabled)
+ /*
+ * Check if there is a need to change
+ * HT OP mode.
+ */
+ && (eSIR_HT_OP_MODE_OVERLAP_LEGACY ==
+ mac_ctx->lim.gHTOperMode)) {
+ if (session_entry->gLimHt20Params.protectionEnabled) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT;
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ } else {
+ mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+ }
+ } else if (LIM_IS_BT_AMP_AP_ROLE(session_entry) && !overlap) {
+ /* Disable protection from 11G stations. */
+ session_entry->gLimHt20Params.protectionEnabled = false;
+
+ /* Change HT op mode appropriately. */
+ if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT ==
+ mac_ctx->lim.gHTOperMode) {
+ mac_ctx->lim.gHTOperMode =
+ eSIR_HT_OP_MODE_PURE;
+ lim_enable_ht_rifs_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ lim_enable_ht_obss_protection(mac_ctx, false,
+ overlap, beaconparams, session_entry);
+ }
+ }
+ if (LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ lim_log(mac_ctx, LOG1,
+ FL("===> Protection from HT 20 Disabled"));
+ beaconparams->ht20MhzCoexist =
+ session_entry->beaconParams.ht20Coexist = false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+
+ if (!LIM_IS_AP_ROLE(session_entry) &&
+ !LIM_IS_BT_AMP_AP_ROLE(session_entry)) {
+ /* For station role */
+ lim_log(mac_ctx, LOG1,
+ FL("===> Protection from HT20 Disabled"));
+ beaconparams->ht20MhzCoexist =
+ session_entry->beaconParams.ht20Coexist = false;
+ beaconparams->paramChangeBitmap |=
+ PARAM_HT20MHZCOEXIST_CHANGED;
+ }
+}
+
+/**
+ * lim_enable_ht20_protection() - Function to enable ht20 protection
+ * @mac_ctx: pointer to Global Mac structure
+ * @enable: 1=> enable protection, 0=> disable protection.
+ * @overlap: 1=> called from overlap context, 0 => called from assoc context.
+ * @beaconparams: pointer to tpUpdateBeaconParams
+ * @session_entry: pointer to tpPESession
+ *
+ * based on cofig enables\disables protection from Ht20
+ *
+ * Return: 0 - success
+ */
+tSirRetStatus lim_enable_ht20_protection(tpAniSirGlobal mac_ctx, uint8_t enable,
+ uint8_t overlap, tpUpdateBeaconParams beaconparams,
+ tpPESession session_entry)
+{
+ /* This protection is only for HT stations. */
+ if (!session_entry->htCapability)
+ return eSIR_SUCCESS;
+
+ /* overlapping protection configuration check. */
+ if (!overlap) {
+ /* normal protection config check */
+ if ((LIM_IS_AP_ROLE(session_entry)) &&
+ !session_entry->cfgProtection.ht20) {
+ /* protection disabled. */
+ lim_log(mac_ctx, LOG3,
+ FL("protection from HT20 is disabled"));
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(session_entry)) {
+ if (!mac_ctx->lim.cfgProtection.ht20) {
+ /* protection disabled. */
+ lim_log(mac_ctx, LOG3,
+ FL("protection from HT20 is disabled"));
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (enable)
+ lim_handle_ht20protection_enabled(mac_ctx, overlap,
+ beaconparams, session_entry);
+ else if (true == session_entry->beaconParams.ht20Coexist)
+ lim_handle_ht20coexist_ht20protection(mac_ctx, beaconparams,
+ session_entry, overlap);
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_enable_ht_non_gf_protection
+ \brief based on cofig enables\disables protection from NonGf.
+ \param uint8_t enable : 1=> enable protection, 0=> disable protection.
+ \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+lim_enable_ht_non_gf_protection(tpAniSirGlobal pMac, uint8_t enable,
+ uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ if (!psessionEntry->htCapability)
+ return eSIR_SUCCESS; /* this protection is only for HT stations. */
+
+ /* overlapping protection configuration check. */
+ if (overlap) {
+ } else {
+ /* normal protection config check */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ !psessionEntry->cfgProtection.nonGf) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL("protection from NonGf is disabled"));
+ )
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+ /* normal protection config check */
+ if (!pMac->lim.cfgProtection.nonGf) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL
+ ("protection from NonGf is disabled"));
+ )
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if ((enable)
+ && (false == psessionEntry->beaconParams.llnNonGFCoexist)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL(" => Protection from non GF Enabled"));
+ )
+ pBeaconParams->llnNonGFCoexist =
+ psessionEntry->beaconParams.llnNonGFCoexist = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ } else if (!enable
+ && (true ==
+ psessionEntry->beaconParams.llnNonGFCoexist)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> Protection from Non GF Disabled"));
+ )
+ pBeaconParams->llnNonGFCoexist =
+ psessionEntry->beaconParams.llnNonGFCoexist = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+ } else {
+ if ((enable)
+ && (false == psessionEntry->beaconParams.llnNonGFCoexist)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL(" => Protection from non GF Enabled"));
+ )
+ pBeaconParams->llnNonGFCoexist =
+ psessionEntry->beaconParams.llnNonGFCoexist = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ } else if (!enable
+ && (true ==
+ psessionEntry->beaconParams.llnNonGFCoexist)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> Protection from Non GF Disabled"));
+ )
+ pBeaconParams->llnNonGFCoexist =
+ psessionEntry->beaconParams.llnNonGFCoexist = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_NON_GF_DEVICES_PRESENT_CHANGED;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_enable_ht_lsig_txop_protection
+ \brief based on cofig enables\disables LsigTxop protection.
+ \param uint8_t enable : 1=> enable protection, 0=> disable protection.
+ \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+lim_enable_ht_lsig_txop_protection(tpAniSirGlobal pMac, uint8_t enable,
+ uint8_t overlap,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ if (!psessionEntry->htCapability)
+ return eSIR_SUCCESS; /* this protection is only for HT stations. */
+
+ /* overlapping protection configuration check. */
+ if (overlap) {
+ } else {
+ /* normal protection config check */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ !psessionEntry->cfgProtection.lsigTxop) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL
+ (" protection from LsigTxop not supported is disabled"));
+ )
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+ /* normal protection config check */
+ if (!pMac->lim.cfgProtection.lsigTxop) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL
+ (" protection from LsigTxop not supported is disabled"));
+ )
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if ((enable)
+ && (false ==
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL(" => Protection from LsigTxop Enabled"));
+ )
+ pBeaconParams->fLsigTXOPProtectionFullSupport =
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ } else if (!enable
+ && (true ==
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> Protection from LsigTxop Disabled"));
+ )
+ pBeaconParams->fLsigTXOPProtectionFullSupport =
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ } else {
+ if ((enable)
+ && (false ==
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL(" => Protection from LsigTxop Enabled"));
+ )
+ pBeaconParams->fLsigTXOPProtectionFullSupport =
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ } else if (!enable
+ && (true ==
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport)) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("===> Protection from LsigTxop Disabled"));
+ )
+ pBeaconParams->fLsigTXOPProtectionFullSupport =
+ psessionEntry->beaconParams.
+ fLsigTXOPProtectionFullSupport = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/* FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. */
+/* This check will be done at the caller. */
+/** -------------------------------------------------------------
+ \fn lim_enable_ht_rifs_protection
+ \brief based on cofig enables\disables Rifs protection.
+ \param uint8_t enable : 1=> enable protection, 0=> disable protection.
+ \param uint8_t overlap: 1=> called from overlap context, 0 => called from assoc context.
+ \param tpUpdateBeaconParams pBeaconParams
+ \return None
+ -------------------------------------------------------------*/
+tSirRetStatus
+lim_enable_ht_rifs_protection(tpAniSirGlobal pMac, uint8_t enable,
+ uint8_t overlap, tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ if (!psessionEntry->htCapability)
+ return eSIR_SUCCESS; /* this protection is only for HT stations. */
+
+ /* overlapping protection configuration check. */
+ if (overlap) {
+ } else {
+ /* normal protection config check */
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ !psessionEntry->cfgProtection.rifs) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL(" protection from Rifs is disabled"));
+ )
+ return eSIR_SUCCESS;
+ } else if (!LIM_IS_AP_ROLE(psessionEntry)) {
+ /* normal protection config check */
+ if (!pMac->lim.cfgProtection.rifs) {
+ /* protection disabled. */
+ PELOG3(lim_log
+ (pMac, LOG3,
+ FL
+ (" protection from Rifs is disabled"));
+ )
+ return eSIR_SUCCESS;
+ }
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ /* Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS */
+ if ((!enable)
+ && (false == psessionEntry->beaconParams.fRIFSMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL(" => Rifs protection Disabled"));
+ )
+ pBeaconParams->fRIFSMode =
+ psessionEntry->beaconParams.fRIFSMode = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_RIFS_MODE_CHANGED;
+ }
+ /* Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS */
+ else if (enable
+ && (true == psessionEntry->beaconParams.fRIFSMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("===> Rifs Protection Enabled"));
+ )
+ pBeaconParams->fRIFSMode =
+ psessionEntry->beaconParams.fRIFSMode = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_RIFS_MODE_CHANGED;
+ }
+ } else {
+ /* Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS */
+ if ((!enable)
+ && (false == psessionEntry->beaconParams.fRIFSMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL(" => Rifs protection Disabled"));
+ )
+ pBeaconParams->fRIFSMode =
+ psessionEntry->beaconParams.fRIFSMode = true;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_RIFS_MODE_CHANGED;
+ }
+ /* Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS */
+ else if (enable
+ && (true == psessionEntry->beaconParams.fRIFSMode)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("===> Rifs Protection Enabled"));
+ )
+ pBeaconParams->fRIFSMode =
+ psessionEntry->beaconParams.fRIFSMode = false;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_RIFS_MODE_CHANGED;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/**
+ * lim_enable_short_preamble
+ *
+ * FUNCTION:
+ * Enable/Disable short preamble
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param enable Flag to enable/disable short preamble
+ * @return None
+ */
+
+tSirRetStatus
+lim_enable_short_preamble(tpAniSirGlobal pMac, uint8_t enable,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry)
+{
+ uint32_t val;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) {
+ /* Could not get short preamble enabled flag from CFG. Log error. */
+ lim_log(pMac, LOGP,
+ FL("could not retrieve short preamble flag"));
+ return eSIR_FAILURE;
+ }
+
+ if (!val)
+ return eSIR_SUCCESS;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve 11G short preamble switching enabled flag"));
+ return eSIR_FAILURE;
+ }
+
+ if (!val) /* 11G short preamble switching is disabled. */
+ return eSIR_SUCCESS;
+
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ if (enable && (psessionEntry->beaconParams.fShortPreamble == 0)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("===> Short Preamble Enabled"));
+ )
+ psessionEntry->beaconParams.fShortPreamble = true;
+ pBeaconParams->fShortPreamble =
+ (uint8_t) psessionEntry->beaconParams.
+ fShortPreamble;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_SHORT_PREAMBLE_CHANGED;
+ } else if (!enable
+ && (psessionEntry->beaconParams.fShortPreamble ==
+ 1)) {
+ PELOG1(lim_log
+ (pMac, LOG1, FL("===> Short Preamble Disabled"));
+ )
+ psessionEntry->beaconParams.fShortPreamble = false;
+ pBeaconParams->fShortPreamble =
+ (uint8_t) psessionEntry->beaconParams.
+ fShortPreamble;
+ pBeaconParams->paramChangeBitmap |=
+ PARAM_SHORT_PREAMBLE_CHANGED;
+ }
+ }
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_tx_complete
+ *
+ * Function:
+ * This is LIM's very own "TX MGMT frame complete" completion routine.
+ *
+ * Logic:
+ * LIM wants to send a MGMT frame (broadcast or unicast)
+ * LIM allocates memory using cds_packet_alloc( ..., **pData, **pPacket )
+ * LIM transmits the MGMT frame using the API:
+ * wma_tx_frame( ... pPacket, ..., (void *) lim_tx_complete, pData )
+ * HDD, via wma_tx_frame/DXE, "transfers" the packet over to BMU
+ * HDD, if it determines that a TX completion routine (in this case
+ * lim_tx_complete) has been provided, will invoke this callback
+ * LIM will try to free the TX MGMT packet that was earlier allocated, in order
+ * to send this MGMT frame, using the PAL API cds_packet_free( ... pData, pPacket )
+ *
+ * Assumptions:
+ * Presently, this is ONLY being used for MGMT frames/packets
+ * TODO:
+ * Would it do good for LIM to have some sort of "signature" validation to
+ * ensure that the pData argument passed in was a buffer that was actually
+ * allocated by LIM and/or is not corrupted?
+ *
+ * Note: FIXME and TODO
+ * Looks like cds_packet_free() is interested in pPacket. But, when this completion
+ * routine is called, only pData is made available to LIM!!
+ *
+ * @param void A pointer to pData. Shouldn't it be pPacket?!
+ *
+ * @return none
+ */
+void lim_tx_complete(tHalHandle hHal, void *data, bool free)
+{
+ if (free)
+ cds_packet_free((void *)data);
+}
+
+/**
+ * \brief This function updates lim global structure, if CB parameters in the BSS
+ * have changed, and sends an indication to HAL also with the
+ * updated HT Parameters.
+ * This function does not detect the change in the primary channel, that is done as part
+ * of channel Swtich IE processing.
+ * If STA is configured with '20Mhz only' mode, then this function does not do anything
+ * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz'
+ *
+ *
+ * \param pMac Pointer to global MAC structure
+ *
+ * \param pRcvdHTInfo Pointer to HT Info IE obtained from a Beacon or
+ * Probe Response
+ *
+ * \param bssIdx BSS Index of the Bss to which Station is associated.
+ *
+ *
+ */
+
+void lim_update_sta_run_time_ht_switch_chnl_params(tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pHTInfo,
+ uint8_t bssIdx,
+ tpPESession psessionEntry)
+{
+ uint8_t center_freq = 0;
+#if !defined WLAN_FEATURE_VOWIFI
+ uint32_t localPwrConstraint;
+#endif
+
+ /* If self capability is set to '20Mhz only', then do not change the CB mode. */
+ if (!lim_get_ht_capability
+ (pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry))
+ return;
+
+#if !defined WLAN_FEATURE_VOWIFI
+ if (wlan_cfg_get_int
+ (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
+ &localPwrConstraint) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("Unable to get Local Power Constraint from cfg"));
+ return;
+ }
+#endif
+
+ if (psessionEntry->ftPEContext.ftPreAuthSession) {
+ lim_log(pMac, LOGE,
+ FL("FT PREAUTH channel change is in progress"));
+ return;
+ }
+
+ if (psessionEntry->htSecondaryChannelOffset !=
+ (uint8_t) pHTInfo->secondaryChannelOffset
+ || psessionEntry->htRecommendedTxWidthSet !=
+ (uint8_t) pHTInfo->recommendedTxWidthSet) {
+ psessionEntry->htSecondaryChannelOffset =
+ (ePhyChanBondState) pHTInfo->secondaryChannelOffset;
+ psessionEntry->htRecommendedTxWidthSet =
+ (uint8_t) pHTInfo->recommendedTxWidthSet;
+ if (eHT_CHANNEL_WIDTH_40MHZ ==
+ psessionEntry->htRecommendedTxWidthSet) {
+ if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY ==
+ pHTInfo->secondaryChannelOffset)
+ center_freq = pHTInfo->primaryChannel + 2;
+ else if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY ==
+ pHTInfo->secondaryChannelOffset)
+ center_freq = pHTInfo->primaryChannel - 2;
+ }
+
+ /* notify HAL */
+ lim_log(pMac, LOGW, FL("Channel Information in HT IE change"
+ "d; sending notification to HAL."));
+ lim_log(pMac, LOGW, FL("Primary Channel: %d, Secondary Chan"
+ "nel Offset: %d, Channel Width: %d"),
+ pHTInfo->primaryChannel, center_freq,
+ psessionEntry->htRecommendedTxWidthSet);
+ psessionEntry->channelChangeReasonCode =
+ LIM_SWITCH_CHANNEL_OPERATION;
+ pMac->lim.gpchangeChannelCallback = NULL;
+ pMac->lim.gpchangeChannelData = NULL;
+
+#if defined WLAN_FEATURE_VOWIFI
+ lim_send_switch_chnl_params(pMac, (uint8_t) pHTInfo->primaryChannel,
+ center_freq, 0,
+ psessionEntry->htRecommendedTxWidthSet,
+ psessionEntry->maxTxPower,
+ psessionEntry->peSessionId,
+ true);
+#else
+ lim_send_switch_chnl_params(pMac, (uint8_t) pHTInfo->primaryChannel,
+ center_freq, 0,
+ psessionEntry->htRecommendedTxWidthSet,
+ (tPowerdBm) localPwrConstraint,
+ psessionEntry->peSessionId,
+ true);
+#endif
+
+ /* In case of IBSS, if STA should update HT Info IE in its beacons. */
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ sch_set_fixed_beacon_fields(pMac, psessionEntry);
+ }
+
+ }
+} /* End limUpdateStaRunTimeHTParams. */
+
+/**
+ * \brief This function updates the lim global structure, if any of the
+ * HT Capabilities have changed.
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param pHTCapability Pointer to HT Capability Information Element
+ * obtained from a Beacon or Probe Response
+ *
+ *
+ *
+ */
+
+void lim_update_sta_run_time_ht_capability(tpAniSirGlobal pMac,
+ tDot11fIEHTCaps *pHTCaps)
+{
+
+ if (pMac->lim.gHTLsigTXOPProtection !=
+ (uint8_t) pHTCaps->lsigTXOPProtection) {
+ pMac->lim.gHTLsigTXOPProtection =
+ (uint8_t) pHTCaps->lsigTXOPProtection;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTAMpduDensity != (uint8_t) pHTCaps->mpduDensity) {
+ pMac->lim.gHTAMpduDensity = (uint8_t) pHTCaps->mpduDensity;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTMaxRxAMpduFactor !=
+ (uint8_t) pHTCaps->maxRxAMPDUFactor) {
+ pMac->lim.gHTMaxRxAMpduFactor =
+ (uint8_t) pHTCaps->maxRxAMPDUFactor;
+ /* Send change notification to HAL */
+ }
+
+} /* End lim_update_sta_run_time_ht_capability. */
+
+/**
+ * \brief This function updates lim global structure, if any of the HT
+ * Info Parameters have changed.
+ *
+ *
+ * \param pMac Pointer to the global MAC structure
+ *
+ * \param pHTInfo Pointer to the HT Info IE obtained from a Beacon or
+ * Probe Response
+ *
+ *
+ */
+
+void lim_update_sta_run_time_ht_info(tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pHTInfo,
+ tpPESession psessionEntry)
+{
+ if (psessionEntry->htRecommendedTxWidthSet !=
+ (uint8_t) pHTInfo->recommendedTxWidthSet) {
+ psessionEntry->htRecommendedTxWidthSet =
+ (uint8_t) pHTInfo->recommendedTxWidthSet;
+ /* Send change notification to HAL */
+ }
+
+ if (psessionEntry->beaconParams.fRIFSMode !=
+ (uint8_t) pHTInfo->rifsMode) {
+ psessionEntry->beaconParams.fRIFSMode =
+ (uint8_t) pHTInfo->rifsMode;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTServiceIntervalGranularity !=
+ (uint8_t) pHTInfo->serviceIntervalGranularity) {
+ pMac->lim.gHTServiceIntervalGranularity =
+ (uint8_t) pHTInfo->serviceIntervalGranularity;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTOperMode != (tSirMacHTOperatingMode) pHTInfo->opMode) {
+ pMac->lim.gHTOperMode =
+ (tSirMacHTOperatingMode) pHTInfo->opMode;
+ /* Send change notification to HAL */
+ }
+
+ if (psessionEntry->beaconParams.llnNonGFCoexist !=
+ pHTInfo->nonGFDevicesPresent) {
+ psessionEntry->beaconParams.llnNonGFCoexist =
+ (uint8_t) pHTInfo->nonGFDevicesPresent;
+ }
+
+ if (pMac->lim.gHTSTBCBasicMCS != (uint8_t) pHTInfo->basicSTBCMCS) {
+ pMac->lim.gHTSTBCBasicMCS = (uint8_t) pHTInfo->basicSTBCMCS;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTDualCTSProtection !=
+ (uint8_t) pHTInfo->dualCTSProtection) {
+ pMac->lim.gHTDualCTSProtection =
+ (uint8_t) pHTInfo->dualCTSProtection;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTSecondaryBeacon != (uint8_t) pHTInfo->secondaryBeacon) {
+ pMac->lim.gHTSecondaryBeacon =
+ (uint8_t) pHTInfo->secondaryBeacon;
+ /* Send change notification to HAL */
+ }
+
+ if (psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport !=
+ (uint8_t) pHTInfo->lsigTXOPProtectionFullSupport) {
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport =
+ (uint8_t) pHTInfo->lsigTXOPProtectionFullSupport;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTPCOActive != (uint8_t) pHTInfo->pcoActive) {
+ pMac->lim.gHTPCOActive = (uint8_t) pHTInfo->pcoActive;
+ /* Send change notification to HAL */
+ }
+
+ if (pMac->lim.gHTPCOPhase != (uint8_t) pHTInfo->pcoPhase) {
+ pMac->lim.gHTPCOPhase = (uint8_t) pHTInfo->pcoPhase;
+ /* Send change notification to HAL */
+ }
+
+} /* End lim_update_sta_run_time_ht_info. */
+
+/** -------------------------------------------------------------
+ \fn lim_process_hal_ind_messages
+ \brief callback function for HAL indication
+ \param tpAniSirGlobal pMac
+ \param uint32_t mesgId
+ \param void *mesgParam
+ \return tSirRetStatu - status
+ -------------------------------------------------------------*/
+
+tSirRetStatus lim_process_hal_ind_messages(tpAniSirGlobal pMac, uint32_t msgId,
+ void *msgParam)
+{
+ /* its PE's responsibility to free msgparam when its done extracting the message parameters. */
+ tSirMsgQ msg;
+
+ switch (msgId) {
+ case SIR_LIM_DEL_TS_IND:
+ case SIR_LIM_DELETE_STA_CONTEXT_IND:
+ case SIR_LIM_BEACON_GEN_IND:
+ msg.type = (uint16_t) msgId;
+ msg.bodyptr = msgParam;
+ msg.bodyval = 0;
+ break;
+
+ default:
+ cdf_mem_free(msgParam);
+ lim_log(pMac, LOGP, FL("invalid message id = %d received"),
+ msgId);
+ return eSIR_FAILURE;
+ }
+
+ if (lim_post_msg_api(pMac, &msg) != eSIR_SUCCESS) {
+ cdf_mem_free(msgParam);
+ lim_log(pMac, LOGP, FL("lim_post_msg_api failed for msgid = %d"),
+ msg.type);
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_validate_delts_req() - This function validates DelTs req
+ * @mac_ctx: pointer to Global Mac structure
+ * @delts_req: pointer to delete traffic stream structure
+ * @peer_mac_addr: variable for peer mac address
+ *
+ * Function validates DelTs req originated by SME or by HAL and also
+ * sends halMsg_DelTs to HAL
+ *
+ * Return: eSIR_SUCCESS - Success, eSIR_FAILURE - Failure
+ */
+
+tSirRetStatus
+lim_validate_delts_req(tpAniSirGlobal mac_ctx, tpSirDeltsReq delts_req,
+ tSirMacAddr peer_mac_addr, tpPESession psession_entry)
+{
+ tpDphHashNode sta;
+ uint8_t ts_status;
+ tSirMacTSInfo *tsinfo;
+ uint32_t i;
+ uint8_t tspec_idx;
+
+ /*
+ * if sta
+ * - verify assoc state
+ * - del tspec locally
+ * if ap
+ * - verify sta is in assoc state
+ * - del sta tspec locally
+ */
+ if (delts_req == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Delete TS request pointer is NULL"));
+ return eSIR_FAILURE;
+ }
+
+ if (LIM_IS_STA_ROLE(psession_entry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psession_entry)) {
+ uint32_t val;
+
+ /* station always talks to the AP */
+ sta = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &psession_entry->dph.dphHashTable);
+
+ val = sizeof(tSirMacAddr);
+ sir_copy_mac_addr(peer_mac_addr, psession_entry->bssId);
+
+ } else {
+ uint16_t associd;
+ uint8_t *macaddr = (uint8_t *) peer_mac_addr;
+
+ associd = delts_req->aid;
+ if (associd != 0)
+ sta = dph_get_hash_entry(mac_ctx, associd,
+ &psession_entry->dph.dphHashTable);
+ else
+ sta = dph_lookup_hash_entry(mac_ctx,
+ delts_req->macAddr,
+ &associd,
+ &psession_entry->dph.
+ dphHashTable);
+
+ if (sta != NULL)
+ /* TBD: check sta assoc state as well */
+ for (i = 0; i < sizeof(tSirMacAddr); i++)
+ macaddr[i] = sta->staAddr[i];
+ }
+
+ if (sta == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Cannot find station context for delts req"));
+ return eSIR_FAILURE;
+ }
+
+ if ((!sta->valid) ||
+ (sta->mlmStaContext.mlmState !=
+ eLIM_MLM_LINK_ESTABLISHED_STATE)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid Sta (or state) for DelTsReq"));
+ return eSIR_FAILURE;
+ }
+
+ delts_req->req.wsmTspecPresent = 0;
+ delts_req->req.wmeTspecPresent = 0;
+ delts_req->req.lleTspecPresent = 0;
+
+ if ((sta->wsmEnabled) &&
+ (delts_req->req.tspec.tsinfo.traffic.accessPolicy !=
+ SIR_MAC_ACCESSPOLICY_EDCA))
+ delts_req->req.wsmTspecPresent = 1;
+ else if (sta->wmeEnabled)
+ delts_req->req.wmeTspecPresent = 1;
+ else if (sta->lleEnabled)
+ delts_req->req.lleTspecPresent = 1;
+ else {
+ lim_log(mac_ctx, LOGW,
+ FL("DELTS_REQ ignore - qos is disabled"));
+ return eSIR_FAILURE;
+ }
+
+ tsinfo = delts_req->req.wmeTspecPresent ? &delts_req->req.tspec.tsinfo
+ : &delts_req->req.tsinfo;
+ lim_log(mac_ctx, LOG1,
+ FL("received DELTS_REQ message (wmeTspecPresent = %d, lleTspecPresent = %d, wsmTspecPresent = %d, tsid %d, up %d, direction = %d)"),
+ delts_req->req.wmeTspecPresent,
+ delts_req->req.lleTspecPresent,
+ delts_req->req.wsmTspecPresent, tsinfo->traffic.tsid,
+ tsinfo->traffic.userPrio, tsinfo->traffic.direction);
+
+ /* if no Access Control, ignore the request */
+ if (lim_admit_control_delete_ts(mac_ctx, sta->assocId, tsinfo,
+ &ts_status, &tspec_idx) != eSIR_SUCCESS) {
+ lim_log(mac_ctx, LOGE,
+ FL("ERROR DELTS request for sta assocId %d (tsid %d, up %d)"),
+ sta->assocId, tsinfo->traffic.tsid,
+ tsinfo->traffic.userPrio);
+ return eSIR_FAILURE;
+ } else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
+ || (tsinfo->traffic.accessPolicy ==
+ SIR_MAC_ACCESSPOLICY_BOTH)) {
+ /* edca only now. */
+ } else if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
+ /* send message to HAL to delete TS */
+ if (eSIR_SUCCESS !=
+ lim_send_hal_msg_del_ts(mac_ctx, sta->staIndex,
+ tspec_idx, delts_req->req,
+ psession_entry->peSessionId,
+ psession_entry->bssId)) {
+ lim_log(mac_ctx, LOGW,
+ FL("DelTs with UP %d failed in lim_send_hal_msg_del_ts - ignoring request"),
+ tsinfo->traffic.userPrio);
+ return eSIR_FAILURE;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn lim_register_hal_ind_call_back
+ \brief registers callback function to HAL for any indication.
+ \param tpAniSirGlobal pMac
+ \return none.
+ -------------------------------------------------------------*/
+void lim_register_hal_ind_call_back(tpAniSirGlobal pMac)
+{
+ tSirMsgQ msg;
+ tpHalIndCB pHalCB;
+
+ pHalCB = cdf_mem_malloc(sizeof(tHalIndCB));
+ if (NULL == pHalCB) {
+ lim_log(pMac, LOGP, FL("AllocateMemory() failed"));
+ return;
+ }
+
+ pHalCB->pHalIndCB = lim_process_hal_ind_messages;
+
+ msg.type = WMA_REGISTER_PE_CALLBACK;
+ msg.bodyptr = pHalCB;
+ msg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type));
+ if (eSIR_SUCCESS != wma_post_ctrl_msg(pMac, &msg)) {
+ cdf_mem_free(pHalCB);
+ lim_log(pMac, LOGP, FL("wma_post_ctrl_msg() failed"));
+ }
+
+ return;
+}
+
+/**
+ * lim_process_del_ts_ind() - handle del_ts_ind from HAL
+ *
+ * @mac_ctx: pointer to Global Mac Structure
+ * @lim_msg: pointer to msg buff
+ *
+ * handles the DeleteTS indication coming from HAL or generated by PE itself
+ * in some error cases. Validates the request, sends the DelTs action frame
+ * to the Peer and sends DelTs indicatoin to HDD.
+ *
+ * Return: none
+ */
+void lim_process_del_ts_ind(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpDphHashNode pSta;
+ tpDelTsParams pDelTsParam = (tpDelTsParams) (limMsg->bodyptr);
+ tpSirDeltsReq pDelTsReq = NULL;
+ tSirMacAddr peerMacAddr;
+ tpSirDeltsReqInfo pDelTsReqInfo;
+ tpLimTspecInfo pTspecInfo;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+
+ psessionEntry = pe_find_session_by_bssid(pMac, pDelTsParam->bssId,
+ &sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("session does not exist for given BssId"));
+ cdf_mem_free(limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ return;
+ }
+
+ pTspecInfo = &(pMac->lim.tspecInfo[pDelTsParam->tspecIdx]);
+ if (pTspecInfo->inuse == false) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("tspec entry with index %d is not in use"),
+ pDelTsParam->tspecIdx);
+ )
+ goto error1;
+ }
+
+ pSta =
+ dph_get_hash_entry(pMac, pTspecInfo->assocId,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Could not find entry in DPH table for assocId = %d"),
+ pTspecInfo->assocId);
+ goto error1;
+ }
+
+ pDelTsReq = cdf_mem_malloc(sizeof(tSirDeltsReq));
+ if (NULL == pDelTsReq) {
+ PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory() failed"));)
+ goto error1;
+ }
+
+ cdf_mem_set((uint8_t *) pDelTsReq, sizeof(tSirDeltsReq), 0);
+
+ if (pSta->wmeEnabled)
+ cdf_mem_copy(&(pDelTsReq->req.tspec), &(pTspecInfo->tspec),
+ sizeof(tSirMacTspecIE));
+ else
+ cdf_mem_copy(&(pDelTsReq->req.tsinfo),
+ &(pTspecInfo->tspec.tsinfo),
+ sizeof(tSirMacTSInfo));
+
+ /* validate the req */
+ if (eSIR_SUCCESS !=
+ lim_validate_delts_req(pMac, pDelTsReq, peerMacAddr, psessionEntry)) {
+ PELOGE(lim_log(pMac, LOGE, FL("lim_validate_delts_req failed"));)
+ goto error2;
+ }
+ PELOG1(lim_log(pMac, LOG1, "Sent DELTS request to station with "
+ "assocId = %d MacAddr = " MAC_ADDRESS_STR,
+ pDelTsReq->aid, MAC_ADDR_ARRAY(peerMacAddr));
+ )
+
+ lim_send_delts_req_action_frame(pMac, peerMacAddr,
+ pDelTsReq->req.wmeTspecPresent,
+ &pDelTsReq->req.tsinfo,
+ &pDelTsReq->req.tspec, psessionEntry);
+
+ /* prepare and send an sme indication to HDD */
+ pDelTsReqInfo = cdf_mem_malloc(sizeof(tSirDeltsReqInfo));
+ if (NULL == pDelTsReqInfo) {
+ PELOGE(lim_log(pMac, LOGE, FL("AllocateMemory() failed"));)
+ goto error3;
+ }
+ cdf_mem_set((uint8_t *) pDelTsReqInfo, sizeof(tSirDeltsReqInfo), 0);
+
+ if (pSta->wmeEnabled)
+ cdf_mem_copy(&(pDelTsReqInfo->tspec), &(pTspecInfo->tspec),
+ sizeof(tSirMacTspecIE));
+ else
+ cdf_mem_copy(&(pDelTsReqInfo->tsinfo),
+ &(pTspecInfo->tspec.tsinfo),
+ sizeof(tSirMacTSInfo));
+
+ lim_send_sme_delts_ind(pMac, pDelTsReqInfo, pDelTsReq->aid, psessionEntry);
+
+error3:
+ cdf_mem_free(pDelTsReqInfo);
+error2:
+ cdf_mem_free(pDelTsReq);
+error1:
+ cdf_mem_free(limMsg->bodyptr);
+ limMsg->bodyptr = NULL;
+ return;
+}
+
+/**
+ * @function : lim_post_sm_state_update()
+ *
+ * @brief : This function Updates the HAL and Softmac about the change in the STA's SMPS state.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param limMsg - Lim Message structure object with the MimoPSparam in body
+ * @return None
+ */
+tSirRetStatus
+lim_post_sm_state_update(tpAniSirGlobal pMac,
+ uint16_t staIdx, tSirMacHTMIMOPowerSaveState state,
+ uint8_t *pPeerStaMac, uint8_t sessionId)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+ tpSetMIMOPS pMIMO_PSParams;
+
+ msgQ.reserved = 0;
+ msgQ.type = WMA_SET_MIMOPS_REQ;
+
+ /* Allocate for WMA_SET_MIMOPS_REQ */
+ pMIMO_PSParams = cdf_mem_malloc(sizeof(tSetMIMOPS));
+ if (NULL == pMIMO_PSParams) {
+ lim_log(pMac, LOGP, FL(" AllocateMemory failed"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ pMIMO_PSParams->htMIMOPSState = state;
+ pMIMO_PSParams->staIdx = staIdx;
+ pMIMO_PSParams->fsendRsp = true;
+ pMIMO_PSParams->sessionId = sessionId;
+ cdf_mem_copy(pMIMO_PSParams->peerMac, pPeerStaMac, sizeof(tSirMacAddr));
+
+ msgQ.bodyptr = pMIMO_PSParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG2, FL("Sending WMA_SET_MIMOPS_REQ..."));
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ retCode = wma_post_ctrl_msg(pMac, &msgQ);
+ if (eSIR_SUCCESS != retCode) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Posting WMA_SET_MIMOPS_REQ to HAL failed! Reason = %d"),
+ retCode);
+ cdf_mem_free(pMIMO_PSParams);
+ return retCode;
+ }
+
+ return retCode;
+}
+
+void lim_pkt_free(tpAniSirGlobal pMac,
+ eFrameType frmType, uint8_t *pRxPacketInfo, void *pBody)
+{
+ (void)pMac;
+ (void)frmType;
+ (void)pRxPacketInfo;
+ (void)pBody;
+}
+
+/**
+ * lim_get_b_dfrom_rx_packet()
+ *
+ ***FUNCTION:
+ * This function is called to get pointer to Polaris
+ * Buffer Descriptor containing MAC header & other control
+ * info from the body of the message posted to LIM.
+ *
+ ***LOGIC:
+ * NA
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param body - Received message body
+ * @param pRxPacketInfo - Pointer to received BD
+ * @return None
+ */
+
+void
+lim_get_b_dfrom_rx_packet(tpAniSirGlobal pMac, void *body, uint32_t **pRxPacketInfo)
+{
+ *pRxPacketInfo = (uint32_t *) body;
+} /*** end lim_get_b_dfrom_rx_packet() ***/
+
+void lim_resset_scan_channel_info(tpAniSirGlobal pMac)
+{
+ cdf_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0);
+}
+
+/**
+ * @function : lim_is_channel_valid_for_channel_switch()
+ *
+ * @brief : This function checks if the channel to which AP
+ * is expecting us to switch, is a valid channel for us.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param channel - New channel to which we are expected to move
+ * @return None
+ */
+tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac, uint8_t channel)
+{
+ uint8_t index;
+ uint32_t validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN;
+ tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN];
+
+ if (wlan_cfg_get_str(pMac, WNI_CFG_VALID_CHANNEL_LIST,
+ (uint8_t *) validChannelList,
+ (uint32_t *) &validChannelListLen) !=
+ eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve valid channel list"));
+ )
+ return eSIR_FALSE;
+ }
+
+ for (index = 0; index < validChannelListLen; index++) {
+ if (validChannelList[index] == channel)
+ return eSIR_TRUE;
+ }
+
+ /* channel does not belong to list of valid channels */
+ return eSIR_FALSE;
+}
+
+/**------------------------------------------------------
+ \fn __lim_fill_tx_control_params
+ \brief Fill the message for stopping/resuming tx.
+
+ \param pMac
+ \param pTxCtrlMsg - Pointer to tx control message.
+ \param type - Which way we want to stop/ resume tx.
+ \param mode - To stop/resume.
+ -------------------------------------------------------*/
+static CDF_STATUS
+__lim_fill_tx_control_params(tpAniSirGlobal pMac, tpTxControlParams pTxCtrlMsg,
+ tLimQuietTxMode type, tLimControlTx mode)
+{
+
+ tpPESession psessionEntry = &pMac->lim.gpSession[0];
+
+ if (mode == eLIM_STOP_TX)
+ pTxCtrlMsg->stopTx = true;
+ else
+ pTxCtrlMsg->stopTx = false;
+
+ switch (type) {
+ case eLIM_TX_ALL:
+ /** Stops/resumes transmission completely */
+ pTxCtrlMsg->fCtrlGlobal = 1;
+ break;
+
+ case eLIM_TX_BSS_BUT_BEACON:
+ /** Stops/resumes transmission on a particular BSS. Stopping BSS, doesnt
+ * stop beacon transmission.
+ */
+ pTxCtrlMsg->ctrlBss = 1;
+ pTxCtrlMsg->bssBitmap |= (1 << psessionEntry->bssIdx);
+ break;
+
+ case eLIM_TX_STA:
+ /** Memory for station bitmap is allocated dynamically in caller of this
+ * so decode properly here and fill the bitmap. Now not implemented,
+ * fall through.
+ */
+ case eLIM_TX_BSS:
+ /* Fall thru... */
+ default:
+ PELOGW(lim_log(pMac, LOGW, FL("Invalid case: Not Handled"));)
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * @function : lim_frame_transmission_control()
+ *
+ * @brief : This API is called by the user to halt/resume any frame
+ * transmission from the device. If stopped, all frames will be
+ * queued starting from hardware. Then back-pressure
+ * is built till the driver.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
+ tLimControlTx mode)
+{
+
+ CDF_STATUS status = CDF_STATUS_E_FAILURE;
+ tpTxControlParams pTxCtrlMsg;
+ tSirMsgQ msgQ;
+ uint8_t nBytes = 0; /* No of bytes required for station bitmap. */
+
+ /** Allocate only required number of bytes for station bitmap
+ * Make it to align to 4 byte boundary */
+ nBytes = (uint8_t) HALMSG_NUMBYTES_STATION_BITMAP(pMac->lim.maxStation);
+
+ pTxCtrlMsg = cdf_mem_malloc(sizeof(*pTxCtrlMsg) + nBytes);
+ if (NULL == pTxCtrlMsg) {
+ lim_log(pMac, LOGP, FL("AllocateMemory() failed"));
+ return;
+ }
+
+ cdf_mem_set((void *)pTxCtrlMsg, (sizeof(*pTxCtrlMsg) + nBytes), 0);
+ status = __lim_fill_tx_control_params(pMac, pTxCtrlMsg, type, mode);
+ if (status != CDF_STATUS_SUCCESS) {
+ cdf_mem_free(pTxCtrlMsg);
+ lim_log(pMac, LOGP,
+ FL("__lim_fill_tx_control_params failed, status = %d"),
+ status);
+ return;
+ }
+
+ msgQ.bodyptr = (void *)pTxCtrlMsg;
+ msgQ.bodyval = 0;
+ msgQ.reserved = 0;
+ msgQ.type = WMA_TRANSMISSION_CONTROL_IND;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ if (wma_post_ctrl_msg(pMac, &msgQ) != eSIR_SUCCESS) {
+ cdf_mem_free(pTxCtrlMsg);
+ lim_log(pMac, LOGP, FL("Posting Message to HAL failed"));
+ return;
+ }
+
+ if (mode == eLIM_STOP_TX) {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("Stopping the transmission of all packets, indicated softmac"));
+ )
+ } else {
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("Resuming the transmission of all packets, indicated softmac"));
+ )
+ }
+ return;
+}
+
+/**
+ * @function : lim_restore_pre_channel_switch_state()
+ *
+ * @brief : This API is called by the user to undo any
+ * specific changes done on the device during
+ * channel switch.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+tSirRetStatus
+lim_restore_pre_channel_switch_state(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ if (!LIM_IS_STA_ROLE(psessionEntry))
+ return retCode;
+
+ /* Channel switch should be ready for the next time */
+ psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
+
+ /* Restore the frame transmission, all the time. */
+ lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+
+ return retCode;
+}
+
+/**--------------------------------------------
+ \fn lim_restore_pre_quiet_state
+ \brief Restore the pre quiet state
+
+ \param pMac
+ \return NONE
+ ---------------------------------------------*/
+tSirRetStatus lim_restore_pre_quiet_state(tpAniSirGlobal pMac,
+ tpPESession psessionEntry)
+{
+
+ tSirRetStatus retCode = eSIR_SUCCESS;
+
+ if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE)
+ return retCode;
+
+ /* Quiet should be ready for the next time */
+ psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
+
+ /* Restore the frame transmission, all the time. */
+ if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING)
+ lim_frame_transmission_control(pMac, eLIM_TX_ALL, eLIM_RESUME_TX);
+
+ return retCode;
+}
+
+/**
+ * @function: lim_prepare_for11h_channel_switch()
+ *
+ * @brief : This API is called by the user to prepare for
+ * 11h channel switch. As of now, the API does
+ * very minimal work. User can add more into the
+ * same API if needed.
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * NA
+ *
+ * NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @param psessionEntry
+ * @return None
+ */
+void
+lim_prepare_for11h_channel_switch(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ if (!LIM_IS_STA_ROLE(psessionEntry))
+ return;
+
+ /* Flag to indicate 11h channel switch in progress */
+ psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING;
+
+ if (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE ||
+ pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE) {
+ PELOGE(lim_log
+ (pMac, LOG1,
+ FL("Posting finish scan as we are in scan state"));
+ )
+ /* Stop ongoing scanning if any */
+ if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) {
+ /* Set the resume channel to Any valid channel (invalid). */
+ /* This will instruct HAL to set it to any previous valid channel. */
+ pe_set_resume_channel(pMac, 0, 0);
+ } else {
+ lim_restore_pre_channel_switch_state(pMac, psessionEntry);
+ }
+ return;
+ } else {
+ PELOGE(lim_log
+ (pMac, LOG1,
+ FL("Not in scan state, start channel switch timer"));
+ )
+ /** We are safe to switch channel at this point */
+ lim_stop_tx_and_switch_channel(pMac, psessionEntry->peSessionId);
+ }
+}
+
+/**----------------------------------------------------
+ \fn lim_get_nw_type
+
+ \brief Get type of the network from data packet or beacon
+ \param pMac
+ \param channelNum - Channel number
+ \param type - Type of packet.
+ \param pBeacon - Pointer to beacon or probe response
+
+ \return Network type a/b/g.
+ -----------------------------------------------------*/
+tSirNwType lim_get_nw_type(tpAniSirGlobal pMac, uint8_t channelNum, uint32_t type,
+ tpSchBeaconStruct pBeacon)
+{
+ tSirNwType nwType = eSIR_11B_NW_TYPE;
+
+ if (type == SIR_MAC_DATA_FRAME) {
+ if ((channelNum > 0) && (channelNum < 15)) {
+ nwType = eSIR_11G_NW_TYPE;
+ } else {
+ nwType = eSIR_11A_NW_TYPE;
+ }
+ } else {
+ if ((channelNum > 0) && (channelNum < 15)) {
+ int i;
+ /* 11b or 11g packet */
+ /* 11g iff extended Rate IE is present or */
+ /* if there is an A rate in suppRate IE */
+ for (i = 0; i < pBeacon->supportedRates.numRates; i++) {
+ if (sirIsArate
+ (pBeacon->supportedRates.rate[i] & 0x7f)) {
+ nwType = eSIR_11G_NW_TYPE;
+ break;
+ }
+ }
+ if (pBeacon->extendedRatesPresent) {
+ PELOG3(lim_log
+ (pMac, LOG3, FL("Beacon, nwtype=G"));
+ )
+ nwType = eSIR_11G_NW_TYPE;
+ }
+ } else {
+ /* 11a packet */
+ PELOG3(lim_log(pMac, LOG3, FL("Beacon, nwtype=A"));)
+ nwType = eSIR_11A_NW_TYPE;
+ }
+ }
+ return nwType;
+}
+
+/**---------------------------------------------------------
+ \fn lim_get_channel_from_beacon
+ \brief To extract channel number from beacon
+
+ \param pMac
+ \param pBeacon - Pointer to beacon or probe rsp
+ \return channel number
+ -----------------------------------------------------------*/
+uint8_t lim_get_channel_from_beacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon)
+{
+ uint8_t channelNum = 0;
+
+ if (pBeacon->dsParamsPresent)
+ channelNum = pBeacon->channelNumber;
+ else if (pBeacon->HTInfo.present)
+ channelNum = pBeacon->HTInfo.primaryChannel;
+ else
+ channelNum = pBeacon->channelNumber;
+
+ return channelNum;
+}
+
+void lim_set_tspec_uapsd_mask_per_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tSirMacTSInfo *pTsInfo, uint32_t action)
+{
+ uint8_t userPrio = (uint8_t) pTsInfo->traffic.userPrio;
+ uint16_t direction = pTsInfo->traffic.direction;
+ uint8_t ac = upToAc(userPrio);
+
+ PELOG1(lim_log
+ (pMac, LOG1, FL("Set UAPSD mask for AC %d, dir %d, action=%d")
+ , ac, direction, action);
+ )
+
+ /* Converting AC to appropriate Uapsd Bit Mask
+ * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3)
+ * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2)
+ * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1)
+ * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0)
+ */
+ ac = ((~ac) & 0x3);
+
+ if (action == CLEAR_UAPSD_MASK) {
+ if (direction == SIR_MAC_DIRECTION_UPLINK)
+ psessionEntry->gUapsdPerAcTriggerEnableMask &=
+ ~(1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_DNLINK)
+ psessionEntry->gUapsdPerAcDeliveryEnableMask &=
+ ~(1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+ psessionEntry->gUapsdPerAcTriggerEnableMask &=
+ ~(1 << ac);
+ psessionEntry->gUapsdPerAcDeliveryEnableMask &=
+ ~(1 << ac);
+ }
+ } else if (action == SET_UAPSD_MASK) {
+ if (direction == SIR_MAC_DIRECTION_UPLINK)
+ psessionEntry->gUapsdPerAcTriggerEnableMask |=
+ (1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_DNLINK)
+ psessionEntry->gUapsdPerAcDeliveryEnableMask |=
+ (1 << ac);
+ else if (direction == SIR_MAC_DIRECTION_BIDIR) {
+ psessionEntry->gUapsdPerAcTriggerEnableMask |=
+ (1 << ac);
+ psessionEntry->gUapsdPerAcDeliveryEnableMask |=
+ (1 << ac);
+ }
+ }
+
+ lim_log(pMac, LOG1,
+ FL("New psessionEntry->gUapsdPerAcTriggerEnableMask = 0x%x "),
+ psessionEntry->gUapsdPerAcTriggerEnableMask);
+ lim_log(pMac, LOG1,
+ FL("New psessionEntry->gUapsdPerAcDeliveryEnableMask = 0x%x "),
+ psessionEntry->gUapsdPerAcDeliveryEnableMask);
+
+ return;
+}
+
+/**
+ * lim_handle_heart_beat_timeout_for_session() - Handle heart beat time out
+ * @mac_ctx: pointer to Global Mac Structure
+ * @psession_entry: pointer to tpPESession
+ *
+ * Function handles heart beat time out for session
+ *
+ * Return: none
+ */
+void lim_handle_heart_beat_timeout_for_session(tpAniSirGlobal mac_ctx,
+ tpPESession psession_entry)
+{
+ if (psession_entry->valid == true) {
+ if (psession_entry->bssType == eSIR_IBSS_MODE)
+ lim_ibss_heart_beat_handle(mac_ctx, psession_entry);
+
+ if ((psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) &&
+ (LIM_IS_STA_ROLE(psession_entry)))
+ lim_handle_heart_beat_failure(mac_ctx, psession_entry);
+ }
+ /*
+ * In the function lim_handle_heart_beat_failure things can change
+ * so check for the session entry valid and the other things
+ * again
+ */
+ if ((psession_entry->valid == true) &&
+ (psession_entry->bssType == eSIR_INFRASTRUCTURE_MODE) &&
+ (LIM_IS_STA_ROLE(psession_entry)) &&
+ (psession_entry->LimHBFailureStatus == true)) {
+ tLimTimers *lim_timer = &mac_ctx->lim.limTimers;
+ /*
+ * Activate Probe After HeartBeat Timer incase HB
+ * Failure detected
+ */
+ PELOGW(lim_log(mac_ctx, LOGW,
+ FL("Sending Probe for Session: %d"),
+ psession_entry->bssIdx);)
+ lim_deactivate_and_change_timer(mac_ctx,
+ eLIM_PROBE_AFTER_HB_TIMER);
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_TIMER_ACTIVATE, 0,
+ eLIM_PROBE_AFTER_HB_TIMER));
+ if (tx_timer_activate(&lim_timer->gLimProbeAfterHBTimer)
+ != TX_SUCCESS)
+ lim_log(mac_ctx, LOGP,
+ FL("Fail to re-activate Probe-after-hb timer"));
+ }
+}
+
+uint8_t lim_get_current_operating_channel(tpAniSirGlobal pMac)
+{
+ uint8_t i;
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if (pMac->lim.gpSession[i].valid == true) {
+ if ((pMac->lim.gpSession[i].bssType ==
+ eSIR_INFRASTRUCTURE_MODE)
+ && (pMac->lim.gpSession[i].limSystemRole ==
+ eLIM_STA_ROLE)) {
+ return pMac->lim.gpSession[i].
+ currentOperChannel;
+ }
+ }
+ }
+ return 0;
+}
+
+void lim_process_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
+{
+ tpPESession psessionEntry;
+ tpAddStaParams pAddStaParams;
+
+ pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr;
+
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ pAddStaParams->sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGP,
+ FL("Session Does not exist for given sessionID"));
+ cdf_mem_free(pAddStaParams);
+ return;
+ }
+ psessionEntry->csaOffloadEnable = pAddStaParams->csaOffloadEnable;
+ if (LIM_IS_IBSS_ROLE(psessionEntry))
+ (void)lim_ibss_add_sta_rsp(pMac, limMsgQ->bodyptr, psessionEntry);
+#ifdef FEATURE_WLAN_TDLS
+ else if (pMac->lim.gLimAddStaTdls) {
+ lim_process_tdls_add_sta_rsp(pMac, limMsgQ->bodyptr, psessionEntry);
+ pMac->lim.gLimAddStaTdls = false;
+ }
+#endif
+ else
+ lim_process_mlm_add_sta_rsp(pMac, limMsgQ, psessionEntry);
+
+}
+
+/**
+ * lim_update_beacon() - This function updates beacon
+ * @mac_ctx: pointer to Global Mac Structure
+ *
+ * This Function is invoked to update the beacon
+ *
+ * Return: none
+ */
+void lim_update_beacon(tpAniSirGlobal mac_ctx)
+{
+ uint8_t i;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ if (mac_ctx->lim.gpSession[i].valid != true)
+ continue;
+ if (((mac_ctx->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE)
+ || (mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_STA_IN_IBSS_ROLE))
+ && (eLIM_SME_NORMAL_STATE ==
+ mac_ctx->lim.gpSession[i].limSmeState)) {
+
+ sch_set_fixed_beacon_fields(mac_ctx,
+ &mac_ctx->lim.gpSession[i]);
+
+ if (false == mac_ctx->sap.SapDfsInfo.
+ is_dfs_cac_timer_running)
+ lim_send_beacon_ind(mac_ctx,
+ &mac_ctx->lim.gpSession[i]);
+ } else if (((mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_BT_AMP_AP_ROLE) ||
+ (mac_ctx->lim.gpSession[i].limSystemRole ==
+ eLIM_BT_AMP_STA_ROLE)) &&
+ (mac_ctx->lim.gpSession[i].statypeForBss ==
+ STA_ENTRY_SELF)){
+ sch_set_fixed_beacon_fields(mac_ctx,
+ &mac_ctx->lim.gpSession[i]);
+ }
+ }
+}
+
+/**
+ * lim_handle_heart_beat_failure_timeout - handle heart beat failure
+ * @mac_ctx: pointer to Global Mac Structure
+ *
+ * Function handle heart beat failure timeout
+ *
+ * Return: none
+ */
+void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal mac_ctx)
+{
+ uint8_t i;
+ tpPESession psession_entry;
+ /*
+ * Probe response is not received after HB failure.
+ * This is handled by LMM sub module.
+ */
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ if (mac_ctx->lim.gpSession[i].valid != true)
+ continue;
+ psession_entry = &mac_ctx->lim.gpSession[i];
+ if (psession_entry->LimHBFailureStatus != true)
+ continue;
+ lim_log(mac_ctx, LOGE, FL("SME %d, MLME %d, HB-Count %d"),
+ psession_entry->limSmeState,
+ psession_entry->limMlmState,
+ psession_entry->LimRxedBeaconCntDuringHB);
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
+ psession_entry, 0, 0);
+#endif
+ if ((psession_entry->limMlmState ==
+ eLIM_MLM_LINK_ESTABLISHED_STATE) &&
+ (psession_entry->limSmeState !=
+ eLIM_SME_WT_DISASSOC_STATE) &&
+ (psession_entry->limSmeState !=
+ eLIM_SME_WT_DEAUTH_STATE) &&
+ ((!LIM_IS_CONNECTION_ACTIVE(psession_entry)) ||
+ /*
+ * Disconnect even if we have not received a single
+ * beacon after connection.
+ */
+ (psession_entry->currentBssBeaconCnt == 0))) {
+ lim_log(mac_ctx, LOGE, FL("for session:%d "),
+ psession_entry->peSessionId);
+ /*
+ * AP did not respond to Probe Request.
+ * Tear down link with it.
+ */
+ lim_tear_down_link_with_ap(mac_ctx,
+ psession_entry->peSessionId,
+ eSIR_BEACON_MISSED);
+ mac_ctx->lim.gLimProbeFailureAfterHBfailedCnt++;
+ } else {
+ lim_log(mac_ctx, LOGE,
+ FL("Unexpected wt-probe-timeout in state "));
+ lim_print_mlm_state(mac_ctx, LOGE,
+ psession_entry->limMlmState);
+ }
+ }
+ /*
+ * Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer,
+ * need not deactivate the timer
+ * tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer);
+ */
+}
+
+/*
+ * This function assumes there will not be more than one IBSS session active at any time.
+ */
+tpPESession lim_is_ibss_session_active(tpAniSirGlobal pMac)
+{
+ uint8_t i;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if ((pMac->lim.gpSession[i].valid) &&
+ (pMac->lim.gpSession[i].limSystemRole ==
+ eLIM_STA_IN_IBSS_ROLE))
+ return &pMac->lim.gpSession[i];
+ }
+
+ return NULL;
+}
+
+tpPESession lim_is_ap_session_active(tpAniSirGlobal pMac)
+{
+ uint8_t i;
+
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if ((pMac->lim.gpSession[i].valid) &&
+ ((pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ||
+ (pMac->lim.gpSession[i].limSystemRole ==
+ eLIM_BT_AMP_AP_ROLE)))
+ return &pMac->lim.gpSession[i];
+ }
+
+ return NULL;
+}
+
+/**---------------------------------------------------------
+ \fn lim_handle_defer_msg_error
+ \brief handles error scenario, when the msg can not be deferred.
+ \param pMac
+ \param pLimMsg LIM msg, which could not be deferred.
+ \return void
+ -----------------------------------------------------------*/
+
+void lim_handle_defer_msg_error(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg)
+{
+ if (SIR_BB_XPORT_MGMT_MSG == pLimMsg->type) {
+ cds_pkt_return_packet((cds_pkt_t *) pLimMsg->bodyptr);
+ pLimMsg->bodyptr = NULL;
+ } else if (pLimMsg->bodyptr != NULL) {
+ cdf_mem_free(pLimMsg->bodyptr);
+ pLimMsg->bodyptr = NULL;
+ }
+
+}
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+/**---------------------------------------------------------
+ \fn lim_diag_event_report
+ \brief This function reports Diag event
+ \param pMac
+ \param eventType
+ \param bssid
+ \param status
+ \param reasonCode
+ \return void
+ -----------------------------------------------------------*/
+void lim_diag_event_report(tpAniSirGlobal pMac, uint16_t eventType,
+ tpPESession pSessionEntry, uint16_t status,
+ uint16_t reasonCode)
+{
+ tSirMacAddr nullBssid = { 0, 0, 0, 0, 0, 0 };
+ WLAN_HOST_DIAG_EVENT_DEF(peEvent, host_event_wlan_pe_payload_type);
+
+ cdf_mem_set(&peEvent, sizeof(host_event_wlan_pe_payload_type), 0);
+
+ if (NULL == pSessionEntry) {
+ cdf_mem_copy(peEvent.bssid, nullBssid, sizeof(tSirMacAddr));
+ peEvent.sme_state = (uint16_t) pMac->lim.gLimSmeState;
+ peEvent.mlm_state = (uint16_t) pMac->lim.gLimMlmState;
+
+ } else {
+ cdf_mem_copy(peEvent.bssid, pSessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ peEvent.sme_state = (uint16_t) pSessionEntry->limSmeState;
+ peEvent.mlm_state = (uint16_t) pSessionEntry->limMlmState;
+ }
+ peEvent.event_type = eventType;
+ peEvent.status = status;
+ peEvent.reason_code = reasonCode;
+
+ WLAN_HOST_DIAG_EVENT_REPORT(&peEvent, EVENT_WLAN_PE);
+ return;
+}
+
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+uint8_t *lim_get_ie_ptr_new(tpAniSirGlobal pMac, uint8_t *pIes, int length,
+ uint8_t eid, eSizeOfLenField size_of_len_field)
+{
+ int left = length;
+ uint8_t *ptr = pIes;
+ uint8_t elem_id;
+ uint16_t elem_len;
+
+ while (left >= (size_of_len_field + 1)) {
+ elem_id = ptr[0];
+ if (size_of_len_field == TWO_BYTE) {
+ elem_len = ((uint16_t) ptr[1]) | (ptr[2] << 8);
+ } else {
+ elem_len = ptr[1];
+ }
+
+ left -= (size_of_len_field + 1);
+ if (elem_len > left) {
+ lim_log(pMac, LOGE,
+ FL
+ ("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
+ eid, elem_len, left);
+ return NULL;
+ }
+ if (elem_id == eid) {
+ return ptr;
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + (size_of_len_field + 1));
+ }
+ return NULL;
+}
+
+/* Returns length of P2P stream and Pointer ie passed to this function is filled with noa stream */
+
+uint8_t lim_build_p2p_ie(tpAniSirGlobal pMac, uint8_t *ie, uint8_t *data,
+ uint8_t ie_len)
+{
+ int length = 0;
+ uint8_t *ptr = ie;
+
+ ptr[length++] = SIR_MAC_EID_VENDOR;
+ ptr[length++] = ie_len + SIR_MAC_P2P_OUI_SIZE;
+ cdf_mem_copy(&ptr[length], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
+ cdf_mem_copy(&ptr[length + SIR_MAC_P2P_OUI_SIZE], data, ie_len);
+ return ie_len + SIR_P2P_IE_HEADER_LEN;
+}
+
+/* Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream */
+
+uint8_t lim_get_noa_attr_stream_in_mult_p2p_ies(tpAniSirGlobal pMac,
+ uint8_t *noaStream, uint8_t noaLen,
+ uint8_t overFlowLen)
+{
+ uint8_t overFlowP2pStream[SIR_MAX_NOA_ATTR_LEN];
+
+ if ((noaLen <= (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) &&
+ (noaLen >= overFlowLen) && (overFlowLen <= SIR_MAX_NOA_ATTR_LEN)) {
+ cdf_mem_copy(overFlowP2pStream,
+ noaStream + noaLen - overFlowLen, overFlowLen);
+ noaStream[noaLen - overFlowLen] = SIR_MAC_EID_VENDOR;
+ noaStream[noaLen - overFlowLen + 1] =
+ overFlowLen + SIR_MAC_P2P_OUI_SIZE;
+ cdf_mem_copy(noaStream + noaLen - overFlowLen + 2,
+ SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE);
+ cdf_mem_copy(noaStream + noaLen + 2 + SIR_MAC_P2P_OUI_SIZE -
+ overFlowLen, overFlowP2pStream, overFlowLen);
+ }
+
+ return noaLen + SIR_P2P_IE_HEADER_LEN;
+
+}
+
+/* Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream */
+uint8_t lim_get_noa_attr_stream(tpAniSirGlobal pMac, uint8_t *pNoaStream,
+ tpPESession psessionEntry)
+{
+ uint8_t len = 0;
+
+ uint8_t *pBody = pNoaStream;
+
+ if ((psessionEntry != NULL) && (psessionEntry->valid) &&
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
+ if ((!(psessionEntry->p2pGoPsUpdate.uNoa1Duration))
+ && (!(psessionEntry->p2pGoPsUpdate.uNoa2Duration))
+ && (!psessionEntry->p2pGoPsUpdate.oppPsFlag)
+ )
+ return 0; /* No NoA Descriptor then return 0 */
+
+ pBody[0] = SIR_P2P_NOA_ATTR;
+
+ pBody[3] = psessionEntry->p2pGoPsUpdate.index;
+ pBody[4] =
+ psessionEntry->p2pGoPsUpdate.ctWin | (psessionEntry->
+ p2pGoPsUpdate.
+ oppPsFlag << 7);
+ len = 5;
+ pBody += len;
+
+ if (psessionEntry->p2pGoPsUpdate.uNoa1Duration) {
+ *pBody = psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt;
+ pBody += 1;
+ len += 1;
+
+ *((uint32_t *) (pBody)) =
+ sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+ uNoa1Duration);
+ pBody += sizeof(uint32_t);
+ len += 4;
+
+ *((uint32_t *) (pBody)) =
+ sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+ uNoa1Interval);
+ pBody += sizeof(uint32_t);
+ len += 4;
+
+ *((uint32_t *) (pBody)) =
+ sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+ uNoa1StartTime);
+ pBody += sizeof(uint32_t);
+ len += 4;
+
+ }
+
+ if (psessionEntry->p2pGoPsUpdate.uNoa2Duration) {
+ *pBody = psessionEntry->p2pGoPsUpdate.uNoa2IntervalCnt;
+ pBody += 1;
+ len += 1;
+
+ *((uint32_t *) (pBody)) =
+ sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+ uNoa2Duration);
+ pBody += sizeof(uint32_t);
+ len += 4;
+
+ *((uint32_t *) (pBody)) =
+ sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+ uNoa2Interval);
+ pBody += sizeof(uint32_t);
+ len += 4;
+
+ *((uint32_t *) (pBody)) =
+ sir_swap_u32if_needed(psessionEntry->p2pGoPsUpdate.
+ uNoa2StartTime);
+ pBody += sizeof(uint32_t);
+ len += 4;
+
+ }
+
+ pBody = pNoaStream + 1;
+ *((uint16_t *) (pBody)) = sir_swap_u16if_needed(len - 3); /*one byte for Attr and 2 bytes for length */
+
+ return len;
+
+ }
+ return 0;
+
+}
+
+void pe_set_resume_channel(tpAniSirGlobal pMac, uint16_t channel,
+ ePhyChanBondState phyCbState)
+{
+
+ pMac->lim.gResumeChannel = channel;
+ pMac->lim.gResumePhyCbState = phyCbState;
+}
+
+bool lim_is_noa_insert_reqd(tpAniSirGlobal pMac)
+{
+ uint8_t i;
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if (pMac->lim.gpSession[i].valid == true) {
+ if ((eLIM_AP_ROLE ==
+ pMac->lim.gpSession[i].limSystemRole)
+ && (CDF_P2P_GO_MODE ==
+ pMac->lim.gpSession[i].pePersona)
+ ) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool lim_isconnected_on_dfs_channel(uint8_t currentChannel)
+{
+ if (CHANNEL_STATE_DFS ==
+ cds_get_channel_state(currentChannel)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+#ifdef WLAN_FEATURE_11W
+void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param)
+{
+ tpAniSirGlobal pMac = (tpAniSirGlobal) pMacGlobal;
+ tPmfSaQueryTimerId timerId;
+ tpPESession psessionEntry;
+ tpDphHashNode pSta;
+ uint32_t maxRetries;
+
+ lim_log(pMac, LOG1, FL("SA Query timer fires"));
+ timerId.value = param;
+
+ /* Check that SA Query is in progress */
+ psessionEntry = pe_find_session_by_session_id(pMac,
+ timerId.fields.sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session does not exist for given session ID %d"),
+ timerId.fields.sessionId);
+ return;
+ }
+ pSta = dph_get_hash_entry(pMac, timerId.fields.peerIdx,
+ &psessionEntry->dph.dphHashTable);
+ if (pSta == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Entry does not exist for given peer index %d"),
+ timerId.fields.peerIdx);
+ return;
+ }
+ if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
+ return;
+
+ /* Increment the retry count, check if reached maximum */
+ if (wlan_cfg_get_int(pMac, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES,
+ &maxRetries) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Could not retrieve PMF SA Query maximum retries value"));
+ pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+ return;
+ }
+ pSta->pmfSaQueryRetryCount++;
+ if (pSta->pmfSaQueryRetryCount >= maxRetries) {
+ lim_log(pMac, LOGE, FL("SA Query timed out,Deleting STA"));
+ lim_print_mac_addr(pMac, pSta->staAddr, LOGE);
+ lim_send_disassoc_mgmt_frame(pMac,
+ eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON,
+ pSta->staAddr, psessionEntry, false);
+ lim_trigger_sta_deletion(pMac, pSta, psessionEntry);
+ pSta->pmfSaQueryState = DPH_SA_QUERY_TIMED_OUT;
+ return;
+ }
+ /* Retry SA Query */
+ lim_send_sa_query_request_frame(pMac,
+ (uint8_t *) &(pSta->
+ pmfSaQueryCurrentTransId),
+ pSta->staAddr, psessionEntry);
+ pSta->pmfSaQueryCurrentTransId++;
+ lim_log(pMac, LOGE, FL("Starting SA Query retry %d"),
+ pSta->pmfSaQueryRetryCount);
+ if (tx_timer_activate(&pSta->pmfSaQueryTimer) != TX_SUCCESS) {
+ lim_log(pMac, LOGE, FL("PMF SA Query timer activation failed!"));
+ pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
+ }
+}
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint8_t chanWidth, uint8_t staId,
+ uint8_t *peerMac)
+{
+ tUpdateVHTOpMode tempParam;
+
+ tempParam.opMode = chanWidth;
+ tempParam.staId = staId;
+ tempParam.smesessionId = psessionEntry->smeSessionId;
+ cdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
+
+ lim_send_mode_update(pMac, &tempParam, psessionEntry);
+
+ return true;
+}
+
+bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint8_t rxNss, uint8_t staId, uint8_t *peerMac)
+{
+ tUpdateRxNss tempParam;
+
+ tempParam.rxNss = rxNss;
+ tempParam.staId = staId;
+ tempParam.smesessionId = psessionEntry->smeSessionId;
+ cdf_mem_copy(tempParam.peer_mac, peerMac, sizeof(tSirMacAddr));
+
+ lim_send_rx_nss_update(pMac, &tempParam, psessionEntry);
+
+ return true;
+}
+
+bool lim_check_membership_user_position(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint32_t membership, uint32_t userPosition,
+ uint8_t staId)
+{
+ tUpdateMembership tempParamMembership;
+ tUpdateUserPos tempParamUserPosition;
+
+ tempParamMembership.membership = membership;
+ tempParamMembership.staId = staId;
+ tempParamMembership.smesessionId = psessionEntry->smeSessionId;
+ cdf_mem_copy(tempParamMembership.peer_mac, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+
+ lim_set_membership(pMac, &tempParamMembership, psessionEntry);
+
+ tempParamUserPosition.userPos = userPosition;
+ tempParamUserPosition.staId = staId;
+ tempParamUserPosition.smesessionId = psessionEntry->smeSessionId;
+ cdf_mem_copy(tempParamUserPosition.peer_mac, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+
+ lim_set_user_pos(pMac, &tempParamUserPosition, psessionEntry);
+
+ return true;
+}
+#endif
+
+void lim_get_short_slot_from_phy_mode(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint32_t phyMode, uint8_t *pShortSlotEnabled)
+{
+ uint8_t val = 0;
+
+ /* only 2.4G band should have short slot enable, rest it should be default */
+ if (phyMode == WNI_CFG_PHY_MODE_11G) {
+ /* short slot is default in all other modes */
+ if ((psessionEntry->pePersona == CDF_SAP_MODE) ||
+ (psessionEntry->pePersona == CDF_IBSS_MODE) ||
+ (psessionEntry->pePersona == CDF_P2P_GO_MODE)) {
+ val = true;
+ }
+ /* Program Polaris based on AP capability */
+ if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) {
+ /* Joining BSS. */
+ val =
+ SIR_MAC_GET_SHORT_SLOT_TIME(psessionEntry->
+ limCurrentBssCaps);
+ } else if (psessionEntry->limMlmState ==
+ eLIM_MLM_WT_REASSOC_RSP_STATE) {
+ /* Reassociating with AP. */
+ val =
+ SIR_MAC_GET_SHORT_SLOT_TIME(psessionEntry->
+ limReassocBssCaps);
+ }
+ } else {
+ /*
+ * 11B does not short slot and short slot is default
+ * for 11A mode. Hence, not need to set this bit
+ */
+ val = false;
+ }
+
+ lim_log(pMac, LOG1, FL("phyMode = %u shortslotsupported = %u"), phyMode,
+ val);
+ *pShortSlotEnabled = val;
+}
+
+#ifdef WLAN_FEATURE_11W
+/**
+ *
+ * \brief This function is called by various LIM modules to correctly set
+ * the Protected bit in the Frame Control Field of the 802.11 frame MAC header
+ *
+ *
+ * \param pMac Pointer to Global MAC structure
+ *
+ * \param psessionEntry Pointer to session corresponding to the connection
+ *
+ * \param peer Peer address of the STA to which the frame is to be sent
+ *
+ * \param pMacHdr Pointer to the frame MAC header
+ *
+ * \return nothing
+ *
+ *
+ */
+void
+lim_set_protected_bit(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr)
+{
+ uint16_t aid;
+ tpDphHashNode pStaDs;
+
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
+
+ pStaDs = dph_lookup_hash_entry(pMac, peer, &aid,
+ &psessionEntry->dph.dphHashTable);
+ if (pStaDs != NULL) {
+ /* rmfenabled will be set at the time of addbss.
+ * but sometimes EAP auth fails and keys are not
+ * installed then if we send any management frame
+ * like deauth/disassoc with this bit set then
+ * firmware crashes. so check for keys are
+ * installed or not also before setting the bit
+ */
+ if (pStaDs->rmfEnabled && pStaDs->is_key_installed)
+ pMacHdr->fc.wep = 1;
+ }
+ } else if (psessionEntry->limRmfEnabled &&
+ psessionEntry->is_key_installed) {
+ pMacHdr->fc.wep = 1;
+ }
+} /*** end lim_set_protected_bit() ***/
+#endif
+
+void lim_set_ht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
+ uint8_t *p_ie_start, uint32_t num_bytes)
+{
+ uint8_t *p_ie = NULL;
+ tDot11fIEHTCaps dot11_ht_cap = {0,};
+
+ populate_dot11f_ht_caps(p_mac, p_session_entry, &dot11_ht_cap);
+ p_ie = lim_get_ie_ptr_new(p_mac, p_ie_start, num_bytes,
+ DOT11F_EID_HTCAPS, ONE_BYTE);
+ lim_log(p_mac, LOG2, FL("p_ie %p dot11_ht_cap.supportedMCSSet[0]=0x%x"),
+ p_ie, dot11_ht_cap.supportedMCSSet[0]);
+ if (p_ie) {
+ /* convert from unpacked to packed structure */
+ tHtCaps *p_ht_cap = (tHtCaps *) &p_ie[2];
+
+ p_ht_cap->advCodingCap = dot11_ht_cap.advCodingCap;
+ p_ht_cap->supportedChannelWidthSet =
+ dot11_ht_cap.supportedChannelWidthSet;
+ p_ht_cap->mimoPowerSave = dot11_ht_cap.mimoPowerSave;
+ p_ht_cap->greenField = dot11_ht_cap.greenField;
+ p_ht_cap->shortGI20MHz = dot11_ht_cap.shortGI20MHz;
+ p_ht_cap->shortGI40MHz = dot11_ht_cap.shortGI40MHz;
+ p_ht_cap->txSTBC = dot11_ht_cap.txSTBC;
+ p_ht_cap->rxSTBC = dot11_ht_cap.rxSTBC;
+ p_ht_cap->delayedBA = dot11_ht_cap.delayedBA;
+ p_ht_cap->maximalAMSDUsize = dot11_ht_cap.maximalAMSDUsize;
+ p_ht_cap->dsssCckMode40MHz = dot11_ht_cap.dsssCckMode40MHz;
+ p_ht_cap->psmp = dot11_ht_cap.psmp;
+ p_ht_cap->stbcControlFrame = dot11_ht_cap.stbcControlFrame;
+ p_ht_cap->lsigTXOPProtection = dot11_ht_cap.lsigTXOPProtection;
+ p_ht_cap->maxRxAMPDUFactor = dot11_ht_cap.maxRxAMPDUFactor;
+ p_ht_cap->mpduDensity = dot11_ht_cap.mpduDensity;
+ cdf_mem_copy((void *)p_ht_cap->supportedMCSSet,
+ (void *)(dot11_ht_cap.supportedMCSSet),
+ sizeof(p_ht_cap->supportedMCSSet));
+ p_ht_cap->pco = dot11_ht_cap.pco;
+ p_ht_cap->transitionTime = dot11_ht_cap.transitionTime;
+ p_ht_cap->mcsFeedback = dot11_ht_cap.mcsFeedback;
+ p_ht_cap->txBF = dot11_ht_cap.txBF;
+ p_ht_cap->rxStaggeredSounding =
+ dot11_ht_cap.rxStaggeredSounding;
+ p_ht_cap->txStaggeredSounding =
+ dot11_ht_cap.txStaggeredSounding;
+ p_ht_cap->rxZLF = dot11_ht_cap.rxZLF;
+ p_ht_cap->txZLF = dot11_ht_cap.txZLF;
+ p_ht_cap->implicitTxBF = dot11_ht_cap.implicitTxBF;
+ p_ht_cap->calibration = dot11_ht_cap.calibration;
+ p_ht_cap->explicitCSITxBF = dot11_ht_cap.explicitCSITxBF;
+ p_ht_cap->explicitUncompressedSteeringMatrix =
+ dot11_ht_cap.explicitUncompressedSteeringMatrix;
+ p_ht_cap->explicitBFCSIFeedback =
+ dot11_ht_cap.explicitBFCSIFeedback;
+ p_ht_cap->explicitUncompressedSteeringMatrixFeedback =
+ dot11_ht_cap.explicitUncompressedSteeringMatrixFeedback;
+ p_ht_cap->explicitCompressedSteeringMatrixFeedback =
+ dot11_ht_cap.explicitCompressedSteeringMatrixFeedback;
+ p_ht_cap->csiNumBFAntennae = dot11_ht_cap.csiNumBFAntennae;
+ p_ht_cap->uncompressedSteeringMatrixBFAntennae =
+ dot11_ht_cap.uncompressedSteeringMatrixBFAntennae;
+ p_ht_cap->compressedSteeringMatrixBFAntennae =
+ dot11_ht_cap.compressedSteeringMatrixBFAntennae;
+ p_ht_cap->antennaSelection = dot11_ht_cap.antennaSelection;
+ p_ht_cap->explicitCSIFeedbackTx =
+ dot11_ht_cap.explicitCSIFeedbackTx;
+ p_ht_cap->antennaIndicesFeedbackTx =
+ dot11_ht_cap.antennaIndicesFeedbackTx;
+ p_ht_cap->explicitCSIFeedback =
+ dot11_ht_cap.explicitCSIFeedback;
+ p_ht_cap->antennaIndicesFeedback =
+ dot11_ht_cap.antennaIndicesFeedback;
+ p_ht_cap->rxAS = dot11_ht_cap.rxAS;
+ p_ht_cap->txSoundingPPDUs = dot11_ht_cap.txSoundingPPDUs;
+ }
+}
+
+#ifdef WLAN_FEATURE_11AC
+void lim_set_vht_caps(tpAniSirGlobal p_mac, tpPESession p_session_entry,
+ uint8_t *p_ie_start, uint32_t num_bytes)
+{
+ uint8_t *p_ie = NULL;
+ tDot11fIEVHTCaps dot11_vht_cap;
+
+ populate_dot11f_vht_caps(p_mac, p_session_entry, &dot11_vht_cap);
+ p_ie = lim_get_ie_ptr_new(p_mac, p_ie_start, num_bytes,
+ DOT11F_EID_VHTCAPS, ONE_BYTE);
+
+ if (p_ie) {
+ tSirMacVHTCapabilityInfo *vht_cap =
+ (tSirMacVHTCapabilityInfo *) &p_ie[2];
+ tSirVhtMcsInfo *vht_mcs = (tSirVhtMcsInfo *) &p_ie[2 +
+ sizeof(tSirMacVHTCapabilityInfo)];
+
+ union {
+ uint16_t u_value;
+ tSirMacVHTRxSupDataRateInfo vht_rx_supp_rate;
+ tSirMacVHTTxSupDataRateInfo vht_tx_supp_rate;
+ } u_vht_data_rate_info;
+
+ vht_cap->maxMPDULen = dot11_vht_cap.maxMPDULen;
+ vht_cap->supportedChannelWidthSet =
+ dot11_vht_cap.supportedChannelWidthSet;
+ vht_cap->ldpcCodingCap = dot11_vht_cap.ldpcCodingCap;
+ vht_cap->shortGI80MHz = dot11_vht_cap.shortGI80MHz;
+ vht_cap->shortGI160and80plus80MHz =
+ dot11_vht_cap.shortGI160and80plus80MHz;
+ vht_cap->txSTBC = dot11_vht_cap.txSTBC;
+ vht_cap->rxSTBC = dot11_vht_cap.rxSTBC;
+ vht_cap->suBeamFormerCap = dot11_vht_cap.suBeamFormerCap;
+ vht_cap->suBeamformeeCap = dot11_vht_cap.suBeamformeeCap;
+ vht_cap->csnofBeamformerAntSup =
+ dot11_vht_cap.csnofBeamformerAntSup;
+ vht_cap->numSoundingDim = dot11_vht_cap.numSoundingDim;
+ vht_cap->muBeamformerCap = dot11_vht_cap.muBeamformerCap;
+ vht_cap->muBeamformeeCap = dot11_vht_cap.muBeamformeeCap;
+ vht_cap->vhtTXOPPS = dot11_vht_cap.vhtTXOPPS;
+ vht_cap->htcVHTCap = dot11_vht_cap.htcVHTCap;
+ vht_cap->maxAMPDULenExp = dot11_vht_cap.maxAMPDULenExp;
+ vht_cap->vhtLinkAdaptCap = dot11_vht_cap.vhtLinkAdaptCap;
+ vht_cap->rxAntPattern = dot11_vht_cap.rxAntPattern;
+ vht_cap->txAntPattern = dot11_vht_cap.txAntPattern;
+ vht_cap->reserved1 = dot11_vht_cap.reserved1;
+
+ /* Populate VHT MCS Information */
+ vht_mcs->rxMcsMap = dot11_vht_cap.rxMCSMap;
+ u_vht_data_rate_info.vht_rx_supp_rate.rxSupDataRate =
+ dot11_vht_cap.rxHighSupDataRate;
+ u_vht_data_rate_info.vht_rx_supp_rate.reserved =
+ dot11_vht_cap.reserved2;
+ vht_mcs->rxHighest = u_vht_data_rate_info.u_value;
+
+ vht_mcs->txMcsMap = dot11_vht_cap.txMCSMap;
+ u_vht_data_rate_info.vht_tx_supp_rate.txSupDataRate =
+ dot11_vht_cap.txSupDataRate;
+ u_vht_data_rate_info.vht_tx_supp_rate.reserved =
+ dot11_vht_cap.reserved3;
+ vht_mcs->txHighest = u_vht_data_rate_info.u_value;
+ }
+}
+#endif /* WLAN_FEATURE_11AC */
+
+/**
+ * lim_validate_received_frame_a1_addr() - To validate received frame's A1 addr
+ * @mac_ctx: pointer to mac context
+ * @a1: received frame's a1 address which is nothing but our self address
+ * @session: PE session pointer
+ *
+ * This routine will validate, A1 addres of the received frame
+ *
+ * Return: true or false
+ */
+bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx,
+ tSirMacAddr a1, tpPESession session)
+{
+ if (mac_ctx == NULL || session == NULL) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ "mac or session context is null");
+ /* let main routine handle it */
+ return true;
+ }
+ if (lim_is_group_addr(a1) || lim_is_addr_bc(a1)) {
+ /* just for fail safe, don't handle MC/BC a1 in this routine */
+ return true;
+ }
+ if (!cdf_mem_compare(a1, session->selfMacAddr, 6)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid A1 address in received frame"));
+ return false;
+ }
+ return true;
+}
+
+/**
+ * lim_check_and_reset_protection_params() - reset protection related parameters
+ *
+ * @mac_ctx: pointer to global mac structure
+ *
+ * resets protection related global parameters if the pe active session count
+ * is zero.
+ *
+ * Return: None
+ */
+void lim_check_and_reset_protection_params(tpAniSirGlobal mac_ctx)
+{
+ if (!pe_get_active_session_count(mac_ctx)) {
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlap11gParams,
+ sizeof(mac_ctx->lim.gLimOverlap11gParams));
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlap11aParams,
+ sizeof(mac_ctx->lim.gLimOverlap11aParams));
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlapHt20Params,
+ sizeof(mac_ctx->lim.gLimOverlapHt20Params));
+ cdf_mem_zero(&mac_ctx->lim.gLimOverlapNonGfParams,
+ sizeof(mac_ctx->lim.gLimOverlapNonGfParams));
+
+ mac_ctx->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE;
+ }
+}
+
+/**
+ * lim_set_stads_rtt_cap() - update station node RTT capability
+ * @sta_ds: Station hash node
+ * @ext_cap: Pointer to extended capability
+ * @mac_ctx: global MAC context
+ *
+ * This funciton update hash node's RTT capability based on received
+ * Extended capability IE.
+ *
+ * Return: None
+ */
+void lim_set_stads_rtt_cap(tpDphHashNode sta_ds, struct s_ext_cap *ext_cap,
+ tpAniSirGlobal mac_ctx)
+{
+ sta_ds->timingMeasCap = 0;
+ sta_ds->timingMeasCap |= (ext_cap->timing_meas) ?
+ RTT_TIMING_MEAS_CAPABILITY :
+ RTT_INVALID;
+ sta_ds->timingMeasCap |= (ext_cap->fine_time_meas_initiator) ?
+ RTT_FINE_TIME_MEAS_INITIATOR_CAPABILITY :
+ RTT_INVALID;
+ sta_ds->timingMeasCap |= (ext_cap->fine_time_meas_responder) ?
+ RTT_FINE_TIME_MEAS_RESPONDER_CAPABILITY :
+ RTT_INVALID;
+
+ lim_log(mac_ctx, LOG1,
+ FL("ExtCap present, timingMeas: %d Initiator: %d Responder: %d"),
+ ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+ ext_cap->fine_time_meas_responder);
+}
+
+/**
+ * lim_send_ext_cap_ie() - send ext cap IE to FW
+ * @mac_ctx: global MAC context
+ * @session_entry: PE session
+ * @extra_extcap: extracted ext cap
+ * @merge: merge extra ext cap
+ *
+ * This function is invoked after VDEV is created to update firmware
+ * about the extended capabilities that the corresponding VDEV is capable
+ * of. Since STA/SAP can have different Extended capabilities set, this function
+ * is called per vdev creation.
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS lim_send_ext_cap_ie(tpAniSirGlobal mac_ctx,
+ uint32_t session_id,
+ tDot11fIEExtCap *extra_extcap, bool merge)
+{
+ tDot11fIEExtCap ext_cap_data = {0};
+ uint32_t dot11mode, num_bytes;
+ bool vht_enabled = false;
+ struct vdev_ie_info *vdev_ie;
+ cds_msg_t msg = {0};
+ tSirRetStatus status;
+ uint8_t *temp, i;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &dot11mode);
+ if (IS_DOT11_MODE_VHT(dot11mode))
+ vht_enabled = true;
+
+ status = populate_dot11f_ext_cap(mac_ctx, vht_enabled, &ext_cap_data,
+ NULL);
+ if (eSIR_SUCCESS != status) {
+ lim_log(mac_ctx, LOGE, FL("Failed to populate ext cap IE"));
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ num_bytes = ext_cap_data.num_bytes;
+
+ if (merge && NULL != extra_extcap && extra_extcap->num_bytes > 0) {
+ if (extra_extcap->num_bytes > ext_cap_data.num_bytes)
+ num_bytes = extra_extcap->num_bytes;
+ lim_merge_extcap_struct(&ext_cap_data, extra_extcap);
+ }
+
+ /* Allocate memory for the WMI request, and copy the parameter */
+ vdev_ie = cdf_mem_malloc(sizeof(*vdev_ie) + num_bytes);
+ if (!vdev_ie) {
+ lim_log(mac_ctx, LOGE, FL("Failed to allocate memory"));
+ return CDF_STATUS_E_NOMEM;
+ }
+
+ vdev_ie->vdev_id = session_id;
+ vdev_ie->ie_id = DOT11F_EID_EXTCAP;
+ vdev_ie->length = num_bytes;
+
+ lim_log(mac_ctx, LOG1, FL("vdev %d ieid %d len %d"), session_id,
+ DOT11F_EID_EXTCAP, num_bytes);
+ temp = ext_cap_data.bytes;
+ for (i = 0; i < num_bytes; i++, temp++)
+ lim_log(mac_ctx, LOG1, FL("%d byte is %02x"), i+1, *temp);
+
+ vdev_ie->data = (uint8_t *)vdev_ie + sizeof(*vdev_ie);
+ cdf_mem_copy(vdev_ie->data, ext_cap_data.bytes, num_bytes);
+
+ msg.type = WMA_SET_IE_INFO;
+ msg.bodyptr = vdev_ie;
+ msg.reserved = 0;
+
+ if (CDF_STATUS_SUCCESS !=
+ cds_mq_post_message(CDF_MODULE_ID_WMA, &msg)) {
+ lim_log(mac_ctx, LOGE,
+ FL("Not able to post WMA_SET_IE_INFO to WDA"));
+ cdf_mem_free(vdev_ie);
+ return CDF_STATUS_E_FAILURE;
+ }
+
+ return CDF_STATUS_SUCCESS;
+}
+
+/**
+ * lim_strip_extcap_ie() - strip extended capability IE from IE buffer
+ * @mac_ctx: global MAC context
+ * @addn_ie: Additional IE buffer
+ * @addn_ielen: Length of additional IE
+ * @extracted_ie: if not NULL, copy the stripped IE to this buffer
+ *
+ * This utility function is used to strip of the extended capability IE present
+ * in additional IE buffer.
+ *
+ * Return: tSirRetStatus
+ */
+tSirRetStatus lim_strip_extcap_ie(tpAniSirGlobal mac_ctx,
+ uint8_t *addn_ie, uint16_t *addn_ielen, uint8_t *extracted_ie)
+{
+ uint8_t *tempbuf = NULL;
+ uint16_t templen = 0;
+ int left = *addn_ielen;
+ uint8_t *ptr = addn_ie;
+ uint8_t elem_id, elem_len;
+
+ if (NULL == addn_ie) {
+ lim_log(mac_ctx, LOG1, FL("NULL addn_ie pointer"));
+ return eSIR_IGNORE_IE;
+ }
+
+ tempbuf = cdf_mem_malloc(left);
+ if (NULL == tempbuf) {
+ lim_log(mac_ctx, LOGE, FL("Unable to allocate memory"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ while (left >= 2) {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if (elem_len > left) {
+ lim_log(mac_ctx, LOGE,
+ FL("Invalid IEs eid = %d elem_len=%d left=%d"),
+ elem_id, elem_len, left);
+ cdf_mem_free(tempbuf);
+ return eSIR_FAILURE;
+ }
+ if (!(DOT11F_EID_EXTCAP == elem_id)) {
+ cdf_mem_copy(tempbuf + templen, &ptr[0], elem_len + 2);
+ templen += (elem_len + 2);
+ } else {
+ if (NULL != extracted_ie) {
+ cdf_mem_set(extracted_ie,
+ DOT11F_IE_EXTCAP_MAX_LEN + 2, 0);
+ if (elem_len <= DOT11F_IE_EXTCAP_MAX_LEN)
+ cdf_mem_copy(extracted_ie, &ptr[0],
+ elem_len + 2);
+ }
+ }
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ cdf_mem_copy(addn_ie, tempbuf, templen);
+
+ *addn_ielen = templen;
+ cdf_mem_free(tempbuf);
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * lim_update_extcap_struct() - poputlate the dot11f structure
+ * @mac_ctx: global MAC context
+ * @buf: extracted IE buffer
+ * @dst: extended capability IE structure to be updated
+ *
+ * This function is used to update the extended capability structure
+ * with @buf.
+ *
+ * Return: None
+ */
+void lim_update_extcap_struct(tpAniSirGlobal mac_ctx,
+ uint8_t *buf, tDot11fIEExtCap *dst)
+{
+ uint8_t out[DOT11F_IE_EXTCAP_MAX_LEN];
+
+ if (NULL == buf) {
+ lim_log(mac_ctx, LOGE, FL("Invalid Buffer Address"));
+ return;
+ }
+
+ if (NULL == dst) {
+ lim_log(mac_ctx, LOGE, FL("NULL dst pointer"));
+ return;
+ }
+
+ if (DOT11F_EID_EXTCAP != buf[0] || buf[1] > DOT11F_IE_EXTCAP_MAX_LEN) {
+ lim_log(mac_ctx, LOG1, FL("Invalid IEs eid = %d elem_len=%d "),
+ buf[0], buf[1]);
+ return;
+ }
+
+ cdf_mem_set((uint8_t *)&out[0], DOT11F_IE_EXTCAP_MAX_LEN, 0);
+ cdf_mem_copy(&out[0], &buf[2], DOT11F_IE_EXTCAP_MAX_LEN);
+
+ if (DOT11F_PARSE_SUCCESS != dot11f_unpack_ie_ext_cap(mac_ctx, &out[0],
+ DOT11F_IE_EXTCAP_MAX_LEN, dst))
+ lim_log(mac_ctx, LOGE, FL("dot11f_unpack Parse Error "));
+}
+
+/**
+ * lim_strip_extcap_update_struct - strip extended capability IE and populate
+ * the dot11f structure
+ * @mac_ctx: global MAC context
+ * @addn_ie: Additional IE buffer
+ * @addn_ielen: Length of additional IE
+ * @dst: extended capability IE structure to be updated
+ *
+ * This function is used to strip extended capability IE from IE buffer and
+ * update the passed structure.
+ *
+ * Return: tSirRetStatus
+ */
+tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
+ uint8_t *addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst)
+{
+ uint8_t extracted_buff[DOT11F_IE_EXTCAP_MAX_LEN + 2];
+ tSirRetStatus status;
+
+ cdf_mem_set((uint8_t *)&extracted_buff[0], DOT11F_IE_EXTCAP_MAX_LEN + 2,
+ 0);
+ status = lim_strip_extcap_ie(mac_ctx, addn_ie, addn_ielen,
+ extracted_buff);
+ if (eSIR_SUCCESS != status) {
+ lim_log(mac_ctx, LOG1,
+ FL("Failed to strip extcap IE status = (%d)."), status);
+ return status;
+ }
+
+ /* update the extracted ExtCap to struct*/
+ lim_update_extcap_struct(mac_ctx, extracted_buff, dst);
+ return status;
+}
+
+/**
+ * lim_merge_extcap_struct() - merge extended capabilities info
+ * @dst: destination extended capabilities
+ * @src: source extended capabilities
+ *
+ * This function is used to take @src info and merge it with @dst
+ * extended capabilities info.
+ *
+ * Return: None
+ */
+void lim_merge_extcap_struct(tDot11fIEExtCap *dst,
+ tDot11fIEExtCap *src)
+{
+ uint8_t *tempdst = (uint8_t *)dst->bytes;
+ uint8_t *tempsrc = (uint8_t *)src->bytes;
+ uint8_t structlen = member_size(tDot11fIEExtCap, bytes);
+
+ while (tempdst && tempsrc && structlen--) {
+ *tempdst |= *tempsrc;
+ tempdst++;
+ tempsrc++;
+ }
+}
+
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
new file mode 100644
index 0000000..76b000c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -0,0 +1,591 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_utils.h contains the utility definitions
+ * LIM uses.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __LIM_UTILS_H
+#define __LIM_UTILS_H
+
+#include "sir_api.h"
+#include "sir_debug.h"
+#include "cfg_api.h"
+
+#include "lim_types.h"
+#include "lim_scan_result_utils.h"
+#include "lim_timer_utils.h"
+#include "lim_trace.h"
+typedef enum {
+ ONE_BYTE = 1,
+ TWO_BYTE = 2
+} eSizeOfLenField;
+
+#define MIN_TX_PWR_CAP 8
+#define MAX_TX_PWR_CAP 22
+
+#define LIM_STA_ID_MASK 0x00FF
+#define LIM_AID_MASK 0xC000
+#define LIM_SPECTRUM_MANAGEMENT_BIT_MASK 0x0100
+#define LIM_RRM_BIT_MASK 0x1000
+#define LIM_SHORT_PREAMBLE_BIT_MASK 0x0020
+#define LIM_IMMEDIATE_BLOCK_ACK_MASK 0x8000
+#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
+#define LIM_MAX_REASSOC_RETRY_LIMIT 2
+#endif
+
+/* classifier ID is coded as 0-3: tsid, 4-5:direction */
+#define LIM_MAKE_CLSID(tsid, dir) (((tsid) & 0x0F) | (((dir) & 0x03) << 4))
+
+#define VHT_MCS_3x3_MASK 0x30
+#define VHT_MCS_2x2_MASK 0x0C
+
+#ifdef WLAN_FEATURE_11W
+typedef union uPmfSaQueryTimerId {
+ struct {
+ uint8_t sessionId;
+ uint16_t peerIdx;
+ } fields;
+ uint32_t value;
+} tPmfSaQueryTimerId, *tpPmfSaQueryTimerId;
+#endif
+
+/* LIM utility functions */
+void limGetBssidFromPkt(tpAniSirGlobal, uint8_t *, uint8_t *, uint32_t *);
+char *lim_dot11_reason_str(uint16_t reasonCode);
+char *lim_mlm_state_str(tLimMlmStates state);
+char *lim_sme_state_str(tLimSmeStates state);
+char *lim_msg_str(uint32_t msgType);
+char *lim_result_code_str(tSirResultCodes resultCode);
+char *lim_dot11_mode_str(tpAniSirGlobal pMac, uint8_t dot11Mode);
+void lim_print_mlm_state(tpAniSirGlobal pMac, uint16_t logLevel,
+ tLimMlmStates state);
+void lim_print_sme_state(tpAniSirGlobal pMac, uint16_t logLevel,
+ tLimSmeStates state);
+void lim_print_msg_name(tpAniSirGlobal pMac, uint16_t logLevel, uint32_t msgType);
+
+#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI
+extern tSirRetStatus lim_send_set_max_tx_power_req(tpAniSirGlobal pMac,
+ tPowerdBm txPower,
+ tpPESession pSessionEntry);
+extern uint8_t lim_get_max_tx_power(tPowerdBm regMax, tPowerdBm apTxPower,
+ uint8_t iniTxPower);
+#endif
+uint8_t lim_is_addr_bc(tSirMacAddr);
+uint8_t lim_is_group_addr(tSirMacAddr);
+
+/* check for type of scan allowed */
+uint8_t lim_active_scan_allowed(tpAniSirGlobal, uint8_t);
+
+/* AID pool management functions */
+void lim_init_peer_idxpool(tpAniSirGlobal, tpPESession);
+uint16_t lim_assign_peer_idx(tpAniSirGlobal, tpPESession);
+
+void lim_enable_overlap11g_protection(tpAniSirGlobal pMac,
+ tpUpdateBeaconParams pBeaconParams,
+ tpSirMacMgmtHdr pMh,
+ tpPESession psessionEntry);
+void lim_update_overlap_sta_param(tpAniSirGlobal pMac, tSirMacAddr bssId,
+ tpLimProtStaParams pStaParams);
+void lim_update_short_preamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry);
+void lim_update_short_slot_time(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry);
+
+/*
+ * The below 'product' check tobe removed if 'Association' is
+ * allowed in IBSS.
+ */
+void lim_release_peer_idx(tpAniSirGlobal, uint16_t, tpPESession);
+
+void lim_decide_ap_protection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tpUpdateBeaconParams pBeaconParams, tpPESession);
+void lim_decide_ap_protection_on_delete(tpAniSirGlobal pMac,
+ tpDphHashNode pStaDs,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry);
+
+extern tSirRetStatus lim_update_11a_protection(tpAniSirGlobal pMac,
+ uint8_t enable,
+ uint8_t overlap,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession);
+extern tSirRetStatus lim_enable11g_protection(tpAniSirGlobal pMac,
+ uint8_t enable,
+ uint8_t overlap,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry);
+extern tSirRetStatus lim_enable_ht_protection_from11g(tpAniSirGlobal pMac,
+ uint8_t enable,
+ uint8_t overlap,
+ tpUpdateBeaconParams
+ pBeaconParams,
+ tpPESession psessionEntry);
+extern tSirRetStatus lim_enable_ht20_protection(tpAniSirGlobal pMac,
+ uint8_t enable, uint8_t overlap,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession sessionEntry);
+extern tSirRetStatus lim_enable_ht_non_gf_protection(tpAniSirGlobal pMac,
+ uint8_t enable, uint8_t overlap,
+ tpUpdateBeaconParams
+ pBeaconParams, tpPESession);
+extern tSirRetStatus lim_enable_ht_rifs_protection(tpAniSirGlobal pMac,
+ uint8_t enable, uint8_t overlap,
+ tpUpdateBeaconParams
+ pBeaconParams,
+ tpPESession psessionEntry);
+extern tSirRetStatus lim_enable_ht_lsig_txop_protection(tpAniSirGlobal pMac,
+ uint8_t enable,
+ uint8_t overlap,
+ tpUpdateBeaconParams
+ pBeaconParams, tpPESession);
+extern tSirRetStatus lim_enable_short_preamble(tpAniSirGlobal pMac,
+ uint8_t enable,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry);
+extern tSirRetStatus lim_enable_ht_obss_protection(tpAniSirGlobal pMac,
+ uint8_t enable, uint8_t overlap,
+ tpUpdateBeaconParams
+ pBeaconParams, tpPESession);
+void lim_decide_sta_protection(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeaconStruct,
+ tpUpdateBeaconParams pBeaconParams,
+ tpPESession psessionEntry);
+void lim_decide_sta_protection_on_assoc(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeaconStruct,
+ tpPESession psessionEntry);
+void lim_update_sta_run_time_ht_switch_chnl_params(tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pHTInfo,
+ uint8_t bssIdx,
+ tpPESession psessionEntry);
+/* Print MAC address utility function */
+void lim_print_mac_addr(tpAniSirGlobal, tSirMacAddr, uint8_t);
+
+/* Deferred Message Queue read/write */
+uint8_t lim_write_deferred_msg_q(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+tSirMsgQ *lim_read_deferred_msg_q(tpAniSirGlobal pMac);
+void lim_handle_defer_msg_error(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg);
+
+/* Deferred Message Queue Reset */
+void lim_reset_deferred_msg_q(tpAniSirGlobal pMac);
+
+tSirRetStatus lim_sys_process_mmh_msg_api(tpAniSirGlobal, tSirMsgQ *, uint8_t);
+
+void lim_handle_update_olbc_cache(tpAniSirGlobal pMac);
+
+uint8_t lim_is_null_ssid(tSirMacSSid *pSsid);
+
+/* 11h Support */
+void lim_stop_tx_and_switch_channel(tpAniSirGlobal pMac, uint8_t sessionId);
+void lim_process_channel_switch_timeout(tpAniSirGlobal);
+tSirRetStatus lim_start_channel_switch(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+void lim_update_channel_switch(tpAniSirGlobal, tpSirProbeRespBeacon,
+ tpPESession psessionEntry);
+void lim_process_quiet_timeout(tpAniSirGlobal);
+void lim_process_quiet_bss_timeout(tpAniSirGlobal);
+
+void lim_start_quiet_timer(tpAniSirGlobal pMac, uint8_t sessionId);
+void lim_switch_primary_channel(tpAniSirGlobal, uint8_t, tpPESession);
+void lim_switch_primary_secondary_channel(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint8_t newChannel,
+ uint8_t ch_center_freq_seg0,
+ uint8_t ch_center_freq_seg1,
+ phy_ch_width ch_width);
+void limUpdateStaRunTimeHTSwtichChnlParams(tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pRcvdHTInfo,
+ uint8_t bssIdx);
+void lim_update_sta_run_time_ht_capability(tpAniSirGlobal pMac,
+ tDot11fIEHTCaps *pHTCaps);
+void lim_update_sta_run_time_ht_info(struct sAniSirGlobal *pMac,
+ tDot11fIEHTInfo *pRcvdHTInfo,
+ tpPESession psessionEntry);
+void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry);
+tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac,
+ uint8_t channel);
+void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
+ tLimControlTx mode);
+tSirRetStatus lim_restore_pre_channel_switch_state(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+tSirRetStatus lim_restore_pre_quiet_state(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+
+void lim_prepare_for11h_channel_switch(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+void lim_switch_channel_cback(tpAniSirGlobal pMac, CDF_STATUS status,
+ uint32_t *data, tpPESession psessionEntry);
+
+static inline tSirRFBand lim_get_rf_band(uint8_t channel)
+{
+ if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
+ (channel <= SIR_11A_CHANNEL_END))
+ return SIR_BAND_5_GHZ;
+
+ if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
+ (channel <= SIR_11B_CHANNEL_END))
+ return SIR_BAND_2_4_GHZ;
+
+ return SIR_BAND_UNKNOWN;
+}
+
+static inline tSirRetStatus
+lim_get_mgmt_staid(tpAniSirGlobal pMac, uint16_t *staid,
+ tpPESession psessionEntry)
+{
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ *staid = 1;
+ else if (LIM_IS_STA_ROLE(psessionEntry))
+ *staid = 0;
+ else
+ return eSIR_FAILURE;
+
+ return eSIR_SUCCESS;
+}
+
+static inline uint8_t lim_is_system_in_set_mimops_state(tpAniSirGlobal pMac)
+{
+ if (pMac->lim.gLimMlmState == eLIM_MLM_WT_SET_MIMOPS_STATE)
+ return true;
+ return false;
+}
+
+static inline uint8_t
+is_entering_mimo_ps(tSirMacHTMIMOPowerSaveState curState,
+ tSirMacHTMIMOPowerSaveState newState)
+{
+ if (curState == eSIR_HT_MIMO_PS_NO_LIMIT &&
+ (newState == eSIR_HT_MIMO_PS_DYNAMIC
+ || newState == eSIR_HT_MIMO_PS_STATIC))
+ return true;
+ return false;
+}
+
+static inline int lim_select_cb_mode(tDphHashNode *pStaDs,
+ tpPESession psessionEntry, uint8_t channel,
+ uint8_t chan_bw)
+{
+ if (pStaDs->mlmStaContext.vhtCapability && chan_bw) {
+ if (channel == 36 || channel == 52 || channel == 100 ||
+ channel == 116 || channel == 149) {
+ return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
+ } else if (channel == 40 || channel == 56 || channel == 104 ||
+ channel == 120 || channel == 153) {
+ return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
+ } else if (channel == 44 || channel == 60 || channel == 108 ||
+ channel == 124 || channel == 157) {
+ return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH - 1;
+ } else if (channel == 48 || channel == 64 || channel == 112 ||
+ channel == 128 || channel == 161) {
+ return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
+ } else if (channel == 165) {
+ return PHY_SINGLE_CHANNEL_CENTERED;
+ }
+ } else if (pStaDs->mlmStaContext.htCapability) {
+ if (channel == 40 || channel == 48 || channel == 56 ||
+ channel == 64 || channel == 104 || channel == 112 ||
+ channel == 120 || channel == 128 || channel == 136 ||
+ channel == 144 || channel == 153 || channel == 161) {
+ return PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
+ } else if (channel == 36 || channel == 44 || channel == 52 ||
+ channel == 60 || channel == 100 ||
+ channel == 108 || channel == 116 ||
+ channel == 124 || channel == 132 ||
+ channel == 140 || channel == 149 ||
+ channel == 157) {
+ return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
+ } else if (channel == 165) {
+ return PHY_SINGLE_CHANNEL_CENTERED;
+ }
+ }
+ return PHY_SINGLE_CHANNEL_CENTERED;
+}
+
+/* ANI peer station count management and associated actions */
+void lim_util_count_sta_add(tpAniSirGlobal pMac, tpDphHashNode pSta,
+ tpPESession psessionEntry);
+void lim_util_count_sta_del(tpAniSirGlobal pMac, tpDphHashNode pSta,
+ tpPESession psessionEntry);
+
+uint8_t lim_get_ht_capability(tpAniSirGlobal, uint32_t, tpPESession);
+void lim_tx_complete(tHalHandle hHal, void *pData, bool free);
+
+/**
+ * This function will be registered with HAL for callback when TSPEC inactivity
+ * timer fires.
+ */
+
+void lim_process_del_ts_ind(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+tSirRetStatus lim_process_hal_ind_messages(tpAniSirGlobal pMac, uint32_t mesgId,
+ void *mesgParam);
+tSirRetStatus lim_validate_delts_req(tpAniSirGlobal pMac,
+ tpSirDeltsReq pDeltsReq,
+ tSirMacAddr peerMacAddr,
+ tpPESession psessionEntry);
+
+/* callback function registration to HAL for any indication. */
+void lim_register_hal_ind_call_back(tpAniSirGlobal pMac);
+void lim_pkt_free(tpAniSirGlobal pMac,
+ eFrameType frmType, uint8_t *pBD, void *body);
+
+void lim_get_b_dfrom_rx_packet(tpAniSirGlobal pMac, void *body, uint32_t **pBD);
+
+/**
+ * utils_power_xy() - calc result of base raised to power
+ * @base: Base value
+ * @power: Base raised to this Power value
+ *
+ * Given a base(X) and power(Y), this API will return
+ * the result of base raised to power - (X ^ Y)
+ *
+ * Return: Result of X^Y
+ *
+ */
+static inline uint32_t utils_power_xy(uint16_t base, uint16_t power)
+{
+ uint32_t result = 1, i;
+
+ for (i = 0; i < power; i++)
+ result *= base;
+
+ return result;
+}
+
+tSirRetStatus lim_post_sm_state_update(tpAniSirGlobal pMac,
+ uint16_t StaIdx,
+ tSirMacHTMIMOPowerSaveState MIMOPSState,
+ uint8_t *pPeerStaMac, uint8_t sessionId);
+
+void lim_delete_sta_context(tpAniSirGlobal pMac, tpSirMsgQ limMsg);
+void lim_delete_dialogue_token_list(tpAniSirGlobal pMac);
+void lim_resset_scan_channel_info(tpAniSirGlobal pMac);
+uint8_t lim_get_channel_from_beacon(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeacon);
+tSirNwType lim_get_nw_type(tpAniSirGlobal pMac, uint8_t channelNum,
+ uint32_t type, tpSchBeaconStruct pBeacon);
+
+void lim_set_tspec_uapsd_mask_per_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tSirMacTSInfo *pTsInfo, uint32_t action);
+
+void lim_handle_heart_beat_timeout_for_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry);
+
+void lim_process_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ pMsgQ);
+
+void lim_update_beacon(tpAniSirGlobal pMac);
+
+void lim_process_ap_mlm_add_sta_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+void lim_process_bt_amp_ap_mlm_del_bss_rsp(tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+
+void lim_process_bt_amp_ap_mlm_del_sta_rsp(tpAniSirGlobal pMac,
+ tpSirMsgQ limMsgQ,
+ tpPESession psessionEntry);
+
+tpPESession lim_is_ibss_session_active(tpAniSirGlobal pMac);
+tpPESession lim_is_ap_session_active(tpAniSirGlobal pMac);
+void lim_handle_heart_beat_failure_timeout(tpAniSirGlobal pMac);
+
+uint8_t *lim_get_ie_ptr_new(tpAniSirGlobal pMac, uint8_t *pIes, int length,
+ uint8_t eid, eSizeOfLenField size_of_len_field);
+
+#define limGetWscIEPtr(pMac, ie, ie_len) \
+ cfg_get_vendor_ie_ptr_from_oui(pMac, SIR_MAC_WSC_OUI, \
+ SIR_MAC_WSC_OUI_SIZE, ie, ie_len)
+
+#define limGetP2pIEPtr(pMac, ie, ie_len) \
+ cfg_get_vendor_ie_ptr_from_oui(pMac, SIR_MAC_P2P_OUI, \
+ SIR_MAC_P2P_OUI_SIZE, ie, ie_len)
+
+uint8_t lim_get_noa_attr_stream_in_mult_p2p_ies(tpAniSirGlobal pMac,
+ uint8_t *noaStream, uint8_t noaLen,
+ uint8_t overFlowLen);
+uint8_t lim_get_noa_attr_stream(tpAniSirGlobal pMac, uint8_t *pNoaStream,
+ tpPESession psessionEntry);
+
+uint8_t lim_build_p2p_ie(tpAniSirGlobal pMac, uint8_t *ie, uint8_t *data,
+ uint8_t ie_len);
+bool lim_is_noa_insert_reqd(tpAniSirGlobal pMac);
+bool lim_isconnected_on_dfs_channel(uint8_t currentChannel);
+uint8_t lim_get_current_operating_channel(tpAniSirGlobal pMac);
+
+#ifdef WLAN_FEATURE_11AC
+bool lim_check_vht_op_mode_change(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint8_t chanWidth, uint8_t staId,
+ uint8_t *peerMac);
+bool lim_set_nss_change(tpAniSirGlobal pMac, tpPESession psessionEntry,
+ uint8_t rxNss, uint8_t staId, uint8_t *peerMac);
+bool lim_check_membership_user_position(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint32_t membership, uint32_t userPosition,
+ uint8_t staId);
+#endif
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+
+typedef enum {
+ WLAN_PE_DIAG_SCAN_REQ_EVENT = 0,
+ WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT,
+ WLAN_PE_DIAG_SCAN_RSP_EVENT,
+ WLAN_PE_DIAG_JOIN_REQ_EVENT,
+ WLAN_PE_DIAG_JOIN_RSP_EVENT,
+ WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT,
+ WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+ WLAN_PE_DIAG_REASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+ WLAN_PE_DIAG_AUTH_REQ_EVENT,
+ WLAN_PE_DIAG_AUTH_RSP_EVENT = 10,
+ WLAN_PE_DIAG_DISASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+ WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+ WLAN_PE_DIAG_DISASSOC_CNF_EVENT,
+ WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
+ WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+ WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+ WLAN_PE_DIAG_START_BSS_REQ_EVENT,
+ WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+ WLAN_PE_DIAG_AUTH_IND_EVENT = 20,
+ WLAN_PE_DIAG_ASSOC_IND_EVENT,
+ WLAN_PE_DIAG_ASSOC_CNF_EVENT,
+ WLAN_PE_DIAG_REASSOC_IND_EVENT,
+ WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT,
+ WLAN_PE_DIAG_STOP_BSS_REQ_EVENT,
+ WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+ WLAN_PE_DIAG_DEAUTH_CNF_EVENT,
+ WLAN_PE_DIAG_ADDTS_REQ_EVENT,
+ WLAN_PE_DIAG_ADDTS_RSP_EVENT,
+ WLAN_PE_DIAG_DELTS_REQ_EVENT = 30,
+ WLAN_PE_DIAG_DELTS_RSP_EVENT,
+ WLAN_PE_DIAG_DELTS_IND_EVENT,
+ WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT,
+ WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT = 40,
+ WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT,
+ WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT,
+ WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT,
+ WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT,
+ WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT,
+ WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT,
+ WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT,
+ WLAN_PE_DIAG_HB_FAILURE_TIMEOUT,
+ WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT,
+ WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT = 50,
+ WLAN_PE_DIAG_PREAUTH_DONE,
+ WLAN_PE_DIAG_REASSOCIATING,
+ WLAN_PE_DIAG_CONNECTED,
+ WLAN_PE_DIAG_ASSOC_REQ_EVENT,
+ WLAN_PE_DIAG_AUTH_COMP_EVENT,
+ WLAN_PE_DIAG_ASSOC_COMP_EVENT,
+ WLAN_PE_DIAG_AUTH_START_EVENT,
+ WLAN_PE_DIAG_ASSOC_START_EVENT,
+ WLAN_PE_DIAG_REASSOC_START_EVENT,
+ WLAN_PE_DIAG_ROAM_AUTH_START_EVENT = 60,
+ WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT,
+ WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT,
+ WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT,
+ RESERVED1, /* = 64 for SCAN_COMPLETE */
+ RESERVED2, /* = 65 for SCAN_RES_FOUND */
+} WLAN_PE_DIAG_EVENT_TYPE;
+
+void lim_diag_event_report(tpAniSirGlobal pMac, uint16_t eventType,
+ tpPESession pSessionEntry, uint16_t status,
+ uint16_t reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+void pe_set_resume_channel(tpAniSirGlobal pMac, uint16_t channel,
+ ePhyChanBondState cbState);
+
+void lim_get_short_slot_from_phy_mode(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint32_t phyMode, uint8_t *pShortSlotEnable);
+
+void lim_clean_up_disassoc_deauth_req(tpAniSirGlobal pMac, uint8_t *staMac,
+ bool cleanRxPath);
+
+bool lim_check_disassoc_deauth_ack_pending(tpAniSirGlobal pMac,
+ uint8_t *staMac);
+
+#ifdef WLAN_FEATURE_11W
+void lim_pmf_sa_query_timer_handler(void *pMacGlobal, uint32_t param);
+#endif
+
+void lim_set_protected_bit(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr);
+
+#ifdef WLAN_FEATURE_11W
+void lim_pmf_comeback_timer_callback(void *context);
+#endif /* WLAN_FEATURE_11W */
+
+void lim_set_ht_caps(tpAniSirGlobal p_mac,
+ tpPESession p_session_ntry,
+ uint8_t *p_ie_start,
+ uint32_t num_bytes);
+
+#ifdef WLAN_FEATURE_11AC
+void lim_set_vht_caps(tpAniSirGlobal p_mac,
+ tpPESession p_session_entry,
+ uint8_t *p_ie_start,
+ uint32_t num_bytes);
+#endif /* WLAN_FEATURE_11AC */
+bool lim_validate_received_frame_a1_addr(tpAniSirGlobal mac_ctx,
+ tSirMacAddr a1, tpPESession session);
+void lim_set_stads_rtt_cap(tpDphHashNode sta_ds, struct s_ext_cap *ext_cap,
+ tpAniSirGlobal mac_ctx);
+
+void lim_check_and_reset_protection_params(tpAniSirGlobal mac_ctx);
+
+CDF_STATUS lim_send_ext_cap_ie(tpAniSirGlobal mac_ctx, uint32_t session_id,
+ tDot11fIEExtCap *extracted_extcap, bool merge);
+
+tSirRetStatus lim_strip_extcap_ie(tpAniSirGlobal mac_ctx, uint8_t *addn_ie,
+ uint16_t *addn_ielen, uint8_t *extracted_extcap);
+void lim_update_extcap_struct(tpAniSirGlobal mac_ctx, uint8_t *buf,
+ tDot11fIEExtCap *ext_cap);
+tSirRetStatus lim_strip_extcap_update_struct(tpAniSirGlobal mac_ctx,
+ uint8_t *addn_ie, uint16_t *addn_ielen, tDot11fIEExtCap *dst);
+void lim_merge_extcap_struct(tDot11fIEExtCap *dst, tDot11fIEExtCap *src);
+
+#endif /* __LIM_UTILS_H */
diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c
new file mode 100644
index 0000000..5b85bf9
--- /dev/null
+++ b/core/mac/src/pe/rrm/rrm_api.c
@@ -0,0 +1,1495 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file rrm_api.c
+
+ \brief implementation for PE RRM APIs
+
+ ========================================================================*/
+
+/* $Header$ */
+
+#if defined WLAN_FEATURE_VOWIFI
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+#include "cds_api.h"
+#include "wni_api.h"
+#include "sir_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+#include "lim_types.h"
+#include "lim_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "parser_api.h"
+#include "lim_send_messages.h"
+#include "rrm_global.h"
+#include "rrm_api.h"
+
+uint8_t
+rrm_get_min_of_max_tx_power(tpAniSirGlobal pMac,
+ tPowerdBm regMax, tPowerdBm apTxPower)
+{
+ uint8_t maxTxPower = 0;
+ uint8_t txPower = CDF_MIN(regMax, (apTxPower));
+ if ((txPower >= RRM_MIN_TX_PWR_CAP) && (txPower <= RRM_MAX_TX_PWR_CAP))
+ maxTxPower = txPower;
+ else if (txPower < RRM_MIN_TX_PWR_CAP)
+ maxTxPower = RRM_MIN_TX_PWR_CAP;
+ else
+ maxTxPower = RRM_MAX_TX_PWR_CAP;
+
+ lim_log(pMac, LOG3,
+ "%s: regulatoryMax = %d, apTxPwr = %d, maxTxpwr = %d",
+ __func__, regMax, apTxPower, maxTxPower);
+ return maxTxPower;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_cache_mgmt_tx_power
+ **
+ * FUNCTION: Store Tx power for management frames.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+void
+rrm_cache_mgmt_tx_power(tpAniSirGlobal pMac, tPowerdBm txPower,
+ tpPESession pSessionEntry)
+{
+ lim_log(pMac, LOG3, "Cache Mgmt Tx Power = %d", txPower);
+
+ if (pSessionEntry == NULL) {
+ lim_log(pMac, LOG3, "%s: pSessionEntry is NULL", __func__);
+ pMac->rrm.rrmPEContext.txMgmtPower = txPower;
+ } else
+ pSessionEntry->txMgmtPower = txPower;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_get_mgmt_tx_power
+ *
+ * FUNCTION: Get the Tx power for management frames.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry session entry.
+ * @return txPower
+ */
+tPowerdBm rrm_get_mgmt_tx_power(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+ lim_log(pMac, LOG3, "RrmGetMgmtTxPower called");
+
+ if (pSessionEntry == NULL) {
+ lim_log(pMac, LOG3, "%s: txpower from rrmPEContext: %d",
+ __func__, pMac->rrm.rrmPEContext.txMgmtPower);
+ return pMac->rrm.rrmPEContext.txMgmtPower;
+ }
+
+ return pSessionEntry->txMgmtPower;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_send_set_max_tx_power_req
+ *
+ * FUNCTION: Send WMA_SET_MAX_TX_POWER_REQ message to change the max tx power.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus
+rrm_send_set_max_tx_power_req(tpAniSirGlobal pMac, tPowerdBm txPower,
+ tpPESession pSessionEntry)
+{
+ tpMaxTxPowerParams pMaxTxParams;
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tSirMsgQ msgQ;
+
+ if (pSessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL("Invalid parameters"));)
+ return eSIR_FAILURE;
+ }
+ pMaxTxParams = cdf_mem_malloc(sizeof(tMaxTxPowerParams));
+ if (NULL == pMaxTxParams) {
+ lim_log(pMac, LOGP,
+ FL("Unable to allocate memory for pMaxTxParams "));
+ return eSIR_MEM_ALLOC_FAILED;
+
+ }
+ /* Allocated memory for pMaxTxParams...will be freed in other module */
+ pMaxTxParams->power = txPower;
+ cdf_mem_copy(pMaxTxParams->bssId, pSessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ cdf_mem_copy(pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr,
+ sizeof(tSirMacAddr));
+
+ msgQ.type = WMA_SET_MAX_TX_POWER_REQ;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pMaxTxParams;
+ msgQ.bodyval = 0;
+
+ lim_log(pMac, LOG3,
+ FL("Sending WMA_SET_MAX_TX_POWER_REQ with power(%d) to HAL"),
+ txPower);
+
+ MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, msgQ.type));
+ if (eSIR_SUCCESS != (retCode = wma_post_ctrl_msg(pMac, &msgQ))) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Posting WMA_SET_MAX_TX_POWER_REQ to HAL failed, reason=%X"),
+ retCode);
+ cdf_mem_free(pMaxTxParams);
+ return retCode;
+ }
+ return retCode;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_set_max_tx_power_rsp
+ *
+ * FUNCTION: Process WMA_SET_MAX_TX_POWER_RSP message.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param txPower txPower to be set.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus rrm_set_max_tx_power_rsp(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ)
+{
+ tSirRetStatus retCode = eSIR_SUCCESS;
+ tpMaxTxPowerParams pMaxTxParams = (tpMaxTxPowerParams) limMsgQ->bodyptr;
+ tpPESession pSessionEntry;
+ uint8_t sessionId, i;
+ tSirMacAddr bssid = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ if (cdf_mem_compare(bssid, pMaxTxParams->bssId, sizeof(tSirMacAddr))) {
+ for (i = 0; i < pMac->lim.maxBssId; i++) {
+ if ((pMac->lim.gpSession[i].valid == true)) {
+ pSessionEntry = &pMac->lim.gpSession[i];
+ rrm_cache_mgmt_tx_power(pMac, pMaxTxParams->power,
+ pSessionEntry);
+ }
+ }
+ } else {
+ if ((pSessionEntry =
+ pe_find_session_by_bssid(pMac, pMaxTxParams->bssId,
+ &sessionId)) == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("Unable to find session:"));
+ )
+ retCode = eSIR_FAILURE;
+ } else {
+ rrm_cache_mgmt_tx_power(pMac, pMaxTxParams->power,
+ pSessionEntry);
+ }
+ }
+
+ cdf_mem_free(limMsgQ->bodyptr);
+ limMsgQ->bodyptr = NULL;
+ return retCode;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_link_measurement_request
+ *
+ * FUNCTION: Processes the Link measurement request and send the report.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pBd pointer to BD to extract RSSI and SNR
+ * @param pLinkReq pointer to the Link request frame structure.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus
+rrm_process_link_measurement_request(tpAniSirGlobal pMac,
+ uint8_t *pRxPacketInfo,
+ tDot11fLinkMeasurementRequest *pLinkReq,
+ tpPESession pSessionEntry)
+{
+ tSirMacLinkReport LinkReport;
+ tpSirMacMgmtHdr pHdr;
+ int8_t currentRSSI = 0;
+
+ lim_log(pMac, LOG3, "Received Link measurement request");
+
+ if (pRxPacketInfo == NULL || pLinkReq == NULL || pSessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE,
+ "%s Invalid parameters - Ignoring the request",
+ __func__);
+ )
+ return eSIR_FAILURE;
+ }
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ LinkReport.txPower = lim_get_max_tx_power(pLinkReq->MaxTxPower.maxTxPower,
+ pLinkReq->MaxTxPower.maxTxPower,
+ pMac->roam.configParam.
+ nTxPowerCap);
+
+ if ((LinkReport.txPower != (uint8_t) (pSessionEntry->maxTxPower)) &&
+ (eSIR_SUCCESS == rrm_send_set_max_tx_power_req(pMac,
+ (tPowerdBm) (LinkReport.
+ txPower),
+ pSessionEntry))) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL(" maxTx power in link report is not same as local..."
+ " Local = %d Link Request TxPower = %d"
+ " Link Report TxPower = %d"),
+ pSessionEntry->maxTxPower, LinkReport.txPower,
+ pLinkReq->MaxTxPower.maxTxPower);
+ )
+ pSessionEntry->maxTxPower =
+ (tPowerdBm) (LinkReport.txPower);
+ }
+
+ LinkReport.dialogToken = pLinkReq->DialogToken.token;
+ LinkReport.rxAntenna = 0;
+ LinkReport.txAntenna = 0;
+ currentRSSI = WMA_GET_RX_RSSI_DB(pRxPacketInfo);
+
+ lim_log(pMac, LOG1, "Received Link report frame with %d", currentRSSI);
+
+ /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */
+ if ((currentRSSI) <= RCPI_LOW_RSSI_VALUE)
+ LinkReport.rcpi = 0;
+ else if ((currentRSSI > RCPI_LOW_RSSI_VALUE) && (currentRSSI <= 0))
+ LinkReport.rcpi = CALCULATE_RCPI(currentRSSI);
+ else
+ LinkReport.rcpi = RCPI_MAX_VALUE;
+
+ LinkReport.rsni = WMA_GET_RX_SNR(pRxPacketInfo);
+
+ lim_log(pMac, LOG3, "Sending Link report frame");
+
+ return lim_send_link_report_action_frame(pMac, &LinkReport, pHdr->sa,
+ pSessionEntry);
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_neighbor_report_response
+ *
+ * FUNCTION: Processes the Neighbor Report response from the peer AP.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pNeighborRep pointer to the Neighbor report frame structure.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus
+rrm_process_neighbor_report_response(tpAniSirGlobal pMac,
+ tDot11fNeighborReportResponse *pNeighborRep,
+ tpPESession pSessionEntry)
+{
+ tSirRetStatus status = eSIR_FAILURE;
+ tpSirNeighborReportInd pSmeNeighborRpt = NULL;
+ uint16_t length;
+ uint8_t i;
+ tSirMsgQ mmhMsg;
+
+ if (pNeighborRep == NULL || pSessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOGE, FL(" Invalid parameters"));)
+ return status;
+ }
+
+ lim_log(pMac, LOG3, FL("Neighbor report response received "));
+
+ /* Dialog token */
+ if (pMac->rrm.rrmPEContext.DialogToken !=
+ pNeighborRep->DialogToken.token) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ "Dialog token mismatch in the received Neighbor report");
+ )
+ return eSIR_FAILURE;
+ }
+ if (pNeighborRep->num_NeighborReport == 0) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ "No neighbor report in the frame...Dropping it");
+ )
+ return eSIR_FAILURE;
+ }
+ length = (sizeof(tSirNeighborReportInd)) +
+ (sizeof(tSirNeighborBssDescription) *
+ (pNeighborRep->num_NeighborReport - 1));
+
+ /* Prepare the request to send to SME. */
+ pSmeNeighborRpt = cdf_mem_malloc(length);
+ if (NULL == pSmeNeighborRpt) {
+ PELOGE(lim_log(pMac, LOGP, FL("Unable to allocate memory"));)
+ return eSIR_MEM_ALLOC_FAILED;
+
+ }
+ cdf_mem_set(pSmeNeighborRpt, length, 0);
+
+ /* Allocated memory for pSmeNeighborRpt...will be freed by other module */
+
+ for (i = 0; i < pNeighborRep->num_NeighborReport; i++) {
+ pSmeNeighborRpt->sNeighborBssDescription[i].length = sizeof(tSirNeighborBssDescription); /*+ any optional ies */
+ cdf_mem_copy(pSmeNeighborRpt->sNeighborBssDescription[i].bssId,
+ pNeighborRep->NeighborReport[i].bssid,
+ sizeof(tSirMacAddr));
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fApPreauthReachable =
+ pNeighborRep->NeighborReport[i].APReachability;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fSameSecurityMode =
+ pNeighborRep->NeighborReport[i].Security;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fSameAuthenticator =
+ pNeighborRep->NeighborReport[i].KeyScope;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fCapSpectrumMeasurement =
+ pNeighborRep->NeighborReport[i].SpecMgmtCap;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fCapQos = pNeighborRep->NeighborReport[i].QosCap;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fCapApsd = pNeighborRep->NeighborReport[i].apsd;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fCapRadioMeasurement = pNeighborRep->NeighborReport[i].rrm;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fCapDelayedBlockAck =
+ pNeighborRep->NeighborReport[i].DelayedBA;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fCapImmediateBlockAck =
+ pNeighborRep->NeighborReport[i].ImmBA;
+ pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.
+ fMobilityDomain =
+ pNeighborRep->NeighborReport[i].MobilityDomain;
+
+ pSmeNeighborRpt->sNeighborBssDescription[i].regClass =
+ pNeighborRep->NeighborReport[i].regulatoryClass;
+ pSmeNeighborRpt->sNeighborBssDescription[i].channel =
+ pNeighborRep->NeighborReport[i].channel;
+ pSmeNeighborRpt->sNeighborBssDescription[i].phyType =
+ pNeighborRep->NeighborReport[i].PhyType;
+ }
+
+ pSmeNeighborRpt->messageType = eWNI_SME_NEIGHBOR_REPORT_IND;
+ pSmeNeighborRpt->length = length;
+ pSmeNeighborRpt->sessionId = pSessionEntry->smeSessionId;
+ pSmeNeighborRpt->numNeighborReports = pNeighborRep->num_NeighborReport;
+ cdf_mem_copy(pSmeNeighborRpt->bssId, pSessionEntry->bssId,
+ sizeof(tSirMacAddr));
+
+ /* Send request to SME. */
+ mmhMsg.type = pSmeNeighborRpt->messageType;
+ mmhMsg.bodyptr = pSmeNeighborRpt;
+ MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, mmhMsg.type));
+ status = lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return status;
+
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_neighbor_report_req
+ *
+ * FUNCTION:
+ *
+ * LOGIC: Create a Neighbor report request and send it to peer.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pNeighborReq Neighbor report request params .
+ * @return None
+ */
+tSirRetStatus
+rrm_process_neighbor_report_req(tpAniSirGlobal pMac,
+ tpSirNeighborReportReqInd pNeighborReq)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ tSirMacNeighborReportReq NeighborReportReq;
+ tpPESession pSessionEntry;
+ uint8_t sessionId;
+
+ if (pNeighborReq == NULL) {
+ PELOGE(lim_log(pMac, LOGE, "NeighborReq is NULL");)
+ return eSIR_FAILURE;
+ }
+ if ((pSessionEntry =
+ pe_find_session_by_bssid(pMac, pNeighborReq->bssId,
+ &sessionId)) == NULL) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("session does not exist for given bssId"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ lim_log(pMac, LOG1, FL("SSID present = %d "), pNeighborReq->noSSID);
+
+ cdf_mem_set(&NeighborReportReq, sizeof(tSirMacNeighborReportReq), 0);
+
+ NeighborReportReq.dialogToken = ++pMac->rrm.rrmPEContext.DialogToken;
+ NeighborReportReq.ssid_present = !pNeighborReq->noSSID;
+ if (NeighborReportReq.ssid_present) {
+ cdf_mem_copy(&NeighborReportReq.ssid, &pNeighborReq->ucSSID,
+ sizeof(tSirMacSSid));
+ PELOGE(sir_dump_buf
+ (pMac, SIR_LIM_MODULE_ID, LOGE,
+ (uint8_t *) NeighborReportReq.ssid.ssId,
+ NeighborReportReq.ssid.length);
+ )
+ }
+
+ status =
+ lim_send_neighbor_report_request_frame(pMac, &NeighborReportReq,
+ pNeighborReq->bssId,
+ pSessionEntry);
+
+ return status;
+}
+
+#define ABS(x) ((x < 0) ? -x : x)
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_beacon_report_req
+ *
+ * FUNCTION: Processes the Beacon report request from the peer AP.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pCurrentReq pointer to the current Req comtext.
+ * @param pBeaconReq pointer to the beacon report request IE from the peer.
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+static tRrmRetStatus
+rrm_process_beacon_report_req(tpAniSirGlobal pMac,
+ tpRRMReq pCurrentReq,
+ tDot11fIEMeasurementRequest *pBeaconReq,
+ tpPESession pSessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tpSirBeaconReportReqInd pSmeBcnReportReq;
+ uint8_t num_channels = 0, num_APChanReport;
+ uint16_t measDuration, maxMeasduration;
+ int8_t maxDuration;
+ uint8_t sign;
+
+ if (pBeaconReq->measurement_request.Beacon.BeaconReporting.present &&
+ (pBeaconReq->measurement_request.Beacon.BeaconReporting.
+ reportingCondition != 0)) {
+ /* Repeated measurement is not supported. This means number of repetitions should be zero.(Already checked) */
+ /* All test case in VoWifi(as of version 0.36) use zero for number of repetitions. */
+ /* Beacon reporting should not be included in request if number of repetitons is zero. */
+ /* IEEE Std 802.11k-2008 Table 7-29g and section 11.10.8.1 */
+
+ PELOGE(lim_log
+ (pMac, LOGE,
+ "Dropping the request: Reporting condition included in beacon report request and it is not zero");
+ )
+ return eRRM_INCAPABLE;
+ }
+
+ /* The logic here is to check the measurement duration passed in the beacon request. Following are the cases handled.
+ Case 1: If measurement duration received in the beacon request is greater than the max measurement duration advertised
+ in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 1, REFUSE the beacon request
+ Case 2: If measurement duration received in the beacon request is greater than the max measurement duration advertised
+ in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 0, perform measurement for
+ the duration advertised in the RRM capabilities
+
+ maxMeasurementDuration = 2^(nonOperatingChanMax - 4) * BeaconInterval
+ */
+ maxDuration =
+ pMac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax - 4;
+ sign = (maxDuration < 0) ? 1 : 0;
+ maxDuration = (1L << ABS(maxDuration));
+ if (!sign)
+ maxMeasduration =
+ maxDuration * pSessionEntry->beaconParams.beaconInterval;
+ else
+ maxMeasduration =
+ pSessionEntry->beaconParams.beaconInterval / maxDuration;
+
+ measDuration = pBeaconReq->measurement_request.Beacon.meas_duration;
+
+ lim_log(pMac, LOG3,
+ "maxDuration = %d sign = %d maxMeasduration = %d measDuration = %d",
+ maxDuration, sign, maxMeasduration, measDuration);
+
+ if (maxMeasduration < measDuration) {
+ if (pBeaconReq->durationMandatory) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ "Dropping the request: duration mandatory and maxduration > measduration");
+ )
+ return eRRM_REFUSED;
+ } else
+ measDuration = maxMeasduration;
+ }
+ /* Cache the data required for sending report. */
+ pCurrentReq->request.Beacon.reportingDetail =
+ pBeaconReq->measurement_request.Beacon.BcnReportingDetail.
+ present ? pBeaconReq->measurement_request.Beacon.BcnReportingDetail.
+ reportingDetail : BEACON_REPORTING_DETAIL_ALL_FF_IE;
+
+ if (pBeaconReq->measurement_request.Beacon.RequestedInfo.present) {
+ pCurrentReq->request.Beacon.reqIes.pElementIds =
+ cdf_mem_malloc(sizeof(uint8_t) *
+ pBeaconReq->measurement_request.Beacon.
+ RequestedInfo.num_requested_eids);
+ if (NULL == pCurrentReq->request.Beacon.reqIes.pElementIds) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory for request IEs buffer"));
+ return eRRM_FAILURE;
+ }
+ lim_log(pMac, LOG3, FL(" Allocated memory for pElementIds"));
+
+ pCurrentReq->request.Beacon.reqIes.num =
+ pBeaconReq->measurement_request.Beacon.RequestedInfo.
+ num_requested_eids;
+ cdf_mem_copy(pCurrentReq->request.Beacon.reqIes.pElementIds,
+ pBeaconReq->measurement_request.Beacon.
+ RequestedInfo.requested_eids,
+ pCurrentReq->request.Beacon.reqIes.num);
+ }
+
+ if (pBeaconReq->measurement_request.Beacon.num_APChannelReport) {
+ for (num_APChanReport = 0;
+ num_APChanReport <
+ pBeaconReq->measurement_request.Beacon.num_APChannelReport;
+ num_APChanReport++)
+ num_channels +=
+ pBeaconReq->measurement_request.Beacon.
+ APChannelReport[num_APChanReport].num_channelList;
+ }
+ /* Prepare the request to send to SME. */
+ pSmeBcnReportReq = cdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
+ if (NULL == pSmeBcnReportReq) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during Beacon Report Req Ind to SME"));
+
+ return eRRM_FAILURE;
+
+ }
+
+ cdf_mem_set(pSmeBcnReportReq, sizeof(tSirBeaconReportReqInd), 0);
+
+ /* Allocated memory for pSmeBcnReportReq....will be freed by other modulea */
+ cdf_mem_copy(pSmeBcnReportReq->bssId, pSessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND;
+ pSmeBcnReportReq->length = sizeof(tSirBeaconReportReqInd);
+ pSmeBcnReportReq->uDialogToken = pBeaconReq->measurement_token;
+ pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_11K;
+ pSmeBcnReportReq->randomizationInterval =
+ SYS_TU_TO_MS(pBeaconReq->measurement_request.Beacon.randomization);
+ pSmeBcnReportReq->channelInfo.regulatoryClass =
+ pBeaconReq->measurement_request.Beacon.regClass;
+ pSmeBcnReportReq->channelInfo.channelNum =
+ pBeaconReq->measurement_request.Beacon.channel;
+ pSmeBcnReportReq->measurementDuration[0] = SYS_TU_TO_MS(measDuration);
+ pSmeBcnReportReq->fMeasurementtype[0] =
+ pBeaconReq->measurement_request.Beacon.meas_mode;
+ cdf_mem_copy(pSmeBcnReportReq->macaddrBssid,
+ pBeaconReq->measurement_request.Beacon.BSSID,
+ sizeof(tSirMacAddr));
+
+ if (pBeaconReq->measurement_request.Beacon.SSID.present) {
+ pSmeBcnReportReq->ssId.length =
+ pBeaconReq->measurement_request.Beacon.SSID.num_ssid;
+ cdf_mem_copy(pSmeBcnReportReq->ssId.ssId,
+ pBeaconReq->measurement_request.Beacon.SSID.ssid,
+ pSmeBcnReportReq->ssId.length);
+ }
+
+ pCurrentReq->token = pBeaconReq->measurement_token;
+
+ pSmeBcnReportReq->channelList.numChannels = num_channels;
+ if (pBeaconReq->measurement_request.Beacon.num_APChannelReport) {
+ uint8_t *pChanList =
+ pSmeBcnReportReq->channelList.channelNumber;
+ for (num_APChanReport = 0;
+ num_APChanReport <
+ pBeaconReq->measurement_request.Beacon.num_APChannelReport;
+ num_APChanReport++) {
+ cdf_mem_copy(pChanList,
+ pBeaconReq->measurement_request.Beacon.
+ APChannelReport[num_APChanReport].
+ channelList,
+ pBeaconReq->measurement_request.Beacon.
+ APChannelReport[num_APChanReport].
+ num_channelList);
+
+ pChanList +=
+ pBeaconReq->measurement_request.Beacon.
+ APChannelReport[num_APChanReport].num_channelList;
+ }
+ }
+ /* Send request to SME. */
+ mmhMsg.type = eWNI_SME_BEACON_REPORT_REQ_IND;
+ mmhMsg.bodyptr = pSmeBcnReportReq;
+ MTRACE(mac_trace_msg_tx(pMac, pSessionEntry->peSessionId, mmhMsg.type));
+ return lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_fill_beacon_ies
+ *
+ * FUNCTION:
+ *
+ * LOGIC: Fills Fixed fields and Ies in bss description to an array of uint8_t.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pIes - pointer to the buffer that should be populated with ies.
+ * @param pNumIes - returns the num of ies filled in this param.
+ * @param pIesMaxSize - Max size of the buffer pIes.
+ * @param eids - pointer to array of eids. If NULL, all ies will be populated.
+ * @param numEids - number of elements in array eids.
+ * @param pBssDesc - pointer to Bss Description.
+ * @return None
+ */
+static void
+rrm_fill_beacon_ies(tpAniSirGlobal pMac,
+ uint8_t *pIes, uint8_t *pNumIes, uint8_t pIesMaxSize,
+ uint8_t *eids, uint8_t numEids, tpSirBssDescription pBssDesc)
+{
+ uint8_t len, *pBcnIes, count = 0, i;
+ uint8_t BcnNumIes;
+
+ if ((pIes == NULL) || (pNumIes == NULL) || (pBssDesc == NULL)) {
+ PELOGE(lim_log(pMac, LOGE, FL(" Invalid parameters"));)
+ return;
+ }
+ /* Make sure that if eid is null, numEids is set to zero. */
+ numEids = (eids == NULL) ? 0 : numEids;
+
+ pBcnIes = (uint8_t *) &pBssDesc->ieFields[0];
+ BcnNumIes = (uint8_t) GET_IE_LEN_IN_BSS(pBssDesc->length);
+
+ *pNumIes = 0;
+
+ *((uint32_t *) pIes) = pBssDesc->timeStamp[0];
+ *pNumIes += sizeof(uint32_t);
+ pIes += sizeof(uint32_t);
+ *((uint32_t *) pIes) = pBssDesc->timeStamp[1];
+ *pNumIes += sizeof(uint32_t);
+ pIes += sizeof(uint32_t);
+ *((uint16_t *) pIes) = pBssDesc->beaconInterval;
+ *pNumIes += sizeof(uint16_t);
+ pIes += sizeof(uint16_t);
+ *((uint16_t *) pIes) = pBssDesc->capabilityInfo;
+ *pNumIes += sizeof(uint16_t);
+ pIes += sizeof(uint16_t);
+
+ while (BcnNumIes > 0) {
+ len = *(pBcnIes + 1) + 2; /* element id + length. */
+ lim_log(pMac, LOG3, "EID = %d, len = %d total = %d",
+ *pBcnIes, *(pBcnIes + 1), len);
+
+ i = 0;
+ do {
+ if (((eids == NULL) || (*pBcnIes == eids[i])) &&
+ ((*pNumIes) + len) < pIesMaxSize) {
+ lim_log(pMac, LOG3, "Adding Eid %d, len=%d",
+ *pBcnIes, len);
+
+ cdf_mem_copy(pIes, pBcnIes, len);
+ pIes += len;
+ *pNumIes += len;
+ count++;
+ break;
+ }
+ i++;
+ } while (i < numEids);
+
+ pBcnIes += len;
+ BcnNumIes -= len;
+ }
+ lim_log(pMac, LOG1, "Total length of Ies added = %d", *pNumIes);
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_beacon_report_xmit
+ *
+ * FUNCTION:
+ *
+ * LOGIC: Create a Radio measurement report action frame and send it to peer.
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pBcnReport Data for beacon report IE from SME.
+ * @return None
+ */
+tSirRetStatus
+rrm_process_beacon_report_xmit(tpAniSirGlobal pMac,
+ tpSirBeaconReportXmitInd pBcnReport)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ tSirMacRadioMeasureReport *pReport = NULL;
+ tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
+ tpPESession pSessionEntry;
+ uint8_t sessionId;
+ uint8_t flagBSSPresent = false, bssDescCnt = 0;
+
+ lim_log(pMac, LOG1, "Received beacon report xmit indication");
+
+ if (NULL == pBcnReport) {
+ PELOGE(lim_log(pMac, LOGE, "Received pBcnReport is NULL in PE");)
+ return eSIR_FAILURE;
+ }
+
+ if (NULL == pCurrentReq) {
+ PELOGE(lim_log(pMac, LOGE,
+ "Received report xmit while there is no request pending in PE");
+ )
+ return eSIR_FAILURE;
+ }
+
+ if ((pBcnReport->numBssDesc) ||
+ (!pBcnReport->numBssDesc && pCurrentReq->sendEmptyBcnRpt)) {
+ pBcnReport->numBssDesc =
+ (pBcnReport->numBssDesc ==
+ RRM_BCN_RPT_NO_BSS_INFO) ? RRM_BCN_RPT_MIN_RPT :
+ pBcnReport->numBssDesc;
+
+ if (NULL == (pSessionEntry = pe_find_session_by_bssid(pMac,
+ pBcnReport->
+ bssId,
+ &sessionId)))
+ {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("session does not exist for given bssId"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ pReport = cdf_mem_malloc(pBcnReport->numBssDesc *
+ sizeof(tSirMacRadioMeasureReport));
+
+ if (NULL == pReport) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("RRM Report is NULL, allocation failed"));
+ )
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_zero(pReport,
+ pBcnReport->numBssDesc *
+ sizeof(tSirMacRadioMeasureReport));
+
+ for (bssDescCnt = 0; bssDescCnt < pBcnReport->numBssDesc;
+ bssDescCnt++) {
+ /* Prepare the beacon report and send it to the peer. */
+ pReport[bssDescCnt].token = pBcnReport->uDialogToken;
+ pReport[bssDescCnt].refused = 0;
+ pReport[bssDescCnt].incapable = 0;
+ pReport[bssDescCnt].type = SIR_MAC_RRM_BEACON_TYPE;
+
+ /* If the scan result is NULL then send report request with */
+ /* option subelement as NULL.. */
+ if (NULL != pBcnReport->pBssDescription[bssDescCnt]) {
+ flagBSSPresent = true;
+ }
+ /* Valid response is included if the size of beacon xmit */
+ /* is == size of beacon xmit ind + ies */
+ if (pBcnReport->length >=
+ sizeof(tSirBeaconReportXmitInd)) {
+ pReport[bssDescCnt].report.beaconReport.
+ regClass = pBcnReport->regClass;
+ if (flagBSSPresent) {
+ pReport[bssDescCnt].report.beaconReport.
+ channel =
+ pBcnReport->
+ pBssDescription[bssDescCnt]->
+ channelId;
+ cdf_mem_copy(pReport[bssDescCnt].report.
+ beaconReport.measStartTime,
+ pBcnReport->
+ pBssDescription
+ [bssDescCnt]->startTSF,
+ sizeof(pBcnReport->
+ pBssDescription
+ [bssDescCnt]->
+ startTSF));
+ pReport[bssDescCnt].report.beaconReport.
+ measDuration =
+ SYS_MS_TO_TU(pBcnReport->duration);
+ pReport[bssDescCnt].report.beaconReport.
+ phyType =
+ pBcnReport->
+ pBssDescription[bssDescCnt]->nwType;
+ pReport[bssDescCnt].report.beaconReport.
+ bcnProbeRsp = 1;
+ pReport[bssDescCnt].report.beaconReport.
+ rsni =
+ pBcnReport->
+ pBssDescription[bssDescCnt]->sinr;
+ pReport[bssDescCnt].report.beaconReport.
+ rcpi =
+ pBcnReport->
+ pBssDescription[bssDescCnt]->rssi;
+
+ pReport[bssDescCnt].report.beaconReport.
+ antennaId = 0;
+ pReport[bssDescCnt].report.beaconReport.
+ parentTSF =
+ pBcnReport->
+ pBssDescription[bssDescCnt]->
+ parentTSF;
+ cdf_mem_copy(pReport[bssDescCnt].report.
+ beaconReport.bssid,
+ pBcnReport->
+ pBssDescription
+ [bssDescCnt]->bssId,
+ sizeof(tSirMacAddr));
+ }
+
+ switch (pCurrentReq->request.Beacon.
+ reportingDetail) {
+ case BEACON_REPORTING_DETAIL_NO_FF_IE:
+ /* 0 No need to include any elements. */
+ lim_log(pMac, LOG3,
+ "No reporting detail requested");
+ break;
+ case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE:
+ /* 1: Include all FFs and Requested Ies. */
+ lim_log(pMac, LOG3,
+ "Only requested IEs in reporting detail requested");
+
+ if (flagBSSPresent) {
+ rrm_fill_beacon_ies(pMac,
+ (uint8_t *) &
+ pReport
+ [bssDescCnt].
+ report.
+ beaconReport.
+ Ies[0],
+ (uint8_t *) &
+ pReport
+ [bssDescCnt].
+ report.
+ beaconReport.
+ numIes,
+ BEACON_REPORT_MAX_IES,
+ pCurrentReq->
+ request.Beacon.
+ reqIes.
+ pElementIds,
+ pCurrentReq->
+ request.Beacon.
+ reqIes.num,
+ pBcnReport->
+ pBssDescription
+ [bssDescCnt]);
+ }
+
+ break;
+ case BEACON_REPORTING_DETAIL_ALL_FF_IE:
+ /* 2 / default - Include all FFs and all Ies. */
+ default:
+ lim_log(pMac, LOG3,
+ "Default all IEs and FFs");
+ if (flagBSSPresent) {
+ rrm_fill_beacon_ies(pMac,
+ (uint8_t *) &
+ pReport
+ [bssDescCnt].
+ report.
+ beaconReport.
+ Ies[0],
+ (uint8_t *) &
+ pReport
+ [bssDescCnt].
+ report.
+ beaconReport.
+ numIes,
+ BEACON_REPORT_MAX_IES,
+ NULL, 0,
+ pBcnReport->
+ pBssDescription
+ [bssDescCnt]);
+ }
+ break;
+ }
+ }
+ }
+
+ lim_log(pMac, LOG1, "Sending Action frame with %d bss info",
+ bssDescCnt);
+ lim_send_radio_measure_report_action_frame(pMac,
+ pCurrentReq->dialog_token,
+ bssDescCnt, pReport,
+ pBcnReport->bssId,
+ pSessionEntry);
+
+ pCurrentReq->sendEmptyBcnRpt = false;
+ }
+
+ if (pBcnReport->fMeasureDone) {
+ lim_log(pMac, LOG3, "Measurement done....cleanup the context");
+
+ rrm_cleanup(pMac);
+ }
+
+ if (NULL != pReport)
+ cdf_mem_free(pReport);
+
+ return status;
+}
+
+void rrm_process_beacon_request_failure(tpAniSirGlobal pMac,
+ tpPESession pSessionEntry, tSirMacAddr peer,
+ tRrmRetStatus status)
+{
+ tpSirMacRadioMeasureReport pReport = NULL;
+ tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
+
+ pReport = cdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
+ if (NULL == pReport) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during RRM Req processing"));
+ return;
+ }
+ cdf_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0);
+ pReport->token = pCurrentReq->token;
+ pReport->type = SIR_MAC_RRM_BEACON_TYPE;
+
+ switch (status) {
+ case eRRM_REFUSED:
+ pReport->refused = 1;
+ break;
+ case eRRM_INCAPABLE:
+ pReport->incapable = 1;
+ break;
+ default:
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ (" Beacon request processing failed no report sent with status %d "),
+ status);
+ );
+ cdf_mem_free(pReport);
+ return;
+ }
+
+ lim_send_radio_measure_report_action_frame(pMac, pCurrentReq->dialog_token, 1,
+ pReport, peer, pSessionEntry);
+
+ cdf_mem_free(pReport);
+ lim_log(pMac, LOG3, FL(" Free memory for pReport"));
+ return;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_radio_measurement_request
+ *
+ * FUNCTION: Processes the Radio Resource Measurement request.
+ *
+ * LOGIC:
+
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param peer Macaddress of the peer requesting the radio measurement.
+ * @param pRRMReq Array of Measurement request IEs
+ * @param pSessionEntry session entry.
+ * @return None
+ */
+tSirRetStatus
+rrm_process_radio_measurement_request(tpAniSirGlobal pMac,
+ tSirMacAddr peer,
+ tDot11fRadioMeasurementRequest *pRRMReq,
+ tpPESession pSessionEntry)
+{
+ uint8_t i;
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpSirMacRadioMeasureReport pReport = NULL;
+ uint8_t num_report = 0;
+ tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq;
+ tRrmRetStatus rrmStatus = eRRM_SUCCESS;
+
+ if (!pRRMReq->num_MeasurementRequest) {
+ /* No measurement requests.... */
+ /* */
+ pReport = cdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
+ if (NULL == pReport) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during RRM Req processing"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0);
+ PELOGE(lim_log(pMac, LOGE,
+ FL
+ ("No requestIes in the measurement request, sending incapable report"));
+ )
+ pReport->incapable = 1;
+ num_report = 1;
+ lim_send_radio_measure_report_action_frame(pMac,
+ pRRMReq->DialogToken.token,
+ num_report, pReport, peer,
+ pSessionEntry);
+ cdf_mem_free(pReport);
+ return eSIR_FAILURE;
+ }
+ /* PF Fix */
+ if (pRRMReq->NumOfRepetitions.repetitions > 0) {
+ lim_log(pMac, LOG1,
+ FL(" number of repetitions %d"),
+ pRRMReq->NumOfRepetitions.repetitions);
+
+ /* Send a report with incapable bit set. Not supporting repetitions. */
+ pReport = cdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
+ if (NULL == pReport) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during RRM Req processing"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0);
+ PELOGE(lim_log(pMac, LOGE, FL(" Allocated memory for pReport"));)
+ pReport->incapable = 1;
+ pReport->type = pRRMReq->MeasurementRequest[0].measurement_type;
+ num_report = 1;
+ goto end;
+
+ }
+
+ for (i = 0; i < pRRMReq->num_MeasurementRequest; i++) {
+ switch (pRRMReq->MeasurementRequest[i].measurement_type) {
+ case SIR_MAC_RRM_BEACON_TYPE:
+ /* Process beacon request. */
+ if (pCurrentReq) {
+ if (pReport == NULL) /* Allocate memory to send reports for any subsequent requests. */
+ {
+ pReport =
+ cdf_mem_malloc(sizeof
+ (tSirMacRadioMeasureReport)
+ *
+ (pRRMReq->
+ num_MeasurementRequest
+ - i));
+ if (NULL == pReport) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during RRM Req processing"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set(pReport,
+ sizeof
+ (tSirMacRadioMeasureReport)
+ *
+ (pRRMReq->
+ num_MeasurementRequest -
+ i), 0);
+ lim_log(pMac, LOG3,
+ FL
+ (" rrm beacon type refused of %d report in beacon table"),
+ num_report);
+
+ }
+ pReport[num_report].refused = 1;
+ pReport[num_report].type =
+ SIR_MAC_RRM_BEACON_TYPE;
+ pReport[num_report].token =
+ pRRMReq->MeasurementRequest[i].
+ measurement_token;
+ num_report++;
+ continue;
+ } else {
+ pCurrentReq =
+ cdf_mem_malloc(sizeof(*pCurrentReq));
+ if (NULL == pCurrentReq) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during RRM Req processing"));
+ cdf_mem_free(pReport);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ lim_log(pMac, LOG3,
+ FL(" Processing Beacon Report request"));
+ cdf_mem_set(pCurrentReq, sizeof(*pCurrentReq),
+ 0);
+ pCurrentReq->dialog_token =
+ pRRMReq->DialogToken.token;
+ pCurrentReq->token =
+ pRRMReq->MeasurementRequest[i].
+ measurement_token;
+ pCurrentReq->sendEmptyBcnRpt = true;
+ pMac->rrm.rrmPEContext.pCurrentReq =
+ pCurrentReq;
+ rrmStatus =
+ rrm_process_beacon_report_req(pMac, pCurrentReq,
+ &pRRMReq->
+ MeasurementRequest
+ [i],
+ pSessionEntry);
+ if (eRRM_SUCCESS != rrmStatus) {
+ rrm_process_beacon_request_failure(pMac,
+ pSessionEntry,
+ peer,
+ rrmStatus);
+ rrm_cleanup(pMac);
+ }
+ }
+ break;
+ case SIR_MAC_RRM_LCI_TYPE:
+ case SIR_MAC_RRM_LOCATION_CIVIC_TYPE:
+ case SIR_MAC_RRM_FINE_TIME_MEAS_TYPE:
+ lim_log(pMac, LOG1,
+ FL("RRM with type: %d sent to userspace"),
+ pRRMReq->MeasurementRequest[i].measurement_type);
+ break;
+ default:
+ /* Send a report with incapabale bit set. */
+ if (pReport == NULL) /* Allocate memory to send reports for any subsequent requests. */
+ {
+ pReport =
+ cdf_mem_malloc(sizeof
+ (tSirMacRadioMeasureReport)
+ *
+ (pRRMReq->
+ num_MeasurementRequest -
+ i));
+ if (NULL == pReport) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Unable to allocate memory during RRM Req processing"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ cdf_mem_set(pReport,
+ sizeof(tSirMacRadioMeasureReport)
+ * (pRRMReq->num_MeasurementRequest -
+ i), 0);
+ lim_log(pMac, LOG3,
+ FL
+ ("rrm beacon type incapable of %d report "),
+ num_report);
+ }
+ pReport[num_report].incapable = 1;
+ pReport[num_report].type =
+ pRRMReq->MeasurementRequest[i].measurement_type;
+ pReport[num_report].token =
+ pRRMReq->MeasurementRequest[i].measurement_token;
+ num_report++;
+ break;
+ }
+ }
+
+end:
+ if (pReport) {
+ lim_send_radio_measure_report_action_frame(pMac,
+ pRRMReq->DialogToken.token,
+ num_report, pReport, peer,
+ pSessionEntry);
+
+ cdf_mem_free(pReport);
+ lim_log(pMac, LOG3, FL(" Free memory for pReport"));
+ }
+ return status;
+
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_update_start_tsf
+ **
+ * FUNCTION: Store start TSF of measurement.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param startTSF - TSF value at the start of measurement.
+ * @return None
+ */
+void rrm_update_start_tsf(tpAniSirGlobal pMac, uint32_t startTSF[2])
+{
+ pMac->rrm.rrmPEContext.startTSF[0] = startTSF[0];
+ pMac->rrm.rrmPEContext.startTSF[1] = startTSF[1];
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_get_start_tsf
+ *
+ * FUNCTION: Get the Start TSF.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param startTSF - store star TSF in this buffer.
+ * @return txPower
+ */
+void rrm_get_start_tsf(tpAniSirGlobal pMac, uint32_t *pStartTSF)
+{
+ pStartTSF[0] = pMac->rrm.rrmPEContext.startTSF[0];
+ pStartTSF[1] = pMac->rrm.rrmPEContext.startTSF[1];
+
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_get_capabilities
+ *
+ * FUNCTION:
+ * Returns a pointer to tpRRMCaps with all the caps enabled in RRM
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry
+ * @return pointer to tRRMCaps
+ */
+tpRRMCaps rrm_get_capabilities(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+ return &pMac->rrm.rrmPEContext.rrmEnabledCaps;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_update_config
+ *
+ * FUNCTION:
+ * Update the configuration. This is called from lim_update_config.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pSessionEntry
+ * @return pointer to tRRMCaps
+ */
+void rrm_update_config(tpAniSirGlobal pMac, tpPESession pSessionEntry)
+{
+ uint32_t val;
+ tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("cfg get rrm enabled failed"));
+ return;
+ }
+ pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_RRM_OPERATING_CHAN_MAX, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("cfg get rrm operating channel max measurement duration failed"));
+ return;
+ }
+ pRRMCaps->operatingChanMax = (uint8_t) val;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL
+ ("cfg get rrm non-operating channel max measurement duration failed"));
+ return;
+ }
+ pRRMCaps->nonOperatingChanMax = (uint8_t) val;
+
+ lim_log(pMac, LOG1,
+ "RRM enabled = %d OperatingChanMax = %d NonOperatingMax = %d",
+ pMac->rrm.rrmPEContext.rrmEnable,
+ pRRMCaps->operatingChanMax, pRRMCaps->nonOperatingChanMax);
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_initialize
+ *
+ * FUNCTION:
+ * Initialize RRM module
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @return None
+ */
+
+tSirRetStatus rrm_initialize(tpAniSirGlobal pMac)
+{
+ tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps;
+
+ pMac->rrm.rrmPEContext.pCurrentReq = NULL;
+ pMac->rrm.rrmPEContext.txMgmtPower = 0;
+ pMac->rrm.rrmPEContext.DialogToken = 0;
+
+ pMac->rrm.rrmPEContext.rrmEnable = 0;
+
+ cdf_mem_set(pRRMCaps, sizeof(tRRMCaps), 0);
+ pRRMCaps->LinkMeasurement = 1;
+ pRRMCaps->NeighborRpt = 1;
+ pRRMCaps->BeaconPassive = 1;
+ pRRMCaps->BeaconActive = 1;
+ pRRMCaps->BeaconTable = 1;
+ pRRMCaps->APChanReport = 1;
+ pRRMCaps->fine_time_meas_rpt = 1;
+ pRRMCaps->lci_capability = 1;
+
+ pRRMCaps->operatingChanMax = 3;
+ pRRMCaps->nonOperatingChanMax = 3;
+
+ return eSIR_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_cleanup
+ *
+ * FUNCTION:
+ * cleanup RRM module
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param mode
+ * @param rate
+ * @return None
+ */
+
+tSirRetStatus rrm_cleanup(tpAniSirGlobal pMac)
+{
+ if (pMac->rrm.rrmPEContext.pCurrentReq) {
+ if (pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.
+ pElementIds) {
+ cdf_mem_free(pMac->rrm.rrmPEContext.pCurrentReq->
+ request.Beacon.reqIes.pElementIds);
+ lim_log(pMac, LOG4, FL(" Free memory for pElementIds"));
+ }
+
+ cdf_mem_free(pMac->rrm.rrmPEContext.pCurrentReq);
+ lim_log(pMac, LOG4, FL(" Free memory for pCurrentReq"));
+ }
+
+ pMac->rrm.rrmPEContext.pCurrentReq = NULL;
+ return eSIR_SUCCESS;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * rrm_process_message
+ *
+ * FUNCTION: Processes the next received Radio Resource Management message
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void rrm_process_message(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ switch (pMsg->type) {
+ case eWNI_SME_NEIGHBOR_REPORT_REQ_IND:
+ rrm_process_neighbor_report_req(pMac, pMsg->bodyptr);
+ break;
+ case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND:
+ rrm_process_beacon_report_xmit(pMac, pMsg->bodyptr);
+ break;
+ }
+
+}
+
+#endif
diff --git a/core/mac/src/pe/sch/sch_api.c b/core/mac/src/pe/sch/sch_api.c
new file mode 100644
index 0000000..1a11104
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_api.c
@@ -0,0 +1,625 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sch_api.cc contains functions related to the API exposed
+ * by scheduler module
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#include "cds_api.h"
+#include "ani_global.h"
+#include "wni_cfg.h"
+
+#include "sir_mac_prot_def.h"
+#include "sir_mac_prop_exts.h"
+#include "sir_common.h"
+
+#include "cfg_api.h"
+
+#include "lim_api.h"
+
+#include "sch_api.h"
+#include "sch_debug.h"
+
+#include "sch_sys_params.h"
+#include "lim_trace.h"
+#include "lim_types.h"
+
+#include "wma_types.h"
+
+/* -------------------------------------------------------------------- */
+/* */
+/* Static Variables */
+/* */
+/* ------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_get_cfp_count
+ *
+ * FUNCTION:
+ * Function used by other Sirius modules to read CFPcount
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+uint8_t sch_get_cfp_count(tpAniSirGlobal pMac)
+{
+ return pMac->sch.schObject.gSchCFPCount;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_get_cfp_dur_remaining
+ *
+ * FUNCTION:
+ * Function used by other Sirius modules to read CFPDuration remaining
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+uint16_t sch_get_cfp_dur_remaining(tpAniSirGlobal pMac)
+{
+ return pMac->sch.schObject.gSchCFPDurRemaining;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_init_globals
+ *
+ * FUNCTION:
+ * Initialize globals
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void sch_init_globals(tpAniSirGlobal pMac)
+{
+ pMac->sch.gSchHcfEnabled = false;
+
+ pMac->sch.gSchScanRequested = false;
+ pMac->sch.gSchScanReqRcvd = false;
+
+ pMac->sch.gSchGenBeacon = 1;
+ pMac->sch.gSchBeaconsSent = 0;
+ pMac->sch.gSchBeaconsWritten = 0;
+ pMac->sch.gSchBcnParseErrorCnt = 0;
+ pMac->sch.gSchBcnIgnored = 0;
+ pMac->sch.gSchBBXportRcvCnt = 0;
+ pMac->sch.gSchUnknownRcvCnt = 0;
+ pMac->sch.gSchBcnRcvCnt = 0;
+ pMac->sch.gSchRRRcvCnt = 0;
+ pMac->sch.qosNullCnt = 0;
+ pMac->sch.numData = 0;
+ pMac->sch.numPoll = 0;
+ pMac->sch.numCorrupt = 0;
+ pMac->sch.numBogusInt = 0;
+ pMac->sch.numTxAct0 = 0;
+ pMac->sch.rrTimeout = SCH_RR_TIMEOUT;
+ pMac->sch.pollPeriod = SCH_POLL_PERIOD;
+ pMac->sch.multipleSched = 1;
+ pMac->sch.maxPollTimeouts = 20;
+ pMac->sch.checkCfbFlagStuck = 0;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_post_message
+ *
+ * FUNCTION:
+ * Post the beacon message to the scheduler message queue
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMsg pointer to message
+ * @return None
+ */
+
+tSirRetStatus sch_post_message(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
+{
+ sch_process_message(pMac, pMsg);
+
+ return eSIR_SUCCESS;
+}
+
+/* --------------------------------------------------------------------------- */
+/**
+ * sch_send_start_scan_rsp
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void sch_send_start_scan_rsp(tpAniSirGlobal pMac)
+{
+ tSirMsgQ msgQ;
+ uint32_t retCode;
+
+ PELOG1(sch_log(pMac, LOG1, FL("Sending LIM message to go into scan"));)
+ msgQ.type = SIR_SCH_START_SCAN_RSP;
+ if ((retCode = lim_post_msg_api(pMac, &msgQ)) != eSIR_SUCCESS)
+ sch_log(pMac, LOGE,
+ FL("Posting START_SCAN_RSP to LIM failed, reason=%X"),
+ retCode);
+}
+
+/**
+ * sch_send_beacon_req
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ * 1) SCH received SIR_SCH_BEACON_GEN_IND
+ * 2) SCH updates TIM IE and other beacon related IE's
+ * 3) SCH sends WMA_SEND_BEACON_REQ to HAL. HAL then copies the beacon
+ * template to memory
+ *
+ * ASSUMPTIONS:
+ * Memory allocation is reqd to send this message and SCH allocates memory.
+ * The assumption is that HAL will "free" this memory.
+ *
+ * NOTE:
+ *
+ * @param pMac global
+ *
+ * @param beaconPayload
+ *
+ * @param size - Length of the beacon
+ *
+ * @return CDF_STATUS
+ */
+tSirRetStatus sch_send_beacon_req(tpAniSirGlobal pMac, uint8_t *beaconPayload,
+ uint16_t size, tpPESession psessionEntry)
+{
+ tSirMsgQ msgQ;
+ tpSendbeaconParams beaconParams = NULL;
+ tSirRetStatus retCode;
+
+ sch_log(pMac, LOG2,
+ FL
+ ("Indicating HAL to copy the beacon template [%d bytes] to memory"),
+ size);
+
+ beaconParams = cdf_mem_malloc(sizeof(tSendbeaconParams));
+ if (NULL == beaconParams)
+ return eSIR_MEM_ALLOC_FAILED;
+
+ msgQ.type = WMA_SEND_BEACON_REQ;
+
+ /* No Dialog Token reqd, as a response is not solicited */
+ msgQ.reserved = 0;
+
+ /* Fill in tSendbeaconParams members */
+ cdf_mem_copy(beaconParams->bssId, psessionEntry->bssId,
+ sizeof(psessionEntry->bssId));
+
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ beaconParams->timIeOffset = 0;
+ } else {
+ beaconParams->timIeOffset = psessionEntry->schBeaconOffsetBegin;
+ }
+
+ /* p2pIeOffset should be atleast greater than timIeOffset */
+ if ((pMac->sch.schObject.p2pIeOffset != 0) &&
+ (pMac->sch.schObject.p2pIeOffset <
+ psessionEntry->schBeaconOffsetBegin)) {
+ sch_log(pMac, LOGE, FL("Invalid p2pIeOffset:[%d]"),
+ pMac->sch.schObject.p2pIeOffset);
+ CDF_ASSERT(0);
+ cdf_mem_free(beaconParams);
+ return eSIR_FAILURE;
+ }
+ beaconParams->p2pIeOffset = pMac->sch.schObject.p2pIeOffset;
+#ifdef WLAN_SOFTAP_FW_BEACON_TX_PRNT_LOG
+ sch_log(pMac, LOGE, FL("TimIeOffset:[%d]"), beaconParams->TimIeOffset);
+#endif
+
+ beaconParams->beacon = beaconPayload;
+ beaconParams->beaconLength = (uint32_t) size;
+ msgQ.bodyptr = beaconParams;
+ msgQ.bodyval = 0;
+
+ /* Keep a copy of recent beacon frame sent */
+
+ /* free previous copy of the beacon */
+ if (psessionEntry->beacon) {
+ cdf_mem_free(psessionEntry->beacon);
+ }
+
+ psessionEntry->bcnLen = 0;
+ psessionEntry->beacon = NULL;
+
+ psessionEntry->beacon = cdf_mem_malloc(size);
+ if (psessionEntry->beacon != NULL) {
+ cdf_mem_copy(psessionEntry->beacon, beaconPayload, size);
+ psessionEntry->bcnLen = size;
+ }
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+ if (eSIR_SUCCESS != (retCode = wma_post_ctrl_msg(pMac, &msgQ))) {
+ sch_log(pMac, LOGE,
+ FL("Posting SEND_BEACON_REQ to HAL failed, reason=%X"),
+ retCode);
+ } else {
+ sch_log(pMac, LOG2,
+ FL("Successfully posted WMA_SEND_BEACON_REQ to HAL"));
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ (pMac->sch.schObject.fBeaconChanged)) {
+ if (eSIR_SUCCESS !=
+ (retCode =
+ lim_send_probe_rsp_template_to_hal(pMac, psessionEntry,
+ &psessionEntry->
+ DefProbeRspIeBitmap
+ [0]))) {
+ /* check whether we have to free any memory */
+ sch_log(pMac, LOGE,
+ FL
+ ("FAILED to send probe response template with retCode %d"),
+ retCode);
+ }
+ }
+ }
+
+ return retCode;
+}
+
+uint32_t lim_remove_p2p_ie_from_add_ie(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint8_t *addIeWoP2pIe,
+ uint32_t *addnIELenWoP2pIe)
+{
+ uint32_t left = psessionEntry->addIeParams.probeRespDataLen;
+ uint8_t *ptr = psessionEntry->addIeParams.probeRespData_buff;
+ uint8_t elem_id,elem_len;
+ uint32_t offset = 0;
+ uint8_t eid = 0xDD;
+
+ cdf_mem_copy(addIeWoP2pIe, ptr, left);
+ *addnIELenWoP2pIe = left;
+
+ if (addIeWoP2pIe != NULL) {
+ while (left >= 2) {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if(elem_len > left) {
+ sch_log(pMac, LOGE, FL("Invalid IEs"));
+ return eSIR_FAILURE;
+ }
+ if ((elem_id == eid) &&
+ (cdf_mem_compare(&ptr[2],
+ "\x50\x6f\x9a\x09", 4))) {
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ cdf_mem_copy(&addIeWoP2pIe[offset], ptr, left);
+ *addnIELenWoP2pIe -= (2 + elem_len);
+ } else {
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ offset += 2 + elem_len;
+ }
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ uint32_t *IeBitmap)
+{
+ tSirMsgQ msgQ;
+ uint8_t *pFrame2Hal = psessionEntry->pSchProbeRspTemplate;
+ tpSendProbeRespParams pprobeRespParams = NULL;
+ uint32_t retCode = eSIR_FAILURE;
+ uint32_t nPayload, nBytes, nStatus;
+ tpSirMacMgmtHdr pMacHdr;
+ uint32_t addnIEPresent = false;
+ uint32_t addnIELen = 0;
+ uint8_t *addIE = NULL;
+ uint8_t *addIeWoP2pIe = NULL;
+ uint32_t addnIELenWoP2pIe = 0;
+ uint32_t retStatus;
+
+ nStatus =
+ dot11f_get_packed_probe_response_size(pMac,
+ &psessionEntry->probeRespFrame,
+ &nPayload);
+ if (DOT11F_FAILED(nStatus)) {
+ sch_log(pMac, LOGE, FL("Failed to calculate the packed size f"
+ "or a Probe Response (0x%08x)."),
+ nStatus);
+ /* We'll fall back on the worst case scenario: */
+ nPayload = sizeof(tDot11fProbeResponse);
+ } else if (DOT11F_WARNED(nStatus)) {
+ sch_log(pMac, LOGE, FL("There were warnings while calculating"
+ "the packed size for a Probe Response "
+ "(0x%08x)."), nStatus);
+ }
+
+ nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+
+ /* Check if probe response IE is present or not */
+ addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0);
+ if (addnIEPresent) {
+ /*
+ * probe response template should not have P2P IE.
+ * In case probe request has P2P IE or WPS IE, the
+ * probe request will be forwarded to the Host and
+ * Host will send the probe response. In other cases
+ * FW will send the probe response. So, if the template
+ * has P2P IE, the probe response sent to non P2P devices
+ * by the FW, may also have P2P IE which will fail
+ * P2P cert case 6.1.3
+ */
+ addIeWoP2pIe = cdf_mem_malloc(psessionEntry->addIeParams.
+ probeRespDataLen);
+ if (NULL == addIeWoP2pIe) {
+ sch_log(pMac, LOGE,
+ FL("FAILED to alloc memory when removing P2P IE"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ retStatus = lim_remove_p2p_ie_from_add_ie(pMac, psessionEntry,
+ addIeWoP2pIe, &addnIELenWoP2pIe);
+ if (retStatus != eSIR_SUCCESS) {
+ cdf_mem_free(addIeWoP2pIe);
+ return eSIR_FAILURE;
+ }
+
+ /* Probe rsp IE available */
+ /*need to check the data length */
+ addIE =
+ cdf_mem_malloc(addnIELenWoP2pIe);
+ if (NULL == addIE) {
+ sch_log(pMac, LOGE,
+ FL
+ ("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length"));
+ cdf_mem_free(addIeWoP2pIe);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ addnIELen = addnIELenWoP2pIe;
+
+ if (addnIELen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIELen
+ && (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE) {
+
+ cdf_mem_copy(addIE,
+ addIeWoP2pIe,
+ addnIELenWoP2pIe);
+ }
+ cdf_mem_free(addIeWoP2pIe);
+ }
+
+ if (addnIEPresent) {
+ if ((nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE)
+ nBytes += addnIELen;
+ else
+ addnIEPresent = false; /* Dont include the IE. */
+ }
+ /* Paranoia: */
+ cdf_mem_set(pFrame2Hal, nBytes, 0);
+
+ /* Next, we fill out the buffer descriptor: */
+ lim_populate_mac_header(pMac, pFrame2Hal, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_PROBE_RSP,
+ psessionEntry->selfMacAddr,
+ psessionEntry->selfMacAddr);
+
+ pMacHdr = (tpSirMacMgmtHdr) pFrame2Hal;
+
+ sir_copy_mac_addr(pMacHdr->bssId, psessionEntry->bssId);
+
+ /* That done, pack the Probe Response: */
+ nStatus =
+ dot11f_pack_probe_response(pMac, &psessionEntry->probeRespFrame,
+ pFrame2Hal + sizeof(tSirMacMgmtHdr),
+ nPayload, &nPayload);
+
+ if (DOT11F_FAILED(nStatus)) {
+ sch_log(pMac, LOGE,
+ FL("Failed to pack a Probe Response (0x%08x)."),
+ nStatus);
+
+ cdf_mem_free(addIE);
+ return retCode; /* allocated! */
+ } else if (DOT11F_WARNED(nStatus)) {
+ sch_log(pMac, LOGE, FL("There were warnings while packing a P"
+ "robe Response (0x%08x)."), nStatus);
+ }
+
+ if (addnIEPresent) {
+ cdf_mem_copy(&pFrame2Hal[nBytes - addnIELen],
+ &addIE[0], addnIELen);
+ }
+
+ /* free the allocated Memory */
+ cdf_mem_free(addIE);
+
+ pprobeRespParams = cdf_mem_malloc(sizeof(tSendProbeRespParams));
+ if (NULL == pprobeRespParams) {
+ sch_log(pMac, LOGE,
+ FL
+ ("lim_send_probe_rsp_template_to_hal: HAL probe response params malloc failed for bytes %d"),
+ nBytes);
+ } else {
+ sir_copy_mac_addr(pprobeRespParams->bssId, psessionEntry->bssId);
+ pprobeRespParams->pProbeRespTemplate = pFrame2Hal;
+ pprobeRespParams->probeRespTemplateLen = nBytes;
+ cdf_mem_copy(pprobeRespParams->ucProxyProbeReqValidIEBmap,
+ IeBitmap, (sizeof(uint32_t) * 8));
+ msgQ.type = WMA_SEND_PROBE_RSP_TMPL;
+ msgQ.reserved = 0;
+ msgQ.bodyptr = pprobeRespParams;
+ msgQ.bodyval = 0;
+
+ if (eSIR_SUCCESS != (retCode = wma_post_ctrl_msg(pMac, &msgQ))) {
+ /* free the allocated Memory */
+ sch_log(pMac, LOGE,
+ FL
+ ("lim_send_probe_rsp_template_to_hal: FAIL bytes %d retcode[%X]"),
+ nBytes, retCode);
+ cdf_mem_free(pprobeRespParams);
+ } else {
+ sch_log(pMac, LOG1,
+ FL
+ ("lim_send_probe_rsp_template_to_hal: Probe response template msg posted to HAL of bytes %d"),
+ nBytes);
+ }
+ }
+
+ return retCode;
+}
+
+/**
+ * sch_gen_timing_advert_frame() - Generate the TA frame and populate the buffer
+ * @pMac: the global MAC context
+ * @self_addr: the self MAC address
+ * @buf: the buffer that will contain the frame
+ * @timestamp_offset: return for the offset of the timestamp field
+ * @time_value_offset: return for the time_value field in the TA IE
+ *
+ * Return: the length of the buffer.
+ */
+int sch_gen_timing_advert_frame(tpAniSirGlobal mac_ctx, tSirMacAddr self_addr,
+ uint8_t **buf, uint32_t *timestamp_offset, uint32_t *time_value_offset)
+{
+ tDot11fTimingAdvertisementFrame frame;
+ uint32_t payload_size, buf_size;
+ int status;
+ struct cdf_mac_addr wildcard_bssid = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ };
+
+ cdf_mem_zero((uint8_t *)&frame, sizeof(tDot11fTimingAdvertisementFrame));
+
+ /* Populate the TA fields */
+ status = populate_dot11f_timing_advert_frame(mac_ctx, &frame);
+ if (status) {
+ sch_log(mac_ctx, LOGE, FL("Error populating TA frame %x"),
+ status);
+ return status;
+ }
+
+ status = dot11f_get_packed_timing_advertisement_frame_size(mac_ctx,
+ &frame, &payload_size);
+ if (DOT11F_FAILED(status)) {
+ sch_log(mac_ctx, LOGE, FL("Error getting packed frame size %x"),
+ status);
+ return status;
+ } else if (DOT11F_WARNED(status)) {
+ sch_log(mac_ctx, LOGW, FL("Warning getting packed frame size"));
+ }
+
+ buf_size = sizeof(tSirMacMgmtHdr) + payload_size;
+ *buf = cdf_mem_malloc(buf_size);
+ if (*buf == NULL) {
+ sch_log(mac_ctx, LOGE, FL("Cannot allocate memory"));
+ return eSIR_FAILURE;
+ }
+ cdf_mem_zero(*buf, buf_size);
+
+ payload_size = 0;
+ status = dot11f_pack_timing_advertisement_frame(mac_ctx, &frame,
+ *buf + sizeof(tSirMacMgmtHdr), buf_size -
+ sizeof(tSirMacMgmtHdr), &payload_size);
+ sch_log(mac_ctx, LOGE, FL("TA payload size2 = %d"), payload_size);
+ if (DOT11F_FAILED(status)) {
+ sch_log(mac_ctx, LOGE, FL("Error packing frame %x"), status);
+ goto fail;
+ } else if (DOT11F_WARNED(status)) {
+ sch_log(mac_ctx, LOGE, FL("Warning packing frame"));
+ }
+
+ lim_populate_mac_header(mac_ctx, *buf, SIR_MAC_MGMT_FRAME,
+ SIR_MAC_MGMT_TIME_ADVERT, wildcard_bssid.bytes, self_addr);
+
+ /* The timestamp field is right after the header */
+ *timestamp_offset = sizeof(tSirMacMgmtHdr);
+
+ *time_value_offset = sizeof(tSirMacMgmtHdr) +
+ sizeof(tDot11fFfTimeStamp) + sizeof(tDot11fFfCapabilities);
+
+ /* Add the Country IE length */
+ dot11f_get_packed_ie_country(mac_ctx, &frame.Country,
+ time_value_offset);
+ /* Add 2 for Country IE EID and Length fields */
+ *time_value_offset += 2;
+
+ /* Add the PowerConstraint IE size */
+ if (frame.Country.present == 1)
+ *time_value_offset += 3;
+
+ /* Add the offset inside TA IE */
+ *time_value_offset += 3;
+
+ return payload_size + sizeof(tSirMacMgmtHdr);
+
+fail:
+ if (*buf)
+ cdf_mem_free(*buf);
+ return status;
+}
diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c
new file mode 100644
index 0000000..365b349
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_beacon_gen.c
@@ -0,0 +1,930 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file sch_beacon_gen.cc contains beacon generation related
+ * functions
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "sir_mac_prot_def.h"
+
+#include "lim_utils.h"
+#include "lim_api.h"
+
+#include "wma_if.h"
+#include "cfg_api.h"
+#include "sch_api.h"
+
+#include "parser_api.h"
+
+#include "sch_debug.h"
+
+/* */
+/* March 15, 2006 */
+/* Temporarily (maybe for all of Alpha-1), assuming TIM = 0 */
+/* */
+
+const uint8_t p2p_oui[] = { 0x50, 0x6F, 0x9A, 0x9 };
+
+tSirRetStatus sch_get_p2p_ie_offset(uint8_t *pExtraIe, uint32_t extraIeLen,
+ uint16_t *pP2pIeOffset)
+{
+ tSirRetStatus status = eSIR_FAILURE;
+ *pP2pIeOffset = 0;
+
+ /* Extra IE is not present */
+ if (0 == extraIeLen) {
+ return status;
+ }
+ /* Calculate the P2P IE Offset */
+ do {
+ if (*pExtraIe == 0xDD) {
+ if (cdf_mem_compare
+ ((void *)(pExtraIe + 2), &p2p_oui, sizeof(p2p_oui))) {
+ status = eSIR_SUCCESS;
+ break;
+ }
+ }
+
+ (*pP2pIeOffset)++;
+ pExtraIe++;
+ } while (--extraIeLen > 0);
+
+ return status;
+}
+
+/**
+ * sch_append_addn_ie() - adds additional IEs to frame
+ * @mac_ctx: mac global context
+ * @session: pe session pointer
+ * @frm: frame where additional IE is to be added
+ * @max_bcn_size: max beacon size
+ * @num_bytes: final size
+ *
+ * Return: status of operation
+ */
+tSirRetStatus
+sch_append_addn_ie(tpAniSirGlobal mac_ctx, tpPESession session,
+ uint8_t *frm, uint32_t max_bcn_size, uint32_t *num_bytes)
+{
+ tSirRetStatus status = eSIR_FAILURE;
+ uint32_t present, len;
+ uint8_t add_ie[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];
+ uint8_t *p2p_ie = NULL;
+ uint8_t noa_len = 0;
+ uint8_t noa_strm[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
+
+ present = (session->addIeParams.probeRespBCNDataLen != 0);
+ if (!present)
+ return status;
+
+ len = session->addIeParams.probeRespBCNDataLen;
+ if (!(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
+ ((len + *num_bytes) <= max_bcn_size)))
+ return status;
+
+ cdf_mem_copy(&add_ie[0], session->addIeParams.probeRespBCNData_buff,
+ len);
+
+ p2p_ie = limGetP2pIEPtr(mac_ctx, &add_ie[0], len);
+ if ((p2p_ie != NULL) && !mac_ctx->beacon_offload) {
+ /* get NoA attribute stream P2P IE */
+ noa_len = lim_get_noa_attr_stream(mac_ctx, noa_strm, session);
+ if (noa_len) {
+ if ((noa_len + len) <=
+ WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
+ cdf_mem_copy(&add_ie[len], noa_strm, noa_len);
+ len += noa_len;
+ p2p_ie[1] += noa_len;
+ } else {
+ sch_log(mac_ctx, LOGE,
+ FL("Not able to insert NoA because of length constraint"));
+ }
+ }
+ }
+ if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) {
+ cdf_mem_copy(frm, &add_ie[0], len);
+ *num_bytes = *num_bytes + len;
+ } else {
+ sch_log(mac_ctx, LOGW,
+ FL("Not able to insert because of len constraint %d"),
+ len);
+ }
+ return status;
+}
+
+/**
+ * sch_set_fixed_beacon_fields() - sets the fixed params in beacon frame
+ * @mac_ctx: mac global context
+ * @session: pe session entry
+ * @band: out param, band caclculated
+ * @opr_ch: operating channels
+ *
+ * Return: status of operation
+ */
+
+tSirRetStatus
+sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session)
+{
+ tpAniBeaconStruct bcn_struct = (tpAniBeaconStruct)
+ session->pSchBeaconFrameBegin;
+ tpSirMacMgmtHdr mac;
+ uint16_t offset;
+ uint8_t *ptr;
+ tDot11fBeacon1 *bcn_1;
+ tDot11fBeacon2 *bcn_2;
+ uint32_t i, n_status, n_bytes;
+ uint32_t wps_ap_enable = 0, tmp;
+ tDot11fIEWscProbeRes *wsc_prb_res;
+ uint8_t *extra_ie = NULL;
+ uint32_t extra_ie_len = 0;
+ uint16_t extra_ie_offset = 0;
+ uint16_t p2p_ie_offset = 0;
+ tSirRetStatus status = eSIR_SUCCESS;
+ bool is_vht_enabled = false;
+
+ bcn_1 = cdf_mem_malloc(sizeof(tDot11fBeacon1));
+ if (NULL == bcn_1) {
+ sch_log(mac_ctx, LOGE, FL("Failed to allocate memory"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ bcn_2 = cdf_mem_malloc(sizeof(tDot11fBeacon2));
+ if (NULL == bcn_2) {
+ sch_log(mac_ctx, LOGE, FL("Failed to allocate memory"));
+ cdf_mem_free(bcn_1);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ wsc_prb_res = cdf_mem_malloc(sizeof(tDot11fIEWscProbeRes));
+ if (NULL == wsc_prb_res) {
+ sch_log(mac_ctx, LOGE, FL("Failed to allocate memory"));
+ cdf_mem_free(bcn_1);
+ cdf_mem_free(bcn_2);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ sch_log(mac_ctx, LOG1, FL("Setting fixed beacon fields"));
+
+ /*
+ * First set the fixed fields:
+ * set the TFP headers, set the mac header
+ */
+ cdf_mem_set((uint8_t *) &bcn_struct->macHdr, sizeof(tSirMacMgmtHdr), 0);
+ mac = (tpSirMacMgmtHdr) &bcn_struct->macHdr;
+ mac->fc.type = SIR_MAC_MGMT_FRAME;
+ mac->fc.subType = SIR_MAC_MGMT_BEACON;
+
+ for (i = 0; i < 6; i++)
+ mac->da[i] = 0xff;
+
+ cdf_mem_copy(mac->sa, session->selfMacAddr,
+ sizeof(session->selfMacAddr));
+ cdf_mem_copy(mac->bssId, session->bssId, sizeof(session->bssId));
+
+ mac->fc.fromDS = 0;
+ mac->fc.toDS = 0;
+
+ /* Now set the beacon body */
+ cdf_mem_set((uint8_t *) bcn_1, sizeof(tDot11fBeacon1), 0);
+
+ /* Skip over the timestamp (it'll be updated later). */
+ bcn_1->BeaconInterval.interval =
+ mac_ctx->sch.schObject.gSchBeaconInterval;
+ populate_dot11f_capabilities(mac_ctx, &bcn_1->Capabilities, session);
+ if (session->ssidHidden) {
+ bcn_1->SSID.present = 1;
+ /* rest of the fileds are 0 for hidden ssid */
+ if ((session->ssId.length) &&
+ (session->ssidHidden == eHIDDEN_SSID_ZERO_CONTENTS))
+ bcn_1->SSID.num_ssid = session->ssId.length;
+ } else {
+ populate_dot11f_ssid(mac_ctx, &session->ssId, &bcn_1->SSID);
+ }
+
+ populate_dot11f_supp_rates(mac_ctx, POPULATE_DOT11F_RATES_OPERATIONAL,
+ &bcn_1->SuppRates, session);
+ populate_dot11f_ds_params(mac_ctx, &bcn_1->DSParams,
+ session->currentOperChannel);
+ populate_dot11f_ibss_params(mac_ctx, &bcn_1->IBSSParams, session);
+
+ offset = sizeof(tAniBeaconStruct);
+ ptr = session->pSchBeaconFrameBegin + offset;
+
+ if (LIM_IS_AP_ROLE(session)) {
+ /* Initialize the default IE bitmap to zero */
+ cdf_mem_set((uint8_t *) &(session->DefProbeRspIeBitmap),
+ (sizeof(uint32_t) * 8), 0);
+
+ /* Initialize the default IE bitmap to zero */
+ cdf_mem_set((uint8_t *) &(session->probeRespFrame),
+ sizeof(session->probeRespFrame), 0);
+
+ /*
+ * Can be efficiently updated whenever new IE added in Probe
+ * response in future
+ */
+ if (lim_update_probe_rsp_template_ie_bitmap_beacon1(mac_ctx,
+ bcn_1, session) != eSIR_SUCCESS)
+ sch_log(mac_ctx, LOGE,
+ FL("Failed to build ProbeRsp template"));
+ }
+
+ n_status = dot11f_pack_beacon1(mac_ctx, bcn_1, ptr,
+ SCH_MAX_BEACON_SIZE - offset, &n_bytes);
+ if (DOT11F_FAILED(n_status)) {
+ sch_log(mac_ctx, LOGE,
+ FL("Failed to packed a tDot11fBeacon1 (0x%08x.)."),
+ n_status);
+ cdf_mem_free(bcn_1);
+ cdf_mem_free(bcn_2);
+ cdf_mem_free(wsc_prb_res);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(n_status)) {
+ sch_log(mac_ctx, LOGE,
+ FL("Warnings while packing a tDot11fBeacon1(0x%08x.)."),
+ n_status);
+ }
+ /*changed to correct beacon corruption */
+ cdf_mem_set((uint8_t *) bcn_2, sizeof(tDot11fBeacon2), 0);
+ session->schBeaconOffsetBegin = offset + (uint16_t) n_bytes;
+ sch_log(mac_ctx, LOG1, FL("Initialized beacon begin, offset %d"),
+ offset);
+
+ /* Initialize the 'new' fields at the end of the beacon */
+
+ if ((session->limSystemRole == eLIM_AP_ROLE) &&
+ session->dfsIncludeChanSwIe == true)
+ populate_dot_11_f_ext_chann_switch_ann(mac_ctx,
+ &bcn_2->ext_chan_switch_ann,
+ session);
+
+ populate_dot11f_country(mac_ctx, &bcn_2->Country, session);
+ if (bcn_1->Capabilities.qos)
+ populate_dot11f_edca_param_set(mac_ctx, &bcn_2->EDCAParamSet,
+ session);
+
+ if (session->lim11hEnable) {
+ populate_dot11f_power_constraints(mac_ctx,
+ &bcn_2->PowerConstraints);
+ populate_dot11f_tpc_report(mac_ctx, &bcn_2->TPCReport, session);
+ /* Need to insert channel switch announcement here */
+ if ((LIM_IS_AP_ROLE(session)
+ || LIM_IS_P2P_DEVICE_GO(session))
+ && session->dfsIncludeChanSwIe == true) {
+ /*
+ * Channel switch announcement only if radar is detected
+ * and SAP has instructed to announce channel switch IEs
+ * in beacon and probe responses
+ */
+ populate_dot11f_chan_switch_ann(mac_ctx,
+ &bcn_2->ChanSwitchAnn, session);
+
+ /*
+ * TODO: depending the CB mode, extended channel switch
+ * announcement need to be called
+ */
+ /*
+ populate_dot11f_ext_chan_switch_ann(mac_ctx,
+ &bcn_2->ExtChanSwitchAnn, session);
+ */
+#ifdef WLAN_FEATURE_11AC
+ /*
+ * TODO: If in 11AC mode, wider bw channel switch
+ * announcement needs to be called
+ */
+ /*
+ populate_dot11f_wider_bw_chan_switch_ann(mac_ctx,
+ &bcn_2->WiderBWChanSwitchAnn, session);
+ */
+#endif
+ /*
+ * Populate the Channel Switch Wrapper Element if
+ * SAP operates in 40/80 Mhz Channel Width.
+ */
+ if (true == session->dfsIncludeChanWrapperIe)
+ populate_dot11f_chan_switch_wrapper(mac_ctx,
+ &bcn_2->ChannelSwitchWrapper, session);
+ }
+ }
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ /* populate proprietary IE for MDM device operating in AP-MCC */
+ populate_dot11f_avoid_channel_ie(mac_ctx, &bcn_2->QComVendorIE,
+ session);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+ if (session->dot11mode != WNI_CFG_DOT11_MODE_11B)
+ populate_dot11f_erp_info(mac_ctx, &bcn_2->ERPInfo, session);
+
+ if (session->htCapability) {
+ populate_dot11f_ht_caps(mac_ctx, session, &bcn_2->HTCaps);
+ populate_dot11f_ht_info(mac_ctx, &bcn_2->HTInfo, session);
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (session->vhtCapability) {
+ sch_log(mac_ctx, LOGW, FL("Populate VHT IEs in Beacon"));
+ populate_dot11f_vht_caps(mac_ctx, session, &bcn_2->VHTCaps);
+ populate_dot11f_vht_operation(mac_ctx, session,
+ &bcn_2->VHTOperation);
+ is_vht_enabled = true;
+ /* following is for MU MIMO: we do not support it yet */
+ /*
+ populate_dot11f_vht_ext_bss_load( mac_ctx, &bcn2.VHTExtBssLoad);
+ */
+ if (session->gLimOperatingMode.present)
+ populate_dot11f_operating_mode(mac_ctx,
+ &bcn_2->OperatingMode, session);
+ }
+#endif
+ populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &bcn_2->ExtCap,
+ session);
+ populate_dot11f_ext_supp_rates(mac_ctx,
+ POPULATE_DOT11F_RATES_OPERATIONAL,
+ &bcn_2->ExtSuppRates, session);
+
+ if (session->pLimStartBssReq != NULL) {
+ populate_dot11f_wpa(mac_ctx, &session->pLimStartBssReq->rsnIE,
+ &bcn_2->WPA);
+ populate_dot11f_rsn_opaque(mac_ctx,
+ &session->pLimStartBssReq->rsnIE,
+ &bcn_2->RSNOpaque);
+ }
+
+ if (session->limWmeEnabled)
+ populate_dot11f_wmm(mac_ctx, &bcn_2->WMMInfoAp,
+ &bcn_2->WMMParams, &bcn_2->WMMCaps, session);
+ if (LIM_IS_AP_ROLE(session)) {
+ if (session->wps_state != SAP_WPS_DISABLED) {
+ populate_dot11f_beacon_wpsi_es(mac_ctx,
+ &bcn_2->WscBeacon, session);
+ }
+ } else {
+ if (wlan_cfg_get_int(mac_ctx,
+ (uint16_t) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS)
+ sch_log(mac_ctx, LOGP, FL("Failed to cfg get id %d"),
+ WNI_CFG_WPS_ENABLE);
+
+ wps_ap_enable = tmp & WNI_CFG_WPS_ENABLE_AP;
+
+ if (wps_ap_enable)
+ populate_dot11f_wsc(mac_ctx, &bcn_2->WscBeacon);
+
+ if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
+ eLIM_WSC_ENROLL_BEGIN) {
+ populate_dot11f_wsc_registrar_info(mac_ctx,
+ &bcn_2->WscBeacon);
+ mac_ctx->lim.wscIeInfo.wscEnrollmentState =
+ eLIM_WSC_ENROLL_IN_PROGRESS;
+ }
+
+ if (mac_ctx->lim.wscIeInfo.wscEnrollmentState ==
+ eLIM_WSC_ENROLL_END) {
+ de_populate_dot11f_wsc_registrar_info(mac_ctx,
+ &bcn_2->WscBeacon);
+ mac_ctx->lim.wscIeInfo.wscEnrollmentState =
+ eLIM_WSC_ENROLL_NOOP;
+ }
+ }
+
+ if ((LIM_IS_AP_ROLE(session))) {
+ /*
+ * Can be efficiently updated whenever new IE added in Probe
+ * response in future
+ */
+ lim_update_probe_rsp_template_ie_bitmap_beacon2(mac_ctx, bcn_2,
+ &session->DefProbeRspIeBitmap[0],
+ &session->probeRespFrame);
+
+ /* update probe response WPS IE instead of beacon WPS IE */
+ if (session->wps_state != SAP_WPS_DISABLED) {
+ if (session->APWPSIEs.SirWPSProbeRspIE.FieldPresent)
+ populate_dot11f_probe_res_wpsi_es(mac_ctx,
+ wsc_prb_res, session);
+ else
+ wsc_prb_res->present = 0;
+ if (wsc_prb_res->present) {
+ set_probe_rsp_ie_bitmap(
+ &session->DefProbeRspIeBitmap[0],
+ SIR_MAC_WPA_EID);
+ cdf_mem_copy((void *)
+ &session->probeRespFrame.WscProbeRes,
+ (void *)wsc_prb_res,
+ sizeof(tDot11fIEWscProbeRes));
+ }
+ }
+
+ }
+
+ n_status = dot11f_pack_beacon2(mac_ctx, bcn_2,
+ session->pSchBeaconFrameEnd,
+ SCH_MAX_BEACON_SIZE, &n_bytes);
+ if (DOT11F_FAILED(n_status)) {
+ sch_log(mac_ctx, LOGE,
+ FL("Failed to packed a tDot11fBeacon2 (0x%08x.)."),
+ n_status);
+ cdf_mem_free(bcn_1);
+ cdf_mem_free(bcn_2);
+ cdf_mem_free(wsc_prb_res);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(n_status)) {
+ sch_log(mac_ctx, LOGE,
+ FL("Warnings while packing a tDot11fBeacon2(0x%08x.)."),
+ n_status);
+ }
+
+ extra_ie = session->pSchBeaconFrameEnd + n_bytes;
+ extra_ie_offset = n_bytes;
+ /* TODO: Append additional IE here. */
+ sch_append_addn_ie(mac_ctx, session,
+ session->pSchBeaconFrameEnd + n_bytes,
+ SCH_MAX_BEACON_SIZE, &n_bytes);
+ session->schBeaconOffsetEnd = (uint16_t) n_bytes;
+ extra_ie_len = n_bytes - extra_ie_offset;
+ /* Get the p2p Ie Offset */
+ status = sch_get_p2p_ie_offset(extra_ie, extra_ie_len, &p2p_ie_offset);
+ if (eSIR_SUCCESS == status)
+ /* Update the P2P Ie Offset */
+ mac_ctx->sch.schObject.p2pIeOffset =
+ session->schBeaconOffsetBegin + TIM_IE_SIZE +
+ extra_ie_offset + p2p_ie_offset;
+ else
+ mac_ctx->sch.schObject.p2pIeOffset = 0;
+
+ sch_log(mac_ctx, LOG1, FL("Initialized beacon end, offset %d"),
+ session->schBeaconOffsetEnd);
+ mac_ctx->sch.schObject.fBeaconChanged = 1;
+ cdf_mem_free(bcn_1);
+ cdf_mem_free(bcn_2);
+ cdf_mem_free(wsc_prb_res);
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus lim_update_probe_rsp_template_ie_bitmap_beacon1(tpAniSirGlobal pMac,
+ tDot11fBeacon1 *beacon1,
+ tpPESession
+ psessionEntry)
+{
+ uint32_t *DefProbeRspIeBitmap;
+ tDot11fProbeResponse *prb_rsp;
+ if (!psessionEntry) {
+ sch_log(pMac, LOGE, FL("PESession is null!"));
+ return eSIR_FAILURE;
+ }
+ DefProbeRspIeBitmap = &psessionEntry->DefProbeRspIeBitmap[0];
+ prb_rsp = &psessionEntry->probeRespFrame;
+ prb_rsp->BeaconInterval = beacon1->BeaconInterval;
+ cdf_mem_copy((void *)&prb_rsp->Capabilities,
+ (void *)&beacon1->Capabilities,
+ sizeof(beacon1->Capabilities));
+
+ /* SSID */
+ if (beacon1->SSID.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_SSID_EID);
+ /* populating it, because probe response has to go with SSID even in hidden case */
+ populate_dot11f_ssid(pMac, &psessionEntry->ssId, &prb_rsp->SSID);
+ }
+ /* supported rates */
+ if (beacon1->SuppRates.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_RATESET_EID);
+ cdf_mem_copy((void *)&prb_rsp->SuppRates,
+ (void *)&beacon1->SuppRates,
+ sizeof(beacon1->SuppRates));
+
+ }
+ /* DS Parameter set */
+ if (beacon1->DSParams.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_DS_PARAM_SET_EID);
+ cdf_mem_copy((void *)&prb_rsp->DSParams,
+ (void *)&beacon1->DSParams,
+ sizeof(beacon1->DSParams));
+
+ }
+
+ /* IBSS params will not be present in the Beacons transmitted by AP */
+ return eSIR_SUCCESS;
+}
+
+void lim_update_probe_rsp_template_ie_bitmap_beacon2(tpAniSirGlobal pMac,
+ tDot11fBeacon2 *beacon2,
+ uint32_t *DefProbeRspIeBitmap,
+ tDot11fProbeResponse *prb_rsp)
+{
+ /* IBSS parameter set - will not be present in probe response tx by AP */
+ /* country */
+ if (beacon2->Country.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_COUNTRY_EID);
+ cdf_mem_copy((void *)&prb_rsp->Country,
+ (void *)&beacon2->Country,
+ sizeof(beacon2->Country));
+
+ }
+ /* Power constraint */
+ if (beacon2->PowerConstraints.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_PWR_CONSTRAINT_EID);
+ cdf_mem_copy((void *)&prb_rsp->PowerConstraints,
+ (void *)&beacon2->PowerConstraints,
+ sizeof(beacon2->PowerConstraints));
+
+ }
+ /* Channel Switch Annoouncement SIR_MAC_CHNL_SWITCH_ANN_EID */
+ if (beacon2->ChanSwitchAnn.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_CHNL_SWITCH_ANN_EID);
+ cdf_mem_copy((void *)&prb_rsp->ChanSwitchAnn,
+ (void *)&beacon2->ChanSwitchAnn,
+ sizeof(beacon2->ChanSwitchAnn));
+
+ }
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ if (beacon2->QComVendorIE.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_QCOM_VENDOR_EID);
+ cdf_mem_copy((void *)&prb_rsp->QComVendorIE,
+ (void *)&beacon2->QComVendorIE,
+ sizeof(beacon2->QComVendorIE));
+ }
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+ /* ERP information */
+ if (beacon2->ERPInfo.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_ERP_INFO_EID);
+ cdf_mem_copy((void *)&prb_rsp->ERPInfo,
+ (void *)&beacon2->ERPInfo,
+ sizeof(beacon2->ERPInfo));
+
+ }
+ /* Extended supported rates */
+ if (beacon2->ExtSuppRates.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_EXTENDED_RATE_EID);
+ cdf_mem_copy((void *)&prb_rsp->ExtSuppRates,
+ (void *)&beacon2->ExtSuppRates,
+ sizeof(beacon2->ExtSuppRates));
+
+ }
+
+ /* WPA */
+ if (beacon2->WPA.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_WPA_EID);
+ cdf_mem_copy((void *)&prb_rsp->WPA, (void *)&beacon2->WPA,
+ sizeof(beacon2->WPA));
+
+ }
+
+ /* RSN */
+ if (beacon2->RSNOpaque.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_RSN_EID);
+ cdf_mem_copy((void *)&prb_rsp->RSNOpaque,
+ (void *)&beacon2->RSNOpaque,
+ sizeof(beacon2->RSNOpaque));
+ }
+
+ /* EDCA Parameter set */
+ if (beacon2->EDCAParamSet.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_EDCA_PARAM_SET_EID);
+ cdf_mem_copy((void *)&prb_rsp->EDCAParamSet,
+ (void *)&beacon2->EDCAParamSet,
+ sizeof(beacon2->EDCAParamSet));
+
+ }
+ /* Vendor specific - currently no vendor specific IEs added */
+ /* Requested IEs - currently we are not processing this will be added later */
+ /* HT capability IE */
+ if (beacon2->HTCaps.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_HT_CAPABILITIES_EID);
+ cdf_mem_copy((void *)&prb_rsp->HTCaps, (void *)&beacon2->HTCaps,
+ sizeof(beacon2->HTCaps));
+ }
+ /* HT Info IE */
+ if (beacon2->HTInfo.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_HT_INFO_EID);
+ cdf_mem_copy((void *)&prb_rsp->HTInfo, (void *)&beacon2->HTInfo,
+ sizeof(beacon2->HTInfo));
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (beacon2->VHTCaps.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_VHT_CAPABILITIES_EID);
+ cdf_mem_copy((void *)&prb_rsp->VHTCaps,
+ (void *)&beacon2->VHTCaps,
+ sizeof(beacon2->VHTCaps));
+ }
+ if (beacon2->VHTOperation.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_VHT_OPERATION_EID);
+ cdf_mem_copy((void *)&prb_rsp->VHTOperation,
+ (void *)&beacon2->VHTOperation,
+ sizeof(beacon2->VHTOperation));
+ }
+ if (beacon2->VHTExtBssLoad.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,
+ SIR_MAC_VHT_EXT_BSS_LOAD_EID);
+ cdf_mem_copy((void *)&prb_rsp->VHTExtBssLoad,
+ (void *)&beacon2->VHTExtBssLoad,
+ sizeof(beacon2->VHTExtBssLoad));
+ }
+#endif
+
+ /* WMM IE */
+ if (beacon2->WMMParams.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_WPA_EID);
+ cdf_mem_copy((void *)&prb_rsp->WMMParams,
+ (void *)&beacon2->WMMParams,
+ sizeof(beacon2->WMMParams));
+ }
+ /* WMM capability - most of the case won't be present */
+ if (beacon2->WMMCaps.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, SIR_MAC_WPA_EID);
+ cdf_mem_copy((void *)&prb_rsp->WMMCaps,
+ (void *)&beacon2->WMMCaps,
+ sizeof(beacon2->WMMCaps));
+ }
+
+ /* Extended Capability */
+ if (beacon2->ExtCap.present) {
+ set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, DOT11F_EID_EXTCAP);
+ cdf_mem_copy((void *)&prb_rsp->ExtCap,
+ (void *)&beacon2->ExtCap,
+ sizeof(beacon2->ExtCap));
+ }
+
+}
+
+void set_probe_rsp_ie_bitmap(uint32_t *IeBitmap, uint32_t pos)
+{
+ uint32_t index, temp;
+
+ index = pos >> 5;
+ if (index >= 8) {
+ return;
+ }
+ temp = IeBitmap[index];
+
+ temp |= 1 << (pos & 0x1F);
+
+ IeBitmap[index] = temp;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * write_beacon_to_memory
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @param size Size of the beacon to write to memory
+ * @param length Length field of the beacon to write to memory
+ * @return None
+ */
+
+void write_beacon_to_memory(tpAniSirGlobal pMac, uint16_t size, uint16_t length,
+ tpPESession psessionEntry)
+{
+ uint16_t i;
+ tpAniBeaconStruct pBeacon;
+
+ /* copy end of beacon only if length > 0 */
+ if (length > 0) {
+ for (i = 0; i < psessionEntry->schBeaconOffsetEnd; i++)
+ psessionEntry->pSchBeaconFrameBegin[size++] =
+ psessionEntry->pSchBeaconFrameEnd[i];
+ }
+ /* Update the beacon length */
+ pBeacon = (tpAniBeaconStruct) psessionEntry->pSchBeaconFrameBegin;
+ /* Do not include the beaconLength indicator itself */
+ if (length == 0) {
+ pBeacon->beaconLength = 0;
+ /* Dont copy entire beacon, Copy length field alone */
+ size = 4;
+ } else
+ pBeacon->beaconLength = (uint32_t) size - sizeof(uint32_t);
+
+ /* write size bytes from pSchBeaconFrameBegin */
+ PELOG2(sch_log(pMac, LOG2, FL("Beacon size - %d bytes"), size);)
+ PELOG2(sir_dump_buf
+ (pMac, SIR_SCH_MODULE_ID, LOG2,
+ psessionEntry->pSchBeaconFrameBegin, size);
+ )
+
+ if (!pMac->sch.schObject.fBeaconChanged)
+ return;
+
+ pMac->sch.gSchGenBeacon = 1;
+ if (pMac->sch.gSchGenBeacon) {
+ pMac->sch.gSchBeaconsSent++;
+
+ /* */
+ /* Copy beacon data to SoftMAC shared memory... */
+ /* Do this by sending a message to HAL */
+ /* */
+
+ size = (size + 3) & (~3);
+ if (eSIR_SUCCESS !=
+ sch_send_beacon_req(pMac, psessionEntry->pSchBeaconFrameBegin,
+ size, psessionEntry))
+ PELOGE(sch_log
+ (pMac, LOGE,
+ FL
+ ("sch_send_beacon_req() returned an error (zsize %d)"),
+ size);
+ )
+ else {
+ pMac->sch.gSchBeaconsWritten++;
+ }
+ }
+ pMac->sch.schObject.fBeaconChanged = 0;
+}
+
+/**
+ * sch_generate_tim
+ *
+ * FUNCTION:
+ * Generate TIM
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param pMac pointer to global mac structure
+ * @param **pPtr pointer to the buffer, where the TIM bit is to be written.
+ * @param *timLength pointer to limLength, which needs to be returned.
+ * @return None
+ */
+void sch_generate_tim(tpAniSirGlobal pMac, uint8_t **pPtr, uint16_t *timLength,
+ uint8_t dtimPeriod)
+{
+ uint8_t *ptr = *pPtr;
+ uint32_t val = 0;
+ uint32_t minAid = 1; /* Always start with AID 1 as minimum */
+ uint32_t maxAid = HAL_NUM_STA;
+
+ /* Generate partial virtual bitmap */
+ uint8_t N1 = minAid / 8;
+ uint8_t N2 = maxAid / 8;
+ if (N1 & 1)
+ N1--;
+
+ *timLength = N2 - N1 + 4;
+ val = dtimPeriod;
+
+ /*
+ * Write 0xFF to firmware's field to detect firmware's mal-function
+ * early. DTIM count and bitmap control usually cannot be 0xFF, so it
+ * is easy to know that firmware never updated DTIM count/bitmap control
+ * field after host driver downloaded beacon template if end-user complaints
+ * that DTIM count and bitmapControl is 0xFF.
+ */
+ *ptr++ = SIR_MAC_TIM_EID;
+ *ptr++ = (uint8_t) (*timLength);
+ /* location for dtimCount. will be filled in by FW. */
+ *ptr++ = 0xFF;
+ *ptr++ = (uint8_t) val;
+ /* location for bitmap control. will be filled in by FW. */
+ *ptr++ = 0xFF;
+ ptr += (N2 - N1 + 1);
+
+ PELOG2(sir_dump_buf
+ (pMac, SIR_SCH_MODULE_ID, LOG2, *pPtr, (*timLength) + 2);
+ )
+ * pPtr = ptr;
+}
+/* -------------------------------------------------------------------- */
+/**
+ * @function: SchProcessPreBeaconInd
+ *
+ * @brief : Process the PreBeacon Indication from the Lim
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param : pMac - tpAniSirGlobal
+ *
+ * @return None
+ */
+
+void sch_process_pre_beacon_ind(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
+{
+ tpBeaconGenParams pMsg = (tpBeaconGenParams) limMsg->bodyptr;
+ uint32_t beaconSize;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+
+ if ((psessionEntry =
+ pe_find_session_by_bssid(pMac, pMsg->bssId, &sessionId)) == NULL) {
+ PELOGE(sch_log(pMac, LOGE, FL("session lookup fails"));)
+ goto end;
+ }
+
+ beaconSize = psessionEntry->schBeaconOffsetBegin;
+
+ /* If SME is not in normal mode, no need to generate beacon */
+ if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) {
+ PELOGE(sch_log
+ (pMac, LOG1,
+ FL("PreBeaconInd received in invalid state: %d"),
+ psessionEntry->limSmeState);
+ )
+ goto end;
+ }
+
+ switch (GET_LIM_SYSTEM_ROLE(psessionEntry)) {
+
+ case eLIM_STA_IN_IBSS_ROLE:
+ case eLIM_BT_AMP_AP_ROLE:
+ case eLIM_BT_AMP_STA_ROLE:
+ /* generate IBSS parameter set */
+ if (psessionEntry->statypeForBss == STA_ENTRY_SELF)
+ write_beacon_to_memory(pMac, (uint16_t) beaconSize,
+ (uint16_t) beaconSize,
+ psessionEntry);
+ else
+ PELOGE(sch_log
+ (pMac, LOGE,
+ FL
+ ("can not send beacon for PEER session entry"));
+ )
+ break;
+
+ case eLIM_AP_ROLE: {
+ uint8_t *ptr =
+ &psessionEntry->pSchBeaconFrameBegin[psessionEntry->
+ schBeaconOffsetBegin];
+ uint16_t timLength = 0;
+ if (psessionEntry->statypeForBss == STA_ENTRY_SELF) {
+ sch_generate_tim(pMac, &ptr, &timLength,
+ psessionEntry->dtimPeriod);
+ beaconSize += 2 + timLength;
+ write_beacon_to_memory(pMac, (uint16_t) beaconSize,
+ (uint16_t) beaconSize,
+ psessionEntry);
+ } else
+ PELOGE(sch_log
+ (pMac, LOGE,
+ FL
+ ("can not send beacon for PEER session entry"));
+ )
+ }
+ break;
+
+ default:
+ PELOGE(sch_log
+ (pMac, LOGE,
+ FL
+ ("Error-PE has Receive PreBeconGenIndication when System is in %d role"),
+ GET_LIM_SYSTEM_ROLE(psessionEntry));
+ )
+ }
+
+end:
+ cdf_mem_free(pMsg);
+
+ }
diff --git a/core/mac/src/pe/sch/sch_beacon_process.c b/core/mac/src/pe/sch/sch_beacon_process.c
new file mode 100644
index 0000000..a8f2a46
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_beacon_process.c
@@ -0,0 +1,1011 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file sch_beacon_process.cc contains beacon processing related
+ * functions
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cds_api.h"
+#include "wni_cfg.h"
+
+#include "cfg_api.h"
+#include "lim_api.h"
+#include "utils_api.h"
+#include "sch_debug.h"
+#include "sch_api.h"
+
+#include "lim_utils.h"
+#include "lim_send_messages.h"
+#include "lim_sta_hash_api.h"
+
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+#include "host_diag_core_log.h"
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+/**
+ * Number of bytes of variation in beacon length from the last beacon
+ * to trigger reprogramming of rx delay register
+ */
+#define SCH_BEACON_LEN_DELTA 3
+
+/* calculate 2^cw - 1 */
+#define CW_GET(cw) (((cw) == 0) ? 1 : ((1 << (cw)) - 1))
+
+static void
+ap_beacon_process_5_ghz(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+ tpSchBeaconStruct bcn_struct,
+ tpUpdateBeaconParams bcn_prm, tpPESession session,
+ uint32_t phy_mode)
+{
+ tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ if (!session->htCapability)
+ return;
+
+ if (bcn_struct->channelNumber != session->currentOperChannel)
+ return;
+
+ /* 11a (non HT) AP overlaps or */
+ /* HT AP with HT op mode as mixed overlaps. */
+ /* HT AP with HT op mode as overlap legacy overlaps. */
+ if (!bcn_struct->HTInfo.present
+ || (eSIR_HT_OP_MODE_MIXED == bcn_struct->HTInfo.opMode)
+ || (eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode)) {
+ lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+ &(mac_ctx->lim.gLimOverlap11aParams));
+
+ if (mac_ctx->lim.gLimOverlap11aParams.numSta
+ && !mac_ctx->lim.gLimOverlap11aParams.protectionEnabled) {
+ lim_update_11a_protection(mac_ctx, true, true,
+ bcn_prm, session);
+ }
+ return;
+ }
+ /* HT AP with HT20 op mode overlaps. */
+ if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT != bcn_struct->HTInfo.opMode)
+ return;
+
+ lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+ &(mac_ctx->lim.gLimOverlapHt20Params));
+
+ if (mac_ctx->lim.gLimOverlapHt20Params.numSta
+ && !mac_ctx->lim.gLimOverlapHt20Params.protectionEnabled)
+ lim_enable_ht20_protection(mac_ctx, true, true,
+ bcn_prm, session);
+}
+
+static void
+ap_beacon_process_24_ghz(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+ tpSchBeaconStruct bcn_struct,
+ tpUpdateBeaconParams bcn_prm, tpPESession session,
+ uint32_t phy_mode)
+{
+ tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+ bool tmp_exp = false;
+ /* We are 11G AP. */
+ if ((phy_mode == WNI_CFG_PHY_MODE_11G) &&
+ (false == session->htCapability)) {
+ if (bcn_struct->channelNumber != session->currentOperChannel)
+ return;
+
+ tmp_exp = (!bcn_struct->erpPresent
+ && !bcn_struct->HTInfo.present)
+ /* if erp not present then 11B AP overlapping */
+ || (!mac_ctx->roam.configParam.ignore_peer_erp_info &&
+ bcn_struct->erpPresent &&
+ (bcn_struct->erpIEInfo.useProtection
+ || bcn_struct->erpIEInfo.nonErpPresent));
+ if (!tmp_exp)
+ return;
+#ifdef FEATURE_WLAN_ESE
+ if (session->isESEconnection)
+ CDF_TRACE(CDF_MODULE_ID_PE,
+ CDF_TRACE_LEVEL_INFO,
+ FL("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d"),
+ bcn_struct->erpPresent,
+ bcn_struct->erpIEInfo.useProtection,
+ bcn_struct->erpIEInfo.nonErpPresent);
+#endif
+ lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
+ mac_hdr, session);
+ return;
+ }
+ /* handling the case when HT AP has overlapping legacy BSS. */
+ if (!session->htCapability)
+ return;
+
+ if (bcn_struct->channelNumber != session->currentOperChannel)
+ return;
+
+ tmp_exp = (!bcn_struct->erpPresent && !bcn_struct->HTInfo.present)
+ /* if erp not present then 11B AP overlapping */
+ || (!mac_ctx->roam.configParam.ignore_peer_erp_info &&
+ bcn_struct->erpPresent &&
+ (bcn_struct->erpIEInfo.useProtection
+ || bcn_struct->erpIEInfo.nonErpPresent));
+ if (tmp_exp) {
+#ifdef FEATURE_WLAN_ESE
+ if (session->isESEconnection) {
+ CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
+ FL("[INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d"),
+ bcn_struct->erpPresent,
+ bcn_struct->erpIEInfo.useProtection,
+ bcn_struct->erpIEInfo.nonErpPresent);
+ }
+#endif
+ lim_enable_overlap11g_protection(mac_ctx, bcn_prm,
+ mac_hdr, session);
+ }
+ /* 11g device overlaps */
+ tmp_exp = bcn_struct->erpPresent
+ && !(bcn_struct->erpIEInfo.useProtection
+ || bcn_struct->erpIEInfo.nonErpPresent)
+ && !(bcn_struct->HTInfo.present);
+ if (tmp_exp) {
+ lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+ &(session->gLimOverlap11gParams));
+
+ if (session->gLimOverlap11gParams.numSta
+ && !session->gLimOverlap11gParams.protectionEnabled)
+ lim_enable_ht_protection_from11g(mac_ctx, true, true,
+ bcn_prm, session);
+ }
+ /* ht device overlaps.
+ * here we will check for HT related devices only which might need
+ * protection. check for 11b and 11g is already done in the previous
+ * blocks. so we will not check for HT operating mode as MIXED.
+ */
+ if (!bcn_struct->HTInfo.present)
+ return;
+
+ /*
+ * if we are not already in mixed mode or legacy mode as HT operating
+ * mode and received beacon has HT operating mode as legacy then we need
+ * to enable protection from 11g station. we don't need protection from
+ * 11b because if that's needed then our operating mode would have
+ * already been set to legacy in the previous blocks.
+ */
+ if (eSIR_HT_OP_MODE_OVERLAP_LEGACY == bcn_struct->HTInfo.opMode) {
+ if (eSIR_HT_OP_MODE_OVERLAP_LEGACY == mac_ctx->lim.gHTOperMode
+ || eSIR_HT_OP_MODE_MIXED == mac_ctx->lim.gHTOperMode)
+ return;
+ lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+ &(session->gLimOverlap11gParams));
+ if (session->gLimOverlap11gParams.numSta
+ && !session->gLimOverlap11gParams.protectionEnabled)
+ lim_enable_ht_protection_from11g(mac_ctx, true, true,
+ bcn_prm, session);
+ return;
+ }
+
+ if (eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == bcn_struct->HTInfo.opMode) {
+ lim_update_overlap_sta_param(mac_ctx, mac_hdr->bssId,
+ &(session->gLimOverlapHt20Params));
+ if (session->gLimOverlapHt20Params.numSta
+ && !session->gLimOverlapHt20Params.protectionEnabled)
+ lim_enable_ht20_protection(mac_ctx, true, true,
+ bcn_prm, session);
+ }
+}
+
+/**
+ * ap_beacon_process() - processes incoming beacons
+ *
+ * @mac_ctx: mac global context
+ * @rx_pkt_info: incoming beacon packet
+ * @bcn_struct: beacon struct
+ * @bcn_prm: beacon params
+ * @session: pe session entry
+ *
+ * Return: void
+ */
+static void
+ap_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+ tpSchBeaconStruct bcn_struct,
+ tpUpdateBeaconParams bcn_prm, tpPESession session)
+{
+ uint32_t phy_mode;
+ tSirRFBand rf_band = SIR_BAND_UNKNOWN;
+ /* Get RF band from session */
+ rf_band = session->limRFBand;
+
+ lim_get_phy_mode(mac_ctx, &phy_mode, session);
+
+ if (SIR_BAND_5_GHZ == rf_band)
+ ap_beacon_process_5_ghz(mac_ctx, rx_pkt_info, bcn_struct,
+ bcn_prm, session, phy_mode);
+ else if (SIR_BAND_2_4_GHZ == rf_band)
+ ap_beacon_process_24_ghz(mac_ctx, rx_pkt_info, bcn_struct,
+ bcn_prm, session, phy_mode);
+ mac_ctx->sch.gSchBcnIgnored++;
+}
+
+/* -------------------------------------------------------------------- */
+
+/**
+ * __sch_beacon_process_no_session
+ *
+ * FUNCTION:
+ * Process the received beacon frame when
+ * -- Station is not scanning
+ * -- No corresponding session is found
+ *
+ * LOGIC:
+ * Following scenarios exist when Session Does not exist:
+ * * IBSS Beacons, when IBSS session already exists with same SSID,
+ * but from STA which has not yet joined and has a different BSSID.
+ * - invoke lim_handle_ibs_scoalescing with the session context of existing IBSS session.
+ *
+ * * IBSS Beacons when IBSS session does not exist, only Infra or BT-AMP session exists,
+ * then save the beacon in the scan results and throw it away.
+ *
+ * * Infra Beacons
+ * - beacons received when no session active
+ * should not come here, it should be handled as part of scanning,
+ * else they should not be getting received, should update scan results and drop it if that happens.
+ * - beacons received when IBSS session active:
+ * update scan results and drop it.
+ * - beacons received when Infra session(STA) is active:
+ * update scan results and drop it
+ * - beacons received when BT-STA session is active:
+ * update scan results and drop it.
+ * - beacons received when Infra/BT-STA or Infra/IBSS is active.
+ * update scan results and drop it.
+ *
+
+ */
+static void __sch_beacon_process_no_session(tpAniSirGlobal pMac,
+ tpSchBeaconStruct pBeacon,
+ uint8_t *pRxPacketInfo)
+{
+ tpPESession psessionEntry = NULL;
+
+ if ((psessionEntry = lim_is_ibss_session_active(pMac)) != NULL) {
+ lim_handle_ibss_coalescing(pMac, pBeacon, pRxPacketInfo,
+ psessionEntry);
+ }
+ /* If station(STA/BT-STA/BT-AP/IBSS) mode, Always save the beacon in the scan results, if atleast one session is active */
+ /* sch_beacon_processNoSession will be called only when there is atleast one session active, so not checking */
+ /* it again here. */
+ lim_check_and_add_bss_description(pMac, pBeacon, pRxPacketInfo, false,
+ false);
+ return;
+}
+
+/**
+ * get_operating_channel_width() - Get operating channel width
+ * @pStaDs - station entry.
+ *
+ * This function returns the oeprating channgl width based on
+ * the supported channel width entry.
+ *
+ * Return: tSirMacHTChannelWidth on success
+ */
+tSirMacHTChannelWidth get_operating_channel_width(tpDphHashNode stads)
+{
+ tSirMacHTChannelWidth ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+
+ if (stads->vhtSupportedChannelWidthSet ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
+ ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+ else if (stads->vhtSupportedChannelWidthSet ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
+ ch_width = eHT_CHANNEL_WIDTH_160MHZ;
+ else if (stads->vhtSupportedChannelWidthSet ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
+ ch_width = eHT_CHANNEL_WIDTH_80MHZ;
+ else if (stads->htSupportedChannelWidthSet)
+ ch_width = eHT_CHANNEL_WIDTH_40MHZ;
+ else
+ ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+
+ return ch_width;
+}
+
+/*
+ * sch_bcn_process_sta_bt_amp_sta() - Process the received beacon frame for sta,
+ * bt_amp_sta
+ *
+ * @mac_ctx: mac_ctx
+ * @bcn: beacon struct
+ * @rx_pkt_info: received packet info
+ * @session: pe session pointer
+ * @bssIdx: bss index
+ * @beaconParams: update beacon params
+ * @sendProbeReq: out flag to indicate if probe rsp is to be sent
+ * @pMh: mac header
+ *
+ * Process the received beacon frame for sta, bt_amp_sta
+ *
+ * Return: success of failure of operation
+ */
+static bool
+sch_bcn_process_sta_bt_amp_sta(tpAniSirGlobal mac_ctx,
+ tpSchBeaconStruct bcn,
+ uint8_t *rx_pkt_info,
+ tpPESession session, uint8_t *bssIdx,
+ tUpdateBeaconParams *beaconParams,
+ uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
+{
+ uint32_t bi;
+ tpDphHashNode pStaDs = NULL;
+ /*
+ * This handles two cases:
+ * -- Infra STA receving beacons from AP
+ * -- BTAMP_STA receving beacons from BTAMP_AP
+ */
+ /* Always save the beacon into LIM's cached scan results */
+ lim_check_and_add_bss_description(mac_ctx, bcn, rx_pkt_info,
+ false, false);
+
+ /**
+ * This is the Beacon received from the AP we're currently associated
+ * with. Check if there are any changes in AP's capabilities
+ */
+ if ((uint8_t) bcn->channelNumber != session->currentOperChannel) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Channel Change from %d --> %d - Ignoring beacon!"),
+ session->currentOperChannel,
+ bcn->channelNumber);)
+ return false;
+ }
+ lim_detect_change_in_ap_capabilities(mac_ctx, bcn, session);
+ if (lim_get_sta_hash_bssidx(mac_ctx, DPH_STA_HASH_INDEX_PEER, bssIdx,
+ session) != eSIR_SUCCESS)
+ return false;
+
+ beaconParams->bssIdx = *bssIdx;
+ cdf_mem_copy((uint8_t *) &session->lastBeaconTimeStamp,
+ (uint8_t *) bcn->timeStamp, sizeof(uint64_t));
+ session->lastBeaconDtimCount = bcn->tim.dtimCount;
+ session->lastBeaconDtimPeriod = bcn->tim.dtimPeriod;
+ session->currentBssBeaconCnt++;
+
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
+ session->peSessionId, bcn->timeStamp[0]);)
+ MTRACE(mac_trace(mac_ctx, TRACE_CODE_RX_MGMT_TSF,
+ session->peSessionId, bcn->timeStamp[1]);)
+
+ /* Read beacon interval session Entry */
+ bi = session->beaconParams.beaconInterval;
+ if (bi != bcn->beaconInterval) {
+ PELOG1(sch_log(mac_ctx, LOG1,
+ FL("Beacon interval changed from %d to %d"),
+ bcn->beaconInterval, bi);)
+
+ bi = bcn->beaconInterval;
+ session->beaconParams.beaconInterval = (uint16_t) bi;
+ beaconParams->paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED;
+ beaconParams->beaconInterval = (uint16_t) bi;
+ }
+
+ if (bcn->cfPresent) {
+ cfg_set_int(mac_ctx, WNI_CFG_CFP_PERIOD,
+ bcn->cfParamSet.cfpPeriod);
+ lim_send_cf_params(mac_ctx, *bssIdx,
+ bcn->cfParamSet.cfpCount,
+ bcn->cfParamSet.cfpPeriod);
+ }
+
+ /* No need to send DTIM Period and Count to HAL/SMAC */
+ /* SMAC already parses TIM bit. */
+ if (bcn->timPresent)
+ cfg_set_int(mac_ctx, WNI_CFG_DTIM_PERIOD, bcn->tim.dtimPeriod);
+
+ if (mac_ctx->lim.gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ lim_decide_sta_protection(mac_ctx, bcn, beaconParams, session);
+
+ if (bcn->erpPresent) {
+ if (bcn->erpIEInfo.barkerPreambleMode)
+ lim_enable_short_preamble(mac_ctx, false,
+ beaconParams, session);
+ else
+ lim_enable_short_preamble(mac_ctx, true,
+ beaconParams, session);
+ }
+ lim_update_short_slot(mac_ctx, bcn, beaconParams, session);
+
+ pStaDs = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
+ &session->dph.dphHashTable);
+ if ((bcn->wmeEdcaPresent && (session->limWmeEnabled))
+ || (bcn->edcaPresent && (session->limQosEnabled))) {
+ if (bcn->edcaParams.qosInfo.count !=
+ session->gLimEdcaParamSetCount) {
+ if (sch_beacon_edca_process(mac_ctx, &bcn->edcaParams,
+ session) != eSIR_SUCCESS) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("EDCA parameter processing error"));)
+ } else if (pStaDs != NULL) {
+ /* If needed, downgrade the EDCA parameters */
+ lim_set_active_edca_params(mac_ctx,
+ session->gLimEdcaParams, session);
+ lim_send_edca_params(mac_ctx,
+ session->gLimEdcaParamsActive,
+ pStaDs->bssId);
+ } else {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Self Entry missing in Hash Table"));)
+ }
+ }
+ return true;
+ }
+
+ if ((bcn->qosCapabilityPresent && session->limQosEnabled)
+ && (bcn->qosCapability.qosInfo.count !=
+ session->gLimEdcaParamSetCount))
+ *sendProbeReq = true;
+
+ return true;
+}
+
+/**
+ * update_nss() - Function to update NSS
+ * @mac_ctx: pointer to Global Mac structure
+ * @sta_ds: pointer to tpDphHashNode
+ * @beacon: pointer to tpSchBeaconStruct
+ * @session_entry: pointer to tpPESession
+ * @mgmt_hdr: pointer to tpSirMacMgmtHdr
+ *
+ * function to update NSS
+ *
+ * Return: none
+ */
+void update_nss(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
+ tpSchBeaconStruct beacon, tpPESession session_entry,
+ tpSirMacMgmtHdr mgmt_hdr)
+{
+ if (sta_ds->vhtSupportedRxNss != (beacon->OperatingMode.rxNSS + 1)) {
+ sta_ds->vhtSupportedRxNss =
+ beacon->OperatingMode.rxNSS + 1;
+ lim_set_nss_change(mac_ctx, session_entry,
+ sta_ds->vhtSupportedRxNss, sta_ds->staIndex,
+ mgmt_hdr->sa);
+ }
+}
+
+/*
+ * sch_bcn_process_sta_bt_amp_sta_ibss() - Process the received beacon frame
+ * for sta, bt_amp_sta and ibss
+ *
+ * @mac_ctx: mac_ctx
+ * @bcn: beacon struct
+ * @rx_pkt_info: received packet info
+ * @session: pe session pointer
+ * @bssIdx: bss index
+ * @beaconParams: update beacon params
+ * @sendProbeReq: out flag to indicate if probe rsp is to be sent
+ * @pMh: mac header
+ *
+ * Process the received beacon frame for sta, bt_amp_sta and ibss
+ *
+ * Return: void
+ */
+static void
+sch_bcn_process_sta_bt_amp_sta_ibss(tpAniSirGlobal mac_ctx,
+ tpSchBeaconStruct bcn,
+ uint8_t *rx_pkt_info,
+ tpPESession session, uint8_t *bssIdx,
+ tUpdateBeaconParams *beaconParams,
+ uint8_t *sendProbeReq, tpSirMacMgmtHdr pMh)
+{
+ tpDphHashNode pStaDs = NULL;
+ uint16_t aid;
+ uint8_t operMode;
+ uint8_t chWidth = 0;
+ uint8_t cb_mode;
+
+ if (RF_CHAN_14 >= session->currentOperChannel)
+ cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
+ else
+ cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
+ /* check for VHT capability */
+ pStaDs = dph_lookup_hash_entry(mac_ctx, pMh->sa, &aid,
+ &session->dph.dphHashTable);
+ if ((NULL == pStaDs) ||
+ (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode))
+ return;
+
+ if (session->vhtCapability && bcn->OperatingMode.present) {
+ operMode = get_operating_channel_width(pStaDs);
+ if (operMode == bcn->OperatingMode.chanWidth)
+ return;
+
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("received OpMode Chanwidth %d, staIdx = %d"),
+ bcn->OperatingMode.chanWidth, pStaDs->staIndex);)
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("MAC - %0x:%0x:%0x:%0x:%0x:%0x"),
+ pMh->sa[0], pMh->sa[1],
+ pMh->sa[2], pMh->sa[3],
+ pMh->sa[4], pMh->sa[5]);)
+
+ if (bcn->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_160MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 160MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ } else if (bcn->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_80MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 80MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ } else if (bcn->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_40MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 40MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ } else if (bcn->OperatingMode.chanWidth ==
+ eHT_CHANNEL_WIDTH_20MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 20MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_20MHZ;
+ }
+ lim_check_vht_op_mode_change(mac_ctx, session,
+ bcn->OperatingMode.chanWidth,
+ pStaDs->staIndex, pMh->sa);
+ update_nss(mac_ctx, pStaDs, bcn, session, pMh);
+ return;
+ }
+
+ if (!(session->vhtCapability && bcn->VHTOperation.present))
+ return;
+
+ operMode = pStaDs->vhtSupportedChannelWidthSet;
+ if (operMode == bcn->VHTOperation.chanWidth)
+ return;
+
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("received VHTOP CHWidth %d staIdx = %d"),
+ bcn->VHTOperation.chanWidth, pStaDs->staIndex);)
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"),
+ pMh->sa[0], pMh->sa[1],
+ pMh->sa[2], pMh->sa[3],
+ pMh->sa[4], pMh->sa[5]);)
+
+ if (bcn->VHTOperation.chanWidth ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 160MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ chWidth = eHT_CHANNEL_WIDTH_160MHZ;
+ } else if (bcn->VHTOperation.chanWidth ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 160MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ;
+ pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
+ chWidth = eHT_CHANNEL_WIDTH_160MHZ;
+ } else if (bcn->VHTOperation.chanWidth ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 80MHz"));)
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
+ pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
+ chWidth = eHT_CHANNEL_WIDTH_80MHZ;
+ } else if (bcn->VHTOperation.chanWidth ==
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) {
+ pStaDs->vhtSupportedChannelWidthSet =
+ WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
+ if (bcn->HTCaps.supportedChannelWidthSet) {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 40MHz"));)
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_40MHZ;
+ chWidth = eHT_CHANNEL_WIDTH_40MHZ;
+ } else {
+ PELOGE(sch_log(mac_ctx, LOGE,
+ FL("Updating the CH Width to 20MHz"));)
+ pStaDs->htSupportedChannelWidthSet =
+ eHT_CHANNEL_WIDTH_20MHZ;
+ chWidth = eHT_CHANNEL_WIDTH_20MHZ;
+ }
+ }
+ lim_check_vht_op_mode_change(mac_ctx, session, chWidth,
+ pStaDs->staIndex, pMh->sa);
+ return;
+}
+
+/*
+ * __sch_beacon_process_for_session() - Process the received beacon frame when
+ * station is not scanning and corresponding session is found
+ *
+ *
+ * @mac_ctx: mac_ctx
+ * @bcn: beacon struct
+ * @rx_pkt_info: received packet info
+ * @session: pe session pointer
+ *
+ * Following scenarios exist when Session exists
+ * IBSS STA receving beacons from IBSS Peers, who are part of IBSS.
+ * - call lim_handle_ibs_scoalescing with that session context.
+ * Infra STA receving beacons from AP to which it is connected
+ * - call sch_beacon_processFromAP with that session's context.
+ * BTAMP STA receving beacons from BTAMP AP
+ * - call sch_beacon_processFromAP with that session's context.
+ * BTAMP AP receiving beacons from BTAMP STA
+ * (here need to make sure BTAP creates session entry for BT STA)
+ * - just update the beacon count for heart beat purposes for now,
+ * for now, don't process the beacon.
+ * Infra/IBSS both active and receives IBSS beacon:
+ * - call lim_handle_ibs_scoalescing with that session context.
+ * Infra/IBSS both active and receives Infra beacon:
+ * - call sch_beacon_processFromAP with that session's context.
+ * any updates to EDCA parameters will be effective for IBSS as well,
+ * even though no WMM for IBSS ?? Need to figure out how to handle
+ * this scenario.
+ * Infra/BTSTA both active and receive Infra beacon.
+ * - change in EDCA parameters on Infra affect the BTSTA link.
+ * Update the same parameters on BT link
+ * Infra/BTSTA both active and receive BT-AP beacon.
+ * - update beacon cnt for heartbeat
+ * Infra/BTAP both active and receive Infra beacon.
+ * - BT-AP starts advertising BE parameters from Infra AP, if they get
+ * changed.
+ * Infra/BTAP both active and receive BTSTA beacon.
+ * - update beacon cnt for heartbeat
+ *
+ * Return: void
+ */
+static void __sch_beacon_process_for_session(tpAniSirGlobal mac_ctx,
+ tpSchBeaconStruct bcn,
+ uint8_t *rx_pkt_info,
+ tpPESession session)
+{
+ tPowerdBm localRRMConstraint = 0;
+ uint8_t bssIdx = 0;
+ tUpdateBeaconParams beaconParams;
+ uint8_t sendProbeReq = false;
+#ifdef WLAN_FEATURE_11AC
+ tpSirMacMgmtHdr pMh = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+#endif
+#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI
+ tPowerdBm regMax = 0, maxTxPower = 0;
+#endif
+ cdf_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams));
+ beaconParams.paramChangeBitmap = 0;
+
+ if (LIM_IS_IBSS_ROLE(session)) {
+ lim_handle_ibss_coalescing(mac_ctx, bcn, rx_pkt_info, session);
+ } else if (LIM_IS_STA_ROLE(session)
+ || LIM_IS_BT_AMP_STA_ROLE(session)) {
+ if (false == sch_bcn_process_sta_bt_amp_sta(mac_ctx, bcn,
+ rx_pkt_info, session, &bssIdx,
+ &beaconParams, &sendProbeReq, pMh))
+ return;
+ }
+
+ if (session->htCapability && bcn->HTInfo.present)
+ lim_update_sta_run_time_ht_switch_chnl_params(mac_ctx,
+ &bcn->HTInfo, bssIdx, session);
+
+ if (LIM_IS_STA_ROLE(session)
+ || LIM_IS_BT_AMP_STA_ROLE(session)
+ || LIM_IS_IBSS_ROLE(session)) {
+ /* Channel Switch information element updated */
+ if (bcn->channelSwitchPresent) {
+ lim_update_channel_switch(mac_ctx, bcn, session);
+ } else if (session->gLimSpecMgmt.dot11hChanSwState ==
+ eLIM_11H_CHANSW_RUNNING) {
+ lim_cancel_dot11h_channel_switch(mac_ctx, session);
+ }
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (LIM_IS_STA_ROLE(session)
+ || LIM_IS_BT_AMP_STA_ROLE(session)
+ || LIM_IS_IBSS_ROLE(session))
+ sch_bcn_process_sta_bt_amp_sta_ibss(mac_ctx, bcn,
+ rx_pkt_info, session, &bssIdx,
+ &beaconParams, &sendProbeReq, pMh);
+#endif
+
+#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI)
+ /* Obtain the Max Tx power for the current regulatory */
+ regMax = cfg_get_regulatory_max_transmit_power(mac_ctx,
+ session->currentOperChannel);
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI
+ if (mac_ctx->rrm.rrmPEContext.rrmEnable
+ && bcn->powerConstraintPresent)
+ localRRMConstraint =
+ bcn->localPowerConstraint.localPowerConstraints;
+ else
+ localRRMConstraint = 0;
+ maxTxPower = lim_get_max_tx_power(regMax, regMax - localRRMConstraint,
+ mac_ctx->roam.configParam.nTxPowerCap);
+#elif defined FEATURE_WLAN_ESE
+ maxTxPower = regMax;
+#endif
+
+#if defined FEATURE_WLAN_ESE
+ if (session->isESEconnection) {
+ tPowerdBm localESEConstraint = 0;
+ if (bcn->eseTxPwr.present) {
+ localESEConstraint = bcn->eseTxPwr.power_limit;
+ maxTxPower = lim_get_max_tx_power(maxTxPower,
+ localESEConstraint,
+ mac_ctx->roam.configParam.nTxPowerCap);
+ }
+ sch_log(mac_ctx, LOG1,
+ FL("RegMax = %d, localEseCons = %d, MaxTx = %d"),
+ regMax, localESEConstraint, maxTxPower);
+ }
+#endif
+
+#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI)
+ /* If maxTxPower is increased or decreased */
+ if (maxTxPower != session->maxTxPower) {
+ sch_log(mac_ctx, LOG1,
+ FL("Local power constraint change..updating new maxTx power %d to HAL"),
+ maxTxPower);
+ if (lim_send_set_max_tx_power_req(mac_ctx, maxTxPower, session)
+ == eSIR_SUCCESS)
+ session->maxTxPower = maxTxPower;
+ }
+#endif
+
+ /* Indicate to LIM that Beacon is received */
+ if (bcn->HTInfo.present)
+ lim_received_hb_handler(mac_ctx,
+ (uint8_t) bcn->HTInfo.primaryChannel, session);
+ else
+ lim_received_hb_handler(mac_ctx, (uint8_t) bcn->channelNumber,
+ session);
+
+ /*
+ * I don't know if any additional IE is required here. Currently, not
+ * include addIE.
+ */
+ if (sendProbeReq)
+ lim_send_probe_req_mgmt_frame(mac_ctx, &session->ssId,
+ session->bssId, session->currentOperChannel,
+ session->selfMacAddr, session->dot11mode, 0, NULL);
+
+ if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+ && beaconParams.paramChangeBitmap) {
+ PELOGW(sch_log(mac_ctx, LOGW,
+ FL("Beacon for session[%d] got changed."),
+ session->peSessionId);)
+ PELOGW(sch_log(mac_ctx, LOGW,
+ FL("sending beacon param change bitmap: 0x%x "),
+ beaconParams.paramChangeBitmap);)
+ lim_send_beacon_params(mac_ctx, &beaconParams, session);
+ }
+}
+
+/**
+ * sch_beacon_process() - process the beacon frame
+ *
+ * @mac_ctx: mac global context
+ * @rx_pkt_info: pointer to buffer descriptor
+ *
+ * @return None
+ */
+void
+sch_beacon_process(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info,
+ tpPESession session)
+{
+ static tSchBeaconStruct bcn;
+ tUpdateBeaconParams bcn_prm;
+ tpPESession ap_session = NULL;
+#ifdef WLAN_FEATURE_MBSSID
+ uint8_t i;
+#endif
+
+ cdf_mem_zero(&bcn_prm, sizeof(tUpdateBeaconParams));
+ bcn_prm.paramChangeBitmap = 0;
+ mac_ctx->sch.gSchBcnRcvCnt++;
+ /* Convert the beacon frame into a structure */
+ if (sir_convert_beacon_frame2_struct(mac_ctx, (uint8_t *) rx_pkt_info,
+ &bcn) != eSIR_SUCCESS) {
+ PELOGE(sch_log(mac_ctx, LOGE, FL("beacon parsing failed"));)
+ mac_ctx->sch.gSchBcnParseErrorCnt++;
+ return;
+ }
+
+ if (bcn.ssidPresent)
+ bcn.ssId.ssId[bcn.ssId.length] = 0;
+ /*
+ * First process the beacon in the context of any existing AP or BTAP
+ * session. This takes cares of following two scenarios:
+ * - session = NULL:
+ * e.g. beacon received from a neighboring BSS, you want to apply the
+ * protection settings to BTAP/InfraAP beacons
+ * - session is non NULL:
+ * e.g. beacon received is from the INFRA AP to which you are connected
+ * on another concurrent link. In this case also, we want to apply the
+ * protection settings(as advertised by Infra AP) to BTAP beacons
+ */
+#ifdef WLAN_FEATURE_MBSSID
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ ap_session = pe_find_session_by_session_id(mac_ctx, i);
+ if (!((ap_session != NULL) &&
+ (!(WMA_GET_OFFLOADSCANLEARN(rx_pkt_info)))))
+ continue;
+
+ if (!LIM_IS_AP_ROLE(ap_session))
+ continue;
+
+ bcn_prm.bssIdx = ap_session->bssIdx;
+ if (ap_session->gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ ap_beacon_process(mac_ctx, rx_pkt_info,
+ &bcn, &bcn_prm, ap_session);
+
+ if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+ && bcn_prm.paramChangeBitmap) {
+ /* Update the bcn and apply the new settings to HAL */
+ sch_set_fixed_beacon_fields(mac_ctx, ap_session);
+ PELOG1(sch_log(mac_ctx, LOG1,
+ FL("Beacon for PE session[%d] got changed."),
+ ap_session->peSessionId);)
+ PELOG1(sch_log(mac_ctx, LOG1,
+ FL("sending beacon param change bitmap: 0x%x"),
+ bcn_prm.paramChangeBitmap);)
+ lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session);
+ }
+ }
+#else
+ ap_session = lim_is_ap_session_active(mac_ctx);
+ if ((ap_session != NULL)
+ && (!(WMA_GET_OFFLOADSCANLEARN(rx_pkt_info)))) {
+ bcn_prm.bssIdx = ap_session->bssIdx;
+ if (ap_session->gLimProtectionControl !=
+ WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
+ ap_beacon_process(mac_ctx, rx_pkt_info, &bcn,
+ &bcn_prm, ap_session);
+
+ if ((false == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)
+ && bcn_prm.paramChangeBitmap) {
+ /* Update the bcn and apply the new settings to HAL */
+ sch_set_fixed_beacon_fields(mac_ctx, ap_session);
+ PELOG1(sch_log(mac_ctx, LOG1,
+ FL("Beacon for PE session[%d] got changed."),
+ ap_session->peSessionId);)
+ PELOG1(sch_log(mac_ctx, LOG1,
+ FL("sending beacon param change bitmap: 0x%x "),
+ bcn_prm.paramChangeBitmap);)
+ lim_send_beacon_params(mac_ctx, &bcn_prm, ap_session);
+ }
+ }
+#endif
+ /*
+ * Now process the beacon in the context of the BSS which is
+ * transmitting the beacons, if one is found
+ */
+ if (session == NULL)
+ __sch_beacon_process_no_session(mac_ctx, &bcn, rx_pkt_info);
+ else
+ __sch_beacon_process_for_session(mac_ctx, &bcn, rx_pkt_info,
+ session);
+}
+
+/**
+ * sch_beacon_edca_process(): Process the EDCA parameter set in the received
+ * beacon frame
+ *
+ * @mac_ctx: mac global context
+ * @edca: reference to edca parameters in beacon struct
+ * @session : pesession entry
+ *
+ * @return status of operation
+ */
+tSirRetStatus
+sch_beacon_edca_process(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca,
+ tpPESession session)
+{
+ uint8_t i;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ host_log_qos_edca_pkt_type *log_ptr = NULL;
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ PELOG1(sch_log(pMac, LOG1,
+ FL("Updating parameter set count: Old %d ---> new %d"),
+ session->gLimEdcaParamSetCount, edca->qosInfo.count);)
+
+ session->gLimEdcaParamSetCount = edca->qosInfo.count;
+ session->gLimEdcaParams[EDCA_AC_BE] = edca->acbe;
+ session->gLimEdcaParams[EDCA_AC_BK] = edca->acbk;
+ session->gLimEdcaParams[EDCA_AC_VI] = edca->acvi;
+ session->gLimEdcaParams[EDCA_AC_VO] = edca->acvo;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ WLAN_HOST_DIAG_LOG_ALLOC(log_ptr, host_log_qos_edca_pkt_type,
+ LOG_WLAN_QOS_EDCA_C);
+ if (log_ptr) {
+ log_ptr->aci_be = session->gLimEdcaParams[EDCA_AC_BE].aci.aci;
+ log_ptr->cw_be =
+ session->gLimEdcaParams[EDCA_AC_BE].cw.max << 4
+ | session->gLimEdcaParams[EDCA_AC_BE].cw.min;
+ log_ptr->txoplimit_be =
+ session->gLimEdcaParams[EDCA_AC_BE].txoplimit;
+ log_ptr->aci_bk =
+ session->gLimEdcaParams[EDCA_AC_BK].aci.aci;
+ log_ptr->cw_bk =
+ session->gLimEdcaParams[EDCA_AC_BK].cw.max << 4
+ | session->gLimEdcaParams[EDCA_AC_BK].cw.min;
+ log_ptr->txoplimit_bk =
+ session->gLimEdcaParams[EDCA_AC_BK].txoplimit;
+ log_ptr->aci_vi =
+ session->gLimEdcaParams[EDCA_AC_VI].aci.aci;
+ log_ptr->cw_vi =
+ session->gLimEdcaParams[EDCA_AC_VI].cw.max << 4
+ | session->gLimEdcaParams[EDCA_AC_VI].cw.min;
+ log_ptr->txoplimit_vi =
+ session->gLimEdcaParams[EDCA_AC_VI].txoplimit;
+ log_ptr->aci_vo =
+ session->gLimEdcaParams[EDCA_AC_VO].aci.aci;
+ log_ptr->cw_vo =
+ session->gLimEdcaParams[EDCA_AC_VO].cw.max << 4
+ | session->gLimEdcaParams[EDCA_AC_VO].cw.min;
+ log_ptr->txoplimit_vo =
+ session->gLimEdcaParams[EDCA_AC_VO].txoplimit;
+ }
+ WLAN_HOST_DIAG_LOG_REPORT(log_ptr);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ PELOG1(sch_log(pMac, LOGE,
+ FL("Updating Local EDCA Params(gLimEdcaParams) to: "));)
+ for (i = 0; i < MAX_NUM_AC; i++) {
+ PELOG1(sch_log(pMac, LOG1,
+ FL("AC[%d]: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d"),
+ i, session->gLimEdcaParams[i].aci.aifsn,
+ session->gLimEdcaParams[i].aci.acm,
+ session->gLimEdcaParams[i].cw.min,
+ session->gLimEdcaParams[i].cw.max,
+ session->gLimEdcaParams[i].txoplimit);)
+ }
+ return eSIR_SUCCESS;
+}
diff --git a/core/mac/src/pe/sch/sch_debug.c b/core/mac/src/pe/sch/sch_debug.c
new file mode 100644
index 0000000..47c0714
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_debug.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sch_debug.cc contains some debug functions.
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "cdf_trace.h"
+#include "sch_debug.h"
+#define LOG_SIZE 256
+
+void sch_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...)
+{
+
+ CDF_TRACE_LEVEL cdf_debug_level;
+ char logBuffer[LOG_SIZE];
+ va_list marker;
+
+ /* getting proper Debug level */
+ cdf_debug_level = get_vos_debug_level(loglevel);
+
+ /* extracting arguments from pstring */
+ va_start(marker, pString);
+ vsnprintf(logBuffer, LOG_SIZE, pString, marker);
+ CDF_TRACE(CDF_MODULE_ID_PE, cdf_debug_level, "%s", logBuffer);
+ va_end(marker);
+}
+
+/* -------------------------------------------------------------------- */
diff --git a/core/mac/src/pe/sch/sch_debug.h b/core/mac/src/pe/sch/sch_debug.h
new file mode 100644
index 0000000..d27f727
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_debug.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sch_debug.h contains some debug macros.
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_DEBUG_H__
+#define __SCH_DEBUG_H__
+
+#include "utils_api.h"
+#include "sir_debug.h"
+
+#if !defined(__printf)
+#define __printf(a, b)
+#endif
+
+void __printf(3, 4) sch_log(tpAniSirGlobal pMac, uint32_t loglevel,
+ const char *pString, ...);
+
+#endif
diff --git a/core/mac/src/pe/sch/sch_message.c b/core/mac/src/pe/sch/sch_message.c
new file mode 100644
index 0000000..e746f8b
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_message.c
@@ -0,0 +1,574 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include "cds_api.h"
+#include "sir_common.h"
+
+#include "wni_cfg.h"
+#include "ani_global.h"
+#include "cfg_api.h"
+#include "lim_api.h"
+#include "lim_send_messages.h"
+
+#include "sch_api.h"
+#include "sch_debug.h"
+
+/* / Minimum beacon interval allowed (in Kus) */
+#define SCH_BEACON_INTERVAL_MIN 10
+
+/* / Maximum beacon interval allowed (in Kus) */
+#define SCH_BEACON_INTERVAL_MAX 10000
+
+/* / convert the CW values into a uint16_t */
+#define GET_CW(pCw) ((uint16_t) ((*(pCw) << 8) + *((pCw) + 1)))
+
+/* local functions */
+static tSirRetStatus get_wmm_local_params(tpAniSirGlobal pMac,
+ uint32_t
+ params[]
+ [WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]);
+static void set_sch_edca_params(tpAniSirGlobal pMac,
+ uint32_t params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN],
+ tpPESession psessionEntry);
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_set_beacon_interval
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void sch_set_beacon_interval(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ uint32_t bi;
+
+ bi = psessionEntry->beaconParams.beaconInterval;
+
+ if (bi < SCH_BEACON_INTERVAL_MIN || bi > SCH_BEACON_INTERVAL_MAX) {
+ sch_log(pMac, LOGE,
+ FL("Invalid beacon interval %d (should be [%d,%d]"), bi,
+ SCH_BEACON_INTERVAL_MIN, SCH_BEACON_INTERVAL_MAX);
+ return;
+ }
+
+ pMac->sch.schObject.gSchBeaconInterval = (uint16_t) bi;
+}
+
+/* -------------------------------------------------------------------- */
+/**
+ * sch_process_message
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param None
+ * @return None
+ */
+
+void sch_process_message(tpAniSirGlobal pMac, tpSirMsgQ pSchMsg)
+{
+ uint32_t val;
+
+ tpPESession psessionEntry = &pMac->lim.gpSession[0];
+ PELOG3(sch_log(pMac, LOG3, FL("Received message (%x) "), pSchMsg->type);)
+
+ switch (pSchMsg->type) {
+
+ case SIR_SCH_CHANNEL_SWITCH_REQUEST:
+ sch_log(pMac, LOGE, FL("Channel switch request not handled"));
+ break;
+
+ case SIR_SCH_START_SCAN_REQ:
+ pMac->sch.gSchScanReqRcvd = true;
+ if (pMac->sch.gSchHcfEnabled) {
+ /* In HCF mode, wait for TFP to stop before sending a response */
+ if (pMac->sch.schObject.gSchCFBInitiated ||
+ pMac->sch.schObject.gSchCFPInitiated) {
+ PELOG1(sch_log(pMac, LOG1,
+ FL
+ ("Waiting for TFP to halt before sending "
+ "start scan response"));
+ )
+ } else
+ sch_send_start_scan_rsp(pMac);
+ } else {
+ /* In eDCF mode, send the response right away */
+ sch_send_start_scan_rsp(pMac);
+ }
+ break;
+
+ case SIR_SCH_END_SCAN_NTF:
+ PELOG3(sch_log(pMac, LOG3,
+ FL("Received STOP_SCAN_NTF from LIM"));
+ )
+ pMac->sch.gSchScanReqRcvd = false;
+ break;
+
+ case SIR_CFG_PARAM_UPDATE_IND:
+
+ if (wlan_cfg_get_int(pMac, (uint16_t) pSchMsg->bodyval, &val) !=
+ eSIR_SUCCESS)
+ sch_log(pMac, LOGP, FL("failed to cfg get id %d"),
+ pSchMsg->bodyval);
+
+ switch (pSchMsg->bodyval) {
+ case WNI_CFG_BEACON_INTERVAL:
+ /* What to do for IBSS ?? - TBD */
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ sch_set_beacon_interval(pMac, psessionEntry);
+ break;
+
+ case WNI_CFG_DTIM_PERIOD:
+ pMac->sch.schObject.gSchDTIMCount = 0;
+ break;
+
+ case WNI_CFG_CFP_PERIOD:
+ pMac->sch.schObject.gSchCFPCount = 0;
+ break;
+
+ case WNI_CFG_EDCA_PROFILE:
+ sch_edca_profile_update(pMac, psessionEntry);
+ break;
+
+ case WNI_CFG_EDCA_ANI_ACBK_LOCAL:
+ case WNI_CFG_EDCA_ANI_ACBE_LOCAL:
+ case WNI_CFG_EDCA_ANI_ACVI_LOCAL:
+ case WNI_CFG_EDCA_ANI_ACVO_LOCAL:
+ case WNI_CFG_EDCA_WME_ACBK_LOCAL:
+ case WNI_CFG_EDCA_WME_ACBE_LOCAL:
+ case WNI_CFG_EDCA_WME_ACVI_LOCAL:
+ case WNI_CFG_EDCA_WME_ACVO_LOCAL:
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ sch_qos_update_local(pMac, psessionEntry);
+ break;
+
+ case WNI_CFG_EDCA_ANI_ACBK:
+ case WNI_CFG_EDCA_ANI_ACBE:
+ case WNI_CFG_EDCA_ANI_ACVI:
+ case WNI_CFG_EDCA_ANI_ACVO:
+ case WNI_CFG_EDCA_WME_ACBK:
+ case WNI_CFG_EDCA_WME_ACBE:
+ case WNI_CFG_EDCA_WME_ACVI:
+ case WNI_CFG_EDCA_WME_ACVO:
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ psessionEntry->gLimEdcaParamSetCount++;
+ sch_qos_update_broadcast(pMac, psessionEntry);
+ }
+ break;
+
+ default:
+ sch_log(pMac, LOGE,
+ FL("Cfg param %d indication not handled"),
+ pSchMsg->bodyval);
+ }
+ break;
+
+ default:
+ sch_log(pMac, LOGE, FL("Unknown message in schMsgQ type %d"),
+ pSchMsg->type);
+ }
+
+}
+
+/* get the local or broadcast parameters based on the profile sepcified in the config */
+/* params are delivered in this order: BK, BE, VI, VO */
+tSirRetStatus
+sch_get_params(tpAniSirGlobal pMac,
+ uint32_t params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], uint8_t local)
+{
+ uint32_t val;
+ uint32_t i, idx;
+ uint32_t *prf;
+
+ uint32_t ani_l[] = {
+ WNI_CFG_EDCA_ANI_ACBE_LOCAL, WNI_CFG_EDCA_ANI_ACBK_LOCAL,
+ WNI_CFG_EDCA_ANI_ACVI_LOCAL, WNI_CFG_EDCA_ANI_ACVO_LOCAL};
+ uint32_t wme_l[] = {
+ WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL,
+ WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL};
+ uint32_t ani_b[] = { WNI_CFG_EDCA_ANI_ACBE, WNI_CFG_EDCA_ANI_ACBK,
+ WNI_CFG_EDCA_ANI_ACVI, WNI_CFG_EDCA_ANI_ACVO};
+ uint32_t wme_b[] = { WNI_CFG_EDCA_WME_ACBE, WNI_CFG_EDCA_WME_ACBK,
+ WNI_CFG_EDCA_WME_ACVI, WNI_CFG_EDCA_WME_ACVO};
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_EDCA_PROFILE, &val) != eSIR_SUCCESS) {
+ sch_log(pMac, LOGP, FL("failed to cfg get EDCA_PROFILE id %d"),
+ WNI_CFG_EDCA_PROFILE);
+ return eSIR_FAILURE;
+ }
+
+ if (val >= WNI_CFG_EDCA_PROFILE_MAX) {
+ sch_log(pMac, LOGE,
+ FL("Invalid EDCA_PROFILE %d, using %d instead"), val,
+ WNI_CFG_EDCA_PROFILE_ANI);
+ val = WNI_CFG_EDCA_PROFILE_ANI;
+ }
+
+ sch_log(pMac, LOGW, FL("EdcaProfile: Using %d (%s)"), val,
+ ((val == WNI_CFG_EDCA_PROFILE_WMM) ? "WMM" : "HiPerf"));
+
+ if (local) {
+ switch (val) {
+ case WNI_CFG_EDCA_PROFILE_WMM:
+ prf = &wme_l[0];
+ break;
+ case WNI_CFG_EDCA_PROFILE_ANI:
+ default:
+ prf = &ani_l[0];
+ break;
+ }
+ } else {
+ switch (val) {
+ case WNI_CFG_EDCA_PROFILE_WMM:
+ prf = &wme_b[0];
+ break;
+ case WNI_CFG_EDCA_PROFILE_ANI:
+ default:
+ prf = &ani_b[0];
+ break;
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ uint8_t data[WNI_CFG_EDCA_ANI_ACBK_LEN];
+ uint32_t len = WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN;
+ if (wlan_cfg_get_str
+ (pMac, (uint16_t) prf[i], (uint8_t *) &data[0],
+ &len) != eSIR_SUCCESS) {
+ sch_log(pMac, LOGP, FL("cfgGet failed for %d"), prf[i]);
+ return eSIR_FAILURE;
+ }
+ if (len > WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN) {
+ sch_log(pMac, LOGE,
+ FL("cfgGet for %d: length is %d instead of %d"),
+ prf[i], len, WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN);
+ return eSIR_FAILURE;
+ }
+ for (idx = 0; idx < len; idx++)
+ params[i][idx] = (uint32_t) data[idx];
+ }
+ PELOG1(sch_log
+ (pMac, LOG1, FL("GetParams: local=%d, profile = %d Done"), local,
+ val);
+ )
+ return eSIR_SUCCESS;
+}
+
+/**
+ * broadcast_wmm_of_concurrent_sta_session() - broadcasts wmm info
+ * @mac_ctx: mac global context
+ * @session: pesession entry
+ *
+ * Return: void
+ */
+static void
+broadcast_wmm_of_concurrent_sta_session(tpAniSirGlobal mac_ctx,
+ tpPESession session)
+{
+ uint8_t i, j;
+ tpPESession concurrent_session = NULL;
+
+ for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+ /*
+ * Find another INFRA STA AP session on same operating channel.
+ * The session entry passed to this API is for GO/SoftAP session
+ * that is getting added currently
+ */
+ if (!((mac_ctx->lim.gpSession[i].valid == true) &&
+ (mac_ctx->lim.gpSession[i].peSessionId !=
+ session->peSessionId)
+ && (mac_ctx->lim.gpSession[i].currentOperChannel ==
+ session->currentOperChannel)
+ && (mac_ctx->lim.gpSession[i].limSystemRole
+ == eLIM_STA_ROLE)))
+ continue;
+
+ concurrent_session = &(mac_ctx->lim.gpSession[i]);
+ break;
+ }
+
+ if (concurrent_session == NULL)
+ return;
+ /*
+ * Once atleast one concurrent session on same channel is found and WMM
+ * broadcast params for current SoftAP/GO session updated, return
+ */
+ for (j = 0; j < MAX_NUM_AC; j++) {
+ session->gLimEdcaParamsBC[j].aci.acm =
+ concurrent_session->gLimEdcaParams[j].aci.acm;
+ session->gLimEdcaParamsBC[j].aci.aifsn =
+ concurrent_session->gLimEdcaParams[j].aci.aifsn;
+ session->gLimEdcaParamsBC[j].cw.min =
+ concurrent_session->gLimEdcaParams[j].cw.min;
+ session->gLimEdcaParamsBC[j].cw.max =
+ concurrent_session->gLimEdcaParams[j].cw.max;
+ session->gLimEdcaParamsBC[j].txoplimit =
+ concurrent_session->gLimEdcaParams[j].txoplimit;
+ PELOG1(sch_log(mac_ctx, LOG1,
+ FL("QoSUpdateBCast changed again due to concurrent INFRA STA session: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d"),
+ j, session->gLimEdcaParamsBC[j].aci.aifsn,
+ session->gLimEdcaParamsBC[j].aci.acm,
+ session->gLimEdcaParamsBC[j].cw.min,
+ session->gLimEdcaParamsBC[j].cw.max,
+ session->gLimEdcaParamsBC[j].txoplimit);)
+ }
+}
+
+void sch_qos_update_broadcast(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ uint32_t params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN];
+ uint32_t cwminidx, cwmaxidx, txopidx;
+ uint32_t phyMode;
+ uint8_t i;
+
+ if (sch_get_params(pMac, params, false) != eSIR_SUCCESS) {
+ PELOGE(sch_log(pMac, LOGE, FL("QosUpdateBroadcast: failed"));)
+ return;
+ }
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ PELOG1(sch_log(pMac, LOG1, "QosUpdBcast: mode %d", phyMode);)
+
+ if (phyMode == WNI_CFG_PHY_MODE_11G) {
+ cwminidx = WNI_CFG_EDCA_PROFILE_CWMING_IDX;
+ cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXG_IDX;
+ txopidx = WNI_CFG_EDCA_PROFILE_TXOPG_IDX;
+ } else if (phyMode == WNI_CFG_PHY_MODE_11B) {
+ cwminidx = WNI_CFG_EDCA_PROFILE_CWMINB_IDX;
+ cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXB_IDX;
+ txopidx = WNI_CFG_EDCA_PROFILE_TXOPB_IDX;
+ } else {
+ /* This can happen if mode is not set yet, assume 11a mode */
+ cwminidx = WNI_CFG_EDCA_PROFILE_CWMINA_IDX;
+ cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXA_IDX;
+ txopidx = WNI_CFG_EDCA_PROFILE_TXOPA_IDX;
+ }
+
+ for (i = 0; i < MAX_NUM_AC; i++) {
+ psessionEntry->gLimEdcaParamsBC[i].aci.acm =
+ (uint8_t) params[i][WNI_CFG_EDCA_PROFILE_ACM_IDX];
+ psessionEntry->gLimEdcaParamsBC[i].aci.aifsn =
+ (uint8_t) params[i][WNI_CFG_EDCA_PROFILE_AIFSN_IDX];
+ psessionEntry->gLimEdcaParamsBC[i].cw.min =
+ convert_cw(GET_CW(¶ms[i][cwminidx]));
+ psessionEntry->gLimEdcaParamsBC[i].cw.max =
+ convert_cw(GET_CW(¶ms[i][cwmaxidx]));
+ psessionEntry->gLimEdcaParamsBC[i].txoplimit =
+ (uint16_t) params[i][txopidx];
+
+ PELOG1(sch_log
+ (pMac, LOG1,
+ "QoSUpdateBCast: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d",
+ i, psessionEntry->gLimEdcaParamsBC[i].aci.aifsn,
+ psessionEntry->gLimEdcaParamsBC[i].aci.acm,
+ psessionEntry->gLimEdcaParamsBC[i].cw.min,
+ psessionEntry->gLimEdcaParamsBC[i].cw.max,
+ psessionEntry->gLimEdcaParamsBC[i].txoplimit);
+ )
+
+ }
+
+ /* If there exists a concurrent STA-AP session, use its WMM params to broadcast in beacons. WFA Wifi Direct test plan 6.1.14 requirement */
+ broadcast_wmm_of_concurrent_sta_session(pMac, psessionEntry);
+
+ if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS)
+ PELOGE(sch_log(pMac, LOGE, "Unable to set beacon fields!");)
+}
+
+void sch_qos_update_local(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ uint32_t params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN];
+
+ if (sch_get_params(pMac, params, true /*local */) != eSIR_SUCCESS) {
+ PELOGE(sch_log(pMac, LOGE, FL("sch_get_params(local) failed"));)
+ return;
+ }
+
+ set_sch_edca_params(pMac, params, psessionEntry);
+
+ /* For AP, the bssID is stored in LIM Global context. */
+ lim_send_edca_params(pMac, psessionEntry->gLimEdcaParams,
+ psessionEntry->bssIdx);
+}
+
+/** ----------------------------------------------------------
+ \fn sch_set_default_edca_params
+ \brief This function sets the gLimEdcaParams to the default
+ \ local wmm profile.
+ \param tpAniSirGlobal pMac
+ \return none
+ \ ------------------------------------------------------------ */
+void sch_set_default_edca_params(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ uint32_t params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN];
+
+ if (get_wmm_local_params(pMac, params) != eSIR_SUCCESS) {
+ PELOGE(sch_log(pMac, LOGE, FL("get_wmm_local_params() failed"));)
+ return;
+ }
+
+ set_sch_edca_params(pMac, params, psessionEntry);
+ return;
+}
+
+/** ----------------------------------------------------------
+ \fn set_sch_edca_params
+ \brief This function fills in the gLimEdcaParams structure
+ \ with the given edca params.
+ \param tpAniSirGlobal pMac
+ \return none
+ \ ------------------------------------------------------------ */
+static void
+set_sch_edca_params(tpAniSirGlobal pMac,
+ uint32_t params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN],
+ tpPESession psessionEntry)
+{
+ uint32_t i;
+ uint32_t cwminidx, cwmaxidx, txopidx;
+ uint32_t phyMode;
+
+ lim_get_phy_mode(pMac, &phyMode, psessionEntry);
+
+ PELOG1(sch_log(pMac, LOG1, FL("lim_get_phy_mode() = %d"), phyMode);)
+ /* if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11G) */
+ if (phyMode == WNI_CFG_PHY_MODE_11G) {
+ cwminidx = WNI_CFG_EDCA_PROFILE_CWMING_IDX;
+ cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXG_IDX;
+ txopidx = WNI_CFG_EDCA_PROFILE_TXOPG_IDX;
+ }
+ /* else if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11B) */
+ else if (phyMode == WNI_CFG_PHY_MODE_11B) {
+ cwminidx = WNI_CFG_EDCA_PROFILE_CWMINB_IDX;
+ cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXB_IDX;
+ txopidx = WNI_CFG_EDCA_PROFILE_TXOPB_IDX;
+ } else {
+ /* This can happen if mode is not set yet, assume 11a mode */
+ cwminidx = WNI_CFG_EDCA_PROFILE_CWMINA_IDX;
+ cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXA_IDX;
+ txopidx = WNI_CFG_EDCA_PROFILE_TXOPA_IDX;
+ }
+
+ for (i = 0; i < MAX_NUM_AC; i++) {
+ psessionEntry->gLimEdcaParams[i].aci.acm =
+ (uint8_t) params[i][WNI_CFG_EDCA_PROFILE_ACM_IDX];
+ psessionEntry->gLimEdcaParams[i].aci.aifsn =
+ (uint8_t) params[i][WNI_CFG_EDCA_PROFILE_AIFSN_IDX];
+ psessionEntry->gLimEdcaParams[i].cw.min =
+ convert_cw(GET_CW(¶ms[i][cwminidx]));
+ psessionEntry->gLimEdcaParams[i].cw.max =
+ convert_cw(GET_CW(¶ms[i][cwmaxidx]));
+ psessionEntry->gLimEdcaParams[i].txoplimit =
+ (uint16_t) params[i][txopidx];
+
+ PELOG1(sch_log
+ (pMac, LOG1,
+ FL
+ ("AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d"),
+ i, psessionEntry->gLimEdcaParams[i].aci.aifsn,
+ psessionEntry->gLimEdcaParams[i].aci.acm,
+ psessionEntry->gLimEdcaParams[i].cw.min,
+ psessionEntry->gLimEdcaParams[i].cw.max,
+ psessionEntry->gLimEdcaParams[i].txoplimit);
+ )
+
+ }
+ return;
+}
+
+/** ----------------------------------------------------------
+ \fn get_wmm_local_params
+ \brief This function gets the WMM local edca parameters.
+ \param tpAniSirGlobal pMac
+ \param uint32_t params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]
+ \return none
+ \ ------------------------------------------------------------ */
+static tSirRetStatus
+get_wmm_local_params(tpAniSirGlobal pMac,
+ uint32_t params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN])
+{
+ uint32_t i, idx;
+ uint32_t *prf;
+ uint32_t wme_l[] = {
+ WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL,
+ WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL};
+
+ prf = &wme_l[0];
+ for (i = 0; i < 4; i++) {
+ uint8_t data[WNI_CFG_EDCA_ANI_ACBK_LEN];
+ uint32_t len = WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN;
+ if (wlan_cfg_get_str
+ (pMac, (uint16_t) prf[i], (uint8_t *) &data[0],
+ &len) != eSIR_SUCCESS) {
+ sch_log(pMac, LOGP, FL("cfgGet failed for %d"), prf[i]);
+ return eSIR_FAILURE;
+ }
+ if (len > WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN) {
+ sch_log(pMac, LOGE,
+ FL("cfgGet for %d: length is %d instead of %d"),
+ prf[i], len, WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN);
+ return eSIR_FAILURE;
+ }
+ for (idx = 0; idx < len; idx++)
+ params[i][idx] = (uint32_t) data[idx];
+ }
+ return eSIR_SUCCESS;
+}
+
+/** ----------------------------------------------------------
+ \fn sch_edca_profile_update
+ \brief This function updates the local and broadcast
+ \ EDCA params in the gLimEdcaParams structure. It also
+ \ updates the edcaParamSetCount.
+ \param tpAniSirGlobal pMac
+ \return none
+ \ ------------------------------------------------------------ */
+void sch_edca_profile_update(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ if (LIM_IS_AP_ROLE(psessionEntry) ||
+ LIM_IS_IBSS_ROLE(psessionEntry)) {
+ sch_qos_update_local(pMac, psessionEntry);
+ psessionEntry->gLimEdcaParamSetCount++;
+ sch_qos_update_broadcast(pMac, psessionEntry);
+ }
+}
+
+/* -------------------------------------------------------------------- */
diff --git a/core/mac/src/pe/sch/sch_sys_params.h b/core/mac/src/pe/sch/sch_sys_params.h
new file mode 100644
index 0000000..adf5c19
--- /dev/null
+++ b/core/mac/src/pe/sch/sch_sys_params.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sch_sys_params.h contains scheduler parameter definitions
+ *
+ * Author: Sandesh Goel
+ * Date: 02/25/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SCH_SYS_PARAMS_H__
+#define __SCH_SYS_PARAMS_H__
+
+/* / Unsolicited poll period (ms) (0 to disable) */
+#define SCH_POLL_PERIOD 1000
+
+/* / RR timeout value (ms) (0 to disable) */
+#define SCH_RR_TIMEOUT_MS 40
+
+/* / Default CP:CFP ratio */
+#define SCH_DEFAULT_CP_TO_CFP_RATIO 0
+
+/* / Default maximum CFP duration (us) */
+#define SCH_DEFAULT_MAX_CFP_TIME 60000
+
+/* / Default minimum CP duration (us) */
+#define SCH_DEFAULT_MIN_CP_TIME 100
+
+/* / Amount of delay prior to starting CFP (us) */
+#define SCH_CFP_START_DELAY 100
+
+/* / Unit of Txop in micro seconds */
+#define TXOP_UNIT_IN_USEC 32
+
+/* / Minimum amount of time granted per instruction on average (units of txop) */
+#define MIN_TXOP_PER_INSTRUCTION 50
+
+/* / Maximum amount of time granted per instruction (units of txop) */
+#define MAX_TXOP_PER_INSTRUCTION 300 /* HACK - 100 */
+
+/* / Maximum amount of time granted to one entire schedule (units of txop) */
+#define MAX_TXOP_PER_SCHEDULE 400
+
+/* / Scheduling quantum (units of TXOP) */
+#define SCH_QUANTUM_QUEUE 4
+
+/* / Maximum unused quantum allowed to be accumulated by a queue */
+#define MAX_ACCUMULATED_QUANTUM 500
+
+/* / Minimum allocated quantum for an uplink flow before a poll instruction is written */
+#define SCH_MIN_UL_ALLOC 12
+
+/* ---- Scheduling Policy ---- */
+
+/* / Number of QOS classes */
+#define SCH_NUM_QOS_CLASSES 2
+
+#define SCH_POLICY_STRICT_PRI 0
+#define SCH_POLICY_DRR 1
+
+/* / Scheduling quantum for each class if using DRR */
+#define SCH_QUANTUM_CLASS 100
+
+/* / The default scheduling policy between classes */
+#define SCH_POLICY_DEFAULT SCH_POLICY_STRICT_PRI
+
+/* Scheduling weights for each priority */
+
+#define SCH_QUANTUM_0 40
+#define SCH_QUANTUM_1 36
+#define SCH_QUANTUM_2 32
+#define SCH_QUANTUM_3 28
+#define SCH_QUANTUM_4 24
+#define SCH_QUANTUM_5 20
+#define SCH_QUANTUM_6 16
+#define SCH_QUANTUM_7 12
+
+#endif
diff --git a/core/mac/src/sys/common/inc/wlan_qct_sys.h b/core/mac/src/sys/common/inc/wlan_qct_sys.h
new file mode 100644
index 0000000..c80b641
--- /dev/null
+++ b/core/mac/src/sys/common/inc/wlan_qct_sys.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#if !defined( WLAN_QCT_SYS_H__ )
+#define WLAN_QCT_SYS_H__
+
+/**===========================================================================
+
+ \file wlan_qct_sys.h
+
+ \brief System module API
+
+ ==========================================================================*/
+
+/* $HEADER$ */
+
+/*---------------------------------------------------------------------------
+ Include files
+ -------------------------------------------------------------------------*/
+#include <cdf_types.h>
+#include <cdf_status.h>
+#include <cds_mq.h>
+
+/*---------------------------------------------------------------------------
+ Preprocessor definitions and constants
+ -------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ Type declarations
+ -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+
+ \brief sysResponseCback() - SYS async resonse callback
+
+ This is a protype for the callback function that SYS makes to various
+ modules in the system.
+
+ \param pUserData - user data that is passed to the Callback function
+ when it is invoked.
+
+ \return Nothing
+
+ \sa sysMcStart(), sysMcThreadProbe(), sysTxThreadProbe()
+
+ --------------------------------------------------------------------------*/
+typedef void (*sysResponseCback)(void *pUserData);
+
+typedef enum {
+ SYS_MSG_ID_MC_START,
+ SYS_MSG_ID_MC_THR_PROBE,
+ SYS_MSG_ID_MC_TIMER,
+ SYS_MSG_ID_MC_STOP,
+ SYS_MSG_ID_FTM_RSP,
+
+} SYS_MSG_ID;
+
+/*---------------------------------------------------------------------------
+ Preprocessor definitions and constants
+ -------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+ Function declarations and documenation
+ -------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+
+ \brief sys_build_message_header() - Build / initialize a SYS message header
+
+ This function will initialize the SYS message header with the message type
+ and any internal fields needed for a new SYS message. This function sets
+ all but the message body, which is up to the caller to setup based on the
+ specific message being built.
+
+ \note There are internal / reserved items in a SYS message that must be
+ set correctly for the message to be recognized as a SYS message by
+ the SYS message handlers. It is important for every SYS message to
+ be setup / built / initialized through this function.
+
+ \param sysMsgId - a valid message ID for a SYS message. See the
+ SYS_MSG_ID enum for all the valid SYS message IDs.
+
+ \param pMsg - pointer to the message structure to be setup.
+
+ \return
+
+ \sa
+
+ --------------------------------------------------------------------------*/
+CDF_STATUS sys_build_message_header(SYS_MSG_ID sysMsgId, cds_msg_t *pMsg);
+
+/*----------------------------------------------------------------------------
+
+ \brief sysMcStart() - start the system Main Controller thread.
+
+ This function starts the SYS (Main Controller) module. Starting this
+ module triggers the CFG download to the 'legacy' MAC software.
+
+ \param p_cds_context - pointer to the CDS Context
+
+ \param userCallback - this is a callback that is called when the SYS
+ has completed the 'start' funciton.
+
+ \param pUserData - pointer to some user data entity that is passed to
+ the callback function as a parameter when invoked.
+
+ \return CDF_STATUS_SUCCESS -
+
+ \todo: We have not 'status' on the callback. How do we notify the
+ callback that there is a failure ?
+
+ \sa
+
+ --------------------------------------------------------------------------*/
+CDF_STATUS sysMcStart(v_CONTEXT_t p_cds_context, sysResponseCback userCallback,
+ void *pUserData);
+
+/*----------------------------------------------------------------------------
+
+ \brief sys_stop() - Stop the SYS module.
+
+ This function stops the SYS module.
+
+ \todo: What else do we need to do on sys_stop()?
+
+ \param p_cds_context - pointer to the CDS Context
+
+ \return CDF_STATUS_SUCCESS - the SYS module is stopped.
+
+ CDF_STATUS_E_FAILURE - the SYS module open failed to stop.
+
+ \sa
+
+ --------------------------------------------------------------------------*/
+CDF_STATUS sys_stop(v_CONTEXT_t p_cds_context);
+
+/*----------------------------------------------------------------------------
+
+ \brief sys_mc_process_msg() - process SYS messages on the Main Controller thread
+
+ This function processes SYS Messages on the Main Controller thread.
+ SYS messages consist of all 'legacy' messages (messages bound for legacy
+ modules like LIM, HAL, PE, etc.) as well as newly defined SYS message
+ types.
+
+ SYS messages are identified by their type (in the SYS_MESSAGES enum) as
+ well as a 'cookie' that is in the reserved field of the message structure.
+ This 'cookie' is introduced to prevent any message type/ID conflicts with
+ the 'legacy' message types.
+
+ Any module attempting to post a message to the SYS module must set the
+ message type to one of the types in the SYS_MESSAGE enum *and* must also
+ set the Reserved field in the message body to SYS_MSG_COOKIE.
+
+ \param p_cds_context - pointer to the CDS Context
+
+ \param pMsg - pointer to the message to be processed.
+
+ \return - CDF_STATUS_SUCCESS - the message was processed successfully.
+
+ CDF_STATUS_E_BADMSG - a bad (unknown type) message was received
+ and subsequently not processed.
+ \sa
+
+ --------------------------------------------------------------------------*/
+CDF_STATUS sys_mc_process_msg(v_CONTEXT_t p_cds_context, cds_msg_t *pMsg);
+
+void wlan_sys_probe(void);
+
+#endif /* WLAN_QCT_SYS_H__ */
diff --git a/core/mac/src/sys/common/src/wlan_qct_sys.c b/core/mac/src/sys/common/src/wlan_qct_sys.c
new file mode 100644
index 0000000..c2c39d1
--- /dev/null
+++ b/core/mac/src/sys/common/src/wlan_qct_sys.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#include <wlan_qct_sys.h>
+#include <cds_api.h>
+#include <sir_types.h> /* needed for tSirRetStatus */
+#include <sir_params.h> /* needed for tSirMbMsg */
+#include <sir_api.h> /* needed for SIR_... message types */
+#include <wni_api.h> /* needed for WNI_... message types */
+#include "ani_global.h"
+#include "wma_types.h"
+#include "sme_api.h"
+#include "mac_init_api.h"
+
+/* Cookie for SYS messages. Note that anyone posting a SYS Message
+ * has to write the COOKIE in the reserved field of the message. The
+ * SYS Module relies on this COOKIE
+ */
+#define SYS_MSG_COOKIE 0xFACE
+
+/* SYS stop timeout 30 seconds */
+#define SYS_STOP_TIMEOUT (30000)
+
+static cdf_event_t g_stop_evt;
+
+CDF_STATUS sys_build_message_header(SYS_MSG_ID sysMsgId, cds_msg_t *pMsg)
+{
+ pMsg->type = sysMsgId;
+ pMsg->reserved = SYS_MSG_COOKIE;
+
+ return (CDF_STATUS_SUCCESS);
+}
+
+void sys_stop_complete_cb(void *pUserData) {
+ cdf_event_t *pStopEvt = (cdf_event_t *) pUserData;
+ CDF_STATUS cdf_status;
+/*-------------------------------------------------------------------------*/
+
+ cdf_status = cdf_event_set(pStopEvt);
+ CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
+
+} /* cds_sys_stop_complete_cback() */
+
+CDF_STATUS sys_stop(v_CONTEXT_t p_cds_context)
+{
+ CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+ cds_msg_t sysMsg;
+
+ /* Initialize the stop event */
+ cdf_status = cdf_event_init(&g_stop_evt);
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ return cdf_status;
+ }
+
+ /* post a message to SYS module in MC to stop SME and MAC */
+ sys_build_message_header(SYS_MSG_ID_MC_STOP, &sysMsg);
+
+ /* Save the user callback and user data */
+ /* finished. */
+ sysMsg.callback = sys_stop_complete_cb;
+ sysMsg.bodyptr = (void *)&g_stop_evt;
+
+ /* post the message.. */
+ cdf_status = cds_mq_post_message(CDS_MQ_ID_SYS, &sysMsg);
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+ cdf_status = CDF_STATUS_E_BADMSG;
+ }
+
+ cdf_status = cdf_wait_single_event(&g_stop_evt, SYS_STOP_TIMEOUT);
+ CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
+
+ cdf_status = cdf_event_destroy(&g_stop_evt);
+ CDF_ASSERT(CDF_IS_STATUS_SUCCESS(cdf_status));
+
+ return (cdf_status);
+}
+
+CDF_STATUS sys_mc_process_msg(v_CONTEXT_t p_cds_context, cds_msg_t *pMsg)
+{
+ CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
+ void *hHal;
+
+ if (NULL == pMsg) {
+ CDF_ASSERT(0);
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "%s: NULL pointer to cds_msg_t", __func__);
+ return CDF_STATUS_E_INVAL;
+ }
+
+ /* All 'new' SYS messages are identified by a cookie in the reserved
+ * field of the message as well as the message type. This prevents
+ * the possibility of overlap in the message types defined for new
+ * SYS messages with the 'legacy' message types. The legacy messages
+ * will not have this cookie in the reserved field
+ */
+ if (SYS_MSG_COOKIE == pMsg->reserved) {
+ /* Process all the new SYS messages.. */
+ switch (pMsg->type) {
+ case SYS_MSG_ID_MC_START:
+ {
+ /* Handling for this message is not needed now so adding
+ *debug print and CDF_ASSERT*/
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ " Received SYS_MSG_ID_MC_START message msgType= %d [0x%08x]",
+ pMsg->type, pMsg->type);
+ CDF_ASSERT(0);
+ break;
+ }
+
+ case SYS_MSG_ID_MC_STOP:
+ {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_INFO,
+ "Processing SYS MC STOP");
+
+ /* get the HAL context... */
+ hHal = cds_get_context(CDF_MODULE_ID_PE);
+ if (NULL == hHal) {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ "%s: Invalid hHal", __func__);
+ } else {
+ cdf_status =
+ sme_stop(hHal,
+ HAL_STOP_TYPE_SYS_DEEP_SLEEP);
+ CDF_ASSERT(CDF_IS_STATUS_SUCCESS
+ (cdf_status));
+
+ cdf_status =
+ mac_stop(hHal,
+ HAL_STOP_TYPE_SYS_DEEP_SLEEP);
+ CDF_ASSERT(CDF_IS_STATUS_SUCCESS
+ (cdf_status));
+
+ ((sysResponseCback) pMsg->
+ callback)((void *)pMsg->bodyptr);
+
+ cdf_status = CDF_STATUS_SUCCESS;
+ }
+ break;
+ }
+
+ /* Process MC thread probe. Just callback to the */
+ /* function that is in the message. */
+ case SYS_MSG_ID_MC_THR_PROBE:
+ {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ " Received SYS_MSG_ID_MC_THR_PROBE message msgType = %d [0x%08x]",
+ pMsg->type, pMsg->type);
+ break;
+ }
+
+ case SYS_MSG_ID_MC_TIMER:
+ {
+ cdf_mc_timer_callback_t timerCB =
+ pMsg->callback;
+
+ if (NULL != timerCB) {
+ timerCB(pMsg->bodyptr);
+ }
+ break;
+ }
+ case SYS_MSG_ID_FTM_RSP:
+ {
+ tpAniSirGlobal mac_ctx = NULL;
+ hHal = cds_get_context(CDF_MODULE_ID_PE);
+ if (NULL == hHal) {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ FL("Invalid hal"));
+ cdf_mem_free(pMsg->bodyptr);
+ break;
+ }
+ mac_ctx = PMAC_STRUCT(hHal);
+ if (NULL == mac_ctx) {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ FL("Invalid mac context"));
+ cdf_mem_free(pMsg->bodyptr);
+ break;
+ }
+ if (NULL == mac_ctx->ftm_msg_processor_callback) {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ FL("callback pointer is NULL"));
+ cdf_mem_free(pMsg->bodyptr);
+ break;
+ }
+ mac_ctx->ftm_msg_processor_callback(
+ (void *)pMsg->bodyptr);
+ cdf_mem_free(pMsg->bodyptr);
+ break;
+ }
+
+ default:
+ {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ "Unknown message type in sys_mc_process_msg() msgType= %d [0x%08x]",
+ pMsg->type, pMsg->type);
+ break;
+ }
+
+ } /* end switch on message type */
+
+ } /* end if cookie set */
+ else {
+ /* Process all 'legacy' messages */
+ switch (pMsg->type) {
+
+ default:
+ {
+ CDF_ASSERT(0);
+
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_ERROR,
+ "Received SYS message cookie with unidentified "
+ "MC message type= %d [0x%08X]",
+ pMsg->type, pMsg->type);
+
+ cdf_status = CDF_STATUS_E_BADMSG;
+ if (pMsg->bodyptr)
+ cdf_mem_free(pMsg->bodyptr);
+ break;
+ }
+ } /* end switch on pMsg->type */
+ } /* end else */
+
+ return (cdf_status);
+}
+
+
+void sys_process_mmh_msg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) {
+ CDS_MQ_ID targetMQ = CDS_MQ_ID_SYS;
+/*-------------------------------------------------------------------------*/
+ /*
+ ** The body of this pMsg is a tSirMbMsg
+ ** Contrary to Gen4, we cannot free it here!
+ ** It is up to the callee to free it
+ */
+
+ if (NULL == pMsg) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "NULL Message Pointer");
+ CDF_ASSERT(0);
+ return;
+ }
+
+ switch (pMsg->type) {
+ /*
+ ** Following messages are routed to SYS
+ */
+ case WNI_CFG_DNLD_REQ:
+ case WNI_CFG_DNLD_CNF:
+ {
+ /* Forward this message to the SYS module */
+ targetMQ = CDS_MQ_ID_SYS;
+
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "Handling for the Message ID %d is removed in SYS\r\n",
+ pMsg->type);
+
+ CDF_ASSERT(0);
+ break;
+ }
+
+ /*
+ ** Following messages are routed to HAL
+ */
+ case WNI_CFG_DNLD_RSP:
+ {
+ /* Forward this message to the HAL module */
+ targetMQ = CDS_MQ_ID_WMA;
+
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "Handling for the Message ID %d is removed as there is no HAL \r\n",
+ pMsg->type);
+
+ CDF_ASSERT(0);
+ break;
+ }
+
+ case WNI_CFG_GET_REQ:
+ case WNI_CFG_SET_REQ:
+ case WNI_CFG_SET_REQ_NO_RSP:
+ case eWNI_SME_SYS_READY_IND:
+ {
+ /* Forward this message to the PE module */
+ targetMQ = CDS_MQ_ID_PE;
+ break;
+ }
+
+ case WNI_CFG_GET_RSP:
+ case WNI_CFG_SET_CNF:
+ {
+ /* Forward this message to the SME module */
+ targetMQ = CDS_MQ_ID_SME;
+ break;
+ }
+
+ default:
+ {
+
+ if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
+ && (pMsg->type <= eWNI_SME_MSG_TYPES_END)) {
+ targetMQ = CDS_MQ_ID_SME;
+ break;
+ }
+
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "Message of ID %d is not yet handled by SYS\r\n",
+ pMsg->type);
+
+ CDF_ASSERT(0);
+ }
+
+ }
+
+ /*
+ ** Post now the message to the appropriate module for handling
+ */
+ if (CDF_STATUS_SUCCESS !=
+ cds_mq_post_message(targetMQ, (cds_msg_t *) pMsg)) {
+ /* Caller doesn't allocate memory for the pMsg. It allocate memory for bodyptr */
+ /* free the mem and return */
+ if (pMsg->bodyptr) {
+ cdf_mem_free(pMsg->bodyptr);
+ }
+ }
+
+} /* sys_process_mmh_msg() */
+
+void wlan_sys_probe(void)
+{
+ cds_msg_t cds_message;
+
+ cds_message.reserved = SYS_MSG_COOKIE;
+ cds_message.type = SYS_MSG_ID_MC_THR_PROBE;
+ cds_message.bodyptr = NULL;
+
+ cds_mq_post_message(CDS_MQ_ID_SYS, &cds_message);
+
+ return;
+}
diff --git a/core/mac/src/sys/legacy/src/platform/inc/sys_wrapper.h b/core/mac/src/sys/legacy/src/platform/inc/sys_wrapper.h
new file mode 100644
index 0000000..6aeb635
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/platform/inc/sys_wrapper.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * @file VossWrapper.h
+ *
+ * @brief This header file contains the various structure definitions and
+ * function prototypes for the RTOS abstraction layer, implemented for VOSS
+ */
+
+#ifndef __VOSS_WRAPPER_H
+#define __VOSS_WRAPPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*---------------------------------------------------------------------------
+ * Include Files
+ * ------------------------------------------------------------------------*/
+
+#include "sir_types.h"
+#include "sir_params.h"
+#include "sys_def.h"
+#include "cdf_mc_timer.h"
+#include "cdf_types.h"
+#include "cdf_trace.h"
+#include "cdf_memory.h"
+
+/* Interlocked Compare Exchange related definitions */
+
+/* Define basic constants for the ThreadX kernel. */
+
+#define TX_NO_WAIT 0
+#define TX_WAIT_FOREVER 0xFFFFFFFFUL
+#define TX_AUTO_ACTIVATE 1
+#define TX_NO_ACTIVATE 0
+
+/* API return values. */
+#define TX_SUCCESS 0x00
+#define TX_QUEUE_FULL 0x01
+/* ... */
+#define TX_NO_INSTANCE 0x0D
+/* ... */
+#define TX_TIMER_ERROR 0x15
+#define TX_TICK_ERROR 0x16
+/* ... */
+
+#ifndef true
+#define true 1
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+/* Following macro specifies the number of milliseconds which constitute 1 ThreadX timer tick. Used
+ for mimicking the ThreadX timer behaviour on VOSS. */
+/* Use the same MACRO used by firmware modules to calculate TICKs from mSec */
+/* Mismatch would cause worng timer value to be programmed */
+#define TX_MSECS_IN_1_TICK SYS_TICK_DUR_MS
+
+/* Signature with which the TX_TIMER struct is initialized, when the timer is created */
+#define TX_AIRGO_TMR_SIGNATURE 0xDEADBEEF
+
+#ifdef TIMER_MANAGER
+#define tx_timer_create(a, b, c, d, e, f, g) tx_timer_create_intern_debug((void *)pMac, a, b, c, d, e, f, g, __FILE__, __LINE__)
+#else
+#define tx_timer_create(a, b, c, d, e, f, g) tx_timer_create_intern((void *)pMac, a, b, c, d, e, f, g)
+#endif
+
+/*--------------------------------------------------------------------*/
+/* Timer structure */
+/* This structure is used to implement ThreadX timer facility. Just */
+/* like ThreadX, timer expiration handler executes at the highest */
+/* possible priority level, i.e. DISPATCH_LEVEL. */
+/*--------------------------------------------------------------------*/
+typedef struct TX_TIMER_STRUCT {
+#ifdef WLAN_DEBUG
+#define TIMER_MAX_NAME_LEN 50
+ char timerName[TIMER_MAX_NAME_LEN];
+#endif
+ uint64_t tmrSignature;
+ void (*pExpireFunc)(void *, uint32_t);
+ uint32_t expireInput;
+ uint64_t initScheduleTimeInMsecs;
+ uint64_t rescheduleTimeInMsecs;
+ cdf_mc_timer_t cdf_timer;
+
+ /* Pointer to the MAC global structure, which stores the context for the NIC, */
+ /* for which this timer is supposed to operate. */
+ void *pMac;
+ uint8_t sessionId;
+
+} TX_TIMER;
+
+#define TX_TIMER_VALID(timer) (timer.pMac != 0)
+
+extern uint64_t tx_time_get(void);
+extern uint32_t tx_timer_activate(TX_TIMER *);
+extern uint32_t tx_timer_change(TX_TIMER *, uint64_t, uint64_t);
+extern uint32_t tx_timer_change_context(TX_TIMER *, uint32_t);
+#ifdef TIMER_MANAGER
+extern uint32_t tx_timer_create_intern_debug(void *, TX_TIMER *,
+ char *, void (*)(void *,
+ uint32_t),
+ uint32_t, uint64_t,
+ uint64_t, uint64_t,
+ char *fileName,
+ uint32_t lineNum);
+#else
+extern uint32_t tx_timer_create_intern(void *, TX_TIMER *, char *,
+ void (*)(void *, uint32_t),
+ uint32_t, uint64_t, uint64_t,
+ uint64_t);
+#endif
+extern uint32_t tx_timer_deactivate(TX_TIMER *);
+extern uint32_t tx_timer_delete(TX_TIMER *);
+extern bool tx_timer_running(TX_TIMER *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c b/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c
new file mode 100644
index 0000000..4749965
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/platform/src/sys_wrapper.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*===========================================================================
+ @file VossWrapper.c
+
+ @brief This source file contains the various function definitions for the
+ RTOS abstraction layer, implemented for VOSS
+ ===========================================================================*/
+
+/*===========================================================================
+
+ EDIT HISTORY FOR FILE
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+ $Header:$ $DateTime: $ $Author: $
+
+ when who what, where, why
+ -------- --- --------------------------------------------------------
+ 03/31/09 sho Remove the use of cdf_timerIsActive flag as it is not
+ thread-safe
+ 02/17/08 sho Fix the timer callback function to work when it is called
+ after the timer has stopped due to a race condition.
+ 02/10/08 sho Refactor the TX timer to use VOS timer directly instead
+ of using VOS utility timer
+ 12/15/08 sho Resolved errors and warnings from the AMSS compiler when
+ this is ported from WM
+ 11/20/08 sho Renamed this to VosWrapper.c; remove all dependencies on
+ WM platform and allow this to work on all VOSS enabled
+ platform
+ 06/24/08 tbh Modified the file to remove the dependecy on HDD files as
+ part of Gen6 bring up process.
+ 10/29/02 Neelay Das Created file.
+
+ ===========================================================================*/
+
+/*---------------------------------------------------------------------------
+ * Include Files
+ * ------------------------------------------------------------------------*/
+#include "sys_wrapper.h"
+
+#ifdef WLAN_DEBUG
+#define TIMER_NAME (timer_ptr->timerName)
+#else
+#define TIMER_NAME "N/A"
+#endif
+
+/**---------------------------------------------------------------------
+ * tx_time_get()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return current system time in units of miliseconds
+ *
+ */
+uint64_t tx_time_get(void)
+{
+ return (cdf_mc_timer_get_system_ticks());
+
+} /* * tx_time_get() */
+
+/**---------------------------------------------------------------------
+ * tx_timer_activate()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_activate(TX_TIMER *timer_ptr)
+{
+ CDF_STATUS status;
+
+ /* Uncomment the asserts, if the intention is to debug the occurence of the */
+ /* following anomalous cnditions. */
+
+ /* Assert that the timer structure pointer passed, is not NULL */
+ /* dbgAssert(NULL != timer_ptr); */
+
+ /* If the NIC is halting just spoof a successful timer activation, so that all */
+ /* the timers can be cleaned up. */
+
+ if (NULL == timer_ptr)
+ return TX_TIMER_ERROR;
+
+ /* Put a check for the free builds */
+ if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+ CDF_ASSERT(timer_ptr->tmrSignature == 0);
+
+ return TX_TIMER_ERROR;
+
+ }
+ /* Check for an uninitialized timer */
+ CDF_ASSERT(0 != strlen(TIMER_NAME));
+
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "Timer %s being activated\n", TIMER_NAME);
+
+ status = cdf_mc_timer_start(&timer_ptr->cdf_timer,
+ timer_ptr->initScheduleTimeInMsecs);
+
+ if (CDF_STATUS_SUCCESS == status) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "Timer %s now activated\n", TIMER_NAME);
+ return TX_SUCCESS;
+ } else if (CDF_STATUS_E_ALREADY == status) {
+ /* starting timer fails because timer is already started; this is okay */
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "Timer %s is already running\n", TIMER_NAME);
+ return TX_SUCCESS;
+ } else {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "Timer %s fails to activate\n", TIMER_NAME);
+ return TX_TIMER_ERROR;
+ }
+} /*** tx_timer_activate() ***/
+
+/**---------------------------------------------------------------------
+ * tx_timer_change()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_change(TX_TIMER *timer_ptr,
+ uint64_t initScheduleTimeInTicks,
+ uint64_t rescheduleTimeInTicks)
+{
+ /* Put a check for the free builds */
+ if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+ CDF_ASSERT(timer_ptr->tmrSignature == 0);
+
+ return TX_TIMER_ERROR;
+ }
+ /* changes cannot be applied until timer stops running */
+ if (CDF_TIMER_STATE_STOPPED ==
+ cdf_mc_timer_get_current_state(&timer_ptr->cdf_timer)) {
+ timer_ptr->initScheduleTimeInMsecs =
+ TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
+ timer_ptr->rescheduleTimeInMsecs =
+ TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
+ return TX_SUCCESS;
+ } else {
+ return TX_TIMER_ERROR;
+ }
+} /*** tx_timer_change() ***/
+
+/**---------------------------------------------------------------------
+ * tx_timer_change_context()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_change_context(TX_TIMER *timer_ptr,
+ uint32_t expiration_input)
+{
+
+ /* Put a check for the free builds */
+ if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+ CDF_ASSERT(timer_ptr->tmrSignature == 0);
+
+ return TX_TIMER_ERROR;
+ }
+ /* changes cannot be applied until timer stops running */
+ if (CDF_TIMER_STATE_STOPPED ==
+ cdf_mc_timer_get_current_state(&timer_ptr->cdf_timer)) {
+ timer_ptr->expireInput = expiration_input;
+ return TX_SUCCESS;
+ } else {
+ return TX_TIMER_ERROR;
+ }
+} /*** tx_timer_change() ***/
+
+/**---------------------------------------------------------------------
+ * tx_main_timer_func()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return None.
+ *
+ */
+static void tx_main_timer_func(void *functionContext)
+{
+ TX_TIMER *timer_ptr = (TX_TIMER *) functionContext;
+
+ if (NULL == timer_ptr) {
+ CDF_ASSERT(0);
+ return;
+ }
+
+ if (NULL == timer_ptr->pExpireFunc) {
+ CDF_ASSERT(0);
+ return;
+ }
+
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "Timer %s triggered", TIMER_NAME);
+
+ /* Now call the actual timer function, taking the function pointer, */
+ /* from the timer structure. */
+ (*timer_ptr->pExpireFunc)(timer_ptr->pMac, timer_ptr->expireInput);
+
+ /* check if this needs to be rescheduled */
+ if (0 != timer_ptr->rescheduleTimeInMsecs) {
+ CDF_STATUS status;
+ status = cdf_mc_timer_start(&timer_ptr->cdf_timer,
+ timer_ptr->rescheduleTimeInMsecs);
+ timer_ptr->rescheduleTimeInMsecs = 0;
+
+ if (CDF_STATUS_SUCCESS != status) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_WARN,
+ "Unable to reschedule timer %s; status=%d",
+ TIMER_NAME, status);
+ }
+ }
+} /*** tx_timer_change() ***/
+
+#ifdef TIMER_MANAGER
+uint32_t tx_timer_create_intern_debug(void *pMacGlobal,
+ TX_TIMER *timer_ptr, char *name_ptr,
+ void (*expiration_function)(void *,
+ uint32_t),
+ uint32_t expiration_input,
+ uint64_t initScheduleTimeInTicks,
+ uint64_t rescheduleTimeInTicks,
+ uint64_t auto_activate, char *fileName,
+ uint32_t lineNum)
+{
+ CDF_STATUS status;
+
+ if (NULL == expiration_function) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "NULL timer expiration");
+ CDF_ASSERT(0);
+ return TX_TIMER_ERROR;
+ }
+
+ if (NULL == name_ptr) {
+
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "NULL name pointer for timer");
+ CDF_ASSERT(0);
+ return TX_TIMER_ERROR;
+ }
+ if (!initScheduleTimeInTicks)
+ return TX_TICK_ERROR;
+
+ if (!timer_ptr)
+ return TX_TIMER_ERROR;
+
+ /* Initialize timer structure */
+ timer_ptr->pExpireFunc = expiration_function;
+ timer_ptr->expireInput = expiration_input;
+ timer_ptr->initScheduleTimeInMsecs =
+ TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
+ timer_ptr->rescheduleTimeInMsecs =
+ TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
+ timer_ptr->pMac = pMacGlobal;
+
+ /* Set the flag indicating that the timer was created */
+ timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE;
+
+#ifdef WLAN_DEBUG
+ /* Store the timer name */
+ strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName));
+#endif /* Store the timer name, for Debug build only */
+
+ status =
+ cdf_mc_timer_init_debug(&timer_ptr->cdf_timer, CDF_TIMER_TYPE_SW,
+ tx_main_timer_func, (void *) timer_ptr,
+ fileName, lineNum);
+ if (CDF_STATUS_SUCCESS != status) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "Cannot create timer for %s\n", TIMER_NAME);
+ return TX_TIMER_ERROR;
+ }
+
+ if (0 != rescheduleTimeInTicks) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "Creating periodic timer for %s\n", TIMER_NAME);
+ }
+ /* Activate this timer if required */
+ if (auto_activate) {
+ tx_timer_activate(timer_ptr);
+ }
+
+ return TX_SUCCESS;
+
+} /* ** tx_timer_create() *** / */
+#else
+uint32_t tx_timer_create_intern(void *pMacGlobal, TX_TIMER *timer_ptr,
+ char *name_ptr,
+ void (*expiration_function)(void *,
+ uint32_t),
+ uint32_t expiration_input,
+ uint64_t initScheduleTimeInTicks,
+ uint64_t rescheduleTimeInTicks,
+ uint64_t auto_activate)
+{
+ CDF_STATUS status;
+
+ if ((NULL == name_ptr) || (NULL == expiration_function))
+ return TX_TIMER_ERROR;
+
+ if (!initScheduleTimeInTicks)
+ return TX_TICK_ERROR;
+
+ if (!timer_ptr)
+ return TX_TIMER_ERROR;
+
+ /* Initialize timer structure */
+ timer_ptr->pExpireFunc = expiration_function;
+ timer_ptr->expireInput = expiration_input;
+ timer_ptr->initScheduleTimeInMsecs =
+ TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
+ timer_ptr->rescheduleTimeInMsecs =
+ TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
+ timer_ptr->pMac = pMacGlobal;
+
+ /* Set the flag indicating that the timer was created */
+ timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE;
+
+#ifdef WLAN_DEBUG
+ /* Store the timer name */
+ strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName));
+#endif /* Store the timer name, for Debug build only */
+
+ status = cdf_mc_timer_init(&timer_ptr->cdf_timer, CDF_TIMER_TYPE_SW,
+ tx_main_timer_func, (void *) timer_ptr);
+ if (CDF_STATUS_SUCCESS != status) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_ERROR,
+ "Cannot create timer for %s\n", TIMER_NAME);
+ return TX_TIMER_ERROR;
+ }
+
+ if (0 != rescheduleTimeInTicks) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "Creating periodic timer for %s\n", TIMER_NAME);
+ }
+ /* Activate this timer if required */
+ if (auto_activate) {
+ tx_timer_activate(timer_ptr);
+ }
+
+ return TX_SUCCESS;
+
+} /* ** tx_timer_create() *** / */
+#endif
+
+/**---------------------------------------------------------------------
+ * tx_timer_deactivate()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+uint32_t tx_timer_deactivate(TX_TIMER *timer_ptr)
+{
+ CDF_STATUS vStatus;
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "tx_timer_deactivate() called for timer %s\n", TIMER_NAME);
+
+ /* Put a check for the free builds */
+ if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+ return TX_TIMER_ERROR;
+ }
+ /* if the timer is not running then we do not need to do anything here */
+ vStatus = cdf_mc_timer_stop(&timer_ptr->cdf_timer);
+ if (CDF_STATUS_SUCCESS != vStatus) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO_HIGH,
+ "Unable to stop timer %s; status =%d\n",
+ TIMER_NAME, vStatus);
+ }
+
+ return TX_SUCCESS;
+
+} /*** tx_timer_deactivate() ***/
+
+uint32_t tx_timer_delete(TX_TIMER *timer_ptr)
+{
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "tx_timer_delete() called for timer %s\n", TIMER_NAME);
+
+ /* Put a check for the free builds */
+ if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
+ return TX_TIMER_ERROR;
+ }
+
+ cdf_mc_timer_destroy(&timer_ptr->cdf_timer);
+ return TX_SUCCESS;
+} /*** tx_timer_delete() ***/
+
+/**---------------------------------------------------------------------
+ * tx_timer_running()
+ *
+ * FUNCTION:
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param
+ *
+ * @return TX_SUCCESS.
+ *
+ */
+bool tx_timer_running(TX_TIMER *timer_ptr)
+{
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO,
+ "tx_timer_running() called for timer %s\n", TIMER_NAME);
+
+ /* Put a check for the free builds */
+ if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature)
+ return false;
+
+ if (CDF_TIMER_STATE_RUNNING ==
+ cdf_mc_timer_get_current_state(&timer_ptr->cdf_timer)) {
+ return true;
+ }
+ return false;
+
+} /*** tx_timer_running() ***/
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_debug.h b/core/mac/src/sys/legacy/src/system/inc/sys_debug.h
new file mode 100644
index 0000000..4a25788
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_debug.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sys_global.h contains the logDump utility for system module.
+ * Author: V. K. Kandarpa
+ * Date: 01/24/2002
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __SYS_DEBUG_H__
+#define __SYS_DEBUG_H__
+
+#include <stdarg.h>
+#include "utils_api.h"
+#include "sir_debug.h"
+#include "sir_params.h"
+
+void sys_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...);
+
+#endif /* __SYS_DEBUG_H__ */
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_def.h b/core/mac/src/sys/legacy/src/system/inc/sys_def.h
new file mode 100644
index 0000000..abdae33
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_def.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sys_def.h contains the common definitions used to bring up
+ * Sirius system.
+ * Author: V. K. Kandarpa
+ * Date: 04/13/2002
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#ifndef __SYSDEF_H
+#define __SYSDEF_H
+
+/* / Sirius system level definitions */
+/* NOTE: Do not program system timer tick duration to less than 1msec */
+
+/* / System timer tick duration in nanoseconds */
+#define SYS_TICK_DUR_NS 10000000 /* 10ms */
+#define SYS_TICK_TO_MICRO_SECOND 10000
+
+/* / System timer tick duration in milliseconds */
+#define SYS_TICK_DUR_MS (SYS_TICK_DUR_NS/1000000)
+
+/* / Clocks in a millisecond */
+#define SYS_CLOCKS_PER_MS 120000 /* 120 MHz */
+
+/* / System timer tick duration in clocks */
+#define SYS_TICK_DUR_CLK (SYS_TICK_DUR_MS * SYS_CLOCKS_PER_MS)
+
+/* / Number of timer ticks in a second */
+#define SYS_TICKS_PER_SECOND (1000/SYS_TICK_DUR_MS)
+
+/* / Macro to convert MS to Ticks */
+#define SYS_MS_TO_TICKS(x) ((x) / SYS_TICK_DUR_MS)
+
+/* / Macro to convert Seconds to Ticks */
+#define SYS_SEC_TO_TICKS(x) ((x) * SYS_TICKS_PER_SECOND)
+
+/* / Macro to convert Minutes to Ticks */
+#define SYS_MIN_TO_TICKS(x) (((x) * 60) * SYS_TICKS_PER_SECOND)
+
+/* / MNT task processing interval in seconds */
+#define SYS_MNT_INTERVAL 60
+
+/* / MS to Time Units */
+#define SYS_MS_TO_TU(x) ((x * 1000) >> 10)
+
+/* / TU to MS */
+#define SYS_TU_TO_MS(x) ((x << 10) / 1000)
+
+/* --------- End of Windows & RTAI ----------- */
+
+/* / Message queue definitions */
+
+/* / gHalMsgQ */
+#define SYS_HAL_Q_SIZE 200 /* Holds up to 25 messages */
+
+/* / gMMHhiPriorityMsgQ */
+#define SYS_MMH_HI_PRI_Q_SIZE 200 /* Holds up to 25 messages */
+
+/* / gMMHprotocolMsgQ */
+#define SYS_MMH_PROT_Q_SIZE 400 /* Holds up to 50 messages */
+
+/* / gMMHdebugMsgQ */
+#define SYS_MMH_DEBUG_Q_SIZE 800 /* Holds up to 100 messages */
+
+/* / gMAINTmsgQ */
+#define SYS_MNT_Q_SIZE 200 /* Holds up to 25 messages */
+
+/* / LIM Message Queue */
+#define SYS_LIM_Q_SIZE 400 /* Holds up to 50 messages */
+
+/* / Scheduler Message Queue */
+#define SYS_SCH_Q_SIZE 800 /* Holds up to 25 messages */
+
+/* / PMM Message Queue */
+#define SYS_PMM_Q_SIZE 800 /* Holds up to 100 messages */
+
+/* / TX Message Queue */
+#define SYS_TX_Q_SIZE 2048 /* Holds up to 400 messages */
+
+/* / RX Message Queue */
+#define SYS_RX_Q_SIZE 2048 /* Holds up to 400 messages */
+
+/* / PTT Message Queue */
+#define SYS_NIM_PTT_Q_SIZE 200 /* Holds up to 25 messages */
+
+/* / Thread definitions */
+/* tHAL */
+
+#define SYS_HAL_THREAD_ENTRY_FUNCTION halEntry
+#define SYS_HAL_STACK_SIZE 8192
+#define SYS_HAL_THREAD_PRIORITY 2
+
+/* tDPH */
+
+#define SYS_DPH_THREAD_ENTRY_FUNCTION dphEntry
+#define SYS_DPH_STACK_SIZE 8192
+#define SYS_DPH_THREAD_PRIORITY 15
+
+/* tBBT */
+
+#define SYS_BBT_THREAD_ENTRY_FUNCTION bbtEntry
+#define SYS_BBT_STACK_SIZE 8192
+#define SYS_BBT_THREAD_PRIORITY 16
+
+/* tSCH */
+
+#define SYS_SCH_STACK_SIZE 8192
+#define SYS_SCH_THREAD_PRIORITY 17
+
+/* tPMM */
+
+#define SYS_PMM_STACK_SIZE 8192
+#define SYS_PMM_THREAD_PRIORITY 17
+
+/* tLIM */
+
+#define SYS_LIM_THREAD_ENTRY_FUNCTION limEntry
+#define SYS_LIM_STACK_SIZE 8192
+#define SYS_LIM_THREAD_PRIORITY 18
+
+/* tMAINT */
+
+#define SYS_MNT_THREAD_ENTRY_FUNCTION mntEntry
+#define SYS_MNT_STACK_SIZE 8192
+#define SYS_MNT_THREAD_PRIORITY 25
+
+/* tMMH */
+
+#define SYS_MMH_THREAD_ENTRY_FUNCTION mmhEntry
+#define SYS_MMH_STACK_SIZE 8192
+#define SYS_MMH_THREAD_PRIORITY 10
+
+/* tNIM_MNT_PKT_GEN */
+
+#define SYS_NIM_PTT_THREAD_STACK_SIZE 8192
+#define SYS_NIM_PTT_THREAD_PRIORITY 28
+
+#endif /* __SYSDEF_H */
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_entry_func.h b/core/mac/src/sys/legacy/src/system/inc/sys_entry_func.h
new file mode 100644
index 0000000..41afc8b
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_entry_func.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011-2012, 2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file sys_entry_func.h contains module entry functions definitions
+ * Author: V. K. Kandarpa
+ * Date: 04/13/2002
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+#ifndef __SYS_ENTRY_FUNC_H
+#define __SYS_ENTRY_FUNC_H
+
+#include "ani_global.h"
+
+extern tSirRetStatus sys_init_globals(tpAniSirGlobal);
+extern void sysBbtEntry(uint32_t dummy);
+extern void sysSchEntry(uint32_t dummy);
+extern void sysPmmEntry(uint32_t dummy);
+extern void sysDphEntry(uint32_t dummy);
+extern void sysLimEntry(uint32_t dummy);
+extern void sysMmhEntry(uint32_t dummy);
+extern void sysMntEntry(uint32_t dummy);
+extern void sysHalEntry(uint32_t dummy);
+extern void sysNimPttEntry(uint32_t dummy);
+
+#endif /* __SYS_ENTRY_FUNC_H */
diff --git a/core/mac/src/sys/legacy/src/system/inc/sys_startup.h b/core/mac/src/sys/legacy/src/system/inc/sys_startup.h
new file mode 100644
index 0000000..e56bd61
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/inc/sys_startup.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * sys_startup.h: System startup header file.
+ * Author: V. K. Kandarpa
+ * Date: 01/29/2002
+ *
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SYSSTARTUP_H
+#define __SYSSTARTUP_H
+
+#include "sir_params.h"
+
+/* Defines */
+
+/* Function */
+
+extern void sysMACCleanup(void *);
+extern tSirRetStatus sys_bbt_process_message_core(struct sAniSirGlobal *, tpSirMsgQ,
+ uint32_t, uint32_t);
+
+#endif /* __SYSSTARTUP_H */
diff --git a/core/mac/src/sys/legacy/src/system/src/mac_init_api.c b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
new file mode 100644
index 0000000..5c0877a
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * mac_init_api.c - This file has all the mac level init functions
+ * for all the defined threads at system level.
+ * Author: Dinesh Upadhyay
+ * Date: 04/23/2007
+ * History:-
+ * Date: 04/08/2008 Modified by: Santosh Mandiganal
+ * Modification Information: Code to allocate and free the memory for DumpTable entry.
+ * --------------------------------------------------------------------------
+ *
+ */
+/* Standard include files */
+#include "cfg_api.h" /* cfg_cleanup */
+#include "lim_api.h" /* lim_cleanup */
+#include "sir_types.h"
+#include "sys_debug.h"
+#include "sys_entry_func.h"
+#include "mac_init_api.h"
+
+#ifdef TRACE_RECORD
+#include "mac_trace.h"
+#endif
+
+extern tSirRetStatus halDoCfgInit(tpAniSirGlobal pMac);
+extern tSirRetStatus halProcessStartEvent(tpAniSirGlobal pMac);
+
+tSirRetStatus mac_start(tHalHandle hHal, void *pHalMacStartParams)
+{
+ tSirRetStatus status = eSIR_SUCCESS;
+ tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
+
+ if (NULL == pMac) {
+ CDF_ASSERT(0);
+ status = eSIR_FAILURE;
+ return status;
+ }
+
+ pMac->gDriverType =
+ ((tHalMacStartParameters *) pHalMacStartParams)->driverType;
+
+ sys_log(pMac, LOG2, FL("called\n"));
+
+ if (ANI_DRIVER_TYPE(pMac) != eDRIVER_TYPE_MFG) {
+ status = pe_start(pMac);
+ }
+
+ return status;
+}
+
+/** -------------------------------------------------------------
+ \fn mac_stop
+ \brief this function will be called from HDD to stop MAC. This function will stop all the mac modules.
+ \ memory with global context will only be initialized not freed here.
+ \param tHalHandle hHal
+ \param tHalStopType
+ \return tSirRetStatus
+ -------------------------------------------------------------*/
+
+tSirRetStatus mac_stop(tHalHandle hHal, tHalStopType stopType)
+{
+ tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
+ pe_stop(pMac);
+ cfg_cleanup(pMac);
+
+ return eSIR_SUCCESS;
+}
+
+/** -------------------------------------------------------------
+ \fn mac_open
+ \brief this function will be called during init. This function is suppose to allocate all the
+ \ memory with the global context will be allocated here.
+ \param tHalHandle pHalHandle
+ \param tHddHandle hHdd
+ \param tHalOpenParameters* pHalOpenParams
+ \return tSirRetStatus
+ -------------------------------------------------------------*/
+
+tSirRetStatus mac_open(tHalHandle *pHalHandle, tHddHandle hHdd,
+ tMacOpenParameters *pMacOpenParms)
+{
+ tpAniSirGlobal p_mac = NULL;
+ tSirRetStatus status = eSIR_SUCCESS;
+
+ if (pHalHandle == NULL)
+ return eSIR_FAILURE;
+
+ /*
+ * Make sure this adapter is not already opened. (Compare pAdapter pointer in already
+ * allocated p_mac structures.)
+ * If it is opened just return pointer to previously allocated p_mac pointer.
+ * Or should this result in error?
+ */
+
+ /* Allocate p_mac */
+ p_mac = cdf_mem_malloc(sizeof(tAniSirGlobal));
+ if (NULL == p_mac)
+ return eSIR_MEM_ALLOC_FAILED;
+
+ /* Initialize the p_mac structure */
+ cdf_mem_set(p_mac, sizeof(tAniSirGlobal), 0);
+
+ /*
+ * Set various global fields of p_mac here
+ * (Could be platform dependant as some variables in p_mac are platform
+ * dependant)
+ */
+ p_mac->hHdd = hHdd;
+ *pHalHandle = (tHalHandle) p_mac;
+
+ {
+ /* Call various PE (and other layer init here) */
+ if (eSIR_SUCCESS != log_init(p_mac)) {
+ cdf_mem_free(p_mac);
+ return eSIR_FAILURE;
+ }
+
+ /* Call routine to initialize CFG data structures */
+ if (eSIR_SUCCESS != cfg_init(p_mac)) {
+ cdf_mem_free(p_mac);
+ return eSIR_FAILURE;
+ }
+
+ sys_init_globals(p_mac);
+ }
+
+ /* FW: 0 to 2047 and Host: 2048 to 4095 */
+ p_mac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN - 1;
+ p_mac->first_scan_done = false;
+
+ status = pe_open(p_mac, pMacOpenParms);
+ if (eSIR_SUCCESS != status) {
+ sys_log(p_mac, LOGE, FL("mac_open failure\n"));
+ cdf_mem_free(p_mac);
+ }
+
+ return status;
+}
+
+/** -------------------------------------------------------------
+ \fn mac_close
+ \brief this function will be called in shutdown sequence from HDD. All the
+ \ allocated memory with global context will be freed here.
+ \param tpAniSirGlobal pMac
+ \return none
+ -------------------------------------------------------------*/
+
+tSirRetStatus mac_close(tHalHandle hHal)
+{
+
+ tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
+
+ if (!pMac)
+ return eSIR_FAILURE;
+
+ pe_close(pMac);
+
+ /* Call routine to free-up all CFG data structures */
+ cfg_de_init(pMac);
+
+ log_deinit(pMac);
+
+ /* Finally, de-allocate the global MAC datastructure: */
+ cdf_mem_free(pMac);
+
+ return eSIR_SUCCESS;
+}
diff --git a/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c b/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
new file mode 100644
index 0000000..304ab3e
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/system/src/sys_entry_func.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * sys_entry_func.cc - This file has all the system level entry functions
+ * for all the defined threads at system level.
+ * Author: V. K. Kandarpa
+ * Date: 01/16/2002
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------------
+ *
+ */
+/* Standard include files */
+
+/* Application Specific include files */
+#include "sir_common.h"
+#include "ani_global.h"
+
+#include "lim_api.h"
+#include "sch_api.h"
+#include "utils_api.h"
+
+#include "sys_debug.h"
+#include "sys_def.h"
+#include "sys_entry_func.h"
+#include "sys_startup.h"
+#include "lim_trace.h"
+#include "wma_types.h"
+
+tSirRetStatus postPTTMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
+
+#include "cdf_types.h"
+#include "cds_packet.h"
+
+#define MAX_DEAUTH_ALLOWED 5
+/* --------------------------------------------------------------------------- */
+/**
+ * sys_init_globals
+ *
+ * FUNCTION:
+ * Initializes system level global parameters
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ *
+ * NOTE:
+ *
+ * @param tpAniSirGlobal Sirius software parameter struct pointer
+ * @return None
+ */
+
+tSirRetStatus sys_init_globals(tpAniSirGlobal pMac)
+{
+
+ cdf_mem_set((uint8_t *) &pMac->sys, sizeof(pMac->sys), 0);
+
+ pMac->sys.gSysEnableScanMode = 1;
+ pMac->sys.gSysEnableLinkMonitorMode = 0;
+ sch_init_globals(pMac);
+
+ return eSIR_SUCCESS;
+}
+
+/**
+ * sys_bbt_process_message_core() - to process BBT messages
+ * @mac_ctx: pointer to mac context
+ * @msg: message pointer
+ * @type: type of persona
+ * @subtype: subtype of persona
+ *
+ * This routine is to process some bbt messages
+ *
+ * Return: None
+ */
+tSirRetStatus
+sys_bbt_process_message_core(tpAniSirGlobal mac_ctx, tpSirMsgQ msg,
+ uint32_t type, uint32_t subtype)
+{
+ uint32_t framecount;
+ tSirRetStatus ret;
+ void *bd_ptr;
+ tMgmtFrmDropReason dropreason;
+ cds_pkt_t *vos_pkt = (cds_pkt_t *) msg->bodyptr;
+ CDF_STATUS cdf_status =
+ wma_ds_peek_rx_packet_info(vos_pkt, &bd_ptr, false);
+ uint8_t sessionid;
+ tpPESession pe_session;
+ tpSirMacMgmtHdr mac_hdr;
+
+ mac_ctx->sys.gSysBbtReceived++;
+
+ if (!CDF_IS_STATUS_SUCCESS(cdf_status))
+ goto fail;
+
+ sys_log(mac_ctx, LOG3, FL("Rx Mgmt Frame Subtype: %d\n"), subtype);
+ sir_dump_buf(mac_ctx, SIR_SYS_MODULE_ID, LOG3,
+ (uint8_t *) WMA_GET_RX_MAC_HEADER(bd_ptr),
+ WMA_GET_RX_MPDU_LEN(bd_ptr));
+ sir_dump_buf(mac_ctx, SIR_SYS_MODULE_ID, LOG3,
+ WMA_GET_RX_MPDU_DATA(bd_ptr),
+ WMA_GET_RX_PAYLOAD_LEN(bd_ptr));
+
+ mac_ctx->sys.gSysFrameCount[type][subtype]++;
+ framecount = mac_ctx->sys.gSysFrameCount[type][subtype];
+
+ if (type == SIR_MAC_MGMT_FRAME) {
+ if (true == mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+ mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
+ pe_session = pe_find_session_by_bssid(mac_ctx,
+ mac_hdr->bssId,
+ &sessionid);
+ if (pe_session &&
+ (pe_session->pePersona == CDF_SAP_MODE)) {
+ CDF_TRACE(CDF_MODULE_ID_SYS,
+ CDF_TRACE_LEVEL_INFO_HIGH,
+ FL("CAC timer is running, dropping the mgmt frame"));
+ goto fail;
+ }
+ }
+
+ /*
+ * Drop beacon frames in deferred state to avoid VOSS run out of
+ * message wrappers.
+ */
+ if ((subtype == SIR_MAC_MGMT_BEACON) &&
+ (!lim_is_system_in_scan_state(mac_ctx)) &&
+ (GET_LIM_PROCESS_DEFD_MESGS(mac_ctx) != true) &&
+ !mac_ctx->lim.gLimSystemInScanLearnMode) {
+ CDF_TRACE(CDF_MODULE_ID_SYS, CDF_TRACE_LEVEL_INFO_HIGH,
+ FL("dropping received beacon in deffered state"));
+ goto fail;
+ }
+
+ dropreason = lim_is_pkt_candidate_for_drop(mac_ctx, bd_ptr,
+ subtype);
+ if (eMGMT_DROP_NO_DROP != dropreason) {
+ sys_log(mac_ctx, LOG1,
+ FL("Mgmt Frame %d being dropped, reason: %d\n"),
+ subtype, dropreason);
+ MTRACE(mac_trace(mac_ctx,
+ TRACE_CODE_RX_MGMT_DROP, NO_SESSION,
+ dropreason);)
+ goto fail;
+ }
+
+ if (subtype == SIR_MAC_MGMT_DEAUTH) {
+ tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
+ sys_log(mac_ctx, LOGE,
+ FL("DEAUTH frame allowed: "
+ "da: " MAC_ADDRESS_STR ", "
+ "sa: " MAC_ADDRESS_STR ", "
+ "bssid: " MAC_ADDRESS_STR ", "
+ "DEAUTH count so far: %d\n"),
+ MAC_ADDR_ARRAY(mac_hdr->da),
+ MAC_ADDR_ARRAY(mac_hdr->sa),
+ MAC_ADDR_ARRAY(mac_hdr->bssId),
+ mac_ctx->sys.gSysFrameCount[type][subtype]);
+ }
+ if (subtype == SIR_MAC_MGMT_DISASSOC) {
+ tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(bd_ptr);
+ sys_log(mac_ctx, LOGE,
+ FL("DISASSOC frame allowed: "
+ "da: " MAC_ADDRESS_STR ", "
+ "sa: " MAC_ADDRESS_STR ", "
+ "bssid: " MAC_ADDRESS_STR ", "
+ "DISASSOC count so far: %d\n"),
+ MAC_ADDR_ARRAY(mac_hdr->da),
+ MAC_ADDR_ARRAY(mac_hdr->sa),
+ MAC_ADDR_ARRAY(mac_hdr->bssId),
+ mac_ctx->sys.gSysFrameCount[type][subtype]);
+ }
+
+ /* Post the message to PE Queue */
+ ret = (tSirRetStatus) lim_post_msg_api(mac_ctx, msg);
+ if (ret != eSIR_SUCCESS) {
+ sys_log(mac_ctx, LOGE,
+ FL("posting to LIM2 failed, ret %d\n"), ret);
+ goto fail;
+ }
+ mac_ctx->sys.gSysBbtPostedToLim++;
+ } else if (type == SIR_MAC_DATA_FRAME) {
+#ifdef FEATURE_WLAN_ESE
+ PELOGW(sys_log(mac_ctx, LOGW, FL("IAPP Frame...\n")););
+ /* Post the message to PE Queue */
+ ret = (tSirRetStatus) lim_post_msg_api(mac_ctx, msg);
+ if (ret != eSIR_SUCCESS) {
+ sys_log(mac_ctx, LOGE,
+ FL("posting to LIM2 failed, ret %d\n"), ret);
+ goto fail;
+ }
+ mac_ctx->sys.gSysBbtPostedToLim++;
+#endif
+ } else {
+ sys_log(mac_ctx, LOG3,
+ "BBT received Invalid type %d subtype %d "
+ "LIM state %X. BD dump is:\n", type, subtype,
+ lim_get_sme_state(mac_ctx));
+ goto fail;
+ }
+ return eSIR_SUCCESS;
+fail:
+ mac_ctx->sys.gSysBbtDropped++;
+ return eSIR_FAILURE;
+}
+
+void sys_log(tpAniSirGlobal pMac, uint32_t loglevel, const char *pString, ...)
+{
+ /* Verify against current log level */
+ if (loglevel >
+ pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_SYS_MODULE_ID)])
+ return;
+ else {
+ va_list marker;
+
+ va_start(marker, pString); /* Initialize variable arguments. */
+
+ log_debug(pMac, SIR_SYS_MODULE_ID, loglevel, pString, marker);
+
+ va_end(marker); /* Reset variable arguments. */
+ }
+}
diff --git a/core/mac/src/sys/legacy/src/utils/inc/dot11fdefs.h b/core/mac/src/sys/legacy/src/utils/inc/dot11fdefs.h
new file mode 100644
index 0000000..8cc4e97
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/inc/dot11fdefs.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011-2012, 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+#ifndef DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582
+#define DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582
+/**
+ * \file dot11fdefs.h
+ *
+ * \brief C defines customizing our framesc-generated code
+ *
+ *
+ *
+ *
+ * 'framesc' generates code written in terms of a number of macros
+ * intended for customization.
+ *
+ *
+ */
+
+#include "parser_api.h"
+
+/* This controls how the "dot11f" code copies memory */
+#define DOT11F_MEMCPY(ctx, dst, src, len) \
+ cdf_mem_copy((uint8_t *)(dst), (uint8_t *)(src), (len))
+
+/* This controls how the "dot11f" code compares memory */
+#define DOT11F_MEMCMP(ctx, lhs, rhs, len) \
+ (!cdf_mem_compare((uint8_t *)(lhs), (uint8_t *)(rhs), (len)))
+
+#if defined(DBG) && (DBG != 0)
+
+# /* define DOT11F_ENABLE_LOGGING */
+# /* define DOT11F_DUMP_FRAMES */
+#define DOT11F_LOG_GATE (4)
+#define FRAMES_SEV_FOR_FRAME(ctx, sig) \
+ (DOT11F_ASSOCREQUEST == (sig) ? 3 : 5)
+
+#if defined(DOT11F_ENABLE_LOGGING)
+
+#define DOT11F_HAVE_LOG_MACROS
+
+#define FRAMES_LOG0(ctx, sev, fmt) \
+ dot11f_log((ctx), (sev), (fmt));
+
+#define FRAMES_LOG1(ctx, sev, fmt, p1) \
+ dot11f_log((ctx), (sev), (fmt), (p1));
+
+#define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \
+ dot11f_log((ctx), (sev), (fmt), (p1), (p2));
+
+#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \
+ dot11f_log((ctx), (sev), (fmt), (p1), (p2), (p3));
+
+#define FRAMES_DUMP(ctx, sev, p, n) \
+ sir_dump_buf((pCtx), SIR_DBG_MODULE_ID, (sev), (p), (n));
+
+#endif /* #if defined( DOT11F_ENABLE_LOGGING ) */
+
+#else
+
+#undef DOT11F_ENABLE_LOGGING
+#undef DOT11F_DUMP_FRAMES
+#define DOT11F_LOG_GATE (1)
+
+#endif
+
+/* #define DOT11F_ENABLE_DBG_BREAK ( 1 ) */
+
+/* Local Variables: */
+/* fill-column: 72 */
+/* indent-tabs-mode: nil */
+/* show-trailing-whitespace: t */
+/* End: */
+
+#endif /* DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 */
diff --git a/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h b/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
new file mode 100644
index 0000000..3b63a0d
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/inc/utils_parser.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file utils_parser.h contains the utility function protos
+ * used internally by the parser
+ * Author: Chandra Modumudi
+ * Date: 02/11/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+#ifndef __UTILS_PARSE_H__
+#define __UTILS_PARSE_H__
+
+#include <stdarg.h>
+#include "sir_api.h"
+#include "dot11f.h"
+#include "utils_api.h"
+
+void convert_ssid(tpAniSirGlobal, tSirMacSSid *, tDot11fIESSID *);
+void convert_supp_rates(tpAniSirGlobal, tSirMacRateSet *, tDot11fIESuppRates *);
+void convert_fh_params(tpAniSirGlobal, tSirMacFHParamSet *,
+ tDot11fIEFHParamSet *);
+void convert_ext_supp_rates(tpAniSirGlobal, tSirMacRateSet *,
+ tDot11fIEExtSuppRates *);
+void convert_qos_caps(tpAniSirGlobal, tSirMacQosCapabilityIE *,
+ tDot11fIEQOSCapsAp *);
+void convert_qos_caps_station(tpAniSirGlobal, tSirMacQosCapabilityStaIE *,
+ tDot11fIEQOSCapsStation *);
+tSirRetStatus convert_wpa(tpAniSirGlobal, tSirMacWpaInfo *, tDot11fIEWPA *);
+tSirRetStatus convert_wpa_opaque(tpAniSirGlobal, tSirMacWpaInfo *,
+ tDot11fIEWPAOpaque *);
+tSirRetStatus convert_wapi_opaque(tpAniSirGlobal, tSirMacWapiInfo *,
+ tDot11fIEWAPIOpaque *);
+tSirRetStatus convert_rsn(tpAniSirGlobal, tSirMacRsnInfo *, tDot11fIERSN *);
+tSirRetStatus convert_rsn_opaque(tpAniSirGlobal, tSirMacRsnInfo *,
+ tDot11fIERSNOpaque *);
+void convert_power_caps(tpAniSirGlobal, tSirMacPowerCapabilityIE *,
+ tDot11fIEPowerCaps *);
+void convert_supp_channels(tpAniSirGlobal, tSirMacSupportedChannelIE *,
+ tDot11fIESuppChannels *);
+void convert_cf_params(tpAniSirGlobal, tSirMacCfParamSet *, tDot11fIECFParams *);
+void convert_tim(tpAniSirGlobal, tSirMacTim *, tDot11fIETIM *);
+void convert_country(tpAniSirGlobal, tSirCountryInformation *,
+ tDot11fIECountry *);
+void convert_wmm_params(tpAniSirGlobal, tSirMacEdcaParamSetIE *,
+ tDot11fIEWMMParams *);
+void convert_erp_info(tpAniSirGlobal, tSirMacErpInfo *, tDot11fIEERPInfo *);
+void convert_edca_param(tpAniSirGlobal, tSirMacEdcaParamSetIE *,
+ tDot11fIEEDCAParamSet *);
+void convert_tspec(tpAniSirGlobal, tSirMacTspecIE *, tDot11fIETSPEC *);
+tSirRetStatus convert_tclas(tpAniSirGlobal, tSirTclasInfo *, tDot11fIETCLAS *);
+void convert_wmmtspec(tpAniSirGlobal, tSirMacTspecIE *, tDot11fIEWMMTSPEC *);
+tSirRetStatus convert_wmmtclas(tpAniSirGlobal, tSirTclasInfo *,
+ tDot11fIEWMMTCLAS *);
+void convert_ts_delay(tpAniSirGlobal, tSirMacTsDelayIE *, tDot11fIETSDelay *);
+void convert_schedule(tpAniSirGlobal, tSirMacScheduleIE *, tDot11fIESchedule *);
+void convert_wmm_schedule(tpAniSirGlobal, tSirMacScheduleIE *,
+ tDot11fIEWMMSchedule *);
+tSirRetStatus convert_wsc_opaque(tpAniSirGlobal, tSirAddie *,
+ tDot11fIEWscIEOpaque *);
+tSirRetStatus convert_p2p_opaque(tpAniSirGlobal, tSirAddie *,
+ tDot11fIEP2PIEOpaque *);
+#ifdef WLAN_FEATURE_WFD
+tSirRetStatus convert_wfd_opaque(tpAniSirGlobal, tSirAddie *,
+ tDot11fIEWFDIEOpaque *);
+#endif
+void convert_qos_mapset_frame(tpAniSirGlobal, tSirQosMapSet *,
+ tDot11fIEQosMapSet *);
+
+#endif
diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
new file mode 100644
index 0000000..6286a01
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
@@ -0,0 +1,21682 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+ /*
+ * \file dot11f.c
+ *
+ * \brief Structures, functions & definitions for
+ * working with 802.11 Frames
+ *
+ *
+ * This file was automatically generated by 'framesc'
+ * Wed Oct 14 10:14:42 2015 from the following file(s):
+ *
+ * dot11f.frms
+ *
+ * PLEASE DON'T EDIT THIS FILE BY HAND!
+ *
+ */
+
+#if !defined ANI_OS_TYPE_OSX && !defined ANI_OS_TYPE_LINUX && !defined ANI_OS_TYPE_ANDROID
+#include <memory.h> /* For memcpy */
+#include <stdio.h> /* For _vsnprintf */
+#include <stddef.h> /* For offsetof */
+#endif
+
+#include <ani_global.h>
+#include <utils_api.h>
+#include "dot11fdefs.h"
+#include "dot11f.h"
+
+#if defined(_MSC_VER)
+#pragma warning (disable:4244)
+#pragma warning (disable:4505)
+#pragma warning (disable:4702)
+#pragma warning (disable:4996)/* ... was declared deprecated */
+#endif /* Microsoft C/C++ */
+
+typedef unsigned char tFRAMES_BOOL;
+typedef void (*pfnGeneric_t)(void);
+
+typedef struct sFFDefn {
+ const char *name;
+ uint32_t offset;
+ uint16_t sig;
+ uint8_t size;
+} tFFDefn;
+
+typedef struct sIEDefn {
+ uint32_t offset;
+ uint32_t presenceOffset;
+ uint32_t countOffset;
+ const char *name;
+ uint16_t arraybound;
+ uint16_t minSize;
+ uint16_t maxSize;
+ uint16_t sig;
+ unsigned char oui[5];
+ unsigned char noui;
+ uint8_t eid;
+ tFRAMES_BOOL fMandatory;
+} tIEDefn;
+
+#if !defined(countof)
+#define countof(x) (sizeof((x)) / sizeof((x)[0]))
+#endif
+
+#if !defined(DOT11F_MEMCPY)
+#define DOT11F_MEMCPY(ctx, dst, src, len) \
+ memcpy((dst), (src), (len))
+#endif
+
+#if !defined(DOT11F_MEMCMP)
+#define DOT11F_MEMCMP(ctx, lhs, rhs, len) \
+ memcmp((lhs), (rhs), (len))
+#endif
+
+#ifndef DOT11F_HAVE_LOG_SEVERITIES
+#define FRLOG_OFF (0)
+#define FRLOGP (1)
+#define FRLOGE (2)
+#define FRLOGW (3)
+#define FRLOG1 (4)
+#define FRLOG2 (5)
+#define FRLOG3 (6)
+#define FRLOG4 (7)
+#endif
+
+#define FRFL(x) x
+
+#define FRAMES_LOG0(ctx, sev, fmt)
+#define FRAMES_LOG1(ctx, sev, fmt, p1)
+#define FRAMES_LOG2(ctx, sev, fmt, p1, p2)
+#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3)
+#define FRAMES_DUMP(ctx, sev, p, n)
+#ifndef FRAMES_SEV_FOR_FRAME
+#define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3
+#endif
+
+#if defined(DOT11F_ENABLE_DBG_BREAK) && defined (WIN32)
+#define FRAMES_DBG_BREAK() { _asm int 3 }
+#else
+#define FRAMES_DBG_BREAK()
+#endif
+
+#if !defined(DOT11F_PARAMETER_CHECK)
+#if defined (DOT11F_HAVE_WIN32_API)
+
+#define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \
+ if (!pBuf || IsBadReadPtr(pBuf, nBuf))\
+ return DOT11F_BAD_INPUT_BUFFER; \
+ if (!pFrm || IsBadWritePtr(pFrm, nFrm))\
+ return DOT11F_BAD_OUTPUT_BUFFER \
+
+#define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \
+ if (!pSrc || IsBadReadPtr(pSrc, 4))\
+ eturn DOT11F_BAD_INPUT_BUFFER; \
+ if (!pBuf || IsBadWritePtr(pBuf, nBuf))\
+ return DOT11F_BAD_OUTPUT_BUFFER; \
+ if (!nBuf)\
+ return DOT11F_BAD_OUTPUT_BUFFER; \
+ if (IsBadWritePtr(pnConsumed, 4))\
+ return DOT11F_BAD_OUTPUT_BUFFER \
+
+#else
+
+#define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \
+ if (!pBuf)\
+ return DOT11F_BAD_INPUT_BUFFER; \
+ if (!pFrm)\
+ return DOT11F_BAD_OUTPUT_BUFFER \
+
+#define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \
+ if (!pSrc)\
+ return DOT11F_BAD_INPUT_BUFFER; \
+ if (!pBuf)\
+ return DOT11F_BAD_OUTPUT_BUFFER; \
+ if (!nBuf)\
+ return DOT11F_BAD_OUTPUT_BUFFER; \
+ if (!pnConsumed)\
+ return DOT11F_BAD_OUTPUT_BUFFER \
+
+#endif
+#endif
+
+static void framesntohs(tpAniSirGlobal pCtx,
+ uint16_t *pOut,
+ uint8_t *pIn,
+ tFRAMES_BOOL fMsb)
+{
+ (void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+ if (!fMsb)
+ DOT11F_MEMCPY(pCtx, (uint16_t *)pOut, pIn, 2);
+ else
+ *pOut = (uint16_t)(*pIn << 8) | *(pIn + 1);
+#else
+ if (!fMsb)
+ *pOut = (uint16_t)(*pIn | (*(pIn + 1) << 8));
+ else
+ DOT11F_MEMCPY(pCtx, (uint16_t *)pOut, pIn, 2);
+#endif
+}
+
+static void framesntohl(tpAniSirGlobal pCtx,
+ uint32_t *pOut,
+ uint8_t *pIn,
+ tFRAMES_BOOL fMsb)
+{
+ (void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+ if (!fMsb)
+ DOT11F_MEMCPY(pCtx, (uint32_t *)pOut, pIn, 4);
+ else
+ *pOut = (uint32_t)(*pIn << 24) |
+ (*(pIn + 1) << 16) |
+ (*(pIn + 2) << 8) |
+ (*(pIn + 3));
+#else
+ if (!fMsb)
+ *pOut = (uint32_t)(*(pIn + 3) << 24) |
+ (*(pIn + 2) << 16) |
+ (*(pIn + 1) << 8) |
+ (*(pIn));
+else
+ *pOut = *(uint32_t *)pIn;
+#endif
+}
+
+static void framesntohq(tpAniSirGlobal pCtx,
+ tDOT11F_U64 *pOut,
+ uint8_t *pIn,
+ tFRAMES_BOOL fMsb)
+{
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+ framesntohl(pCtx, &((*pOut)[0]), pIn, fMsb);
+ framesntohl(pCtx, &((*pOut)[1]), pIn + 4, fMsb);
+#else
+ framesntohl(pCtx, &((*pOut)[1]), pIn, fMsb);
+ framesntohl(pCtx, &((*pOut)[0]), pIn + 4, fMsb);
+#endif
+}
+
+static void frameshtons(tpAniSirGlobal pCtx,
+ uint8_t *pOut,
+ uint16_t pIn,
+ tFRAMES_BOOL fMsb)
+{
+ (void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+ if (!fMsb) {
+ DOT11F_MEMCPY(pCtx, pOut, &pIn, 2);
+ } else {
+ *pOut = (pIn & 0xff00) >> 8;
+ *(pOut + 1) = pIn & 0xff;
+ }
+#else
+ if (!fMsb) {
+ *pOut = pIn & 0xff;
+ *(pOut + 1) = (pIn & 0xff00) >> 8;
+ } else {
+ DOT11F_MEMCPY(pCtx, pOut, &pIn, 2);
+ }
+#endif
+}
+
+static void frameshtonl(tpAniSirGlobal pCtx,
+ uint8_t *pOut,
+ uint32_t pIn,
+ tFRAMES_BOOL fMsb)
+{
+ (void)pCtx;
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+ if (!fMsb) {
+ DOT11F_MEMCPY(pCtx, pOut, &pIn, 4);
+ } else {
+ *pOut = (pIn & 0xff000000) >> 24;
+ *(pOut + 1) = (pIn & 0x00ff0000) >> 16;
+ *(pOut + 2) = (pIn & 0x0000ff00) >> 8;
+ *(pOut + 3) = (pIn & 0x000000ff);
+ }
+#else
+ if (!fMsb) {
+ *pOut = (pIn & 0x000000ff);
+ *(pOut + 1) = (pIn & 0x0000ff00) >> 8;
+ *(pOut + 2) = (pIn & 0x00ff0000) >> 16;
+ *(pOut + 3) = (pIn & 0xff000000) >> 24;
+ } else {
+ DOT11F_MEMCPY(pCtx, pOut, &pIn, 4);
+ }
+#endif
+}
+
+static void frameshtonq(tpAniSirGlobal pCtx,
+ uint8_t *pOut,
+ tDOT11F_U64 pIn,
+ tFRAMES_BOOL fMsb)
+{
+#if defined (DOT11F_LITTLE_ENDIAN_HOST)
+ frameshtonl(pCtx, pOut, pIn[0], fMsb);
+ frameshtonl(pCtx, pOut + 4, pIn[1], fMsb);
+#else
+ frameshtonl(pCtx, pOut + 4, pIn[1], fMsb);
+ frameshtonl(pCtx, pOut, pIn[0], fMsb);
+#endif
+}
+
+static const tIEDefn *find_ie_defn(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ const tIEDefn IEs[])
+{
+ const tIEDefn *pIe;
+ (void)pCtx;
+
+ pIe = &(IEs[0]);
+ while (0xff != pIe->eid) {
+ if (*pBuf == pIe->eid) {
+ if (0 == pIe->noui)
+ return pIe;
+
+ if ((nBuf > (uint32_t)(pIe->noui + 2)) &&
+ (!DOT11F_MEMCMP(pCtx, pBuf + 2, pIe->oui,
+ pIe->noui)))
+ return pIe;
+ }
+
+ ++pIe;
+ }
+
+ return NULL;
+}
+
+static uint32_t get_container_ies_len(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint8_t *pnConsumed,
+ const tIEDefn IEs[])
+{
+ const tIEDefn *pIe, *pIeFirst;
+ uint8_t *pBufRemaining = pBuf;
+ uint8_t len = 0;
+ (void)pCtx;
+
+ pIeFirst = &(IEs[0]);
+
+ if (*pBufRemaining != pIeFirst->eid)
+ return DOT11F_INTERNAL_ERROR;
+ len += *(pBufRemaining+1);
+ pBufRemaining += len + 2;
+ len += 2;
+ while (len < nBuf) {
+ pIe = find_ie_defn(pCtx, pBufRemaining, nBuf + len, IEs);
+ if (NULL == pIe)
+ break;
+ if (pIe->eid == pIeFirst->eid)
+ break;
+ len += *(pBufRemaining + 1) + 2;
+ pBufRemaining += *(pBufRemaining + 1) + 2;
+ }
+
+ *pnConsumed = len;
+ return DOT11F_PARSE_SUCCESS;
+
+}
+
+
+static uint32_t unpack_core(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ const tFFDefn FFs[],
+ const tIEDefn IEs[],
+ uint8_t *pFrm,
+ size_t nFrm);
+static uint32_t pack_core(tpAniSirGlobal pCtx,
+ uint8_t *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed,
+ const tFFDefn FFs[],
+ const tIEDefn IEs[]);
+static uint32_t get_packed_size_core(tpAniSirGlobal pCtx,
+ uint8_t *pFrm,
+ uint32_t *pnNeeded,
+ const tIEDefn IEs[]);
+
+uint32_t dot11f_unpack_tlv_common_func(tpAniSirGlobal pCtx, uint8_t *pBuf,
+ uint16_t tlvlen, uint8_t *pDstPresent,
+ uint8_t *pDstField)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)tlvlen; /* Shutup the compiler */
+
+ *pDstPresent = 1;
+ *pDstField = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_common_func. */
+
+uint32_t dot11f_unpack_tlv_common_func2(tpAniSirGlobal pCtx, uint8_t *pBuf,
+ uint16_t tlvlen, uint8_t *pDstPresent,
+ uint16_t *pDstState)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)tlvlen; /* Shutup the compiler */
+
+ *pDstPresent = 1;
+ framesntohs(pCtx, pDstState, pBuf, 1);
+ (void)pCtx;
+ return status;
+
+} /* End dot11f_unpack_tlv_common_func2. */
+
+void dot11f_unpack_ff_common_func(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint16_t *pDstField)
+{
+ framesntohs(pCtx, pDstField, pBuf, 0);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_common_func. */
+
+uint32_t dot11f_unpack_ie_common_func(tpAniSirGlobal pCtx, uint8_t *pBuf,
+ uint8_t ielen, uint8_t *pDstPresent ,
+ uint8_t *pDstField)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)ielen;
+ (void)pBuf;
+ if ((*pDstPresent))
+ status = DOT11F_DUPLICATE_IE;
+ *pDstPresent = 1;
+ *pDstField = *pBuf;
+ (void)pCtx;
+
+ return status;
+} /* End dot11f_unpack_ie_common_func */
+
+typedef struct sTLVDefn {
+ uint32_t offset;
+ uint32_t presenceOffset;
+ const char *name;
+ uint16_t sig;
+ uint32_t id;
+ uint32_t pec;
+ uint32_t minSize;
+ uint32_t maxSize;
+ uint8_t fMandatory;
+ uint8_t sType;
+ uint8_t sLen;
+ uint8_t fMsb;
+} tTLVDefn;
+
+static const tTLVDefn *find_tlv_defn(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ const tTLVDefn TLVs[])
+{
+ const tTLVDefn *pTlv;
+ uint32_t pec;
+ uint16_t id;
+
+ pTlv = &(TLVs[0]);
+ (void)pCtx;
+ if (pTlv->sType == 2)
+ framesntohs(pCtx, &id, pBuf, 1);
+ else
+ id = *pBuf;
+
+ while (0xffff != pTlv->id) {
+ if (id == pTlv->id) {
+ if (0 == pTlv->pec)
+ return pTlv;
+
+ if (nBuf > 5) {
+ pec = ((*(pBuf + 4)) << 16) |
+ ((*(pBuf + 5)) << 8) |
+ *(pBuf + 6);
+ if (pec == pTlv->pec)
+ return pTlv;
+ }
+ }
+
+ ++pTlv;
+ }
+
+ return NULL;
+}
+
+static uint32_t unpack_tlv_core(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ const tTLVDefn TLVs[],
+ uint8_t *pFrm,
+ size_t nFrm);
+static uint32_t pack_tlv_core(tpAniSirGlobal pCtx,
+ uint8_t *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed,
+ const tTLVDefn TLVs[],
+ uint32_t *pidx);
+static uint32_t get_packed_size_tlv_core(tpAniSirGlobal pCtx,
+ uint8_t *pFrm,
+ uint32_t *pnNeeded,
+ const tTLVDefn TLVs[]);
+
+#define SigFfAID (0x0001)
+
+void dot11f_unpack_ff_action(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfAction *pDst)
+{
+ pDst->action = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_action. */
+
+#define SigFfAction (0x0002)
+
+#define SigFfAuthAlgo (0x0003)
+
+#define SigFfAuthSeqNo (0x0004)
+
+#define SigFfBeaconInterval (0x0005)
+
+void dot11f_unpack_ff_capabilities(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfCapabilities *pDst)
+{
+ uint16_t tmp0__;
+ framesntohs(pCtx, &tmp0__, pBuf, 0);
+ pDst->ess = tmp0__ >> 0 & 0x1;
+ pDst->ibss = tmp0__ >> 1 & 0x1;
+ pDst->cfPollable = tmp0__ >> 2 & 0x1;
+ pDst->cfPollReq = tmp0__ >> 3 & 0x1;
+ pDst->privacy = tmp0__ >> 4 & 0x1;
+ pDst->shortPreamble = tmp0__ >> 5 & 0x1;
+ pDst->pbcc = tmp0__ >> 6 & 0x1;
+ pDst->channelAgility = tmp0__ >> 7 & 0x1;
+ pDst->spectrumMgt = tmp0__ >> 8 & 0x1;
+ pDst->qos = tmp0__ >> 9 & 0x1;
+ pDst->shortSlotTime = tmp0__ >> 10 & 0x1;
+ pDst->apsd = tmp0__ >> 11 & 0x1;
+ pDst->rrm = tmp0__ >> 12 & 0x1;
+ pDst->dsssOfdm = tmp0__ >> 13 & 0x1;
+ pDst->delayedBA = tmp0__ >> 14 & 0x1;
+ pDst->immediateBA = tmp0__ >> 15 & 0x1;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_capabilities. */
+
+#define SigFfCapabilities (0x0006)
+
+void dot11f_unpack_ff_category(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfCategory *pDst)
+{
+ pDst->category = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_category. */
+
+#define SigFfCategory (0x0007)
+
+void dot11f_unpack_ff_current_ap_address(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfCurrentAPAddress *pDst)
+{
+ DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_current_ap_address. */
+
+#define SigFfCurrentAPAddress (0x0008)
+
+void dot11f_unpack_ff_dialog_token(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfDialogToken *pDst)
+{
+ pDst->token = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_dialog_token. */
+
+#define SigFfDialogToken (0x0009)
+
+void dot11f_unpack_ff_link_margin(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfLinkMargin *pDst)
+{
+ pDst->linkMargin = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_link_margin. */
+
+#define SigFfLinkMargin (0x000a)
+
+#define SigFfListenInterval (0x000b)
+
+void dot11f_unpack_ff_max_tx_power(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfMaxTxPower *pDst)
+{
+ pDst->maxTxPower = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_max_tx_power. */
+
+#define SigFfMaxTxPower (0x000c)
+
+void dot11f_unpack_ff_num_of_repetitions(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfNumOfRepetitions *pDst)
+{
+ framesntohs(pCtx, &pDst->repetitions, pBuf, 0);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_num_of_repetitions. */
+
+#define SigFfNumOfRepetitions (0x000d)
+
+void dot11f_unpack_ff_operating_mode(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfOperatingMode *pDst)
+{
+ uint8_t tmp1__;
+ tmp1__ = *pBuf;
+ pDst->chanWidth = tmp1__ >> 0 & 0x3;
+ pDst->reserved = tmp1__ >> 2 & 0x3;
+ pDst->rxNSS = tmp1__ >> 4 & 0x7;
+ pDst->rxNSSType = tmp1__ >> 7 & 0x1;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_operating_mode. */
+
+#define SigFfOperatingMode (0x000e)
+
+void dot11f_unpack_ff_rcpi(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfRCPI *pDst)
+{
+ pDst->rcpi = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_rcpi. */
+
+#define SigFfRCPI (0x000f)
+
+void dot11f_unpack_ff_rsni(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfRSNI *pDst)
+{
+ pDst->rsni = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_rsni. */
+
+#define SigFfRSNI (0x0010)
+
+#define SigFfReason (0x0011)
+
+void dot11f_unpack_ff_rx_antenna_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfRxAntennaId *pDst)
+{
+ pDst->antennaId = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_rx_antenna_id. */
+
+#define SigFfRxAntennaId (0x0012)
+
+void dot11f_unpack_ff_sm_power_mode_set(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfSMPowerModeSet *pDst)
+{
+ uint8_t tmp2__;
+ tmp2__ = *pBuf;
+ pDst->PowerSave_En = tmp2__ >> 0 & 0x1;
+ pDst->Mode = tmp2__ >> 1 & 0x1;
+ pDst->reserved = tmp2__ >> 2 & 0x3f;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_sm_power_mode_set. */
+
+#define SigFfSMPowerModeSet (0x0013)
+
+#define SigFfStatus (0x0014)
+
+void dot11f_unpack_ff_status_code(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfStatusCode *pDst)
+{
+ pDst->statusCode = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_status_code. */
+
+#define SigFfStatusCode (0x0015)
+
+void dot11f_unpack_ff_tpc_ele_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTPCEleID *pDst)
+{
+ pDst->TPCId = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_tpc_ele_id. */
+
+#define SigFfTPCEleID (0x0016)
+
+void dot11f_unpack_ff_tpc_ele_len(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTPCEleLen *pDst)
+{
+ pDst->TPCLen = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_tpc_ele_len. */
+
+#define SigFfTPCEleLen (0x0017)
+
+void dot11f_unpack_ff_ts_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTSInfo *pDst)
+{
+ uint32_t tmp3__;
+ framesntohl(pCtx, &tmp3__, pBuf, 0);
+ pDst->traffic_type = tmp3__ >> 0 & 0x1;
+ pDst->tsid = tmp3__ >> 1 & 0xf;
+ pDst->direction = tmp3__ >> 5 & 0x3;
+ pDst->access_policy = tmp3__ >> 7 & 0x3;
+ pDst->aggregation = tmp3__ >> 9 & 0x1;
+ pDst->psb = tmp3__ >> 10 & 0x1;
+ pDst->user_priority = tmp3__ >> 11 & 0x7;
+ pDst->tsinfo_ack_pol = tmp3__ >> 14 & 0x3;
+ pDst->schedule = tmp3__ >> 16 & 0x1;
+ pDst->unused = tmp3__ >> 17 & 0x7fff;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_ts_info. */
+
+#define SigFfTSInfo (0x0018)
+
+void dot11f_unpack_ff_time_stamp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTimeStamp *pDst)
+{
+ framesntohq(pCtx, &pDst->timestamp, pBuf, 0);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_time_stamp. */
+
+#define SigFfTimeStamp (0x0019)
+
+void dot11f_unpack_ff_transaction_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTransactionId *pDst)
+{
+ DOT11F_MEMCPY(pCtx, pDst->transId, pBuf, 2);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_transaction_id. */
+
+#define SigFfTransactionId (0x001a)
+
+void dot11f_unpack_ff_tx_antenna_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTxAntennaId *pDst)
+{
+ pDst->antennaId = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_tx_antenna_id. */
+
+#define SigFfTxAntennaId (0x001b)
+
+void dot11f_unpack_ff_tx_power(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfTxPower *pDst)
+{
+ pDst->txPower = *pBuf;
+ (void)pCtx;
+} /* End dot11f_unpack_ff_tx_power. */
+
+#define SigFfTxPower (0x001c)
+
+void dot11f_unpack_ff_vht_membership_status_array(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfVhtMembershipStatusArray *pDst)
+{
+ DOT11F_MEMCPY(pCtx, pDst->membershipStatusArray, pBuf, 8);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_vht_membership_status_array. */
+
+#define SigFfVhtMembershipStatusArray (0x001d)
+
+void dot11f_unpack_ff_vht_user_position_array(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ tDot11fFfVhtUserPositionArray *pDst)
+{
+ DOT11F_MEMCPY(pCtx, pDst->userPositionArray, pBuf, 16);
+ (void)pCtx;
+} /* End dot11f_unpack_ff_vht_user_position_array. */
+
+#define SigFfVhtUserPositionArray (0x001e)
+
+uint32_t dot11f_unpack_tlv_authorized_ma_cs(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVAuthorizedMACs *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6);
+ pBuf += 6;
+ tlvlen -= (uint8_t)6;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_authorized_ma_cs. */
+
+#define SigTlvAuthorizedMACs (0x0001)
+
+
+#define SigTlvRequestToEnroll (0x0002)
+
+
+uint32_t dot11f_unpack_tlv_version2(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVVersion2 *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp4__;
+ pDst->present = 1;
+ tmp4__ = *pBuf;
+ pBuf += 1;
+ tlvlen -= 1;
+ pDst->minor = tmp4__ >> 0 & 0xf;
+ pDst->major = tmp4__ >> 4 & 0xf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_version2. */
+
+#define SigTlvVersion2 (0x0003)
+
+
+#define SigTlvAPSetupLocked (0x0004)
+
+
+#define SigTlvAssociationState (0x0005)
+
+
+#define SigTlvConfigMethods (0x0006)
+
+
+#define SigTlvConfigurationError (0x0007)
+
+
+uint32_t dot11f_unpack_tlv_device_name(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVDeviceName *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->num_text = (uint8_t)(tlvlen);
+ if (tlvlen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_device_name. */
+
+#define SigTlvDeviceName (0x0008)
+
+
+#define SigTlvDevicePasswordID (0x0009)
+
+
+uint32_t dot11f_unpack_tlv_extended_listen_timing(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVExtendedListenTiming *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->availibilityPeriod, pBuf, 0);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->availibilityInterval, pBuf, 0);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_extended_listen_timing. */
+
+#define SigTlvExtendedListenTiming (0x000a)
+
+
+uint32_t dot11f_unpack_tlv_listen_channel(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVListenChannel *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
+ pBuf += 3;
+ tlvlen -= (uint8_t)3;
+ pDst->regulatoryClass = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ pDst->channel = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_listen_channel. */
+
+#define SigTlvListenChannel (0x000b)
+
+
+uint32_t dot11f_unpack_tlv_manufacturer(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVManufacturer *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->num_name = (uint8_t)(tlvlen);
+ if (tlvlen > 64) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->name, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_manufacturer. */
+
+#define SigTlvManufacturer (0x000c)
+
+
+#define SigTlvMinorReasonCode (0x000d)
+
+
+uint32_t dot11f_unpack_tlv_model_name(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVModelName *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->num_text = (uint8_t)(tlvlen);
+ if (tlvlen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_model_name. */
+
+#define SigTlvModelName (0x000e)
+
+
+uint32_t dot11f_unpack_tlv_model_number(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVModelNumber *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->num_text = (uint8_t)(tlvlen);
+ if (tlvlen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_model_number. */
+
+#define SigTlvModelNumber (0x000f)
+
+
+uint32_t dot11f_unpack_tlv_notice_of_absence(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVNoticeOfAbsence *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->index = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ pDst->CTSWindowOppPS = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ pDst->num_NoADesc = (uint8_t)(tlvlen);
+ if (tlvlen > 36) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->NoADesc, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_notice_of_absence. */
+
+#define SigTlvNoticeOfAbsence (0x0010)
+
+
+uint32_t dot11f_unpack_tlv_operating_channel(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVOperatingChannel *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3);
+ pBuf += 3;
+ tlvlen -= (uint8_t)3;
+ pDst->regulatoryClass = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ pDst->channel = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_operating_channel. */
+
+#define SigTlvOperatingChannel (0x0011)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_capability(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVP2PCapability *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->deviceCapability = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ pDst->groupCapability = *pBuf;
+ pBuf += 1;
+ tlvlen -= (uint8_t)1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_p2_p_capability. */
+
+#define SigTlvP2PCapability (0x0012)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_device_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVP2PDeviceId *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
+ pBuf += 6;
+ tlvlen -= (uint8_t)6;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_p2_p_device_id. */
+
+#define SigTlvP2PDeviceId (0x0013)
+
+
+static const tTLVDefn TLVS_P2PDeviceInfo[] = {
+ { offsetof(tDot11fTLVP2PDeviceInfo, DeviceName),
+ offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+ DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_tlv_p2_p_device_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVP2PDeviceInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
+ pBuf += 6;
+ tlvlen -= (uint8_t)6;
+ framesntohs(pCtx, &pDst->configMethod, pBuf, 0);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ DOT11F_MEMCPY(pCtx, pDst->primaryDeviceType, pBuf, 8);
+ pBuf += 8;
+ tlvlen -= (uint8_t)8;
+ (void)pCtx;
+ status |= unpack_tlv_core(pCtx,
+ pBuf,
+ tlvlen,
+ TLVS_P2PDeviceInfo,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_tlv_p2_p_device_info. */
+
+#define SigTlvP2PDeviceInfo (0x0014)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_group_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVP2PGroupInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->num_P2PClientInfoDesc = (uint8_t)(tlvlen);
+ DOT11F_MEMCPY(pCtx, pDst->P2PClientInfoDesc, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_p2_p_group_info. */
+
+#define SigTlvP2PGroupInfo (0x0015)
+
+
+#define SigTlvP2PStatus (0x0016)
+
+
+uint32_t dot11f_unpack_tlv_primary_device_type(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVPrimaryDeviceType *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)tlvlen; /* Shutup the compiler */
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->primary_category, pBuf, 1);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4);
+ pBuf += 4;
+ tlvlen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->sub_category, pBuf, 1);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_primary_device_type. */
+
+#define SigTlvPrimaryDeviceType (0x0017)
+
+
+#define SigTlvRFBands (0x0018)
+
+
+uint32_t dot11f_unpack_tlv_request_device_type(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVRequestDeviceType *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->primary_category, pBuf, 1);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4);
+ pBuf += 4;
+ tlvlen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->sub_category, pBuf, 1);
+ pBuf += 2;
+ tlvlen -= (uint8_t)2;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_request_device_type. */
+
+#define SigTlvRequestDeviceType (0x0019)
+
+
+#define SigTlvRequestType (0x001a)
+
+
+#define SigTlvResponseType (0x001b)
+
+
+#define SigTlvSelectedRegistrar (0x001c)
+
+
+#define SigTlvSelectedRegistrarConfigMethods (0x001d)
+
+
+uint32_t dot11f_unpack_tlv_serial_number(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVSerialNumber *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ pDst->num_text = (uint8_t)(tlvlen);
+ if (tlvlen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (tlvlen));
+ pBuf += (tlvlen);
+ tlvlen -= (tlvlen);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_serial_number. */
+
+#define SigTlvSerialNumber (0x001e)
+
+
+uint32_t dot11f_unpack_tlv_uuid_e(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVUUID_E *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16);
+ pBuf += 16;
+ tlvlen -= (uint8_t)16;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_uuid_e. */
+
+#define SigTlvUUID_E (0x001f)
+
+
+uint32_t dot11f_unpack_tlv_uuid_r(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVUUID_R *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16);
+ pBuf += 16;
+ tlvlen -= (uint8_t)16;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_uuid_r. */
+
+#define SigTlvUUID_R (0x0020)
+
+
+static const tTLVDefn TLVS_VendorExtension[] = {
+ { offsetof(tDot11fTLVVendorExtension, Version2),
+ offsetof(tDot11fTLVVersion2, present), "Version2", SigTlvVersion2,
+ DOT11F_TLV_VERSION2, 0, 3, 3, 0, 1, 1, 1, },
+ { offsetof(tDot11fTLVVendorExtension, AuthorizedMACs),
+ offsetof(tDot11fTLVAuthorizedMACs, present), "AuthorizedMACs",
+ SigTlvAuthorizedMACs, DOT11F_TLV_AUTHORIZEDMACS, 0, 8, 8, 0, 1, 1, 1, },
+ { offsetof(tDot11fTLVVendorExtension, RequestToEnroll),
+ offsetof(tDot11fTLVRequestToEnroll, present), "RequestToEnroll",
+ SigTlvRequestToEnroll, DOT11F_TLV_REQUESTTOENROLL,
+ 0, 3, 3, 0, 1, 1, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_tlv_vendor_extension(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVVendorExtension *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->vendorId, pBuf, 3);
+ pBuf += 3;
+ tlvlen -= (uint8_t)3;
+ (void)pCtx;
+ status |= unpack_tlv_core(pCtx,
+ pBuf,
+ tlvlen,
+ TLVS_VendorExtension,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_tlv_vendor_extension. */
+
+#define SigTlvVendorExtension (0x0021)
+
+
+uint32_t dot11f_unpack_tlv_version(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVVersion *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp5__;
+ pDst->present = 1;
+ tmp5__ = *pBuf;
+ pBuf += 1;
+ tlvlen -= 1;
+ pDst->minor = tmp5__ >> 0 & 0xf;
+ pDst->major = tmp5__ >> 4 & 0xf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_version. */
+
+#define SigTlvVersion (0x0022)
+
+
+#define SigTlvWPSState (0x0023)
+
+
+uint32_t dot11f_unpack_tlv_p2_p_interface(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint16_t tlvlen,
+ tDot11fTLVP2PInterface *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6);
+ pBuf += 6;
+ tlvlen -= (uint8_t)6;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_tlv_p2_p_interface. */
+
+#define SigTlvP2PInterface (0x0024)
+
+
+#define SigTlvP2PManageability (0x0025)
+
+
+uint32_t dot11f_unpack_ie_condensed_country_str(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIECondensedCountryStr *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->countryStr, pBuf, 2);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_condensed_country_str. */
+
+#define SigIeCondensedCountryStr (0x0001)
+
+
+uint32_t dot11f_unpack_ie_gtk(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEGTK *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp6__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &tmp6__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->keyId = tmp6__ >> 0 & 0x3;
+ pDst->reserved = tmp6__ >> 2 & 0x3feb;
+ pDst->keyLength = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->RSC, pBuf, 8);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ pDst->num_key = (uint8_t)(ielen);
+ if (ielen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->key, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_gtk. */
+
+#define SigIeGTK (0x0002)
+
+
+uint32_t dot11f_unpack_ie_igtk(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEIGTK *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->keyID, pBuf, 2);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ DOT11F_MEMCPY(pCtx, pDst->IPN, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ pDst->keyLength = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->key, pBuf, 24);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_igtk. */
+
+#define SigIeIGTK (0x0003)
+
+
+uint32_t dot11f_unpack_ie_r0_kh_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIER0KH_ID *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_PMK_R0_ID = (uint8_t)(ielen);
+ if (ielen > 48) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->PMK_R0_ID, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_r0_kh_id. */
+
+#define SigIeR0KH_ID (0x0004)
+
+
+uint32_t dot11f_unpack_ie_r1_kh_id(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIER1KH_ID *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->PMK_R1_ID, pBuf, 6);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_r1_kh_id. */
+
+#define SigIeR1KH_ID (0x0005)
+
+
+uint32_t dot11f_unpack_ie_tsf_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETSFInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->TsfOffset, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->BeaconIntvl, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_tsf_info. */
+
+#define SigIeTSFInfo (0x0006)
+
+
+uint32_t dot11f_unpack_ie_ap_channel_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEAPChannelReport *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->regulatoryClass = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_channelList = (uint8_t)(ielen);
+ if (ielen > 50) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ap_channel_report. */
+
+#define SigIeAPChannelReport (0x0007)
+
+
+uint32_t dot11f_unpack_ie_bcn_reporting_detail(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEBcnReportingDetail *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->reportingDetail = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_bcn_reporting_detail. */
+
+#define SigIeBcnReportingDetail (0x0008)
+
+
+uint32_t dot11f_unpack_ie_beacon_report_frm_body(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEBeaconReportFrmBody *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_reportedFields = (uint8_t)(ielen);
+ if (ielen > 224) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->reportedFields, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_beacon_report_frm_body. */
+
+#define SigIeBeaconReportFrmBody (0x0009)
+
+
+uint32_t dot11f_unpack_ie_beacon_reporting(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEBeaconReporting *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->reportingCondition = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->threshold = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_beacon_reporting. */
+
+#define SigIeBeaconReporting (0x000a)
+
+
+uint32_t dot11f_unpack_ie_measurement_pilot(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEMeasurementPilot *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->measurementPilot = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_vendorSpecific = (uint8_t)(ielen);
+ DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_measurement_pilot. */
+
+#define SigIeMeasurementPilot (0x000b)
+
+
+uint32_t dot11f_unpack_ie_multi_bssid(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEMultiBssid *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->maxBSSIDIndicator = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_vendorSpecific = (uint8_t)(ielen);
+ DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_multi_bssid. */
+
+#define SigIeMultiBssid (0x000c)
+
+
+uint32_t dot11f_unpack_ie_ric_data(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERICData *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->Identifier = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->resourceDescCount = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->statusCode, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ric_data. */
+
+#define SigIeRICData (0x000d)
+
+
+uint32_t dot11f_unpack_ie_ric_descriptor(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERICDescriptor *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->resourceType = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_variableData = (uint8_t)(ielen);
+ DOT11F_MEMCPY(pCtx, pDst->variableData, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ric_descriptor. */
+
+#define SigIeRICDescriptor (0x000e)
+
+
+uint32_t dot11f_unpack_ie_rrm_enabled_cap(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERRMEnabledCap *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp7__;
+ uint8_t tmp8__;
+ uint8_t tmp9__;
+ uint8_t tmp10__;
+ uint8_t tmp11__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp7__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->LinkMeasurement = tmp7__ >> 0 & 0x1;
+ pDst->NeighborRpt = tmp7__ >> 1 & 0x1;
+ pDst->parallel = tmp7__ >> 2 & 0x1;
+ pDst->repeated = tmp7__ >> 3 & 0x1;
+ pDst->BeaconPassive = tmp7__ >> 4 & 0x1;
+ pDst->BeaconActive = tmp7__ >> 5 & 0x1;
+ pDst->BeaconTable = tmp7__ >> 6 & 0x1;
+ pDst->BeaconRepCond = tmp7__ >> 7 & 0x1;
+ tmp8__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->FrameMeasurement = tmp8__ >> 0 & 0x1;
+ pDst->ChannelLoad = tmp8__ >> 1 & 0x1;
+ pDst->NoiseHistogram = tmp8__ >> 2 & 0x1;
+ pDst->statistics = tmp8__ >> 3 & 0x1;
+ pDst->LCIMeasurement = tmp8__ >> 4 & 0x1;
+ pDst->LCIAzimuth = tmp8__ >> 5 & 0x1;
+ pDst->TCMCapability = tmp8__ >> 6 & 0x1;
+ pDst->triggeredTCM = tmp8__ >> 7 & 0x1;
+ tmp9__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->APChanReport = tmp9__ >> 0 & 0x1;
+ pDst->RRMMIBEnabled = tmp9__ >> 1 & 0x1;
+ pDst->operatingChanMax = tmp9__ >> 2 & 0x7;
+ pDst->nonOperatinChanMax = tmp9__ >> 5 & 0x7;
+ tmp10__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->MeasurementPilot = tmp10__ >> 0 & 0x7;
+ pDst->MeasurementPilotEnabled = tmp10__ >> 3 & 0x1;
+ pDst->NeighborTSFOffset = tmp10__ >> 4 & 0x1;
+ pDst->RCPIMeasurement = tmp10__ >> 5 & 0x1;
+ pDst->RSNIMeasurement = tmp10__ >> 6 & 0x1;
+ pDst->BssAvgAccessDelay = tmp10__ >> 7 & 0x1;
+ tmp11__ = *pBuf;
+ pDst->BSSAvailAdmission = tmp11__ >> 0 & 0x1;
+ pDst->AntennaInformation = tmp11__ >> 1 & 0x1;
+ pDst->fine_time_meas_rpt = tmp11__ >> 2 & 0x1;
+ pDst->lci_capability = tmp11__ >> 3 & 0x1;
+ pDst->reserved = tmp11__ >> 4 & 0xf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_rrm_enabled_cap. */
+
+#define SigIeRRMEnabledCap (0x000f)
+
+
+uint32_t dot11f_unpack_ie_requested_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERequestedInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_requested_eids = (uint8_t)(ielen);
+ DOT11F_MEMCPY(pCtx, pDst->requested_eids, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_requested_info. */
+
+#define SigIeRequestedInfo (0x0010)
+
+
+uint32_t dot11f_unpack_ie_ssid(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIESSID *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present) {
+ status = DOT11F_DUPLICATE_IE;
+ return status;
+ }
+ pDst->present = 1;
+ pDst->num_ssid = (uint8_t)(ielen);
+ if (ielen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->ssid, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ssid. */
+
+#define SigIeSSID (0x0011)
+
+
+uint32_t dot11f_unpack_ie_schedule(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIESchedule *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp12__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &tmp12__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->aggregation = tmp12__ >> 0 & 0x1;
+ pDst->tsid = tmp12__ >> 1 & 0xf;
+ pDst->direction = tmp12__ >> 5 & 0x3;
+ pDst->reserved = tmp12__ >> 7 & 0x1ff;
+ framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->service_interval, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->spec_interval, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_schedule. */
+
+#define SigIeSchedule (0x0012)
+
+
+uint32_t dot11f_unpack_ie_tclas(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETCLAS *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->user_priority = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->classifier_type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->classifier_mask = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ switch (pDst->classifier_type) {
+ case 0:
+ DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ case 1:
+ pDst->info.IpParams.version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ switch (pDst->info.IpParams.version) {
+ case 4:
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->info.IpParams.params.IpV4Params.proto = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->info.IpParams.params.IpV4Params.reserved = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ break;
+ case 6:
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3);
+ pBuf += 3;
+ ielen -= (uint8_t)3;
+ break;
+ }
+ break;
+ case 2:
+ framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_tclas. */
+
+#define SigIeTCLAS (0x0013)
+
+
+#define SigIeTCLASSPROC (0x0014)
+
+
+uint32_t dot11f_unpack_ie_ts_delay(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETSDelay *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohl(pCtx, &pDst->delay, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ts_delay. */
+
+#define SigIeTSDelay (0x0015)
+
+
+uint32_t dot11f_unpack_ie_tspec(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETSPEC *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp13__;
+ uint8_t tmp14__;
+ uint16_t tmp15__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &tmp13__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->traffic_type = tmp13__ >> 0 & 0x1;
+ pDst->tsid = tmp13__ >> 1 & 0xf;
+ pDst->direction = tmp13__ >> 5 & 0x3;
+ pDst->access_policy = tmp13__ >> 7 & 0x3;
+ pDst->aggregation = tmp13__ >> 9 & 0x1;
+ pDst->psb = tmp13__ >> 10 & 0x1;
+ pDst->user_priority = tmp13__ >> 11 & 0x7;
+ pDst->tsinfo_ack_pol = tmp13__ >> 14 & 0x3;
+ tmp14__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->schedule = tmp14__ >> 0 & 0x1;
+ pDst->unused = tmp14__ >> 1 & 0x7f;
+ framesntohs(pCtx, &tmp15__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->size = tmp15__ >> 0 & 0x7fff;
+ pDst->fixed = tmp15__ >> 15 & 0x1;
+ framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohl(pCtx, &pDst->min_service_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->max_service_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->suspension_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->burst_size, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->delay_bound, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->medium_time, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_tspec. */
+
+#define SigIeTSPEC (0x0016)
+
+
+uint32_t dot11f_unpack_ie_vht_caps(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEVHTCaps *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t tmp16__;
+ uint16_t tmp17__;
+ uint16_t tmp18__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohl(pCtx, &tmp16__, pBuf, 0);
+ pBuf += 4;
+ ielen -= 4;
+ pDst->maxMPDULen = tmp16__ >> 0 & 0x3;
+ pDst->supportedChannelWidthSet = tmp16__ >> 2 & 0x3;
+ pDst->ldpcCodingCap = tmp16__ >> 4 & 0x1;
+ pDst->shortGI80MHz = tmp16__ >> 5 & 0x1;
+ pDst->shortGI160and80plus80MHz = tmp16__ >> 6 & 0x1;
+ pDst->txSTBC = tmp16__ >> 7 & 0x1;
+ pDst->rxSTBC = tmp16__ >> 8 & 0x7;
+ pDst->suBeamFormerCap = tmp16__ >> 11 & 0x1;
+ pDst->suBeamformeeCap = tmp16__ >> 12 & 0x1;
+ pDst->csnofBeamformerAntSup = tmp16__ >> 13 & 0x7;
+ pDst->numSoundingDim = tmp16__ >> 16 & 0x7;
+ pDst->muBeamformerCap = tmp16__ >> 19 & 0x1;
+ pDst->muBeamformeeCap = tmp16__ >> 20 & 0x1;
+ pDst->vhtTXOPPS = tmp16__ >> 21 & 0x1;
+ pDst->htcVHTCap = tmp16__ >> 22 & 0x1;
+ pDst->maxAMPDULenExp = tmp16__ >> 23 & 0x7;
+ pDst->vhtLinkAdaptCap = tmp16__ >> 26 & 0x3;
+ pDst->rxAntPattern = tmp16__ >> 28 & 0x1;
+ pDst->txAntPattern = tmp16__ >> 29 & 0x1;
+ pDst->reserved1 = tmp16__ >> 30 & 0x3;
+ framesntohs(pCtx, &pDst->rxMCSMap, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &tmp17__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->rxHighSupDataRate = tmp17__ >> 0 & 0x1fff;
+ pDst->reserved2 = tmp17__ >> 13 & 0x7;
+ framesntohs(pCtx, &pDst->txMCSMap, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &tmp18__, pBuf, 0);
+ pDst->txSupDataRate = tmp18__ >> 0 & 0x1fff;
+ pDst->reserved3 = tmp18__ >> 13 & 0x7;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_vht_caps. */
+
+#define SigIeVHTCaps (0x0017)
+
+
+uint32_t dot11f_unpack_ie_vht_operation(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEVHTOperation *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->chanWidth = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->chanCenterFreqSeg1 = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->chanCenterFreqSeg2 = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->basicMCSSet, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_vht_operation. */
+
+#define SigIeVHTOperation (0x0018)
+
+
+uint32_t dot11f_unpack_ie_wmm_schedule(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMSchedule *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp19__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ framesntohs(pCtx, &tmp19__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->aggregation = tmp19__ >> 0 & 0x1;
+ pDst->tsid = tmp19__ >> 1 & 0xf;
+ pDst->direction = tmp19__ >> 5 & 0x3;
+ pDst->reserved = tmp19__ >> 7 & 0x1ff;
+ framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->service_interval, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->spec_interval, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmm_schedule. */
+
+#define SigIeWMMSchedule (0x0019)
+
+
+uint32_t dot11f_unpack_ie_wmmtclas(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMTCLAS *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ pDst->user_priority = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->classifier_type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->classifier_mask = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ switch (pDst->classifier_type) {
+ case 0:
+ DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ case 1:
+ pDst->info.IpParams.version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ switch (pDst->info.IpParams.version) {
+ case 4:
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->info.IpParams.params.IpV4Params.proto = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->info.IpParams.params.IpV4Params.reserved = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ break;
+ case 6:
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3);
+ pBuf += 3;
+ ielen -= (uint8_t)3;
+ break;
+ }
+ break;
+ case 2:
+ framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmmtclas. */
+
+#define SigIeWMMTCLAS (0x001a)
+
+
+uint32_t dot11f_unpack_ie_wmmtclasproc(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMTCLASPROC *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ pDst->processing = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmmtclasproc. */
+
+#define SigIeWMMTCLASPROC (0x001b)
+
+
+uint32_t dot11f_unpack_ie_wmmts_delay(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMTSDelay *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ framesntohl(pCtx, &pDst->delay, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmmts_delay. */
+
+#define SigIeWMMTSDelay (0x001c)
+
+
+uint32_t dot11f_unpack_ie_wmmtspec(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMTSPEC *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp20__;
+ uint8_t tmp21__;
+ uint16_t tmp22__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ framesntohs(pCtx, &tmp20__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->traffic_type = tmp20__ >> 0 & 0x1;
+ pDst->tsid = tmp20__ >> 1 & 0xf;
+ pDst->direction = tmp20__ >> 5 & 0x3;
+ pDst->access_policy = tmp20__ >> 7 & 0x3;
+ pDst->aggregation = tmp20__ >> 9 & 0x1;
+ pDst->psb = tmp20__ >> 10 & 0x1;
+ pDst->user_priority = tmp20__ >> 11 & 0x7;
+ pDst->tsinfo_ack_pol = tmp20__ >> 14 & 0x3;
+ tmp21__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->tsinfo_rsvd = tmp21__ >> 0 & 0x7f;
+ pDst->burst_size_defn = tmp21__ >> 7 & 0x1;
+ framesntohs(pCtx, &tmp22__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->size = tmp22__ >> 0 & 0x7fff;
+ pDst->fixed = tmp22__ >> 15 & 0x1;
+ framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohl(pCtx, &pDst->min_service_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->max_service_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->suspension_int, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->service_start_time, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->burst_size, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->delay_bound, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->medium_time, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmmtspec. */
+
+#define SigIeWMMTSPEC (0x001d)
+
+
+uint32_t dot11f_unpack_ie_wider_bw_chan_switch_ann(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWiderBWChanSwitchAnn *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->newChanWidth = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->newCenterChanFreq0 = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->newCenterChanFreq1 = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wider_bw_chan_switch_ann. */
+
+#define SigIeWiderBWChanSwitchAnn (0x001e)
+
+
+uint32_t dot11f_unpack_ie_aid(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEAID *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->assocId, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_aid. */
+
+#define SigIeAID (0x001f)
+
+
+uint32_t dot11f_unpack_ie_cf_params(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIECFParams *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->cfp_count = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->cfp_period = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->cfp_maxduration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->cfp_durremaining, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_cf_params. */
+
+#define SigIeCFParams (0x0020)
+
+
+uint32_t dot11f_unpack_ie_challenge_text(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEChallengeText *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_text = (uint8_t)(ielen);
+ if (ielen > 253) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->text, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_challenge_text. */
+
+#define SigIeChallengeText (0x0021)
+
+
+uint32_t dot11f_unpack_ie_chan_switch_ann(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEChanSwitchAnn *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->switchMode = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->newChannel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->switchCount = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_chan_switch_ann. */
+
+#define SigIeChanSwitchAnn (0x0022)
+
+
+static const tFFDefn FFS_ChannelSwitchWrapper[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ChannelSwitchWrapper[] = {
+ { offsetof(tDot11fIEChannelSwitchWrapper, WiderBWChanSwitchAnn),
+ offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+ "WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_channel_switch_wrapper(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEChannelSwitchWrapper *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ (void)pCtx;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_ChannelSwitchWrapper,
+ IES_ChannelSwitchWrapper,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_channel_switch_wrapper. */
+
+#define SigIeChannelSwitchWrapper (0x0023)
+
+
+uint32_t dot11f_unpack_ie_country(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIECountry *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->country, pBuf, 3);
+ pBuf += 3;
+ ielen -= (uint8_t)3;
+ if (!ielen) {
+ pDst->num_triplets = 0U;
+ return 0U;
+ } else {
+ pDst->num_triplets = (uint8_t)(ielen / 3);
+ if (ielen > 84 * 3) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->triplets, pBuf, (ielen));
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_country. */
+
+#define SigIeCountry (0x0024)
+
+
+#define SigIeDSParams (0x0025)
+
+
+uint32_t dot11f_unpack_ie_edca_param_set(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEEDCAParamSet *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp23__;
+ uint8_t tmp24__;
+ uint8_t tmp25__;
+ uint8_t tmp26__;
+ uint8_t tmp27__;
+ uint8_t tmp28__;
+ uint8_t tmp29__;
+ uint8_t tmp30__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->qos = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->reserved = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp23__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbe_aifsn = tmp23__ >> 0 & 0xf;
+ pDst->acbe_acm = tmp23__ >> 4 & 0x1;
+ pDst->acbe_aci = tmp23__ >> 5 & 0x3;
+ pDst->unused1 = tmp23__ >> 7 & 0x1;
+ tmp24__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbe_acwmin = tmp24__ >> 0 & 0xf;
+ pDst->acbe_acwmax = tmp24__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp25__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbk_aifsn = tmp25__ >> 0 & 0xf;
+ pDst->acbk_acm = tmp25__ >> 4 & 0x1;
+ pDst->acbk_aci = tmp25__ >> 5 & 0x3;
+ pDst->unused2 = tmp25__ >> 7 & 0x1;
+ tmp26__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbk_acwmin = tmp26__ >> 0 & 0xf;
+ pDst->acbk_acwmax = tmp26__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp27__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvi_aifsn = tmp27__ >> 0 & 0xf;
+ pDst->acvi_acm = tmp27__ >> 4 & 0x1;
+ pDst->acvi_aci = tmp27__ >> 5 & 0x3;
+ pDst->unused3 = tmp27__ >> 7 & 0x1;
+ tmp28__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvi_acwmin = tmp28__ >> 0 & 0xf;
+ pDst->acvi_acwmax = tmp28__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp29__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvo_aifsn = tmp29__ >> 0 & 0xf;
+ pDst->acvo_acm = tmp29__ >> 4 & 0x1;
+ pDst->acvo_aci = tmp29__ >> 5 & 0x3;
+ pDst->unused4 = tmp29__ >> 7 & 0x1;
+ tmp30__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvo_acwmin = tmp30__ >> 0 & 0xf;
+ pDst->acvo_acwmax = tmp30__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_edca_param_set. */
+
+#define SigIeEDCAParamSet (0x0026)
+
+
+uint32_t dot11f_unpack_ie_erp_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEERPInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp31__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp31__ = *pBuf;
+ pDst->non_erp_present = tmp31__ >> 0 & 0x1;
+ pDst->use_prot = tmp31__ >> 1 & 0x1;
+ pDst->barker_preamble = tmp31__ >> 2 & 0x1;
+ pDst->unused = tmp31__ >> 3 & 0x1f;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_erp_info. */
+
+#define SigIeERPInfo (0x0027)
+
+
+uint32_t dot11f_unpack_ie_ese_cckm_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEESECckmOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 20) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ese_cckm_opaque. */
+
+#define SigIeESECckmOpaque (0x0028)
+
+
+uint32_t dot11f_unpack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEESERadMgmtCap *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp32__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->mgmt_state = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp32__ = *pBuf;
+ pDst->mbssid_mask = tmp32__ >> 0 & 0x7;
+ pDst->reserved = tmp32__ >> 3 & 0x1f;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ese_rad_mgmt_cap. */
+
+#define SigIeESERadMgmtCap (0x0029)
+
+
+uint32_t dot11f_unpack_ie_ese_traf_strm_met(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEESETrafStrmMet *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->tsid = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->state = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->msmt_interval, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ese_traf_strm_met. */
+
+#define SigIeESETrafStrmMet (0x002a)
+
+
+uint32_t dot11f_unpack_ie_ese_traf_strm_rate_set(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEESETrafStrmRateSet *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->tsid = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_tsrates = (uint8_t)(ielen);
+ if (ielen > 8) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->tsrates, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ese_traf_strm_rate_set. */
+
+#define SigIeESETrafStrmRateSet (0x002b)
+
+
+uint32_t dot11f_unpack_ie_ese_txmit_power(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEESETxmitPower *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->power_limit = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->reserved = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ese_txmit_power. */
+
+#define SigIeESETxmitPower (0x002c)
+
+
+uint32_t dot11f_unpack_ie_ese_version(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEESEVersion *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ese_version. */
+
+#define SigIeESEVersion (0x002d)
+
+
+uint32_t dot11f_unpack_ie_ext_cap(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEExtCap *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+
+ if (!ielen) /* Check to ensure copying of ielen bytes */
+ goto endUnpackIeExtCap;
+ pDst->num_bytes = (uint8_t)(ielen);
+ if (ielen > 9) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->bytes, pBuf, (ielen));
+
+endUnpackIeExtCap:
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ext_cap. */
+
+#define SigIeExtCap (0x002e)
+
+
+uint32_t dot11f_unpack_ie_ext_supp_rates(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEExtSuppRates *pDst)
+{
+ uint8_t i;
+ uint8_t rate_indx = 0;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ for (i = 0; i < ielen; i++) {
+ if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) &&
+ (rate_indx < 12)) {
+ pDst->rates[rate_indx++] = pBuf[i];
+ }
+ }
+
+ if (rate_indx == 0) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ pDst->num_rates = rate_indx;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ext_supp_rates. */
+
+#define SigIeExtSuppRates (0x002f)
+
+
+uint32_t dot11f_unpack_ie_fh_param_set(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEFHParamSet *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->dwell_time, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->hop_set = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->hop_pattern = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->hop_index = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_fh_param_set. */
+
+#define SigIeFHParamSet (0x0030)
+
+
+uint32_t dot11f_unpack_ie_fh_params(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEFHParams *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->radix = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->nchannels = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_fh_params. */
+
+#define SigIeFHParams (0x0031)
+
+
+uint32_t dot11f_unpack_ie_fh_patt_table(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEFHPattTable *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->flag = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->nsets = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->modulus = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->offset = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_randtable = (uint8_t)(ielen);
+ if (ielen > 251) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->randtable, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_fh_patt_table. */
+
+#define SigIeFHPattTable (0x0032)
+
+
+static const tFFDefn FFS_FTInfo[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_FTInfo[] = {
+ { offsetof(tDot11fIEFTInfo, R1KH_ID), offsetof(tDot11fIER1KH_ID, present),
+ 0, "R1KH_ID", 0, 8, 8, SigIeR1KH_ID, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_R1KH_ID, 0, },
+ { offsetof(tDot11fIEFTInfo, GTK), offsetof(tDot11fIEGTK, present), 0, "GTK",
+ 0, 18, 45, SigIeGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_GTK, 0, },
+ { offsetof(tDot11fIEFTInfo, R0KH_ID), offsetof(tDot11fIER0KH_ID, present),
+ 0, "R0KH_ID", 0, 3, 50, SigIeR0KH_ID, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_R0KH_ID, 0, },
+ { offsetof(tDot11fIEFTInfo, IGTK), offsetof(tDot11fIEIGTK, present), 0,
+ "IGTK", 0, 35, 35, SigIeIGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IGTK, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_ft_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEFTInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp33__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &tmp33__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->reserved = tmp33__ >> 0 & 0xff;
+ pDst->IECount = tmp33__ >> 8 & 0xff;
+ DOT11F_MEMCPY(pCtx, pDst->MIC, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ DOT11F_MEMCPY(pCtx, pDst->Anonce, pBuf, 32);
+ pBuf += 32;
+ ielen -= (uint8_t)32;
+ DOT11F_MEMCPY(pCtx, pDst->Snonce, pBuf, 32);
+ pBuf += 32;
+ ielen -= (uint8_t)32;
+ (void)pCtx;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_FTInfo,
+ IES_FTInfo,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_ft_info. */
+
+#define SigIeFTInfo (0x0033)
+
+
+uint32_t dot11f_unpack_ie_ht_caps(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEHTCaps *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp34__;
+ uint8_t tmp35__;
+ uint16_t tmp36__;
+ uint32_t tmp37__;
+ uint8_t tmp38__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &tmp34__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->advCodingCap = tmp34__ >> 0 & 0x1;
+ pDst->supportedChannelWidthSet = tmp34__ >> 1 & 0x1;
+ pDst->mimoPowerSave = tmp34__ >> 2 & 0x3;
+ pDst->greenField = tmp34__ >> 4 & 0x1;
+ pDst->shortGI20MHz = tmp34__ >> 5 & 0x1;
+ pDst->shortGI40MHz = tmp34__ >> 6 & 0x1;
+ pDst->txSTBC = tmp34__ >> 7 & 0x1;
+ pDst->rxSTBC = tmp34__ >> 8 & 0x3;
+ pDst->delayedBA = tmp34__ >> 10 & 0x1;
+ pDst->maximalAMSDUsize = tmp34__ >> 11 & 0x1;
+ pDst->dsssCckMode40MHz = tmp34__ >> 12 & 0x1;
+ pDst->psmp = tmp34__ >> 13 & 0x1;
+ pDst->stbcControlFrame = tmp34__ >> 14 & 0x1;
+ pDst->lsigTXOPProtection = tmp34__ >> 15 & 0x1;
+ tmp35__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->maxRxAMPDUFactor = tmp35__ >> 0 & 0x3;
+ pDst->mpduDensity = tmp35__ >> 2 & 0x7;
+ pDst->reserved1 = tmp35__ >> 5 & 0x7;
+ DOT11F_MEMCPY(pCtx, pDst->supportedMCSSet, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ framesntohs(pCtx, &tmp36__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->pco = tmp36__ >> 0 & 0x1;
+ pDst->transitionTime = tmp36__ >> 1 & 0x3;
+ pDst->reserved2 = tmp36__ >> 3 & 0x1f;
+ pDst->mcsFeedback = tmp36__ >> 8 & 0x3;
+ pDst->reserved3 = tmp36__ >> 10 & 0x3f;
+ framesntohl(pCtx, &tmp37__, pBuf, 0);
+ pBuf += 4;
+ ielen -= 4;
+ pDst->txBF = tmp37__ >> 0 & 0x1;
+ pDst->rxStaggeredSounding = tmp37__ >> 1 & 0x1;
+ pDst->txStaggeredSounding = tmp37__ >> 2 & 0x1;
+ pDst->rxZLF = tmp37__ >> 3 & 0x1;
+ pDst->txZLF = tmp37__ >> 4 & 0x1;
+ pDst->implicitTxBF = tmp37__ >> 5 & 0x1;
+ pDst->calibration = tmp37__ >> 6 & 0x3;
+ pDst->explicitCSITxBF = tmp37__ >> 8 & 0x1;
+ pDst->explicitUncompressedSteeringMatrix = tmp37__ >> 9 & 0x1;
+ pDst->explicitBFCSIFeedback = tmp37__ >> 10 & 0x7;
+ pDst->explicitUncompressedSteeringMatrixFeedback = tmp37__ >> 13 & 0x7;
+ pDst->explicitCompressedSteeringMatrixFeedback = tmp37__ >> 16 & 0x7;
+ pDst->csiNumBFAntennae = tmp37__ >> 19 & 0x3;
+ pDst->uncompressedSteeringMatrixBFAntennae = tmp37__ >> 21 & 0x3;
+ pDst->compressedSteeringMatrixBFAntennae = tmp37__ >> 23 & 0x3;
+ pDst->reserved4 = tmp37__ >> 25 & 0x7f;
+ tmp38__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->antennaSelection = tmp38__ >> 0 & 0x1;
+ pDst->explicitCSIFeedbackTx = tmp38__ >> 1 & 0x1;
+ pDst->antennaIndicesFeedbackTx = tmp38__ >> 2 & 0x1;
+ pDst->explicitCSIFeedback = tmp38__ >> 3 & 0x1;
+ pDst->antennaIndicesFeedback = tmp38__ >> 4 & 0x1;
+ pDst->rxAS = tmp38__ >> 5 & 0x1;
+ pDst->txSoundingPPDUs = tmp38__ >> 6 & 0x1;
+ pDst->reserved5 = tmp38__ >> 7 & 0x1;
+ pDst->num_rsvd = (uint8_t)(ielen);
+ if (ielen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ht_caps. */
+
+#define SigIeHTCaps (0x0034)
+
+
+uint32_t dot11f_unpack_ie_ht_info(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEHTInfo *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp39__;
+ uint16_t tmp40__;
+ uint16_t tmp41__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->primaryChannel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp39__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->secondaryChannelOffset = tmp39__ >> 0 & 0x3;
+ pDst->recommendedTxWidthSet = tmp39__ >> 2 & 0x1;
+ pDst->rifsMode = tmp39__ >> 3 & 0x1;
+ pDst->controlledAccessOnly = tmp39__ >> 4 & 0x1;
+ pDst->serviceIntervalGranularity = tmp39__ >> 5 & 0x7;
+ framesntohs(pCtx, &tmp40__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->opMode = tmp40__ >> 0 & 0x3;
+ pDst->nonGFDevicesPresent = tmp40__ >> 2 & 0x1;
+ pDst->transmitBurstLimit = tmp40__ >> 3 & 0x1;
+ pDst->obssNonHTStaPresent = tmp40__ >> 4 & 0x1;
+ pDst->reserved = tmp40__ >> 5 & 0x7ff;
+ framesntohs(pCtx, &tmp41__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->basicSTBCMCS = tmp41__ >> 0 & 0x7f;
+ pDst->dualCTSProtection = tmp41__ >> 7 & 0x1;
+ pDst->secondaryBeacon = tmp41__ >> 8 & 0x1;
+ pDst->lsigTXOPProtectionFullSupport = tmp41__ >> 9 & 0x1;
+ pDst->pcoActive = tmp41__ >> 10 & 0x1;
+ pDst->pcoPhase = tmp41__ >> 11 & 0x1;
+ pDst->reserved2 = tmp41__ >> 12 & 0xf;
+ DOT11F_MEMCPY(pCtx, pDst->basicMCSSet, pBuf, 16);
+ pBuf += 16;
+ ielen -= (uint8_t)16;
+ pDst->num_rsvd = (uint8_t)(ielen);
+ if (ielen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ht_info. */
+
+#define SigIeHTInfo (0x0035)
+
+
+uint32_t dot11f_unpack_ie_ibss_params(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEIBSSParams *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->atim, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ibss_params. */
+
+#define SigIeIBSSParams (0x0036)
+
+
+uint32_t dot11f_unpack_ie_link_identifier(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIELinkIdentifier *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ DOT11F_MEMCPY(pCtx, pDst->InitStaAddr, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ DOT11F_MEMCPY(pCtx, pDst->RespStaAddr, pBuf, 6);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_link_identifier. */
+
+#define SigIeLinkIdentifier (0x0037)
+
+
+static const tFFDefn FFS_reportBeacon[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_reportBeacon[] = {
+ { offsetof(tDot11fIEMeasurementReport,
+ report.Beacon.BeaconReportFrmBody),
+ offsetof(tDot11fIEBeaconReportFrmBody, present), 0, "BeaconReportFrmBody",
+ 0, 2, 226, SigIeBeaconReportFrmBody, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_BEACONREPORTFRMBODY, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEMeasurementReport *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp42__;
+ uint8_t tmp43__;
+ uint8_t tmp44__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->token = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp42__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->late = tmp42__ >> 0 & 0x1;
+ pDst->incapable = tmp42__ >> 1 & 0x1;
+ pDst->refused = tmp42__ >> 2 & 0x1;
+ pDst->unused = tmp42__ >> 3 & 0x1f;
+ pDst->type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (!ielen) {
+ return 0U;
+ } else {
+ switch (pDst->type) {
+ case 0:
+ pDst->report.Basic.channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohq(pCtx, &pDst->report.Basic.meas_start_time, pBuf, 0);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->report.Basic.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp43__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->report.Basic.bss = tmp43__ >> 0 & 0x1;
+ pDst->report.Basic.ofdm_preamble = tmp43__ >> 1 & 0x1;
+ pDst->report.Basic.unid_signal = tmp43__ >> 2 & 0x1;
+ pDst->report.Basic.rader = tmp43__ >> 3 & 0x1;
+ pDst->report.Basic.unmeasured = tmp43__ >> 4 & 0x1;
+ pDst->report.Basic.unused = tmp43__ >> 5 & 0x7;
+ break;
+ case 1:
+ pDst->report.CCA.channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohq(pCtx, &pDst->report.CCA.meas_start_time, pBuf, 0);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->report.CCA.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->report.CCA.cca_busy_fraction = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ break;
+ case 2:
+ pDst->report.RPIHistogram.channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohq(pCtx, &pDst->report.RPIHistogram.meas_start_time, pBuf, 0);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->report.RPIHistogram.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->report.RPIHistogram.rpi0_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi1_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi2_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi3_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi4_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi5_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi6_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.RPIHistogram.rpi7_density = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ break;
+ case 5:
+ pDst->report.Beacon.regClass = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.Beacon.channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohq(pCtx, &pDst->report.Beacon.meas_start_time, pBuf, 0);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->report.Beacon.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp44__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->report.Beacon.condensed_PHY = tmp44__ >> 0 & 0x7f;
+ pDst->report.Beacon.reported_frame_type = tmp44__ >> 7 & 0x1;
+ pDst->report.Beacon.RCPI = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->report.Beacon.RSNI = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->report.Beacon.BSSID, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ pDst->report.Beacon.antenna_id = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohl(pCtx, &pDst->report.Beacon.parent_TSF, pBuf, 0);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_reportBeacon,
+ IES_reportBeacon,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ break;
+ }
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_measurement_report. */
+
+#define SigIeMeasurementReport (0x0038)
+
+
+static const tFFDefn FFS_measurement_requestBeacon[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_measurement_requestBeacon[] = {
+ { offsetof(tDot11fIEMeasurementRequest,
+ measurement_request.Beacon.SSID), offsetof(tDot11fIESSID, present), 0,
+ "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, },
+ { offsetof(tDot11fIEMeasurementRequest,
+ measurement_request.Beacon.BeaconReporting),
+ offsetof(tDot11fIEBeaconReporting, present), 0, "BeaconReporting",
+ 0, 4, 4, SigIeBeaconReporting, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_BEACONREPORTING, 0, },
+ { offsetof(tDot11fIEMeasurementRequest,
+ measurement_request.Beacon.BcnReportingDetail),
+ offsetof(tDot11fIEBcnReportingDetail, present), 0, "BcnReportingDetail",
+ 0, 3, 3, SigIeBcnReportingDetail, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_BCNREPORTINGDETAIL, 0, },
+ { offsetof(tDot11fIEMeasurementRequest,
+ measurement_request.Beacon.RequestedInfo),
+ offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo",
+ 0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_REQUESTEDINFO, 0, },
+ { offsetof(tDot11fIEMeasurementRequest,
+ measurement_request.Beacon.APChannelReport),
+ offsetof(tDot11fIEAPChannelReport, present),
+ offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.num_APChannelReport), "APChannelReport", 2, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEMeasurementRequest *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp45__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->measurement_token = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp45__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->parallel = tmp45__ >> 0 & 0x1;
+ pDst->enable = tmp45__ >> 1 & 0x1;
+ pDst->request = tmp45__ >> 2 & 0x1;
+ pDst->report = tmp45__ >> 3 & 0x1;
+ pDst->durationMandatory = tmp45__ >> 4 & 0x1;
+ pDst->unused = tmp45__ >> 5 & 0x7;
+ pDst->measurement_type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ switch (pDst->measurement_type) {
+ case 0:
+ pDst->measurement_request.Basic.channel_no = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->measurement_request.Basic.meas_start_time, pBuf, 8);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->measurement_request.Basic.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ case 1:
+ pDst->measurement_request.CCA.channel_no = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->measurement_request.CCA.meas_start_time, pBuf, 8);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->measurement_request.CCA.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ case 2:
+ pDst->measurement_request.RPIHistogram.channel_no = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->measurement_request.RPIHistogram.meas_start_time, pBuf, 8);
+ pBuf += 8;
+ ielen -= (uint8_t)8;
+ framesntohs(pCtx, &pDst->measurement_request.RPIHistogram.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ break;
+ case 5:
+ pDst->measurement_request.Beacon.regClass = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->measurement_request.Beacon.channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->measurement_request.Beacon.randomization, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->measurement_request.Beacon.meas_duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->measurement_request.Beacon.meas_mode = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->measurement_request.Beacon.BSSID, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_measurement_requestBeacon,
+ IES_measurement_requestBeacon,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ break;
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_measurement_request. */
+
+#define SigIeMeasurementRequest (0x0039)
+
+
+uint32_t dot11f_unpack_ie_mobility_domain(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEMobilityDomain *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp46__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->MDID, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp46__ = *pBuf;
+ pDst->overDSCap = tmp46__ >> 0 & 0x1;
+ pDst->resourceReqCap = tmp46__ >> 1 & 0x1;
+ pDst->reserved = tmp46__ >> 2 & 0x3f;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_mobility_domain. */
+
+#define SigIeMobilityDomain (0x003a)
+
+
+static const tFFDefn FFS_NeighborReport[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_NeighborReport[] = {
+ { offsetof(tDot11fIENeighborReport, TSFInfo), offsetof(tDot11fIETSFInfo,
+ present), 0, "TSFInfo", 0, 6, 6, SigIeTSFInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TSFINFO, 0, },
+ { offsetof(tDot11fIENeighborReport, CondensedCountryStr),
+ offsetof(tDot11fIECondensedCountryStr, present), 0, "CondensedCountryStr",
+ 0, 4, 4, SigIeCondensedCountryStr, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CONDENSEDCOUNTRYSTR, 0, },
+ { offsetof(tDot11fIENeighborReport, MeasurementPilot),
+ offsetof(tDot11fIEMeasurementPilot, present), 0, "MeasurementPilot",
+ 0, 3, 258, SigIeMeasurementPilot, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MEASUREMENTPILOT, 0, },
+ { offsetof(tDot11fIENeighborReport, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fIENeighborReport, MultiBssid),
+ offsetof(tDot11fIEMultiBssid, present), 0, "MultiBssid",
+ 0, 3, 258, SigIeMultiBssid, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MULTIBSSID, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_neighbor_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIENeighborReport *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp47__;
+ uint8_t tmp48__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6);
+ pBuf += 6;
+ ielen -= (uint8_t)6;
+ tmp47__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->APReachability = tmp47__ >> 0 & 0x3;
+ pDst->Security = tmp47__ >> 2 & 0x1;
+ pDst->KeyScope = tmp47__ >> 3 & 0x1;
+ pDst->SpecMgmtCap = tmp47__ >> 4 & 0x1;
+ pDst->QosCap = tmp47__ >> 5 & 0x1;
+ pDst->apsd = tmp47__ >> 6 & 0x1;
+ pDst->rrm = tmp47__ >> 7 & 0x1;
+ tmp48__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->DelayedBA = tmp48__ >> 0 & 0x1;
+ pDst->ImmBA = tmp48__ >> 1 & 0x1;
+ pDst->MobilityDomain = tmp48__ >> 2 & 0x1;
+ pDst->reserved = tmp48__ >> 3 & 0x1f;
+ framesntohs(pCtx, &pDst->reserved1, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->regulatoryClass = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->PhyType = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ (void)pCtx;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_NeighborReport,
+ IES_NeighborReport,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_neighbor_report. */
+
+#define SigIeNeighborReport (0x003b)
+
+
+uint32_t dot11f_unpack_ie_obss_scan_parameters(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEOBSSScanParameters *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->obssScanPassiveDwell, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->obssScanActiveDwell, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->bssChannelWidthTriggerScanInterval, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->obssScanPassiveTotalPerChannel, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->obssScanActiveTotalPerChannel, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->bssWidthChannelTransitionDelayFactor, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->obssScanActivityThreshold, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_obss_scan_parameters. */
+
+#define SigIeOBSSScanParameters (0x003c)
+
+
+uint32_t dot11f_unpack_ie_operating_mode(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEOperatingMode *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp49__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp49__ = *pBuf;
+ pDst->chanWidth = tmp49__ >> 0 & 0x3;
+ pDst->reserved = tmp49__ >> 2 & 0x3;
+ pDst->rxNSS = tmp49__ >> 4 & 0x7;
+ pDst->rxNSSType = tmp49__ >> 7 & 0x1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_operating_mode. */
+
+#define SigIeOperatingMode (0x003d)
+
+
+static const tTLVDefn TLVS_P2PAssocReq[] = {
+ { offsetof(tDot11fIEP2PAssocReq, P2PCapability),
+ offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+ SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PAssocReq, ExtendedListenTiming),
+ offsetof(tDot11fTLVExtendedListenTiming, present),
+ "ExtendedListenTiming", SigTlvExtendedListenTiming,
+ DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PAssocReq, P2PDeviceInfo),
+ offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo",
+ SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_assoc_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PAssocReq *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PAssocReq,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_assoc_req. */
+
+#define SigIeP2PAssocReq (0x003e)
+
+
+static const tTLVDefn TLVS_P2PAssocRes[] = {
+ { offsetof(tDot11fIEP2PAssocRes, P2PStatus),
+ offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus,
+ DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PAssocRes, ExtendedListenTiming),
+ offsetof(tDot11fTLVExtendedListenTiming, present),
+ "ExtendedListenTiming", SigTlvExtendedListenTiming,
+ DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_assoc_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PAssocRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PAssocRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_assoc_res. */
+
+#define SigIeP2PAssocRes (0x003f)
+
+
+static const tTLVDefn TLVS_P2PBeacon[] = {
+ { offsetof(tDot11fIEP2PBeacon, P2PCapability),
+ offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+ SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeacon, P2PDeviceId),
+ offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId",
+ SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeacon, NoticeOfAbsence),
+ offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence",
+ SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE,
+ 0, 5, 41, 0, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_beacon(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PBeacon *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PBeacon,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_beacon. */
+
+#define SigIeP2PBeacon (0x0040)
+
+
+static const tTLVDefn TLVS_P2PBeaconProbeRes[] = {
+ { offsetof(tDot11fIEP2PBeaconProbeRes, P2PCapability),
+ offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+ SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceId),
+ offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId",
+ SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeaconProbeRes, ExtendedListenTiming),
+ offsetof(tDot11fTLVExtendedListenTiming, present),
+ "ExtendedListenTiming", SigTlvExtendedListenTiming,
+ DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeaconProbeRes, NoticeOfAbsence),
+ offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence",
+ SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE,
+ 0, 5, 41, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceInfo),
+ offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo",
+ SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PBeaconProbeRes, P2PGroupInfo),
+ offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo",
+ SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_beacon_probe_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PBeaconProbeRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PBeaconProbeRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_beacon_probe_res. */
+
+#define SigIeP2PBeaconProbeRes (0x0041)
+
+
+static const tTLVDefn TLVS_P2PDeAuth[] = {
+ { offsetof(tDot11fIEP2PDeAuth, MinorReasonCode),
+ offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode",
+ SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE,
+ 0, 4, 4, 1, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_de_auth(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PDeAuth *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PDeAuth,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_de_auth. */
+
+#define SigIeP2PDeAuth (0x0042)
+
+
+static const tTLVDefn TLVS_P2PDisAssoc[] = {
+ { offsetof(tDot11fIEP2PDisAssoc, MinorReasonCode),
+ offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode",
+ SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE,
+ 0, 4, 4, 1, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_dis_assoc(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PDisAssoc *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PDisAssoc,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_dis_assoc. */
+
+#define SigIeP2PDisAssoc (0x0043)
+
+
+uint32_t dot11f_unpack_ie_p2_pie_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PIEOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 249) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_p2_pie_opaque. */
+
+#define SigIeP2PIEOpaque (0x0044)
+
+
+static const tTLVDefn TLVS_P2PProbeReq[] = {
+ { offsetof(tDot11fIEP2PProbeReq, P2PCapability),
+ offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+ SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeReq, P2PDeviceId),
+ offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId",
+ SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeReq, ListenChannel),
+ offsetof(tDot11fTLVListenChannel, present), "ListenChannel",
+ SigTlvListenChannel, DOT11F_TLV_LISTENCHANNEL, 0, 8, 8, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeReq, ExtendedListenTiming),
+ offsetof(tDot11fTLVExtendedListenTiming, present),
+ "ExtendedListenTiming", SigTlvExtendedListenTiming,
+ DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeReq, OperatingChannel),
+ offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel",
+ SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL,
+ 0, 8, 8, 0, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_probe_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PProbeReq *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PProbeReq,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_probe_req. */
+
+#define SigIeP2PProbeReq (0x0045)
+
+
+static const tTLVDefn TLVS_P2PProbeRes[] = {
+ { offsetof(tDot11fIEP2PProbeRes, P2PCapability),
+ offsetof(tDot11fTLVP2PCapability, present), "P2PCapability",
+ SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeRes, ExtendedListenTiming),
+ offsetof(tDot11fTLVExtendedListenTiming, present),
+ "ExtendedListenTiming", SigTlvExtendedListenTiming,
+ DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeRes, NoticeOfAbsence),
+ offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence",
+ SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE,
+ 0, 5, 41, 0, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeRes, P2PDeviceInfo),
+ offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo",
+ SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, },
+ { offsetof(tDot11fIEP2PProbeRes, P2PGroupInfo),
+ offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo",
+ SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_p2_p_probe_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEP2PProbeRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_P2PProbeRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_p2_p_probe_res. */
+
+#define SigIeP2PProbeRes (0x0046)
+
+
+uint32_t dot11f_unpack_ie_pti_control(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEPTIControl *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->tid = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->sequence_control, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_pti_control. */
+
+#define SigIePTIControl (0x0047)
+
+
+uint32_t dot11f_unpack_ie_pu_buffer_status(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEPUBufferStatus *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp50__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp50__ = *pBuf;
+ pDst->ac_bk_traffic_aval = tmp50__ >> 0 & 0x1;
+ pDst->ac_be_traffic_aval = tmp50__ >> 1 & 0x1;
+ pDst->ac_vi_traffic_aval = tmp50__ >> 2 & 0x1;
+ pDst->ac_vo_traffic_aval = tmp50__ >> 3 & 0x1;
+ pDst->reserved = tmp50__ >> 4 & 0xf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_pu_buffer_status. */
+
+#define SigIePUBufferStatus (0x0048)
+
+
+uint32_t dot11f_unpack_ie_power_caps(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEPowerCaps *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->minTxPower = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->maxTxPower = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_power_caps. */
+
+#define SigIePowerCaps (0x0049)
+
+
+uint32_t dot11f_unpack_ie_power_constraints(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEPowerConstraints *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->localPowerConstraints = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_power_constraints. */
+
+#define SigIePowerConstraints (0x004a)
+
+
+uint32_t dot11f_unpack_ie_qbss_load(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEQBSSLoad *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->stacount, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ pDst->chautil = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->avail, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_qbss_load. */
+
+#define SigIeQBSSLoad (0x004b)
+
+
+uint32_t dot11f_unpack_ie_QComVendorIE(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEQComVendorIE *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->channel = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_QComVendorIE. */
+
+#define SigIeQComVendorIE (0x004c)
+
+
+uint32_t dot11f_unpack_ie_qos_caps_ap(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEQOSCapsAp *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp51__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp51__ = *pBuf;
+ pDst->count = tmp51__ >> 0 & 0xf;
+ pDst->qack = tmp51__ >> 4 & 0x1;
+ pDst->qreq = tmp51__ >> 5 & 0x1;
+ pDst->txopreq = tmp51__ >> 6 & 0x1;
+ pDst->reserved = tmp51__ >> 7 & 0x1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_qos_caps_ap. */
+
+#define SigIeQOSCapsAp (0x004d)
+
+
+uint32_t dot11f_unpack_ie_qos_caps_station(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEQOSCapsStation *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp52__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp52__ = *pBuf;
+ pDst->acvo_uapsd = tmp52__ >> 0 & 0x1;
+ pDst->acvi_uapsd = tmp52__ >> 1 & 0x1;
+ pDst->acbk_uapsd = tmp52__ >> 2 & 0x1;
+ pDst->acbe_uapsd = tmp52__ >> 3 & 0x1;
+ pDst->qack = tmp52__ >> 4 & 0x1;
+ pDst->max_sp_length = tmp52__ >> 5 & 0x3;
+ pDst->more_data_ack = tmp52__ >> 7 & 0x1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_qos_caps_station. */
+
+#define SigIeQOSCapsStation (0x004e)
+
+
+uint32_t dot11f_unpack_ie_qos_map_set(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEQosMapSet *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_dscp_exceptions = (uint8_t)(ielen);
+ if (ielen > 60) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->dscp_exceptions, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_qos_map_set. */
+
+#define SigIeQosMapSet (0x004f)
+
+
+uint32_t dot11f_unpack_ie_quiet(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEQuiet *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->count = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->period = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohs(pCtx, &pDst->duration, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ framesntohs(pCtx, &pDst->offset, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_quiet. */
+
+#define SigIeQuiet (0x0050)
+
+
+uint32_t dot11f_unpack_ie_rcpiie(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERCPIIE *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->rcpi = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_rcpiie. */
+
+#define SigIeRCPIIE (0x0051)
+
+
+static const tFFDefn FFS_RICDataDesc[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_RICDataDesc[] = {
+ { offsetof(tDot11fIERICDataDesc, RICData), offsetof(tDot11fIERICData,
+ present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATA, 1, },
+ { offsetof(tDot11fIERICDataDesc, RICDescriptor),
+ offsetof(tDot11fIERICDescriptor, present), 0, "RICDescriptor",
+ 0, 3, 258, SigIeRICDescriptor, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDESCRIPTOR, 0, },
+ { offsetof(tDot11fIERICDataDesc, TSPEC), offsetof(tDot11fIETSPEC,
+ present), 0, "TSPEC", 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TSPEC, 0, },
+ { offsetof(tDot11fIERICDataDesc, TCLAS), offsetof(tDot11fIETCLAS,
+ present), offsetof(tDot11fIERICDataDesc, num_TCLAS), "TCLAS",
+ 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, },
+ { offsetof(tDot11fIERICDataDesc, TCLASSPROC),
+ offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC",
+ 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TCLASSPROC, 0, },
+ { offsetof(tDot11fIERICDataDesc, TSDelay), offsetof(tDot11fIETSDelay,
+ present), 0, "TSDelay", 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TSDELAY, 0, },
+ { offsetof(tDot11fIERICDataDesc, Schedule), offsetof(tDot11fIESchedule,
+ present), 0, "Schedule", 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SCHEDULE, 0, },
+ { offsetof(tDot11fIERICDataDesc, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fIERICDataDesc, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS,
+ present), offsetof(tDot11fIERICDataDesc, num_WMMTCLAS), "WMMTCLAS",
+ 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6},
+ 5, DOT11F_EID_WMMTCLAS, 0, },
+ { offsetof(tDot11fIERICDataDesc, WMMTCLASPROC),
+ offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC",
+ 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7},
+ 5, DOT11F_EID_WMMTCLASPROC, 0, },
+ { offsetof(tDot11fIERICDataDesc, WMMTSDelay),
+ offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay",
+ 0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8},
+ 5, DOT11F_EID_WMMTSDELAY, 0, },
+ { offsetof(tDot11fIERICDataDesc, WMMSchedule),
+ offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule",
+ 0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9},
+ 5, DOT11F_EID_WMMSCHEDULE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_ric_data_desc(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERICDataDesc *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ (void)pCtx;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_RICDataDesc,
+ IES_RICDataDesc,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_ric_data_desc. */
+
+#define SigIeRICDataDesc (0x0052)
+
+
+uint32_t dot11f_unpack_ie_rsn(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERSN *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->version, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ if (!ielen) {
+ pDst->pwise_cipher_suite_count = 0U;
+ pDst->akm_suite_count = 0U;
+ pDst->pmkid_count = 0U;
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->pwise_cipher_suite_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (pDst->pwise_cipher_suite_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->pwise_cipher_suites, pBuf, (pDst->pwise_cipher_suite_count * 4));
+ pBuf += (pDst->pwise_cipher_suite_count * 4);
+ ielen -= (pDst->pwise_cipher_suite_count * 4);
+ if (!ielen) {
+ pDst->akm_suite_count = 0U;
+ pDst->pmkid_count = 0U;
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (pDst->akm_suite_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, (pDst->akm_suite_count * 4));
+ pBuf += (pDst->akm_suite_count * 4);
+ ielen -= (pDst->akm_suite_count * 4);
+ if (!ielen) {
+ pDst->pmkid_count = 0U;
+ return 0U;
+ } else {
+ DOT11F_MEMCPY(pCtx, pDst->RSN_Cap, pBuf, 2);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (!ielen) {
+ pDst->pmkid_count = 0U;
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->pmkid_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (pDst->pmkid_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->pmkid, pBuf, (pDst->pmkid_count * 16));
+ pBuf += (pDst->pmkid_count * 16);
+ ielen -= (pDst->pmkid_count * 16);
+ if (!ielen) {
+ return 0U;
+ } else {
+ DOT11F_MEMCPY(pCtx, pDst->gp_mgmt_cipher_suite, pBuf, 4);
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_rsn. */
+
+#define SigIeRSN (0x0053)
+
+
+uint32_t dot11f_unpack_ie_rsniie(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERSNIIE *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->rsni = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_rsniie. */
+
+#define SigIeRSNIIE (0x0054)
+
+
+uint32_t dot11f_unpack_ie_rsn_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIERSNOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 253) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_rsn_opaque. */
+
+#define SigIeRSNOpaque (0x0055)
+
+
+uint32_t dot11f_unpack_ie_supp_channels(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIESuppChannels *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_bands = (uint8_t)(ielen / 2);
+ if (ielen > 48 * 2) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->bands, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_supp_channels. */
+
+#define SigIeSuppChannels (0x0056)
+
+
+uint32_t dot11f_unpack_ie_supp_operating_classes(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIESuppOperatingClasses *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_classes = (uint8_t)(ielen);
+ if (ielen > 32) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->classes, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_supp_operating_classes. */
+
+#define SigIeSuppOperatingClasses (0x0057)
+
+
+uint32_t dot11f_unpack_ie_supp_rates(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIESuppRates *pDst)
+{
+ uint8_t i;
+ uint8_t rate_indx = 0;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ for (i = 0; i < ielen; i++) {
+ if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) &&
+ (rate_indx < 12)) {
+ pDst->rates[rate_indx++] = pBuf[i];
+ }
+ }
+
+ if (rate_indx == 0) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ pDst->num_rates = rate_indx;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_supp_rates. */
+
+#define SigIeSuppRates (0x0058)
+
+
+uint32_t dot11f_unpack_ie_tim(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETIM *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->dtim_count = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->dtim_period = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->bmpctl = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_vbmp = (uint8_t)(ielen);
+ if (ielen > 251) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->vbmp, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_tim. */
+
+#define SigIeTIM (0x0059)
+
+
+uint32_t dot11f_unpack_ie_tpc_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETPCReport *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->tx_power = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->link_margin = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_tpc_report. */
+
+#define SigIeTPCReport (0x005a)
+
+
+uint32_t dot11f_unpack_ie_tpc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETPCRequest *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_tpc_request. */
+
+#define SigIeTPCRequest (0x005b)
+
+
+uint32_t dot11f_unpack_ie_time_advertisement(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETimeAdvertisement *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->timing_capabilities = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ DOT11F_MEMCPY(pCtx, pDst->time_value, pBuf, 10);
+ pBuf += 10;
+ ielen -= (uint8_t)10;
+ DOT11F_MEMCPY(pCtx, pDst->time_error, pBuf, 5);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_time_advertisement. */
+
+#define SigIeTimeAdvertisement (0x005c)
+
+
+uint32_t dot11f_unpack_ie_timeout_interval(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIETimeoutInterval *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->timeoutType = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ framesntohl(pCtx, &pDst->timeoutValue, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_timeout_interval. */
+
+#define SigIeTimeoutInterval (0x005d)
+
+
+uint32_t dot11f_unpack_ie_vht_ext_bss_load(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEVHTExtBssLoad *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->muMIMOCapStaCount = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->ssUnderUtil = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->FortyMHzUtil = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->EightyMHzUtil = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->OneSixtyMHzUtil = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_vht_ext_bss_load. */
+
+#define SigIeVHTExtBssLoad (0x005e)
+
+
+uint32_t dot11f_unpack_ie_vendor1_ie(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEVendor1IE *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_vendor1_ie. */
+
+#define SigIeVendor1IE (0x005f)
+
+
+uint32_t dot11f_unpack_ie_vendor3_ie(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEVendor3IE *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_vendor3_ie. */
+
+#define SigIeVendor3IE (0x0060)
+
+
+uint32_t dot11f_unpack_ie_wapi(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWAPI *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint16_t tmp53__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->version, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ if (pDst->akm_suite_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, (pDst->akm_suite_count * 4));
+ pBuf += (pDst->akm_suite_count * 4);
+ ielen -= (pDst->akm_suite_count * 4);
+ framesntohs(pCtx, &pDst->unicast_cipher_suite_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ if (pDst->unicast_cipher_suite_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->unicast_cipher_suites, pBuf, (pDst->unicast_cipher_suite_count * 4));
+ pBuf += (pDst->unicast_cipher_suite_count * 4);
+ ielen -= (pDst->unicast_cipher_suite_count * 4);
+ DOT11F_MEMCPY(pCtx, pDst->multicast_cipher_suite, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ framesntohs(pCtx, &tmp53__, pBuf, 0);
+ pBuf += 2;
+ ielen -= 2;
+ pDst->preauth = tmp53__ >> 0 & 0x1;
+ pDst->reserved = tmp53__ >> 1 & 0x7fff;
+ if (!ielen) {
+ pDst->bkid_count = 0U;
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->bkid_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (pDst->bkid_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->bkid, pBuf, (pDst->bkid_count * 16));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wapi. */
+
+#define SigIeWAPI (0x0061)
+
+
+uint32_t dot11f_unpack_ie_wapi_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWAPIOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 253) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wapi_opaque. */
+
+#define SigIeWAPIOpaque (0x0062)
+
+
+uint32_t dot11f_unpack_ie_wfatpc(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWFATPC *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->txPower = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->linkMargin = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wfatpc. */
+
+#define SigIeWFATPC (0x0063)
+
+
+uint32_t dot11f_unpack_ie_wfdie_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWFDIEOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 249) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wfdie_opaque. */
+
+#define SigIeWFDIEOpaque (0x0064)
+
+
+uint32_t dot11f_unpack_ie_wmm_caps(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMCaps *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp54__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ tmp54__ = *pBuf;
+ pDst->reserved = tmp54__ >> 0 & 0xf;
+ pDst->qack = tmp54__ >> 4 & 0x1;
+ pDst->queue_request = tmp54__ >> 5 & 0x1;
+ pDst->txop_request = tmp54__ >> 6 & 0x1;
+ pDst->more_ack = tmp54__ >> 7 & 0x1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmm_caps. */
+
+#define SigIeWMMCaps (0x0065)
+
+
+uint32_t dot11f_unpack_ie_wmm_info_ap(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMInfoAp *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp55__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp55__ = *pBuf;
+ pDst->param_set_count = tmp55__ >> 0 & 0xf;
+ pDst->reserved = tmp55__ >> 4 & 0x7;
+ pDst->uapsd = tmp55__ >> 7 & 0x1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmm_info_ap. */
+
+#define SigIeWMMInfoAp (0x0066)
+
+
+uint32_t dot11f_unpack_ie_wmm_info_station(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMInfoStation *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp56__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp56__ = *pBuf;
+ pDst->acvo_uapsd = tmp56__ >> 0 & 0x1;
+ pDst->acvi_uapsd = tmp56__ >> 1 & 0x1;
+ pDst->acbk_uapsd = tmp56__ >> 2 & 0x1;
+ pDst->acbe_uapsd = tmp56__ >> 3 & 0x1;
+ pDst->reserved1 = tmp56__ >> 4 & 0x1;
+ pDst->max_sp_length = tmp56__ >> 5 & 0x3;
+ pDst->reserved2 = tmp56__ >> 7 & 0x1;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmm_info_station. */
+
+#define SigIeWMMInfoStation (0x0067)
+
+
+uint32_t dot11f_unpack_ie_wmm_params(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWMMParams *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp57__;
+ uint8_t tmp58__;
+ uint8_t tmp59__;
+ uint8_t tmp60__;
+ uint8_t tmp61__;
+ uint8_t tmp62__;
+ uint8_t tmp63__;
+ uint8_t tmp64__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->version = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ pDst->qosInfo = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->reserved2 = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ tmp57__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbe_aifsn = tmp57__ >> 0 & 0xf;
+ pDst->acbe_acm = tmp57__ >> 4 & 0x1;
+ pDst->acbe_aci = tmp57__ >> 5 & 0x3;
+ pDst->unused1 = tmp57__ >> 7 & 0x1;
+ tmp58__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbe_acwmin = tmp58__ >> 0 & 0xf;
+ pDst->acbe_acwmax = tmp58__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp59__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbk_aifsn = tmp59__ >> 0 & 0xf;
+ pDst->acbk_acm = tmp59__ >> 4 & 0x1;
+ pDst->acbk_aci = tmp59__ >> 5 & 0x3;
+ pDst->unused2 = tmp59__ >> 7 & 0x1;
+ tmp60__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acbk_acwmin = tmp60__ >> 0 & 0xf;
+ pDst->acbk_acwmax = tmp60__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp61__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvi_aifsn = tmp61__ >> 0 & 0xf;
+ pDst->acvi_acm = tmp61__ >> 4 & 0x1;
+ pDst->acvi_aci = tmp61__ >> 5 & 0x3;
+ pDst->unused3 = tmp61__ >> 7 & 0x1;
+ tmp62__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvi_acwmin = tmp62__ >> 0 & 0xf;
+ pDst->acvi_acwmax = tmp62__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ tmp63__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvo_aifsn = tmp63__ >> 0 & 0xf;
+ pDst->acvo_acm = tmp63__ >> 4 & 0x1;
+ pDst->acvo_aci = tmp63__ >> 5 & 0x3;
+ pDst->unused4 = tmp63__ >> 7 & 0x1;
+ tmp64__ = *pBuf;
+ pBuf += 1;
+ ielen -= 1;
+ pDst->acvo_acwmin = tmp64__ >> 0 & 0xf;
+ pDst->acvo_acwmax = tmp64__ >> 4 & 0xf;
+ framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0);
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wmm_params. */
+
+#define SigIeWMMParams (0x0068)
+
+
+uint32_t dot11f_unpack_ie_wpa(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWPA *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ framesntohs(pCtx, &pDst->version, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ if (pDst->version != 0x1) {
+ pDst->present = 0;
+ return status | DOT11F_BAD_FIXED_VALUE;
+ }
+ if (!ielen) {
+ pDst->multicast_cipher_present = 0U;
+ pDst->unicast_cipher_count = 0U;
+ pDst->auth_suite_count = 0U;
+ return 0U;
+ } else {
+ pDst->multicast_cipher_present = 1U;
+ DOT11F_MEMCPY(pCtx, pDst->multicast_cipher, pBuf, 4);
+ pBuf += 4;
+ ielen -= (uint8_t)4;
+ }
+ if (!ielen) {
+ pDst->unicast_cipher_count = 0U;
+ pDst->auth_suite_count = 0U;
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->unicast_cipher_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (pDst->unicast_cipher_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->unicast_ciphers, pBuf, (pDst->unicast_cipher_count * 4));
+ pBuf += (pDst->unicast_cipher_count * 4);
+ ielen -= (pDst->unicast_cipher_count * 4);
+ if (!ielen) {
+ pDst->auth_suite_count = 0U;
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->auth_suite_count, pBuf, 0);
+ pBuf += 2;
+ ielen -= (uint8_t)2;
+ }
+ if (pDst->auth_suite_count > 4) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->auth_suites, pBuf, (pDst->auth_suite_count * 4));
+ pBuf += (pDst->auth_suite_count * 4);
+ ielen -= (pDst->auth_suite_count * 4);
+ if (!ielen) {
+ return 0U;
+ } else {
+ framesntohs(pCtx, &pDst->caps, pBuf, 0);
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wpa. */
+
+#define SigIeWPA (0x0069)
+
+
+uint32_t dot11f_unpack_ie_wpa_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWPAOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 249) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wpa_opaque. */
+
+#define SigIeWPAOpaque (0x006a)
+
+
+static const tTLVDefn TLVS_WSC[] = {
+ { offsetof(tDot11fIEWSC, Version), offsetof(tDot11fTLVVersion, present),
+ "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, WPSState), offsetof(tDot11fTLVWPSState, present),
+ "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, APSetupLocked),
+ offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+ SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, SelectedRegistrarConfigMethods),
+ offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+ "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+ DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, UUID_E), offsetof(tDot11fTLVUUID_E, present),
+ "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, UUID_R), offsetof(tDot11fTLVUUID_R, present),
+ "UUID_R", SigTlvUUID_R, DOT11F_TLV_UUID_R, 0, 20, 20, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, RFBands), offsetof(tDot11fTLVRFBands, present),
+ "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, SelectedRegistrar),
+ offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+ SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, ConfigMethods),
+ offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+ SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, AssociationState),
+ offsetof(tDot11fTLVAssociationState, present), "AssociationState",
+ SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE,
+ 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, ConfigurationError),
+ offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError",
+ SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR,
+ 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, Manufacturer), offsetof(tDot11fTLVManufacturer,
+ present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER,
+ 0, 4, 68, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, ModelName), offsetof(tDot11fTLVModelName,
+ present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME,
+ 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, ModelNumber), offsetof(tDot11fTLVModelNumber,
+ present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER,
+ 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, SerialNumber), offsetof(tDot11fTLVSerialNumber,
+ present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER,
+ 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, DeviceName), offsetof(tDot11fTLVDeviceName,
+ present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME,
+ 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, DevicePasswordID),
+ offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+ SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+ 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, PrimaryDeviceType),
+ offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+ SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+ 0, 12, 12, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, RequestType), offsetof(tDot11fTLVRequestType,
+ present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, ResponseType), offsetof(tDot11fTLVResponseType,
+ present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWSC, RequestDeviceType),
+ offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType",
+ SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE,
+ 0, 12, 12, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWSC *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WSC,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc. */
+
+#define SigIeWSC (0x006b)
+
+
+static const tTLVDefn TLVS_WscAssocReq[] = {
+ { offsetof(tDot11fIEWscAssocReq, Version), offsetof(tDot11fTLVVersion,
+ present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscAssocReq, RequestType),
+ offsetof(tDot11fTLVRequestType, present), "RequestType",
+ SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscAssocReq, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_assoc_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscAssocReq *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscAssocReq,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_assoc_req. */
+
+#define SigIeWscAssocReq (0x006c)
+
+
+static const tTLVDefn TLVS_WscAssocRes[] = {
+ { offsetof(tDot11fIEWscAssocRes, Version), offsetof(tDot11fTLVVersion,
+ present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscAssocRes, ResponseType),
+ offsetof(tDot11fTLVResponseType, present), "ResponseType",
+ SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscAssocRes, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_assoc_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscAssocRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscAssocRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_assoc_res. */
+
+#define SigIeWscAssocRes (0x006d)
+
+
+static const tTLVDefn TLVS_WscBeacon[] = {
+ { offsetof(tDot11fIEWscBeacon, Version), offsetof(tDot11fTLVVersion,
+ present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, WPSState), offsetof(tDot11fTLVWPSState,
+ present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, APSetupLocked),
+ offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+ SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, SelectedRegistrar),
+ offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+ SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, DevicePasswordID),
+ offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+ SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+ 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, SelectedRegistrarConfigMethods),
+ offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+ "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+ DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, UUID_E), offsetof(tDot11fTLVUUID_E,
+ present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E,
+ 0, 20, 20, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, RFBands), offsetof(tDot11fTLVRFBands,
+ present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeacon, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_beacon(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscBeacon *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscBeacon,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_beacon. */
+
+#define SigIeWscBeacon (0x006e)
+
+
+static const tTLVDefn TLVS_WscBeaconProbeRes[] = {
+ { offsetof(tDot11fIEWscBeaconProbeRes, Version),
+ offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion,
+ DOT11F_TLV_VERSION, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, WPSState),
+ offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState,
+ DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, APSetupLocked),
+ offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+ SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrar),
+ offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+ SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, DevicePasswordID),
+ offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+ SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+ 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrarConfigMethods),
+ offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+ "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+ DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, ResponseType),
+ offsetof(tDot11fTLVResponseType, present), "ResponseType",
+ SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, UUID_E),
+ offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E,
+ DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, Manufacturer),
+ offsetof(tDot11fTLVManufacturer, present), "Manufacturer",
+ SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, ModelName),
+ offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName,
+ DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, ModelNumber),
+ offsetof(tDot11fTLVModelNumber, present), "ModelNumber",
+ SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, SerialNumber),
+ offsetof(tDot11fTLVSerialNumber, present), "SerialNumber",
+ SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, PrimaryDeviceType),
+ offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+ SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+ 0, 12, 12, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, DeviceName),
+ offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+ DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, ConfigMethods),
+ offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+ SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, RFBands),
+ offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands,
+ DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscBeaconProbeRes, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscBeaconProbeRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscBeaconProbeRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_beacon_probe_res. */
+
+#define SigIeWscBeaconProbeRes (0x006f)
+
+
+uint32_t dot11f_unpack_ie_wsc_ie_opaque(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscIEOpaque *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->num_data = (uint8_t)(ielen);
+ if (ielen > 249) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->data, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_wsc_ie_opaque. */
+
+#define SigIeWscIEOpaque (0x0070)
+
+
+static const tTLVDefn TLVS_WscProbeReq[] = {
+ { offsetof(tDot11fIEWscProbeReq, Version), offsetof(tDot11fTLVVersion,
+ present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, RequestType),
+ offsetof(tDot11fTLVRequestType, present), "RequestType",
+ SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, ConfigMethods),
+ offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+ SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, UUID_E), offsetof(tDot11fTLVUUID_E,
+ present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E,
+ 0, 20, 20, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, PrimaryDeviceType),
+ offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+ SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+ 0, 12, 12, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, RFBands), offsetof(tDot11fTLVRFBands,
+ present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, AssociationState),
+ offsetof(tDot11fTLVAssociationState, present), "AssociationState",
+ SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE,
+ 0, 6, 6, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, ConfigurationError),
+ offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError",
+ SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR,
+ 0, 6, 6, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, DevicePasswordID),
+ offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+ SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+ 0, 6, 6, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, Manufacturer),
+ offsetof(tDot11fTLVManufacturer, present), "Manufacturer",
+ SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, ModelName),
+ offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName,
+ DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, ModelNumber),
+ offsetof(tDot11fTLVModelNumber, present), "ModelNumber",
+ SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, DeviceName),
+ offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+ DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeReq, RequestDeviceType),
+ offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType",
+ SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE,
+ 0, 12, 12, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_probe_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscProbeReq *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscProbeReq,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_probe_req. */
+
+#define SigIeWscProbeReq (0x0071)
+
+
+static const tTLVDefn TLVS_WscProbeRes[] = {
+ { offsetof(tDot11fIEWscProbeRes, Version), offsetof(tDot11fTLVVersion,
+ present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, WPSState), offsetof(tDot11fTLVWPSState,
+ present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, APSetupLocked),
+ offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked",
+ SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, SelectedRegistrar),
+ offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar",
+ SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, DevicePasswordID),
+ offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID",
+ SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID,
+ 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, SelectedRegistrarConfigMethods),
+ offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present),
+ "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods,
+ DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, ResponseType),
+ offsetof(tDot11fTLVResponseType, present), "ResponseType",
+ SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, UUID_E), offsetof(tDot11fTLVUUID_E,
+ present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E,
+ 0, 20, 20, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, Manufacturer),
+ offsetof(tDot11fTLVManufacturer, present), "Manufacturer",
+ SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, ModelName),
+ offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName,
+ DOT11F_TLV_MODELNAME, 0, 4, 36, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, ModelNumber),
+ offsetof(tDot11fTLVModelNumber, present), "ModelNumber",
+ SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, SerialNumber),
+ offsetof(tDot11fTLVSerialNumber, present), "SerialNumber",
+ SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, PrimaryDeviceType),
+ offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType",
+ SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE,
+ 0, 12, 12, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, DeviceName),
+ offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName,
+ DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, ConfigMethods),
+ offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods",
+ SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, RFBands), offsetof(tDot11fTLVRFBands,
+ present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS,
+ 0, 5, 5, 0, 2, 2, 1, },
+ { offsetof(tDot11fIEWscProbeRes, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_probe_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscProbeRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscProbeRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_probe_res. */
+
+#define SigIeWscProbeRes (0x0072)
+
+
+static const tTLVDefn TLVS_WscReassocRes[] = {
+ { offsetof(tDot11fIEWscReassocRes, Version), offsetof(tDot11fTLVVersion,
+ present), "Version", SigTlvVersion, DOT11F_TLV_VERSION,
+ 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscReassocRes, ResponseType),
+ offsetof(tDot11fTLVResponseType, present), "ResponseType",
+ SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, },
+ { offsetof(tDot11fIEWscReassocRes, VendorExtension),
+ offsetof(tDot11fTLVVendorExtension, present), "VendorExtension",
+ SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION,
+ 0, 7, 21, 0, 2, 2, 1, },
+ {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0},
+};
+
+uint32_t dot11f_unpack_ie_wsc_reassoc_res(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEWscReassocRes *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pBuf; (void)ielen; /* Shutup the compiler */
+ pDst->present = 1;
+ status = unpack_tlv_core(pCtx, pBuf, ielen,
+ TLVS_WscReassocRes,
+ (uint8_t *)pDst, sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_wsc_reassoc_res. */
+
+#define SigIeWscReassocRes (0x0073)
+
+
+uint32_t dot11f_unpack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEext_chan_switch_ann *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->switch_mode = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->new_reg_class = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->new_channel = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->switch_count = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ext_chan_switch_ann. */
+
+#define SigIeext_chan_switch_ann (0x0074)
+
+
+uint32_t dot11f_unpack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEht2040_bss_coexistence *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint8_t tmp65__;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ tmp65__ = *pBuf;
+ pDst->info_request = tmp65__ >> 0 & 0x1;
+ pDst->forty_mhz_intolerant = tmp65__ >> 1 & 0x1;
+ pDst->twenty_mhz_bsswidth_req = tmp65__ >> 2 & 0x1;
+ pDst->obss_scan_exemption_req = tmp65__ >> 3 & 0x1;
+ pDst->obss_scan_exemption_grant = tmp65__ >> 4 & 0x1;
+ pDst->unused = tmp65__ >> 5 & 0x7;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ht2040_bss_coexistence. */
+
+#define SigIeht2040_bss_coexistence (0x0075)
+
+
+uint32_t dot11f_unpack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEht2040_bss_intolerant_report *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->operating_class = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->num_channel_list = (uint8_t)(ielen);
+ if (ielen > 50) {
+ pDst->present = 0;
+ return DOT11F_SKIPPED_BAD_IE;
+ }
+
+ DOT11F_MEMCPY(pCtx, pDst->channel_list, pBuf, (ielen));
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_ht2040_bss_intolerant_report. */
+
+#define SigIeht2040_bss_intolerant_report (0x0076)
+
+
+uint32_t dot11f_unpack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEsec_chan_offset_ele *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->secondaryChannelOffset = *pBuf;
+ (void)pCtx;
+ return status;
+} /* End dot11f_unpack_ie_sec_chan_offset_ele. */
+
+#define SigIesec_chan_offset_ele (0x0077)
+
+
+static const tFFDefn FFS_vendor2_ie[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_vendor2_ie[] = {
+ { offsetof(tDot11fIEvendor2_ie, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fIEvendor2_ie, VHTOperation),
+ offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+ 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },
+};
+
+uint32_t dot11f_unpack_ie_vendor2_ie(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint8_t ielen,
+ tDot11fIEvendor2_ie *pDst)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void) pBuf; (void)ielen; /* Shutup the compiler */
+ if (pDst->present)
+ status = DOT11F_DUPLICATE_IE;
+ pDst->present = 1;
+ pDst->type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ pDst->sub_type = *pBuf;
+ pBuf += 1;
+ ielen -= (uint8_t)1;
+ (void)pCtx;
+ status |= unpack_core(pCtx,
+ pBuf,
+ ielen,
+ FFS_vendor2_ie,
+ IES_vendor2_ie,
+ (uint8_t *)pDst,
+ sizeof(*pDst));
+ return status;
+} /* End dot11f_unpack_ie_vendor2_ie. */
+
+#define SigIevendor2_ie (0x0078)
+
+
+static const tFFDefn FFS_AddTSRequest[] = {
+ { "Category", offsetof(tDot11fAddTSRequest, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fAddTSRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fAddTSRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AddTSRequest[] = {
+ { offsetof(tDot11fAddTSRequest, TSPEC), offsetof(tDot11fIETSPEC, present),
+ 0, "TSPEC", 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TSPEC, 1, },
+ { offsetof(tDot11fAddTSRequest, TCLAS), offsetof(tDot11fIETCLAS, present),
+ offsetof(tDot11fAddTSRequest, num_TCLAS), "TCLAS", 2, 7, 45, SigIeTCLAS,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, },
+ { offsetof(tDot11fAddTSRequest, TCLASSPROC),
+ offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC",
+ 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TCLASSPROC, 0, },
+ { offsetof(tDot11fAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fAddTSRequest, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS,
+ present), offsetof(tDot11fAddTSRequest, num_WMMTCLAS), "WMMTCLAS",
+ 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6},
+ 5, DOT11F_EID_WMMTCLAS, 0, },
+ { offsetof(tDot11fAddTSRequest, WMMTCLASPROC),
+ offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC",
+ 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7},
+ 5, DOT11F_EID_WMMTCLASPROC, 0, },
+ { offsetof(tDot11fAddTSRequest, ESETrafStrmRateSet),
+ offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+ 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+ 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_add_ts_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAddTSRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_AddTSRequest, IES_AddTSRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_add_ts_request. */
+
+static const tFFDefn FFS_AddTSResponse[] = {
+ { "Category", offsetof(tDot11fAddTSResponse, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fAddTSResponse, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fAddTSResponse, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "Status", offsetof(tDot11fAddTSResponse, Status), SigFfStatus,
+ DOT11F_FF_STATUS_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AddTSResponse[] = {
+ { offsetof(tDot11fAddTSResponse, TSDelay), offsetof(tDot11fIETSDelay,
+ present), 0, "TSDelay", 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TSDELAY, 1, },
+ { offsetof(tDot11fAddTSResponse, TSPEC), offsetof(tDot11fIETSPEC,
+ present), 0, "TSPEC", 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TSPEC, 1, },
+ { offsetof(tDot11fAddTSResponse, TCLAS), offsetof(tDot11fIETCLAS,
+ present), offsetof(tDot11fAddTSResponse, num_TCLAS), "TCLAS",
+ 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, },
+ { offsetof(tDot11fAddTSResponse, TCLASSPROC),
+ offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC",
+ 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TCLASSPROC, 0, },
+ { offsetof(tDot11fAddTSResponse, Schedule), offsetof(tDot11fIESchedule,
+ present), 0, "Schedule", 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SCHEDULE, 0, },
+ { offsetof(tDot11fAddTSResponse, WMMTSDelay),
+ offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay",
+ 0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8},
+ 5, DOT11F_EID_WMMTSDELAY, 0, },
+ { offsetof(tDot11fAddTSResponse, WMMSchedule),
+ offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule",
+ 0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9},
+ 5, DOT11F_EID_WMMSCHEDULE, 0, },
+ { offsetof(tDot11fAddTSResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fAddTSResponse, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS,
+ present), offsetof(tDot11fAddTSResponse, num_WMMTCLAS), "WMMTCLAS",
+ 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6},
+ 5, DOT11F_EID_WMMTCLAS, 0, },
+ { offsetof(tDot11fAddTSResponse, WMMTCLASPROC),
+ offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC",
+ 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7},
+ 5, DOT11F_EID_WMMTCLASPROC, 0, },
+ { offsetof(tDot11fAddTSResponse, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_add_ts_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAddTSResponse *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_AddTSResponse, IES_AddTSResponse,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_add_ts_response. */
+
+static const tFFDefn FFS_AssocRequest[] = {
+ { "Capabilities", offsetof(tDot11fAssocRequest, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { "ListenInterval", offsetof(tDot11fAssocRequest, ListenInterval),
+ SigFfListenInterval, DOT11F_FF_LISTENINTERVAL_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AssocRequest[] = {
+ { offsetof(tDot11fAssocRequest, SSID), offsetof(tDot11fIESSID, present), 0,
+ "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fAssocRequest, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fAssocRequest, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fAssocRequest, PowerCaps), offsetof(tDot11fIEPowerCaps,
+ present), 0, "PowerCaps", 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_POWERCAPS, 0, },
+ { offsetof(tDot11fAssocRequest, SuppChannels),
+ offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+ 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPCHANNELS, 0, },
+ { offsetof(tDot11fAssocRequest, RSNOpaque), offsetof(tDot11fIERSNOpaque,
+ present), 0, "RSNOpaque", 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNOPAQUE, 0, },
+ { offsetof(tDot11fAssocRequest, QOSCapsStation),
+ offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+ 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSCAPSSTATION, 0, },
+ { offsetof(tDot11fAssocRequest, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fAssocRequest, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque,
+ present), 0, "WPAOpaque", 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0},
+ 4, DOT11F_EID_WPAOPAQUE, 0, },
+ { offsetof(tDot11fAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps,
+ present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fAssocRequest, WMMInfoStation),
+ offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+ 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOSTATION, 0, },
+ { offsetof(tDot11fAssocRequest, WscIEOpaque),
+ offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque",
+ 0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCIEOPAQUE, 0, },
+ { offsetof(tDot11fAssocRequest, WAPIOpaque),
+ offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque",
+ 0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_WAPIOPAQUE, 0, },
+ { offsetof(tDot11fAssocRequest, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+ "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, },
+ { offsetof(tDot11fAssocRequest, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fAssocRequest, ESEVersion),
+ offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion",
+ 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+ 4, DOT11F_EID_ESEVERSION, 0, },
+ { offsetof(tDot11fAssocRequest, P2PIEOpaque),
+ offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque",
+ 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PIEOPAQUE, 0, },
+ { offsetof(tDot11fAssocRequest, WFDIEOpaque),
+ offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque",
+ 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0},
+ 4, DOT11F_EID_WFDIEOPAQUE, 0, },
+ { offsetof(tDot11fAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fAssocRequest, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ { offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet,
+ present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSMAPSET, 0, },
+ { offsetof(tDot11fAssocRequest, vendor2_ie),
+ offsetof(tDot11fIEvendor2_ie, present), 0, "vendor2_ie",
+ 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_assoc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAssocRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_AssocRequest, IES_AssocRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_assoc_request. */
+
+static const tFFDefn FFS_AssocResponse[] = {
+ { "Capabilities", offsetof(tDot11fAssocResponse, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { "Status", offsetof(tDot11fAssocResponse, Status), SigFfStatus,
+ DOT11F_FF_STATUS_LEN, },
+ { "AID", offsetof(tDot11fAssocResponse, AID), SigFfAID,
+ DOT11F_FF_AID_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_AssocResponse[] = {
+ { offsetof(tDot11fAssocResponse, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fAssocResponse, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fAssocResponse, EDCAParamSet),
+ offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+ 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE,
+ present), 0, "RCPIIE", 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RCPIIE, 0, },
+ { offsetof(tDot11fAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE,
+ present), 0, "RSNIIE", 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNIIE, 0, },
+ { offsetof(tDot11fAssocResponse, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fAssocResponse, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fAssocResponse, RICDataDesc),
+ offsetof(tDot11fIERICDataDesc, present),
+ offsetof(tDot11fAssocResponse, num_RICDataDesc), "RICDataDesc",
+ 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATADESC, 0, },
+ { offsetof(tDot11fAssocResponse, WPA), offsetof(tDot11fIEWPA, present), 0,
+ "WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, },
+ { offsetof(tDot11fAssocResponse, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo,
+ present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fAssocResponse, WMMParams), offsetof(tDot11fIEWMMParams,
+ present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fAssocResponse, WMMCaps), offsetof(tDot11fIEWMMCaps,
+ present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fAssocResponse, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fAssocResponse, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ { offsetof(tDot11fAssocResponse, ESETxmitPower),
+ offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+ 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESETXMITPOWER, 0, },
+ { offsetof(tDot11fAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), offsetof(tDot11fAssocResponse, num_WMMTSPEC), "WMMTSPEC",
+ 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fAssocResponse, WscAssocRes),
+ offsetof(tDot11fIEWscAssocRes, present), 0, "WscAssocRes",
+ 0, 6, 37, SigIeWscAssocRes, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCASSOCRES, 0, },
+ { offsetof(tDot11fAssocResponse, P2PAssocRes),
+ offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes",
+ 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PASSOCRES, 0, },
+ { offsetof(tDot11fAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fAssocResponse, VHTOperation),
+ offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+ 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fAssocResponse, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fAssocResponse, OBSSScanParameters),
+ offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+ 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ { offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet,
+ present), 0, "QosMapSet", 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSMAPSET, 0, },
+ { offsetof(tDot11fAssocResponse, vendor2_ie),
+ offsetof(tDot11fIEvendor2_ie, present), 0, "vendor2_ie",
+ 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_assoc_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAssocResponse *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_AssocResponse, IES_AssocResponse,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_assoc_response. */
+
+static const tFFDefn FFS_Authentication[] = {
+ { "AuthAlgo", offsetof(tDot11fAuthentication, AuthAlgo), SigFfAuthAlgo,
+ DOT11F_FF_AUTHALGO_LEN, },
+ { "AuthSeqNo", offsetof(tDot11fAuthentication, AuthSeqNo), SigFfAuthSeqNo,
+ DOT11F_FF_AUTHSEQNO_LEN, },
+ { "Status", offsetof(tDot11fAuthentication, Status), SigFfStatus,
+ DOT11F_FF_STATUS_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Authentication[] = {
+ { offsetof(tDot11fAuthentication, ChallengeText),
+ offsetof(tDot11fIEChallengeText, present), 0, "ChallengeText",
+ 0, 3, 255, SigIeChallengeText, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CHALLENGETEXT, 0, },
+ { offsetof(tDot11fAuthentication, RSNOpaque),
+ offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque",
+ 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNOPAQUE, 0, },
+ { offsetof(tDot11fAuthentication, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fAuthentication, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fAuthentication, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fAuthentication, RICDataDesc),
+ offsetof(tDot11fIERICDataDesc, present),
+ offsetof(tDot11fAuthentication, num_RICDataDesc), "RICDataDesc",
+ 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATADESC, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_authentication(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fAuthentication *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_Authentication, IES_Authentication,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_authentication. */
+
+static const tFFDefn FFS_Beacon[] = {
+ { "TimeStamp", offsetof(tDot11fBeacon, TimeStamp), SigFfTimeStamp,
+ DOT11F_FF_TIMESTAMP_LEN, },
+ { "BeaconInterval", offsetof(tDot11fBeacon, BeaconInterval),
+ SigFfBeaconInterval, DOT11F_FF_BEACONINTERVAL_LEN, },
+ { "Capabilities", offsetof(tDot11fBeacon, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Beacon[] = {
+ { offsetof(tDot11fBeacon, SSID), offsetof(tDot11fIESSID, present), 0,
+ "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fBeacon, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fBeacon, FHParamSet), offsetof(tDot11fIEFHParamSet,
+ present), 0, "FHParamSet", 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPARAMSET, 0, },
+ { offsetof(tDot11fBeacon, DSParams), offsetof(tDot11fIEDSParams, present),
+ 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_DSPARAMS, 0, },
+ { offsetof(tDot11fBeacon, CFParams), offsetof(tDot11fIECFParams, present),
+ 0, "CFParams", 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CFPARAMS, 0, },
+ { offsetof(tDot11fBeacon, IBSSParams), offsetof(tDot11fIEIBSSParams,
+ present), 0, "IBSSParams", 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_IBSSPARAMS, 0, },
+ { offsetof(tDot11fBeacon, TIM), offsetof(tDot11fIETIM, present), 0, "TIM",
+ 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, },
+ { offsetof(tDot11fBeacon, Country), offsetof(tDot11fIECountry, present), 0,
+ "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fBeacon, FHParams), offsetof(tDot11fIEFHParams, present),
+ 0, "FHParams", 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPARAMS, 0, },
+ { offsetof(tDot11fBeacon, FHPattTable), offsetof(tDot11fIEFHPattTable,
+ present), 0, "FHPattTable", 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPATTTABLE, 0, },
+ { offsetof(tDot11fBeacon, PowerConstraints),
+ offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+ 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_POWERCONSTRAINTS, 0, },
+ { offsetof(tDot11fBeacon, ChanSwitchAnn),
+ offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+ 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CHANSWITCHANN, 0, },
+ { offsetof(tDot11fBeacon, ext_chan_switch_ann),
+ offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+ 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, },
+ { offsetof(tDot11fBeacon, Quiet), offsetof(tDot11fIEQuiet, present), 0,
+ "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, },
+ { offsetof(tDot11fBeacon, TPCReport), offsetof(tDot11fIETPCReport,
+ present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TPCREPORT, 0, },
+ { offsetof(tDot11fBeacon, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0,
+ "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_ERPINFO, 0, },
+ { offsetof(tDot11fBeacon, ExtSuppRates), offsetof(tDot11fIEExtSuppRates,
+ present), 0, "ExtSuppRates", 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fBeacon, RSN), offsetof(tDot11fIERSN, present), 0, "RSN",
+ 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
+ { offsetof(tDot11fBeacon, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present),
+ 0, "QBSSLoad", 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QBSSLOAD, 0, },
+ { offsetof(tDot11fBeacon, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet,
+ present), 0, "EDCAParamSet", 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fBeacon, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp,
+ present), 0, "QOSCapsAp", 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSCAPSAP, 0, },
+ { offsetof(tDot11fBeacon, APChannelReport),
+ offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+ 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_APCHANNELREPORT, 0, },
+ { offsetof(tDot11fBeacon, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fBeacon, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fBeacon, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA",
+ 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, },
+ { offsetof(tDot11fBeacon, HTCaps), offsetof(tDot11fIEHTCaps, present), 0,
+ "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fBeacon, HTInfo), offsetof(tDot11fIEHTInfo, present), 0,
+ "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fBeacon, sec_chan_offset_ele),
+ offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+ 0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, },
+ { offsetof(tDot11fBeacon, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+ present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOAP, 0, },
+ { offsetof(tDot11fBeacon, WMMParams), offsetof(tDot11fIEWMMParams,
+ present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fBeacon, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0,
+ "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fBeacon, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+ "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, },
+ { offsetof(tDot11fBeacon, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fBeacon, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ { offsetof(tDot11fBeacon, ESETxmitPower),
+ offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+ 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESETXMITPOWER, 0, },
+ { offsetof(tDot11fBeacon, WscBeacon), offsetof(tDot11fIEWscBeacon,
+ present), 0, "WscBeacon", 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCBEACON, 0, },
+ { offsetof(tDot11fBeacon, P2PBeacon), offsetof(tDot11fIEP2PBeacon,
+ present), 0, "P2PBeacon", 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PBEACON, 0, },
+ { offsetof(tDot11fBeacon, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0,
+ "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fBeacon, VHTOperation), offsetof(tDot11fIEVHTOperation,
+ present), 0, "VHTOperation", 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fBeacon, VHTExtBssLoad),
+ offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+ 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
+ { offsetof(tDot11fBeacon, ExtCap), offsetof(tDot11fIEExtCap, present), 0,
+ "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fBeacon, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ { offsetof(tDot11fBeacon, WiderBWChanSwitchAnn),
+ offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+ "WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
+ { offsetof(tDot11fBeacon, OBSSScanParameters),
+ offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+ 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ { offsetof(tDot11fBeacon, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+ present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+ 3, DOT11F_EID_VENDOR1IE, 0, },
+ { offsetof(tDot11fBeacon, vendor2_ie), offsetof(tDot11fIEvendor2_ie,
+ present), 0, "vendor2_ie", 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ { offsetof(tDot11fBeacon, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+ present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+ 3, DOT11F_EID_VENDOR3IE, 0, },
+ { offsetof(tDot11fBeacon, ChannelSwitchWrapper),
+ offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+ "ChannelSwitchWrapper", 0, 2, 7, SigIeChannelSwitchWrapper,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, },
+ { offsetof(tDot11fBeacon, QComVendorIE), offsetof(tDot11fIEQComVendorIE,
+ present), 0, "QComVendorIE", 0, 7, 7, SigIeQComVendorIE,
+ {0, 160, 198, 0, 0}, 3, DOT11F_EID_QCOMVENDORIE, 0, },
+ { offsetof(tDot11fBeacon, ESEVersion), offsetof(tDot11fIEESEVersion,
+ present), 0, "ESEVersion", 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+ 4, DOT11F_EID_ESEVERSION, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeacon *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_Beacon, IES_Beacon,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_beacon. */
+
+static const tFFDefn FFS_Beacon1[] = {
+ { "TimeStamp", offsetof(tDot11fBeacon1, TimeStamp), SigFfTimeStamp,
+ DOT11F_FF_TIMESTAMP_LEN, },
+ { "BeaconInterval", offsetof(tDot11fBeacon1, BeaconInterval),
+ SigFfBeaconInterval, DOT11F_FF_BEACONINTERVAL_LEN, },
+ { "Capabilities", offsetof(tDot11fBeacon1, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Beacon1[] = {
+ { offsetof(tDot11fBeacon1, SSID), offsetof(tDot11fIESSID, present), 0,
+ "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fBeacon1, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fBeacon1, DSParams), offsetof(tDot11fIEDSParams,
+ present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_DSPARAMS, 0, },
+ { offsetof(tDot11fBeacon1, IBSSParams), offsetof(tDot11fIEIBSSParams,
+ present), 0, "IBSSParams", 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_IBSSPARAMS, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon1(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeacon1 *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_Beacon1, IES_Beacon1,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_beacon1. */
+
+static const tFFDefn FFS_Beacon2[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Beacon2[] = {
+ { offsetof(tDot11fBeacon2, Country), offsetof(tDot11fIECountry, present),
+ 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fBeacon2, PowerConstraints),
+ offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+ 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_POWERCONSTRAINTS, 0, },
+ { offsetof(tDot11fBeacon2, ChanSwitchAnn),
+ offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+ 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CHANSWITCHANN, 0, },
+ { offsetof(tDot11fBeacon2, ext_chan_switch_ann),
+ offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+ 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, },
+ { offsetof(tDot11fBeacon2, Quiet), offsetof(tDot11fIEQuiet, present), 0,
+ "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, },
+ { offsetof(tDot11fBeacon2, TPCReport), offsetof(tDot11fIETPCReport,
+ present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TPCREPORT, 0, },
+ { offsetof(tDot11fBeacon2, ERPInfo), offsetof(tDot11fIEERPInfo, present),
+ 0, "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_ERPINFO, 0, },
+ { offsetof(tDot11fBeacon2, ExtSuppRates), offsetof(tDot11fIEExtSuppRates,
+ present), 0, "ExtSuppRates", 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fBeacon2, RSNOpaque), offsetof(tDot11fIERSNOpaque,
+ present), 0, "RSNOpaque", 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNOPAQUE, 0, },
+ { offsetof(tDot11fBeacon2, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet,
+ present), 0, "EDCAParamSet", 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fBeacon2, APChannelReport),
+ offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+ 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_APCHANNELREPORT, 0, },
+ { offsetof(tDot11fBeacon2, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fBeacon2, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fBeacon2, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA",
+ 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, },
+ { offsetof(tDot11fBeacon2, HTCaps), offsetof(tDot11fIEHTCaps, present), 0,
+ "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fBeacon2, HTInfo), offsetof(tDot11fIEHTInfo, present), 0,
+ "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fBeacon2, sec_chan_offset_ele),
+ offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+ 0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, },
+ { offsetof(tDot11fBeacon2, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+ present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOAP, 0, },
+ { offsetof(tDot11fBeacon2, WMMParams), offsetof(tDot11fIEWMMParams,
+ present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fBeacon2, WMMCaps), offsetof(tDot11fIEWMMCaps, present),
+ 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fBeacon2, WscBeacon), offsetof(tDot11fIEWscBeacon,
+ present), 0, "WscBeacon", 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCBEACON, 0, },
+ { offsetof(tDot11fBeacon2, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+ "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, },
+ { offsetof(tDot11fBeacon2, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fBeacon2, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ { offsetof(tDot11fBeacon2, ESETxmitPower),
+ offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+ 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESETXMITPOWER, 0, },
+ { offsetof(tDot11fBeacon2, P2PBeacon), offsetof(tDot11fIEP2PBeacon,
+ present), 0, "P2PBeacon", 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PBEACON, 0, },
+ { offsetof(tDot11fBeacon2, VHTCaps), offsetof(tDot11fIEVHTCaps, present),
+ 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fBeacon2, VHTOperation), offsetof(tDot11fIEVHTOperation,
+ present), 0, "VHTOperation", 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fBeacon2, VHTExtBssLoad),
+ offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+ 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
+ { offsetof(tDot11fBeacon2, ExtCap), offsetof(tDot11fIEExtCap, present), 0,
+ "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fBeacon2, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ { offsetof(tDot11fBeacon2, WiderBWChanSwitchAnn),
+ offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+ "WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
+ { offsetof(tDot11fBeacon2, OBSSScanParameters),
+ offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+ 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ { offsetof(tDot11fBeacon2, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+ present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+ 3, DOT11F_EID_VENDOR1IE, 0, },
+ { offsetof(tDot11fBeacon2, vendor2_ie), offsetof(tDot11fIEvendor2_ie,
+ present), 0, "vendor2_ie", 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ { offsetof(tDot11fBeacon2, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+ present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+ 3, DOT11F_EID_VENDOR3IE, 0, },
+ { offsetof(tDot11fBeacon2, ChannelSwitchWrapper),
+ offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+ "ChannelSwitchWrapper", 0, 2, 7, SigIeChannelSwitchWrapper,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, },
+ { offsetof(tDot11fBeacon2, QComVendorIE), offsetof(tDot11fIEQComVendorIE,
+ present), 0, "QComVendorIE", 0, 7, 7, SigIeQComVendorIE,
+ {0, 160, 198, 0, 0}, 3, DOT11F_EID_QCOMVENDORIE, 0, },
+ { offsetof(tDot11fBeacon2, ESEVersion), offsetof(tDot11fIEESEVersion,
+ present), 0, "ESEVersion", 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+ 4, DOT11F_EID_ESEVERSION, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon2(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeacon2 *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_Beacon2, IES_Beacon2,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_beacon2. */
+
+static const tFFDefn FFS_BeaconIEs[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_BeaconIEs[] = {
+ { offsetof(tDot11fBeaconIEs, SSID), offsetof(tDot11fIESSID, present), 0,
+ "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fBeaconIEs, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fBeaconIEs, FHParamSet), offsetof(tDot11fIEFHParamSet,
+ present), 0, "FHParamSet", 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPARAMSET, 0, },
+ { offsetof(tDot11fBeaconIEs, DSParams), offsetof(tDot11fIEDSParams,
+ present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_DSPARAMS, 0, },
+ { offsetof(tDot11fBeaconIEs, CFParams), offsetof(tDot11fIECFParams,
+ present), 0, "CFParams", 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CFPARAMS, 0, },
+ { offsetof(tDot11fBeaconIEs, IBSSParams), offsetof(tDot11fIEIBSSParams,
+ present), 0, "IBSSParams", 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_IBSSPARAMS, 0, },
+ { offsetof(tDot11fBeaconIEs, TIM), offsetof(tDot11fIETIM, present), 0,
+ "TIM", 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, },
+ { offsetof(tDot11fBeaconIEs, Country), offsetof(tDot11fIECountry,
+ present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fBeaconIEs, FHParams), offsetof(tDot11fIEFHParams,
+ present), 0, "FHParams", 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPARAMS, 0, },
+ { offsetof(tDot11fBeaconIEs, FHPattTable), offsetof(tDot11fIEFHPattTable,
+ present), 0, "FHPattTable", 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPATTTABLE, 0, },
+ { offsetof(tDot11fBeaconIEs, PowerConstraints),
+ offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+ 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_POWERCONSTRAINTS, 0, },
+ { offsetof(tDot11fBeaconIEs, ChanSwitchAnn),
+ offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+ 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CHANSWITCHANN, 0, },
+ { offsetof(tDot11fBeaconIEs, ext_chan_switch_ann),
+ offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+ 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, },
+ { offsetof(tDot11fBeaconIEs, Quiet), offsetof(tDot11fIEQuiet, present), 0,
+ "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, },
+ { offsetof(tDot11fBeaconIEs, TPCReport), offsetof(tDot11fIETPCReport,
+ present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TPCREPORT, 0, },
+ { offsetof(tDot11fBeaconIEs, ERPInfo), offsetof(tDot11fIEERPInfo,
+ present), 0, "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_ERPINFO, 0, },
+ { offsetof(tDot11fBeaconIEs, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fBeaconIEs, RSN), offsetof(tDot11fIERSN, present), 0,
+ "RSN", 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
+ { offsetof(tDot11fBeaconIEs, QBSSLoad), offsetof(tDot11fIEQBSSLoad,
+ present), 0, "QBSSLoad", 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QBSSLOAD, 0, },
+ { offsetof(tDot11fBeaconIEs, EDCAParamSet),
+ offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+ 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fBeaconIEs, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp,
+ present), 0, "QOSCapsAp", 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSCAPSAP, 0, },
+ { offsetof(tDot11fBeaconIEs, APChannelReport),
+ offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+ 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_APCHANNELREPORT, 0, },
+ { offsetof(tDot11fBeaconIEs, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fBeaconIEs, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fBeaconIEs, WPA), offsetof(tDot11fIEWPA, present), 0,
+ "WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, },
+ { offsetof(tDot11fBeaconIEs, HTCaps), offsetof(tDot11fIEHTCaps, present),
+ 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fBeaconIEs, HTInfo), offsetof(tDot11fIEHTInfo, present),
+ 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fBeaconIEs, sec_chan_offset_ele),
+ offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+ 0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, },
+ { offsetof(tDot11fBeaconIEs, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+ present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOAP, 0, },
+ { offsetof(tDot11fBeaconIEs, WMMParams), offsetof(tDot11fIEWMMParams,
+ present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fBeaconIEs, WMMCaps), offsetof(tDot11fIEWMMCaps,
+ present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fBeaconIEs, WAPI), offsetof(tDot11fIEWAPI, present), 0,
+ "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, },
+ { offsetof(tDot11fBeaconIEs, ESEVersion), offsetof(tDot11fIEESEVersion,
+ present), 0, "ESEVersion", 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+ 4, DOT11F_EID_ESEVERSION, 0, },
+ { offsetof(tDot11fBeaconIEs, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fBeaconIEs, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ { offsetof(tDot11fBeaconIEs, ESETxmitPower),
+ offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+ 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESETXMITPOWER, 0, },
+ { offsetof(tDot11fBeaconIEs, WscBeaconProbeRes),
+ offsetof(tDot11fIEWscBeaconProbeRes, present), 0, "WscBeaconProbeRes",
+ 0, 6, 319, SigIeWscBeaconProbeRes, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCBEACONPROBERES, 0, },
+ { offsetof(tDot11fBeaconIEs, P2PBeaconProbeRes),
+ offsetof(tDot11fIEP2PBeaconProbeRes, present), 0, "P2PBeaconProbeRes",
+ 0, 6, 1150, SigIeP2PBeaconProbeRes, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PBEACONPROBERES, 0, },
+ { offsetof(tDot11fBeaconIEs, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fBeaconIEs, VHTOperation),
+ offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+ 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fBeaconIEs, VHTExtBssLoad),
+ offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+ 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
+ { offsetof(tDot11fBeaconIEs, ExtCap), offsetof(tDot11fIEExtCap, present),
+ 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fBeaconIEs, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ { offsetof(tDot11fBeaconIEs, WiderBWChanSwitchAnn),
+ offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+ "WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
+ { offsetof(tDot11fBeaconIEs, OBSSScanParameters),
+ offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+ 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ { offsetof(tDot11fBeaconIEs, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+ present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+ 3, DOT11F_EID_VENDOR1IE, 0, },
+ { offsetof(tDot11fBeaconIEs, vendor2_ie), offsetof(tDot11fIEvendor2_ie,
+ present), 0, "vendor2_ie", 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ { offsetof(tDot11fBeaconIEs, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+ present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+ 3, DOT11F_EID_VENDOR3IE, 0, },
+ { offsetof(tDot11fBeaconIEs, ChannelSwitchWrapper),
+ offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+ "ChannelSwitchWrapper", 0, 2, 7, SigIeChannelSwitchWrapper,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, },
+ { offsetof(tDot11fBeaconIEs, QComVendorIE),
+ offsetof(tDot11fIEQComVendorIE, present), 0, "QComVendorIE",
+ 0, 7, 7, SigIeQComVendorIE, {0, 160, 198, 0, 0},
+ 3, DOT11F_EID_QCOMVENDORIE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_beacon_i_es(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fBeaconIEs *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_BeaconIEs, IES_BeaconIEs,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_beacon_i_es. */
+
+static const tFFDefn FFS_ChannelSwitch[] = {
+ { "Category", offsetof(tDot11fChannelSwitch, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fChannelSwitch, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ChannelSwitch[] = {
+ { offsetof(tDot11fChannelSwitch, ChanSwitchAnn),
+ offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+ 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CHANSWITCHANN, 1, },
+ { offsetof(tDot11fChannelSwitch, sec_chan_offset_ele),
+ offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+ 0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, },
+ { offsetof(tDot11fChannelSwitch, WiderBWChanSwitchAnn),
+ offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0,
+ "WiderBWChanSwitchAnn", 0, 5, 5, SigIeWiderBWChanSwitchAnn,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_channel_switch(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fChannelSwitch *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_ChannelSwitch, IES_ChannelSwitch,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_channel_switch. */
+
+static const tFFDefn FFS_DeAuth[] = {
+ { "Reason", offsetof(tDot11fDeAuth, Reason), SigFfReason,
+ DOT11F_FF_REASON_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_DeAuth[] = {
+ { offsetof(tDot11fDeAuth, P2PDeAuth), offsetof(tDot11fIEP2PDeAuth,
+ present), 0, "P2PDeAuth", 0, 6, 10, SigIeP2PDeAuth, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PDEAUTH, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_de_auth(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fDeAuth *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_DeAuth, IES_DeAuth,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_de_auth. */
+
+static const tFFDefn FFS_DelTS[] = {
+ { "Category", offsetof(tDot11fDelTS, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fDelTS, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "TSInfo", offsetof(tDot11fDelTS, TSInfo), SigFfTSInfo,
+ DOT11F_FF_TSINFO_LEN, },
+ { "Reason", offsetof(tDot11fDelTS, Reason), SigFfReason,
+ DOT11F_FF_REASON_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_DelTS[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_del_ts(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fDelTS *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_DelTS, IES_DelTS,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_del_ts. */
+
+static const tFFDefn FFS_Disassociation[] = {
+ { "Reason", offsetof(tDot11fDisassociation, Reason), SigFfReason,
+ DOT11F_FF_REASON_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_Disassociation[] = {
+ { offsetof(tDot11fDisassociation, P2PDisAssoc),
+ offsetof(tDot11fIEP2PDisAssoc, present), 0, "P2PDisAssoc",
+ 0, 6, 10, SigIeP2PDisAssoc, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PDISASSOC, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_disassociation(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fDisassociation *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_Disassociation, IES_Disassociation,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_disassociation. */
+
+static const tFFDefn FFS_LinkMeasurementReport[] = {
+ { "Category", offsetof(tDot11fLinkMeasurementReport, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fLinkMeasurementReport, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fLinkMeasurementReport, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "TPCEleID", offsetof(tDot11fLinkMeasurementReport, TPCEleID),
+ SigFfTPCEleID, DOT11F_FF_TPCELEID_LEN, },
+ { "TPCEleLen", offsetof(tDot11fLinkMeasurementReport, TPCEleLen),
+ SigFfTPCEleLen, DOT11F_FF_TPCELELEN_LEN, },
+ { "TxPower", offsetof(tDot11fLinkMeasurementReport, TxPower),
+ SigFfTxPower, DOT11F_FF_TXPOWER_LEN, },
+ { "LinkMargin", offsetof(tDot11fLinkMeasurementReport, LinkMargin),
+ SigFfLinkMargin, DOT11F_FF_LINKMARGIN_LEN, },
+ { "RxAntennaId", offsetof(tDot11fLinkMeasurementReport, RxAntennaId),
+ SigFfRxAntennaId, DOT11F_FF_RXANTENNAID_LEN, },
+ { "TxAntennaId", offsetof(tDot11fLinkMeasurementReport, TxAntennaId),
+ SigFfTxAntennaId, DOT11F_FF_TXANTENNAID_LEN, },
+ { "RCPI", offsetof(tDot11fLinkMeasurementReport, RCPI), SigFfRCPI,
+ DOT11F_FF_RCPI_LEN, },
+ { "RSNI", offsetof(tDot11fLinkMeasurementReport, RSNI), SigFfRSNI,
+ DOT11F_FF_RSNI_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_LinkMeasurementReport[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_link_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fLinkMeasurementReport *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_LinkMeasurementReport, IES_LinkMeasurementReport,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_link_measurement_report. */
+
+static const tFFDefn FFS_LinkMeasurementRequest[] = {
+ { "Category", offsetof(tDot11fLinkMeasurementRequest, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fLinkMeasurementRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fLinkMeasurementRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "TxPower", offsetof(tDot11fLinkMeasurementRequest, TxPower),
+ SigFfTxPower, DOT11F_FF_TXPOWER_LEN, },
+ { "MaxTxPower", offsetof(tDot11fLinkMeasurementRequest, MaxTxPower),
+ SigFfMaxTxPower, DOT11F_FF_MAXTXPOWER_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_LinkMeasurementRequest[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_link_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fLinkMeasurementRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_link_measurement_request. */
+
+static const tFFDefn FFS_MeasurementReport[] = {
+ { "Category", offsetof(tDot11fMeasurementReport, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fMeasurementReport, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fMeasurementReport, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_MeasurementReport[] = {
+ { offsetof(tDot11fMeasurementReport, MeasurementReport),
+ offsetof(tDot11fIEMeasurementReport, present), 0, "MeasurementReport",
+ 0, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MEASUREMENTREPORT, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fMeasurementReport *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_MeasurementReport, IES_MeasurementReport,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_measurement_report. */
+
+static const tFFDefn FFS_MeasurementRequest[] = {
+ { "Category", offsetof(tDot11fMeasurementRequest, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fMeasurementRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fMeasurementRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_MeasurementRequest[] = {
+ { offsetof(tDot11fMeasurementRequest, MeasurementRequest),
+ offsetof(tDot11fIEMeasurementRequest, present),
+ offsetof(tDot11fMeasurementRequest, num_MeasurementRequest),
+ "MeasurementRequest", 4, 16, 18, SigIeMeasurementRequest,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fMeasurementRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_MeasurementRequest, IES_MeasurementRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_measurement_request. */
+
+static const tFFDefn FFS_NeighborReportRequest[] = {
+ { "Category", offsetof(tDot11fNeighborReportRequest, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fNeighborReportRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fNeighborReportRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_NeighborReportRequest[] = {
+ { offsetof(tDot11fNeighborReportRequest, SSID), offsetof(tDot11fIESSID,
+ present), 0, "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SSID, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_neighbor_report_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fNeighborReportRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_NeighborReportRequest, IES_NeighborReportRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_neighbor_report_request. */
+
+static const tFFDefn FFS_NeighborReportResponse[] = {
+ { "Category", offsetof(tDot11fNeighborReportResponse, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fNeighborReportResponse, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fNeighborReportResponse, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_NeighborReportResponse[] = {
+ { offsetof(tDot11fNeighborReportResponse, NeighborReport),
+ offsetof(tDot11fIENeighborReport, present),
+ offsetof(tDot11fNeighborReportResponse, num_NeighborReport),
+ "NeighborReport", 15, 15, 548, SigIeNeighborReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_NEIGHBORREPORT, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_neighbor_report_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fNeighborReportResponse *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_NeighborReportResponse, IES_NeighborReportResponse,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_neighbor_report_response. */
+
+static const tFFDefn FFS_OperatingMode[] = {
+ { "Category", offsetof(tDot11fOperatingMode, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fOperatingMode, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "OperatingMode", offsetof(tDot11fOperatingMode, OperatingMode),
+ SigFfOperatingMode, DOT11F_FF_OPERATINGMODE_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_OperatingMode[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_operating_mode(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fOperatingMode *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_OperatingMode, IES_OperatingMode,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_operating_mode. */
+
+static const tFFDefn FFS_ProbeRequest[] = {
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ProbeRequest[] = {
+ { offsetof(tDot11fProbeRequest, SSID), offsetof(tDot11fIESSID, present), 0,
+ "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fProbeRequest, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fProbeRequest, RequestedInfo),
+ offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo",
+ 0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_REQUESTEDINFO, 0, },
+ { offsetof(tDot11fProbeRequest, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fProbeRequest, DSParams), offsetof(tDot11fIEDSParams,
+ present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_DSPARAMS, 0, },
+ { offsetof(tDot11fProbeRequest, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fProbeRequest, WscProbeReq),
+ offsetof(tDot11fIEWscProbeReq, present), 0, "WscProbeReq",
+ 0, 6, 286, SigIeWscProbeReq, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCPROBEREQ, 0, },
+ { offsetof(tDot11fProbeRequest, WFATPC), offsetof(tDot11fIEWFATPC,
+ present), 0, "WFATPC", 0, 9, 9, SigIeWFATPC, {0, 80, 242, 8, 0},
+ 5, DOT11F_EID_WFATPC, 0, },
+ { offsetof(tDot11fProbeRequest, P2PProbeReq),
+ offsetof(tDot11fIEP2PProbeReq, present), 0, "P2PProbeReq",
+ 0, 6, 43, SigIeP2PProbeReq, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PPROBEREQ, 0, },
+ { offsetof(tDot11fProbeRequest, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fProbeRequest, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_probe_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fProbeRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_ProbeRequest, IES_ProbeRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_probe_request. */
+
+static const tFFDefn FFS_ProbeResponse[] = {
+ { "TimeStamp", offsetof(tDot11fProbeResponse, TimeStamp), SigFfTimeStamp,
+ DOT11F_FF_TIMESTAMP_LEN, },
+ { "BeaconInterval", offsetof(tDot11fProbeResponse, BeaconInterval),
+ SigFfBeaconInterval, DOT11F_FF_BEACONINTERVAL_LEN, },
+ { "Capabilities", offsetof(tDot11fProbeResponse, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ProbeResponse[] = {
+ { offsetof(tDot11fProbeResponse, SSID), offsetof(tDot11fIESSID, present),
+ 0, "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fProbeResponse, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fProbeResponse, FHParamSet),
+ offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet",
+ 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPARAMSET, 0, },
+ { offsetof(tDot11fProbeResponse, DSParams), offsetof(tDot11fIEDSParams,
+ present), 0, "DSParams", 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_DSPARAMS, 0, },
+ { offsetof(tDot11fProbeResponse, CFParams), offsetof(tDot11fIECFParams,
+ present), 0, "CFParams", 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CFPARAMS, 0, },
+ { offsetof(tDot11fProbeResponse, IBSSParams),
+ offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams",
+ 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_IBSSPARAMS, 0, },
+ { offsetof(tDot11fProbeResponse, Country), offsetof(tDot11fIECountry,
+ present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fProbeResponse, FHParams), offsetof(tDot11fIEFHParams,
+ present), 0, "FHParams", 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPARAMS, 0, },
+ { offsetof(tDot11fProbeResponse, FHPattTable),
+ offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable",
+ 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FHPATTTABLE, 0, },
+ { offsetof(tDot11fProbeResponse, PowerConstraints),
+ offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+ 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_POWERCONSTRAINTS, 0, },
+ { offsetof(tDot11fProbeResponse, ChanSwitchAnn),
+ offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn",
+ 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_CHANSWITCHANN, 0, },
+ { offsetof(tDot11fProbeResponse, ext_chan_switch_ann),
+ offsetof(tDot11fIEext_chan_switch_ann, present), 0, "ext_chan_switch_ann",
+ 0, 6, 6, SigIeext_chan_switch_ann, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXT_CHAN_SWITCH_ANN, 0, },
+ { offsetof(tDot11fProbeResponse, Quiet), offsetof(tDot11fIEQuiet,
+ present), 0, "Quiet", 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QUIET, 0, },
+ { offsetof(tDot11fProbeResponse, TPCReport), offsetof(tDot11fIETPCReport,
+ present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TPCREPORT, 0, },
+ { offsetof(tDot11fProbeResponse, ERPInfo), offsetof(tDot11fIEERPInfo,
+ present), 0, "ERPInfo", 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_ERPINFO, 0, },
+ { offsetof(tDot11fProbeResponse, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fProbeResponse, RSNOpaque), offsetof(tDot11fIERSNOpaque,
+ present), 0, "RSNOpaque", 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNOPAQUE, 0, },
+ { offsetof(tDot11fProbeResponse, QBSSLoad), offsetof(tDot11fIEQBSSLoad,
+ present), 0, "QBSSLoad", 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QBSSLOAD, 0, },
+ { offsetof(tDot11fProbeResponse, EDCAParamSet),
+ offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+ 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fProbeResponse, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fProbeResponse, APChannelReport),
+ offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport",
+ 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_APCHANNELREPORT, 0, },
+ { offsetof(tDot11fProbeResponse, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fProbeResponse, WPA), offsetof(tDot11fIEWPA, present), 0,
+ "WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, },
+ { offsetof(tDot11fProbeResponse, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fProbeResponse, HTInfo), offsetof(tDot11fIEHTInfo,
+ present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fProbeResponse, sec_chan_offset_ele),
+ offsetof(tDot11fIEsec_chan_offset_ele, present), 0, "sec_chan_offset_ele",
+ 0, 3, 3, SigIesec_chan_offset_ele, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SEC_CHAN_OFFSET_ELE, 0, },
+ { offsetof(tDot11fProbeResponse, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp,
+ present), 0, "WMMInfoAp", 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOAP, 0, },
+ { offsetof(tDot11fProbeResponse, WMMParams), offsetof(tDot11fIEWMMParams,
+ present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fProbeResponse, WMMCaps), offsetof(tDot11fIEWMMCaps,
+ present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fProbeResponse, WAPI), offsetof(tDot11fIEWAPI, present),
+ 0, "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_WAPI, 0, },
+ { offsetof(tDot11fProbeResponse, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fProbeResponse, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ { offsetof(tDot11fProbeResponse, ESETxmitPower),
+ offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+ 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESETXMITPOWER, 0, },
+ { offsetof(tDot11fProbeResponse, WscProbeRes),
+ offsetof(tDot11fIEWscProbeRes, present), 0, "WscProbeRes",
+ 0, 6, 319, SigIeWscProbeRes, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCPROBERES, 0, },
+ { offsetof(tDot11fProbeResponse, P2PProbeRes),
+ offsetof(tDot11fIEP2PProbeRes, present), 0, "P2PProbeRes",
+ 0, 6, 1141, SigIeP2PProbeRes, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PPROBERES, 0, },
+ { offsetof(tDot11fProbeResponse, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fProbeResponse, VHTOperation),
+ offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+ 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fProbeResponse, VHTExtBssLoad),
+ offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad",
+ 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTEXTBSSLOAD, 0, },
+ { offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fProbeResponse, OBSSScanParameters),
+ offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+ 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ { offsetof(tDot11fProbeResponse, Vendor1IE), offsetof(tDot11fIEVendor1IE,
+ present), 0, "Vendor1IE", 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+ 3, DOT11F_EID_VENDOR1IE, 0, },
+ { offsetof(tDot11fProbeResponse, vendor2_ie),
+ offsetof(tDot11fIEvendor2_ie, present), 0, "vendor2_ie",
+ 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ { offsetof(tDot11fProbeResponse, Vendor3IE), offsetof(tDot11fIEVendor3IE,
+ present), 0, "Vendor3IE", 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+ 3, DOT11F_EID_VENDOR3IE, 0, },
+ { offsetof(tDot11fProbeResponse, ChannelSwitchWrapper),
+ offsetof(tDot11fIEChannelSwitchWrapper, present), 0,
+ "ChannelSwitchWrapper", 0, 2, 7, SigIeChannelSwitchWrapper,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANNELSWITCHWRAPPER, 0, },
+ { offsetof(tDot11fProbeResponse, QComVendorIE),
+ offsetof(tDot11fIEQComVendorIE, present), 0, "QComVendorIE",
+ 0, 7, 7, SigIeQComVendorIE, {0, 160, 198, 0, 0},
+ 3, DOT11F_EID_QCOMVENDORIE, 0, },
+ { offsetof(tDot11fProbeResponse, ESEVersion),
+ offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion",
+ 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+ 4, DOT11F_EID_ESEVERSION, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_probe_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fProbeResponse *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_ProbeResponse, IES_ProbeResponse,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_probe_response. */
+
+static const tFFDefn FFS_QosMapConfigure[] = {
+ { "Category", offsetof(tDot11fQosMapConfigure, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fQosMapConfigure, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_QosMapConfigure[] = {
+ { offsetof(tDot11fQosMapConfigure, QosMapSet),
+ offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet",
+ 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_qos_map_configure(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fQosMapConfigure *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_QosMapConfigure, IES_QosMapConfigure,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_qos_map_configure. */
+
+static const tFFDefn FFS_RadioMeasurementReport[] = {
+ { "Category", offsetof(tDot11fRadioMeasurementReport, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fRadioMeasurementReport, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fRadioMeasurementReport, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_RadioMeasurementReport[] = {
+ { offsetof(tDot11fRadioMeasurementReport, MeasurementReport),
+ offsetof(tDot11fIEMeasurementReport, present),
+ offsetof(tDot11fRadioMeasurementReport, num_MeasurementReport),
+ "MeasurementReport", 4, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MEASUREMENTREPORT, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_radio_measurement_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fRadioMeasurementReport *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_RadioMeasurementReport, IES_RadioMeasurementReport,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_radio_measurement_report. */
+
+static const tFFDefn FFS_RadioMeasurementRequest[] = {
+ { "Category", offsetof(tDot11fRadioMeasurementRequest, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fRadioMeasurementRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fRadioMeasurementRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "NumOfRepetitions", offsetof(tDot11fRadioMeasurementRequest,
+ NumOfRepetitions), SigFfNumOfRepetitions,
+ DOT11F_FF_NUMOFREPETITIONS_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_RadioMeasurementRequest[] = {
+ { offsetof(tDot11fRadioMeasurementRequest, MeasurementRequest),
+ offsetof(tDot11fIEMeasurementRequest, present),
+ offsetof(tDot11fRadioMeasurementRequest, num_MeasurementRequest),
+ "MeasurementRequest", 2, 16, 18, SigIeMeasurementRequest,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_radio_measurement_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fRadioMeasurementRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_radio_measurement_request. */
+
+static const tFFDefn FFS_ReAssocRequest[] = {
+ { "Capabilities", offsetof(tDot11fReAssocRequest, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { "ListenInterval", offsetof(tDot11fReAssocRequest, ListenInterval),
+ SigFfListenInterval, DOT11F_FF_LISTENINTERVAL_LEN, },
+ { "CurrentAPAddress", offsetof(tDot11fReAssocRequest, CurrentAPAddress),
+ SigFfCurrentAPAddress, DOT11F_FF_CURRENTAPADDRESS_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ReAssocRequest[] = {
+ { offsetof(tDot11fReAssocRequest, SSID), offsetof(tDot11fIESSID, present),
+ 0, "SSID", 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, },
+ { offsetof(tDot11fReAssocRequest, SuppRates),
+ offsetof(tDot11fIESuppRates, present), 0, "SuppRates",
+ 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fReAssocRequest, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fReAssocRequest, PowerCaps),
+ offsetof(tDot11fIEPowerCaps, present), 0, "PowerCaps",
+ 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCAPS, 0, },
+ { offsetof(tDot11fReAssocRequest, SuppChannels),
+ offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+ 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPCHANNELS, 0, },
+ { offsetof(tDot11fReAssocRequest, RSNOpaque),
+ offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque",
+ 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, QOSCapsStation),
+ offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+ 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSCAPSSTATION, 0, },
+ { offsetof(tDot11fReAssocRequest, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fReAssocRequest, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fReAssocRequest, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fReAssocRequest, RICDataDesc),
+ offsetof(tDot11fIERICDataDesc, present),
+ offsetof(tDot11fReAssocRequest, num_RICDataDesc), "RICDataDesc",
+ 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATADESC, 0, },
+ { offsetof(tDot11fReAssocRequest, WPAOpaque),
+ offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque",
+ 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0},
+ 4, DOT11F_EID_WPAOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fReAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps,
+ present), 0, "WMMCaps", 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5},
+ 5, DOT11F_EID_WMMCAPS, 0, },
+ { offsetof(tDot11fReAssocRequest, WMMInfoStation),
+ offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+ 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOSTATION, 0, },
+ { offsetof(tDot11fReAssocRequest, WscIEOpaque),
+ offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque",
+ 0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCIEOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, WAPIOpaque),
+ offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque",
+ 0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_WAPIOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, WAPI), offsetof(tDot11fIEWAPI, present),
+ 0, "WAPI", 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_WAPI, 0, },
+ { offsetof(tDot11fReAssocRequest, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fReAssocRequest, ESEVersion),
+ offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion",
+ 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0},
+ 4, DOT11F_EID_ESEVERSION, 0, },
+ { offsetof(tDot11fReAssocRequest, ESECckmOpaque),
+ offsetof(tDot11fIEESECckmOpaque, present), 0, "ESECckmOpaque",
+ 0, 12, 26, SigIeESECckmOpaque, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESECCKMOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), offsetof(tDot11fReAssocRequest, num_WMMTSPEC), "WMMTSPEC",
+ 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fReAssocRequest, ESETrafStrmRateSet),
+ offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+ 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+ 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, },
+ { offsetof(tDot11fReAssocRequest, P2PIEOpaque),
+ offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque",
+ 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PIEOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, WFDIEOpaque),
+ offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque",
+ 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0},
+ 4, DOT11F_EID_WFDIEOPAQUE, 0, },
+ { offsetof(tDot11fReAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fReAssocRequest, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ { offsetof(tDot11fReAssocRequest, QosMapSet),
+ offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet",
+ 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
+ { offsetof(tDot11fReAssocRequest, vendor2_ie),
+ offsetof(tDot11fIEvendor2_ie, present), 0, "vendor2_ie",
+ 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_re_assoc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fReAssocRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_ReAssocRequest, IES_ReAssocRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_re_assoc_request. */
+
+static const tFFDefn FFS_ReAssocResponse[] = {
+ { "Capabilities", offsetof(tDot11fReAssocResponse, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { "Status", offsetof(tDot11fReAssocResponse, Status), SigFfStatus,
+ DOT11F_FF_STATUS_LEN, },
+ { "AID", offsetof(tDot11fReAssocResponse, AID), SigFfAID,
+ DOT11F_FF_AID_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ReAssocResponse[] = {
+ { offsetof(tDot11fReAssocResponse, SuppRates),
+ offsetof(tDot11fIESuppRates, present), 0, "SuppRates",
+ 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fReAssocResponse, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fReAssocResponse, EDCAParamSet),
+ offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+ 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fReAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE,
+ present), 0, "RCPIIE", 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RCPIIE, 0, },
+ { offsetof(tDot11fReAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE,
+ present), 0, "RSNIIE", 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNIIE, 0, },
+ { offsetof(tDot11fReAssocResponse, RRMEnabledCap),
+ offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap",
+ 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RRMENABLEDCAP, 0, },
+ { offsetof(tDot11fReAssocResponse, RSNOpaque),
+ offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque",
+ 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RSNOPAQUE, 0, },
+ { offsetof(tDot11fReAssocResponse, MobilityDomain),
+ offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain",
+ 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_MOBILITYDOMAIN, 0, },
+ { offsetof(tDot11fReAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fReAssocResponse, RICDataDesc),
+ offsetof(tDot11fIERICDataDesc, present),
+ offsetof(tDot11fReAssocResponse, num_RICDataDesc), "RICDataDesc",
+ 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATADESC, 0, },
+ { offsetof(tDot11fReAssocResponse, WPA), offsetof(tDot11fIEWPA, present),
+ 0, "WPA", 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, },
+ { offsetof(tDot11fReAssocResponse, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fReAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fReAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo,
+ present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fReAssocResponse, WMMParams),
+ offsetof(tDot11fIEWMMParams, present), 0, "WMMParams",
+ 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fReAssocResponse, ESERadMgmtCap),
+ offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap",
+ 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0},
+ 4, DOT11F_EID_ESERADMGMTCAP, 0, },
+ { offsetof(tDot11fReAssocResponse, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ { offsetof(tDot11fReAssocResponse, ESETxmitPower),
+ offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower",
+ 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0},
+ 4, DOT11F_EID_ESETXMITPOWER, 0, },
+ { offsetof(tDot11fReAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), offsetof(tDot11fReAssocResponse, num_WMMTSPEC), "WMMTSPEC",
+ 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fReAssocResponse, ESETrafStrmRateSet),
+ offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+ 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+ 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, },
+ { offsetof(tDot11fReAssocResponse, WscReassocRes),
+ offsetof(tDot11fIEWscReassocRes, present), 0, "WscReassocRes",
+ 0, 6, 37, SigIeWscReassocRes, {0, 80, 242, 4, 0},
+ 4, DOT11F_EID_WSCREASSOCRES, 0, },
+ { offsetof(tDot11fReAssocResponse, P2PAssocRes),
+ offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes",
+ 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0},
+ 4, DOT11F_EID_P2PASSOCRES, 0, },
+ { offsetof(tDot11fReAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fReAssocResponse, VHTOperation),
+ offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+ 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fReAssocResponse, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fReAssocResponse, OBSSScanParameters),
+ offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters",
+ 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, },
+ { offsetof(tDot11fReAssocResponse, QosMapSet),
+ offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet",
+ 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, },
+ { offsetof(tDot11fReAssocResponse, vendor2_ie),
+ offsetof(tDot11fIEvendor2_ie, present), 0, "vendor2_ie",
+ 0, 7, 28, SigIevendor2_ie, {0, 144, 76, 0, 0},
+ 3, DOT11F_EID_VENDOR2_IE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_re_assoc_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fReAssocResponse *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_ReAssocResponse, IES_ReAssocResponse,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_re_assoc_response. */
+
+static const tFFDefn FFS_SMPowerSave[] = {
+ { "Category", offsetof(tDot11fSMPowerSave, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fSMPowerSave, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "SMPowerModeSet", offsetof(tDot11fSMPowerSave, SMPowerModeSet),
+ SigFfSMPowerModeSet, DOT11F_FF_SMPOWERMODESET_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_SMPowerSave[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_sm_power_save(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fSMPowerSave *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_SMPowerSave, IES_SMPowerSave,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_sm_power_save. */
+
+static const tFFDefn FFS_SaQueryReq[] = {
+ { "Category", offsetof(tDot11fSaQueryReq, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fSaQueryReq, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "TransactionId", offsetof(tDot11fSaQueryReq, TransactionId),
+ SigFfTransactionId, DOT11F_FF_TRANSACTIONID_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_SaQueryReq[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_sa_query_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fSaQueryReq *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_SaQueryReq, IES_SaQueryReq,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_sa_query_req. */
+
+static const tFFDefn FFS_SaQueryRsp[] = {
+ { "Category", offsetof(tDot11fSaQueryRsp, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fSaQueryRsp, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "TransactionId", offsetof(tDot11fSaQueryRsp, TransactionId),
+ SigFfTransactionId, DOT11F_FF_TRANSACTIONID_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_SaQueryRsp[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_sa_query_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fSaQueryRsp *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_SaQueryRsp, IES_SaQueryRsp,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_sa_query_rsp. */
+
+static const tFFDefn FFS_TDLSDisReq[] = {
+ { "Category", offsetof(tDot11fTDLSDisReq, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSDisReq, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSDisReq, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSDisReq[] = {
+ { offsetof(tDot11fTDLSDisReq, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_dis_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSDisReq *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSDisReq, IES_TDLSDisReq,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_dis_req. */
+
+static const tFFDefn FFS_TDLSDisRsp[] = {
+ { "Category", offsetof(tDot11fTDLSDisRsp, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSDisRsp, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSDisRsp, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "Capabilities", offsetof(tDot11fTDLSDisRsp, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSDisRsp[] = {
+ { offsetof(tDot11fTDLSDisRsp, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fTDLSDisRsp, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fTDLSDisRsp, SuppChannels),
+ offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+ 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPCHANNELS, 0, },
+ { offsetof(tDot11fTDLSDisRsp, SuppOperatingClasses),
+ offsetof(tDot11fIESuppOperatingClasses, present), 0,
+ "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, },
+ { offsetof(tDot11fTDLSDisRsp, RSN), offsetof(tDot11fIERSN, present), 0,
+ "RSN", 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
+ { offsetof(tDot11fTDLSDisRsp, ExtCap), offsetof(tDot11fIEExtCap, present),
+ 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fTDLSDisRsp, FTInfo), offsetof(tDot11fIEFTInfo, present),
+ 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fTDLSDisRsp, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fTDLSDisRsp, RICData), offsetof(tDot11fIERICData,
+ present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATA, 0, },
+ { offsetof(tDot11fTDLSDisRsp, HTCaps), offsetof(tDot11fIEHTCaps, present),
+ 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fTDLSDisRsp, ht2040_bss_coexistence),
+ offsetof(tDot11fIEht2040_bss_coexistence, present), 0,
+ "ht2040_bss_coexistence", 0, 3, 3, SigIeht2040_bss_coexistence,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, },
+ { offsetof(tDot11fTDLSDisRsp, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 1, },
+ { offsetof(tDot11fTDLSDisRsp, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSDisRsp *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSDisRsp, IES_TDLSDisRsp,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_dis_rsp. */
+
+static const tFFDefn FFS_TDLSPeerTrafficInd[] = {
+ { "Category", offsetof(tDot11fTDLSPeerTrafficInd, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSPeerTrafficInd, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSPeerTrafficInd, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSPeerTrafficInd[] = {
+ { offsetof(tDot11fTDLSPeerTrafficInd, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 1, },
+ { offsetof(tDot11fTDLSPeerTrafficInd, PTIControl),
+ offsetof(tDot11fIEPTIControl, present), 0, "PTIControl",
+ 0, 5, 5, SigIePTIControl, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_PTICONTROL, 0, },
+ { offsetof(tDot11fTDLSPeerTrafficInd, PUBufferStatus),
+ offsetof(tDot11fIEPUBufferStatus, present), 0, "PUBufferStatus",
+ 0, 3, 3, SigIePUBufferStatus, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_PUBUFFERSTATUS, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSPeerTrafficInd *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_ind. */
+
+static const tFFDefn FFS_TDLSPeerTrafficRsp[] = {
+ { "Category", offsetof(tDot11fTDLSPeerTrafficRsp, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSPeerTrafficRsp, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSPeerTrafficRsp, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSPeerTrafficRsp[] = {
+ { offsetof(tDot11fTDLSPeerTrafficRsp, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSPeerTrafficRsp *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_rsp. */
+
+static const tFFDefn FFS_TDLSSetupCnf[] = {
+ { "Category", offsetof(tDot11fTDLSSetupCnf, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSSetupCnf, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "Status", offsetof(tDot11fTDLSSetupCnf, Status), SigFfStatus,
+ DOT11F_FF_STATUS_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSSetupCnf, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSSetupCnf[] = {
+ { offsetof(tDot11fTDLSSetupCnf, RSN), offsetof(tDot11fIERSN, present), 0,
+ "RSN", 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, EDCAParamSet),
+ offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet",
+ 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EDCAPARAMSET, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, HTInfo), offsetof(tDot11fIEHTInfo,
+ present), 0, "HTInfo", 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTINFO, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, WMMParams), offsetof(tDot11fIEWMMParams,
+ present), 0, "WMMParams", 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1},
+ 5, DOT11F_EID_WMMPARAMS, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, VHTOperation),
+ offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation",
+ 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTOPERATION, 0, },
+ { offsetof(tDot11fTDLSSetupCnf, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSSetupCnf *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSSetupCnf, IES_TDLSSetupCnf,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_setup_cnf. */
+
+static const tFFDefn FFS_TDLSSetupReq[] = {
+ { "Category", offsetof(tDot11fTDLSSetupReq, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSSetupReq, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSSetupReq, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "Capabilities", offsetof(tDot11fTDLSSetupReq, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSSetupReq[] = {
+ { offsetof(tDot11fTDLSSetupReq, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 1, },
+ { offsetof(tDot11fTDLSSetupReq, Country), offsetof(tDot11fIECountry,
+ present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fTDLSSetupReq, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fTDLSSetupReq, SuppChannels),
+ offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+ 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPCHANNELS, 0, },
+ { offsetof(tDot11fTDLSSetupReq, RSN), offsetof(tDot11fIERSN, present), 0,
+ "RSN", 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
+ { offsetof(tDot11fTDLSSetupReq, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fTDLSSetupReq, SuppOperatingClasses),
+ offsetof(tDot11fIESuppOperatingClasses, present), 0,
+ "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, },
+ { offsetof(tDot11fTDLSSetupReq, QOSCapsStation),
+ offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+ 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSCAPSSTATION, 0, },
+ { offsetof(tDot11fTDLSSetupReq, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fTDLSSetupReq, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fTDLSSetupReq, RICData), offsetof(tDot11fIERICData,
+ present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATA, 0, },
+ { offsetof(tDot11fTDLSSetupReq, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fTDLSSetupReq, ht2040_bss_coexistence),
+ offsetof(tDot11fIEht2040_bss_coexistence, present), 0,
+ "ht2040_bss_coexistence", 0, 3, 3, SigIeht2040_bss_coexistence,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, },
+ { offsetof(tDot11fTDLSSetupReq, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 1, },
+ { offsetof(tDot11fTDLSSetupReq, WMMInfoStation),
+ offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+ 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOSTATION, 0, },
+ { offsetof(tDot11fTDLSSetupReq, AID), offsetof(tDot11fIEAID, present), 0,
+ "AID", 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, },
+ { offsetof(tDot11fTDLSSetupReq, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_setup_req(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSSetupReq *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSSetupReq, IES_TDLSSetupReq,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_setup_req. */
+
+static const tFFDefn FFS_TDLSSetupRsp[] = {
+ { "Category", offsetof(tDot11fTDLSSetupRsp, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSSetupRsp, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "Status", offsetof(tDot11fTDLSSetupRsp, Status), SigFfStatus,
+ DOT11F_FF_STATUS_LEN, },
+ { "DialogToken", offsetof(tDot11fTDLSSetupRsp, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "Capabilities", offsetof(tDot11fTDLSSetupRsp, Capabilities),
+ SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSSetupRsp[] = {
+ { offsetof(tDot11fTDLSSetupRsp, SuppRates), offsetof(tDot11fIESuppRates,
+ present), 0, "SuppRates", 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPRATES, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, Country), offsetof(tDot11fIECountry,
+ present), 0, "Country", 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, ExtSuppRates),
+ offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates",
+ 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTSUPPRATES, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, SuppChannels),
+ offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels",
+ 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_SUPPCHANNELS, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, RSN), offsetof(tDot11fIERSN, present), 0,
+ "RSN", 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, ExtCap), offsetof(tDot11fIEExtCap,
+ present), 0, "ExtCap", 0, 10, 11, SigIeExtCap, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, SuppOperatingClasses),
+ offsetof(tDot11fIESuppOperatingClasses, present), 0,
+ "SuppOperatingClasses", 0, 3, 34, SigIeSuppOperatingClasses,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, QOSCapsStation),
+ offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation",
+ 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_QOSCAPSSTATION, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, TimeoutInterval),
+ offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval",
+ 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEOUTINTERVAL, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, RICData), offsetof(tDot11fIERICData,
+ present), 0, "RICData", 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_RICDATA, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, HTCaps), offsetof(tDot11fIEHTCaps,
+ present), 0, "HTCaps", 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HTCAPS, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, ht2040_bss_coexistence),
+ offsetof(tDot11fIEht2040_bss_coexistence, present), 0,
+ "ht2040_bss_coexistence", 0, 3, 3, SigIeht2040_bss_coexistence,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, WMMInfoStation),
+ offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation",
+ 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0},
+ 5, DOT11F_EID_WMMINFOSTATION, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, AID), offsetof(tDot11fIEAID, present), 0,
+ "AID", 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, VHTCaps), offsetof(tDot11fIEVHTCaps,
+ present), 0, "VHTCaps", 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_VHTCAPS, 0, },
+ { offsetof(tDot11fTDLSSetupRsp, OperatingMode),
+ offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode",
+ 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_OPERATINGMODE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSSetupRsp *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSSetupRsp, IES_TDLSSetupRsp,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_setup_rsp. */
+
+static const tFFDefn FFS_TDLSTeardown[] = {
+ { "Category", offsetof(tDot11fTDLSTeardown, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTDLSTeardown, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "Reason", offsetof(tDot11fTDLSTeardown, Reason), SigFfReason,
+ DOT11F_FF_REASON_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TDLSTeardown[] = {
+ { offsetof(tDot11fTDLSTeardown, FTInfo), offsetof(tDot11fIEFTInfo,
+ present), 0, "FTInfo", 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_FTINFO, 0, },
+ { offsetof(tDot11fTDLSTeardown, LinkIdentifier),
+ offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier",
+ 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_LINKIDENTIFIER, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tdls_teardown(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTDLSTeardown *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TDLSTeardown, IES_TDLSTeardown,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tdls_teardown. */
+
+static const tFFDefn FFS_TPCReport[] = {
+ { "Category", offsetof(tDot11fTPCReport, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTPCReport, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTPCReport, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TPCReport[] = {
+ { offsetof(tDot11fTPCReport, TPCReport), offsetof(tDot11fIETPCReport,
+ present), 0, "TPCReport", 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TPCREPORT, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tpc_report(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTPCReport *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TPCReport, IES_TPCReport,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tpc_report. */
+
+static const tFFDefn FFS_TPCRequest[] = {
+ { "Category", offsetof(tDot11fTPCRequest, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fTPCRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fTPCRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TPCRequest[] = {
+ { offsetof(tDot11fTPCRequest, TPCRequest), offsetof(tDot11fIETPCRequest,
+ present), 0, "TPCRequest", 0, 2, 2, SigIeTPCRequest, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TPCREQUEST, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_tpc_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTPCRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TPCRequest, IES_TPCRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_tpc_request. */
+
+static const tFFDefn FFS_TimingAdvertisementFrame[] = {
+ { "TimeStamp", offsetof(tDot11fTimingAdvertisementFrame, TimeStamp),
+ SigFfTimeStamp, DOT11F_FF_TIMESTAMP_LEN, },
+ { "Capabilities", offsetof(tDot11fTimingAdvertisementFrame,
+ Capabilities), SigFfCapabilities, DOT11F_FF_CAPABILITIES_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_TimingAdvertisementFrame[] = {
+ { offsetof(tDot11fTimingAdvertisementFrame, Country),
+ offsetof(tDot11fIECountry, present), 0, "Country", 0, 5, 257, SigIeCountry,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, },
+ { offsetof(tDot11fTimingAdvertisementFrame, PowerConstraints),
+ offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints",
+ 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_POWERCONSTRAINTS, 0, },
+ { offsetof(tDot11fTimingAdvertisementFrame, TimeAdvertisement),
+ offsetof(tDot11fIETimeAdvertisement, present), 0, "TimeAdvertisement",
+ 0, 18, 18, SigIeTimeAdvertisement, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_TIMEADVERTISEMENT, 0, },
+ { offsetof(tDot11fTimingAdvertisementFrame, ExtCap),
+ offsetof(tDot11fIEExtCap, present), 0, "ExtCap", 0, 10, 11, SigIeExtCap,
+ {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, },
+ { offsetof(tDot11fTimingAdvertisementFrame, Vendor1IE),
+ offsetof(tDot11fIEVendor1IE, present), 0, "Vendor1IE",
+ 0, 5, 5, SigIeVendor1IE, {0, 16, 24, 0, 0},
+ 3, DOT11F_EID_VENDOR1IE, 0, },
+ { offsetof(tDot11fTimingAdvertisementFrame, Vendor3IE),
+ offsetof(tDot11fIEVendor3IE, present), 0, "Vendor3IE",
+ 0, 5, 5, SigIeVendor3IE, {0, 22, 50, 0, 0},
+ 3, DOT11F_EID_VENDOR3IE, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fTimingAdvertisementFrame *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_TimingAdvertisementFrame, IES_TimingAdvertisementFrame,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_timing_advertisement_frame. */
+
+static const tFFDefn FFS_VHTGidManagementActionFrame[] = {
+ { "Category", offsetof(tDot11fVHTGidManagementActionFrame, Category),
+ SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fVHTGidManagementActionFrame, Action),
+ SigFfAction, DOT11F_FF_ACTION_LEN, },
+ { "VhtMembershipStatusArray",
+ offsetof(tDot11fVHTGidManagementActionFrame, VhtMembershipStatusArray),
+ SigFfVhtMembershipStatusArray,
+ DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN, },
+ { "VhtUserPositionArray", offsetof(tDot11fVHTGidManagementActionFrame,
+ VhtUserPositionArray), SigFfVhtUserPositionArray,
+ DOT11F_FF_VHTUSERPOSITIONARRAY_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_VHTGidManagementActionFrame[] = {
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fVHTGidManagementActionFrame *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_vht_gid_management_action_frame. */
+
+static const tFFDefn FFS_WMMAddTSRequest[] = {
+ { "Category", offsetof(tDot11fWMMAddTSRequest, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fWMMAddTSRequest, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fWMMAddTSRequest, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "StatusCode", offsetof(tDot11fWMMAddTSRequest, StatusCode),
+ SigFfStatusCode, DOT11F_FF_STATUSCODE_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_WMMAddTSRequest[] = {
+ { offsetof(tDot11fWMMAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 1, },
+ { offsetof(tDot11fWMMAddTSRequest, ESETrafStrmRateSet),
+ offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet",
+ 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0},
+ 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fWMMAddTSRequest *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_WMMAddTSRequest, IES_WMMAddTSRequest,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_wmm_add_ts_request. */
+
+static const tFFDefn FFS_WMMAddTSResponse[] = {
+ { "Category", offsetof(tDot11fWMMAddTSResponse, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fWMMAddTSResponse, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fWMMAddTSResponse, DialogToken),
+ SigFfDialogToken, DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "StatusCode", offsetof(tDot11fWMMAddTSResponse, StatusCode),
+ SigFfStatusCode, DOT11F_FF_STATUSCODE_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_WMMAddTSResponse[] = {
+ { offsetof(tDot11fWMMAddTSResponse, WMMTSPEC),
+ offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC",
+ 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 0, },
+ { offsetof(tDot11fWMMAddTSResponse, ESETrafStrmMet),
+ offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet",
+ 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0},
+ 4, DOT11F_EID_ESETRAFSTRMMET, 0, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fWMMAddTSResponse *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_WMMAddTSResponse, IES_WMMAddTSResponse,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_wmm_add_ts_response. */
+
+static const tFFDefn FFS_WMMDelTS[] = {
+ { "Category", offsetof(tDot11fWMMDelTS, Category), SigFfCategory,
+ DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fWMMDelTS, Action), SigFfAction,
+ DOT11F_FF_ACTION_LEN, },
+ { "DialogToken", offsetof(tDot11fWMMDelTS, DialogToken), SigFfDialogToken,
+ DOT11F_FF_DIALOGTOKEN_LEN, },
+ { "StatusCode", offsetof(tDot11fWMMDelTS, StatusCode), SigFfStatusCode,
+ DOT11F_FF_STATUSCODE_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_WMMDelTS[] = {
+ { offsetof(tDot11fWMMDelTS, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC,
+ present), 0, "WMMTSPEC", 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2},
+ 5, DOT11F_EID_WMMTSPEC, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_wmm_del_ts(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fWMMDelTS *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_WMMDelTS, IES_WMMDelTS,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_wmm_del_ts. */
+
+static const tFFDefn FFS_ht2040_bss_coexistence_mgmt_action_frame[] = {
+ { "Category", offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+ Category), SigFfCategory, DOT11F_FF_CATEGORY_LEN, },
+ { "Action", offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+ Action), SigFfAction, DOT11F_FF_ACTION_LEN, },
+ { NULL, 0, 0, 0,},
+};
+
+static const tIEDefn IES_ht2040_bss_coexistence_mgmt_action_frame[] = {
+ { offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+ ht2040_bss_coexistence), offsetof(tDot11fIEht2040_bss_coexistence,
+ present), 0, "ht2040_bss_coexistence",
+ 0, 3, 3, SigIeht2040_bss_coexistence, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HT2040_BSS_COEXISTENCE, 1, },
+ { offsetof(tDot11fht2040_bss_coexistence_mgmt_action_frame,
+ ht2040_bss_intolerant_report),
+ offsetof(tDot11fIEht2040_bss_intolerant_report, present), 0,
+ "ht2040_bss_intolerant_report",
+ 0, 3, 53, SigIeht2040_bss_intolerant_report, {0, 0, 0, 0, 0},
+ 0, DOT11F_EID_HT2040_BSS_INTOLERANT_REPORT, 1, },
+ {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
+
+uint32_t dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+ uint8_t *pBuf, uint32_t nBuf,
+ tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ status = unpack_core(pCtx, pBuf, nBuf,
+ FFS_ht2040_bss_coexistence_mgmt_action_frame, IES_ht2040_bss_coexistence_mgmt_action_frame,
+ (uint8_t *)pFrm, sizeof(*pFrm));
+
+ (void)i;
+ return status;
+
+} /* End dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame. */
+
+static uint32_t unpack_core(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ const tFFDefn FFs[],
+ const tIEDefn IEs[],
+ uint8_t *pFrm,
+ size_t nFrm)
+{
+ const tFFDefn *pFf;
+ const tIEDefn *pIe;
+ uint8_t *pBufRemaining;
+ uint32_t nBufRemaining, status;
+ uint8_t eid, len;
+ tFRAMES_BOOL *pfFound;
+ uint32_t countOffset = 0;
+
+ DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm);
+ (void)nFrm;
+
+ (void)pCtx;
+ status = DOT11F_PARSE_SUCCESS;
+ pBufRemaining = pBuf;
+ nBufRemaining = nBuf;
+
+ pIe = &IEs[0];
+ while (0xff != pIe->eid) {
+ pfFound = (tFRAMES_BOOL *)(pFrm + pIe->offset +
+ pIe->presenceOffset);
+ *pfFound = 0U;
+ if (pIe->countOffset)
+ *(uint16_t *)(pFrm + pIe->countOffset) = 0U;
+ ++pIe;
+ }
+
+ pFf = &FFs[0];
+ while (pFf->size) {
+ if (pFf->size > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGE, FRFL("Fixed field %s is %d"
+ "bytes in size, but there are only %d bytes left i"
+ "n this frame.\n"), pFf->name, pFf->size,
+ nBufRemaining);
+ FRAMES_DBG_BREAK();
+ return DOT11F_MISSING_FIXED_FIELD;
+ }
+
+ switch (pFf->sig) {
+
+ case SigFfAID:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfAID *)
+ (pFrm + pFf->offset))->associd));
+ break;
+ case SigFfAction:
+ dot11f_unpack_ff_action(pCtx,
+ pBufRemaining, (tDot11fFfAction *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfAuthAlgo:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfAuthAlgo *)
+ (pFrm + pFf->offset))->algo));
+ break;
+ case SigFfAuthSeqNo:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfAuthSeqNo *)
+ (pFrm + pFf->offset))->no));
+ break;
+ case SigFfBeaconInterval:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfBeaconInterval *)
+ (pFrm + pFf->offset))->interval));
+ break;
+ case SigFfCapabilities:
+ dot11f_unpack_ff_capabilities(pCtx,
+ pBufRemaining, (tDot11fFfCapabilities *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfCategory:
+ dot11f_unpack_ff_category(pCtx,
+ pBufRemaining, (tDot11fFfCategory *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfCurrentAPAddress:
+ dot11f_unpack_ff_current_ap_address(pCtx,
+ pBufRemaining, (tDot11fFfCurrentAPAddress *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfDialogToken:
+ dot11f_unpack_ff_dialog_token(pCtx,
+ pBufRemaining, (tDot11fFfDialogToken *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfLinkMargin:
+ dot11f_unpack_ff_link_margin(pCtx,
+ pBufRemaining, (tDot11fFfLinkMargin *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfListenInterval:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfListenInterval *)
+ (pFrm + pFf->offset))->interval));
+ break;
+ case SigFfMaxTxPower:
+ dot11f_unpack_ff_max_tx_power(pCtx,
+ pBufRemaining, (tDot11fFfMaxTxPower *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfNumOfRepetitions:
+ dot11f_unpack_ff_num_of_repetitions(pCtx,
+ pBufRemaining, (tDot11fFfNumOfRepetitions *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfOperatingMode:
+ dot11f_unpack_ff_operating_mode(pCtx,
+ pBufRemaining, (tDot11fFfOperatingMode *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfRCPI:
+ dot11f_unpack_ff_rcpi(pCtx,
+ pBufRemaining, (tDot11fFfRCPI *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfRSNI:
+ dot11f_unpack_ff_rsni(pCtx,
+ pBufRemaining, (tDot11fFfRSNI *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfReason:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfReason *)
+ (pFrm + pFf->offset))->code));
+ break;
+ case SigFfRxAntennaId:
+ dot11f_unpack_ff_rx_antenna_id(pCtx,
+ pBufRemaining, (tDot11fFfRxAntennaId *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfSMPowerModeSet:
+ dot11f_unpack_ff_sm_power_mode_set(pCtx,
+ pBufRemaining, (tDot11fFfSMPowerModeSet *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfStatus:
+ dot11f_unpack_ff_common_func(pCtx,
+ pBufRemaining, (uint16_t *)&(((tDot11fFfStatus *)
+ (pFrm + pFf->offset))->status));
+ break;
+ case SigFfStatusCode:
+ dot11f_unpack_ff_status_code(pCtx,
+ pBufRemaining, (tDot11fFfStatusCode *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTPCEleID:
+ dot11f_unpack_ff_tpc_ele_id(pCtx,
+ pBufRemaining, (tDot11fFfTPCEleID *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTPCEleLen:
+ dot11f_unpack_ff_tpc_ele_len(pCtx,
+ pBufRemaining, (tDot11fFfTPCEleLen *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTSInfo:
+ dot11f_unpack_ff_ts_info(pCtx,
+ pBufRemaining, (tDot11fFfTSInfo *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTimeStamp:
+ dot11f_unpack_ff_time_stamp(pCtx,
+ pBufRemaining, (tDot11fFfTimeStamp *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTransactionId:
+ dot11f_unpack_ff_transaction_id(pCtx,
+ pBufRemaining, (tDot11fFfTransactionId *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTxAntennaId:
+ dot11f_unpack_ff_tx_antenna_id(pCtx,
+ pBufRemaining, (tDot11fFfTxAntennaId *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfTxPower:
+ dot11f_unpack_ff_tx_power(pCtx,
+ pBufRemaining, (tDot11fFfTxPower *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfVhtMembershipStatusArray:
+ dot11f_unpack_ff_vht_membership_status_array(pCtx,
+ pBufRemaining, (tDot11fFfVhtMembershipStatusArray *)
+ (pFrm + pFf->offset));
+ break;
+ case SigFfVhtUserPositionArray:
+ dot11f_unpack_ff_vht_user_position_array(pCtx,
+ pBufRemaining, (tDot11fFfVhtUserPositionArray *)
+ (pFrm + pFf->offset));
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I don'"
+ "t know about the FF signature %d-- this is most "
+ "likely a 'framesc' bug.\n"), pFf->sig);
+ return DOT11F_INTERNAL_ERROR;
+ }
+
+ pBufRemaining += pFf->size;
+ nBufRemaining -= pFf->size;
+ ++pFf;
+ }
+
+ while (nBufRemaining) {
+ if (1 == nBufRemaining) {
+ FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+ "only one byte remaining after it's fixed fields.\n"));
+ status |= DOT11F_INCOMPLETE_IE;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+
+ pIe = find_ie_defn(pCtx, pBufRemaining, nBufRemaining, IEs);
+
+ eid = *pBufRemaining++; --nBufRemaining;
+ len = *pBufRemaining++; --nBufRemaining;
+
+ if (pIe && pIe->noui) {
+ if (pIe->noui > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGW, FRFL("IE %d reports "
+ "length %d, but it has an OUI of %d bytes.\n"),
+ eid, len, pIe->noui);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by"
+ "tes of this buffer, and show %d left.\n"),
+ pBufRemaining - pBuf, nBufRemaining);
+ status |= DOT11F_INCOMPLETE_IE;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+ pBufRemaining += pIe->noui;
+ nBufRemaining -= pIe->noui;
+ len -= pIe->noui;
+ }
+
+ if (len > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGW, FRFL("IE %d reports length %"
+ "d, but there are only %d bytes remaining in this"
+ " frame.\n"), eid, len, nBufRemaining);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by"
+ "tes of this buffer, and show %d left.\n"),
+ pBufRemaining - pBuf, nBufRemaining);
+ status |= DOT11F_INCOMPLETE_IE;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+
+ if (pIe) {
+ if (nBufRemaining < pIe->minSize - pIe->noui - 2U) {
+ FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be "
+ "at least %d bytes in size, but there are onl"
+ "y %d bytes remaining in this frame.\n"),
+ pIe->name, pIe->minSize, nBufRemaining);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ status |= DOT11F_INCOMPLETE_IE;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ } else {
+ if (len > pIe->maxSize - pIe->noui - 2U) {
+ FRAMES_LOG1(pCtx, FRLOGW, FRFL("The IE %s reports "
+ "an unexpectedly large size; it is presumably "
+ "more up-to-date than this parser, but this wa"
+ "rning may also indicate a corrupt frame.\n"),
+ pIe->name);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ }
+
+ countOffset = ((0 != pIe->arraybound) *
+ (*(uint16_t *)(pFrm + pIe->countOffset)));
+ switch (pIe->sig) {
+ case SigIeCondensedCountryStr:
+ status |=
+ dot11f_unpack_ie_condensed_country_str(
+ pCtx, pBufRemaining, len,
+ (tDot11fIECondensedCountryStr *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIECondensedCountryStr) *
+ countOffset));
+ break;
+ case SigIeGTK:
+ status |=
+ dot11f_unpack_ie_gtk(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEGTK *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEGTK) *
+ countOffset));
+ break;
+ case SigIeIGTK:
+ status |=
+ dot11f_unpack_ie_igtk(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEIGTK *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEIGTK) *
+ countOffset));
+ break;
+ case SigIeR0KH_ID:
+ status |=
+ dot11f_unpack_ie_r0_kh_id(
+ pCtx, pBufRemaining, len,
+ (tDot11fIER0KH_ID *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIER0KH_ID) *
+ countOffset));
+ break;
+ case SigIeR1KH_ID:
+ status |=
+ dot11f_unpack_ie_r1_kh_id(
+ pCtx, pBufRemaining, len,
+ (tDot11fIER1KH_ID *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIER1KH_ID) *
+ countOffset));
+ break;
+ case SigIeTSFInfo:
+ status |=
+ dot11f_unpack_ie_tsf_info(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETSFInfo *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETSFInfo) *
+ countOffset));
+ break;
+ case SigIeAPChannelReport:
+ status |=
+ dot11f_unpack_ie_ap_channel_report(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEAPChannelReport *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEAPChannelReport) *
+ countOffset));
+ break;
+ case SigIeBcnReportingDetail:
+ status |=
+ dot11f_unpack_ie_bcn_reporting_detail(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEBcnReportingDetail *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEBcnReportingDetail) *
+ countOffset));
+ break;
+ case SigIeBeaconReportFrmBody:
+ status |=
+ dot11f_unpack_ie_beacon_report_frm_body(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEBeaconReportFrmBody *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEBeaconReportFrmBody) *
+ countOffset));
+ break;
+ case SigIeBeaconReporting:
+ status |=
+ dot11f_unpack_ie_beacon_reporting(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEBeaconReporting *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEBeaconReporting) *
+ countOffset));
+ break;
+ case SigIeMeasurementPilot:
+ status |=
+ dot11f_unpack_ie_measurement_pilot(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEMeasurementPilot *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEMeasurementPilot) *
+ countOffset));
+ break;
+ case SigIeMultiBssid:
+ status |=
+ dot11f_unpack_ie_multi_bssid(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEMultiBssid *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEMultiBssid) *
+ countOffset));
+ break;
+ case SigIeRICData:
+ status |=
+ dot11f_unpack_ie_ric_data(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERICData *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERICData) *
+ countOffset));
+ break;
+ case SigIeRICDescriptor:
+ status |=
+ dot11f_unpack_ie_ric_descriptor(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERICDescriptor *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERICDescriptor) *
+ countOffset));
+ break;
+ case SigIeRRMEnabledCap:
+ status |=
+ dot11f_unpack_ie_rrm_enabled_cap(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERRMEnabledCap *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERRMEnabledCap) *
+ countOffset));
+ break;
+ case SigIeRequestedInfo:
+ status |=
+ dot11f_unpack_ie_requested_info(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERequestedInfo *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERequestedInfo) *
+ countOffset));
+ break;
+ case SigIeSSID:
+ status |=
+ dot11f_unpack_ie_ssid(
+ pCtx, pBufRemaining, len,
+ (tDot11fIESSID *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIESSID) *
+ countOffset));
+ break;
+ case SigIeSchedule:
+ status |=
+ dot11f_unpack_ie_schedule(
+ pCtx, pBufRemaining, len,
+ (tDot11fIESchedule *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIESchedule) *
+ countOffset));
+ break;
+ case SigIeTCLAS:
+ status |=
+ dot11f_unpack_ie_tclas(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETCLAS *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETCLAS) *
+ countOffset));
+ break;
+ case SigIeTCLASSPROC:
+ status |= dot11f_unpack_ie_common_func(pCtx, pBufRemaining, len,
+ (uint8_t *) &(((tDot11fIETCLASSPROC *)(pFrm + pIe->offset + sizeof(tDot11fIETCLASSPROC)*countOffset))->present),
+ (uint8_t *) &(((tDot11fIETCLASSPROC *)(pFrm + pIe->offset + sizeof(tDot11fIETCLASSPROC)*countOffset))->processing));
+ break;
+ case SigIeTSDelay:
+ status |=
+ dot11f_unpack_ie_ts_delay(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETSDelay *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETSDelay) *
+ countOffset));
+ break;
+ case SigIeTSPEC:
+ status |=
+ dot11f_unpack_ie_tspec(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETSPEC *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETSPEC) *
+ countOffset));
+ break;
+ case SigIeVHTCaps:
+ status |=
+ dot11f_unpack_ie_vht_caps(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEVHTCaps *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEVHTCaps) *
+ countOffset));
+ break;
+ case SigIeVHTOperation:
+ status |=
+ dot11f_unpack_ie_vht_operation(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEVHTOperation *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEVHTOperation) *
+ countOffset));
+ break;
+ case SigIeWMMSchedule:
+ status |=
+ dot11f_unpack_ie_wmm_schedule(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMSchedule *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMSchedule) *
+ countOffset));
+ break;
+ case SigIeWMMTCLAS:
+ status |=
+ dot11f_unpack_ie_wmmtclas(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMTCLAS *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMTCLAS) *
+ countOffset));
+ break;
+ case SigIeWMMTCLASPROC:
+ status |=
+ dot11f_unpack_ie_wmmtclasproc(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMTCLASPROC *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMTCLASPROC) *
+ countOffset));
+ break;
+ case SigIeWMMTSDelay:
+ status |=
+ dot11f_unpack_ie_wmmts_delay(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMTSDelay *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMTSDelay) *
+ countOffset));
+ break;
+ case SigIeWMMTSPEC:
+ status |=
+ dot11f_unpack_ie_wmmtspec(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMTSPEC *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMTSPEC) *
+ countOffset));
+ break;
+ case SigIeWiderBWChanSwitchAnn:
+ status |=
+ dot11f_unpack_ie_wider_bw_chan_switch_ann(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWiderBWChanSwitchAnn *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWiderBWChanSwitchAnn) *
+ countOffset));
+ break;
+ case SigIeAID:
+ status |=
+ dot11f_unpack_ie_aid(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEAID *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEAID) *
+ countOffset));
+ break;
+ case SigIeCFParams:
+ status |=
+ dot11f_unpack_ie_cf_params(
+ pCtx, pBufRemaining, len,
+ (tDot11fIECFParams *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIECFParams) *
+ countOffset));
+ break;
+ case SigIeChallengeText:
+ status |=
+ dot11f_unpack_ie_challenge_text(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEChallengeText *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEChallengeText) *
+ countOffset));
+ break;
+ case SigIeChanSwitchAnn:
+ status |=
+ dot11f_unpack_ie_chan_switch_ann(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEChanSwitchAnn *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEChanSwitchAnn) *
+ countOffset));
+ break;
+ case SigIeChannelSwitchWrapper:
+ status |=
+ dot11f_unpack_ie_channel_switch_wrapper(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEChannelSwitchWrapper *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEChannelSwitchWrapper) *
+ countOffset));
+ break;
+ case SigIeCountry:
+ status |=
+ dot11f_unpack_ie_country(
+ pCtx, pBufRemaining, len,
+ (tDot11fIECountry *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIECountry) *
+ countOffset));
+ break;
+ case SigIeDSParams:
+ status |= dot11f_unpack_ie_common_func(pCtx, pBufRemaining, len,
+ (uint8_t *) &(((tDot11fIEDSParams *)(pFrm + pIe->offset + sizeof(tDot11fIEDSParams)*countOffset))->present),
+ (uint8_t *) &(((tDot11fIEDSParams *)(pFrm + pIe->offset + sizeof(tDot11fIEDSParams)*countOffset))->curr_channel));
+ break;
+ case SigIeEDCAParamSet:
+ status |=
+ dot11f_unpack_ie_edca_param_set(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEEDCAParamSet *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEEDCAParamSet) *
+ countOffset));
+ break;
+ case SigIeERPInfo:
+ status |=
+ dot11f_unpack_ie_erp_info(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEERPInfo *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEERPInfo) *
+ countOffset));
+ break;
+ case SigIeESECckmOpaque:
+ status |=
+ dot11f_unpack_ie_ese_cckm_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEESECckmOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEESECckmOpaque) *
+ countOffset));
+ break;
+ case SigIeESERadMgmtCap:
+ status |=
+ dot11f_unpack_ie_ese_rad_mgmt_cap(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEESERadMgmtCap *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEESERadMgmtCap) *
+ countOffset));
+ break;
+ case SigIeESETrafStrmMet:
+ status |=
+ dot11f_unpack_ie_ese_traf_strm_met(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEESETrafStrmMet *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEESETrafStrmMet) *
+ countOffset));
+ break;
+ case SigIeESETrafStrmRateSet:
+ status |=
+ dot11f_unpack_ie_ese_traf_strm_rate_set(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEESETrafStrmRateSet *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEESETrafStrmRateSet) *
+ countOffset));
+ break;
+ case SigIeESETxmitPower:
+ status |=
+ dot11f_unpack_ie_ese_txmit_power(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEESETxmitPower *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEESETxmitPower) *
+ countOffset));
+ break;
+ case SigIeESEVersion:
+ status |=
+ dot11f_unpack_ie_ese_version(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEESEVersion *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEESEVersion) *
+ countOffset));
+ break;
+ case SigIeExtCap:
+ status |=
+ dot11f_unpack_ie_ext_cap(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEExtCap *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEExtCap) *
+ countOffset));
+ break;
+ case SigIeExtSuppRates:
+ status |=
+ dot11f_unpack_ie_ext_supp_rates(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEExtSuppRates *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEExtSuppRates) *
+ countOffset));
+ break;
+ case SigIeFHParamSet:
+ status |=
+ dot11f_unpack_ie_fh_param_set(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEFHParamSet *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEFHParamSet) *
+ countOffset));
+ break;
+ case SigIeFHParams:
+ status |=
+ dot11f_unpack_ie_fh_params(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEFHParams *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEFHParams) *
+ countOffset));
+ break;
+ case SigIeFHPattTable:
+ status |=
+ dot11f_unpack_ie_fh_patt_table(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEFHPattTable *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEFHPattTable) *
+ countOffset));
+ break;
+ case SigIeFTInfo:
+ status |=
+ dot11f_unpack_ie_ft_info(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEFTInfo *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEFTInfo) *
+ countOffset));
+ break;
+ case SigIeHTCaps:
+ status |=
+ dot11f_unpack_ie_ht_caps(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEHTCaps *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEHTCaps) *
+ countOffset));
+ break;
+ case SigIeHTInfo:
+ status |=
+ dot11f_unpack_ie_ht_info(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEHTInfo *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEHTInfo) *
+ countOffset));
+ break;
+ case SigIeIBSSParams:
+ status |=
+ dot11f_unpack_ie_ibss_params(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEIBSSParams *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEIBSSParams) *
+ countOffset));
+ break;
+ case SigIeLinkIdentifier:
+ status |=
+ dot11f_unpack_ie_link_identifier(
+ pCtx, pBufRemaining, len,
+ (tDot11fIELinkIdentifier *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIELinkIdentifier) *
+ countOffset));
+ break;
+ case SigIeMeasurementReport:
+ status |=
+ dot11f_unpack_ie_measurement_report(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEMeasurementReport *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEMeasurementReport) *
+ countOffset));
+ break;
+ case SigIeMeasurementRequest:
+ status |=
+ dot11f_unpack_ie_measurement_request(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEMeasurementRequest *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEMeasurementRequest) *
+ countOffset));
+ break;
+ case SigIeMobilityDomain:
+ status |=
+ dot11f_unpack_ie_mobility_domain(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEMobilityDomain *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEMobilityDomain) *
+ countOffset));
+ break;
+ case SigIeNeighborReport:
+ if (countOffset < MAX_SUPPORTED_NEIGHBOR_RPT) {
+ status |=
+ dot11f_unpack_ie_neighbor_report(
+ pCtx, pBufRemaining, len,
+ (tDot11fIENeighborReport *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIENeighborReport) *
+ countOffset));
+ } else {
+ status |= DOT11F_BUFFER_OVERFLOW;
+ }
+ break;
+ case SigIeOBSSScanParameters:
+ status |=
+ dot11f_unpack_ie_obss_scan_parameters(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEOBSSScanParameters *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEOBSSScanParameters) *
+ countOffset));
+ break;
+ case SigIeOperatingMode:
+ status |=
+ dot11f_unpack_ie_operating_mode(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEOperatingMode *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEOperatingMode) *
+ countOffset));
+ break;
+ case SigIeP2PAssocReq:
+ status |=
+ dot11f_unpack_ie_p2_p_assoc_req(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PAssocReq *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PAssocReq) *
+ countOffset));
+ break;
+ case SigIeP2PAssocRes:
+ status |=
+ dot11f_unpack_ie_p2_p_assoc_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PAssocRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PAssocRes) *
+ countOffset));
+ break;
+ case SigIeP2PBeacon:
+ status |=
+ dot11f_unpack_ie_p2_p_beacon(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PBeacon *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PBeacon) *
+ countOffset));
+ break;
+ case SigIeP2PBeaconProbeRes:
+ status |=
+ dot11f_unpack_ie_p2_p_beacon_probe_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PBeaconProbeRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PBeaconProbeRes) *
+ countOffset));
+ break;
+ case SigIeP2PDeAuth:
+ status |=
+ dot11f_unpack_ie_p2_p_de_auth(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PDeAuth *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PDeAuth) *
+ countOffset));
+ break;
+ case SigIeP2PDisAssoc:
+ status |=
+ dot11f_unpack_ie_p2_p_dis_assoc(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PDisAssoc *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PDisAssoc) *
+ countOffset));
+ break;
+ case SigIeP2PIEOpaque:
+ status |=
+ dot11f_unpack_ie_p2_pie_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PIEOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PIEOpaque) *
+ countOffset));
+ break;
+ case SigIeP2PProbeReq:
+ status |=
+ dot11f_unpack_ie_p2_p_probe_req(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PProbeReq *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PProbeReq) *
+ countOffset));
+ break;
+ case SigIeP2PProbeRes:
+ status |=
+ dot11f_unpack_ie_p2_p_probe_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEP2PProbeRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEP2PProbeRes) *
+ countOffset));
+ break;
+ case SigIePTIControl:
+ status |=
+ dot11f_unpack_ie_pti_control(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEPTIControl *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEPTIControl) *
+ countOffset));
+ break;
+ case SigIePUBufferStatus:
+ status |=
+ dot11f_unpack_ie_pu_buffer_status(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEPUBufferStatus *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEPUBufferStatus) *
+ countOffset));
+ break;
+ case SigIePowerCaps:
+ status |=
+ dot11f_unpack_ie_power_caps(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEPowerCaps *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEPowerCaps) *
+ countOffset));
+ break;
+ case SigIePowerConstraints:
+ status |=
+ dot11f_unpack_ie_power_constraints(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEPowerConstraints *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEPowerConstraints) *
+ countOffset));
+ break;
+ case SigIeQBSSLoad:
+ status |=
+ dot11f_unpack_ie_qbss_load(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEQBSSLoad *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEQBSSLoad) *
+ countOffset));
+ break;
+ case SigIeQComVendorIE:
+ status |=
+ dot11f_unpack_ie_QComVendorIE(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEQComVendorIE *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEQComVendorIE) *
+ countOffset));
+ break;
+ case SigIeQOSCapsAp:
+ status |=
+ dot11f_unpack_ie_qos_caps_ap(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEQOSCapsAp *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEQOSCapsAp) *
+ countOffset));
+ break;
+ case SigIeQOSCapsStation:
+ status |=
+ dot11f_unpack_ie_qos_caps_station(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEQOSCapsStation *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEQOSCapsStation) *
+ countOffset));
+ break;
+ case SigIeQosMapSet:
+ status |=
+ dot11f_unpack_ie_qos_map_set(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEQosMapSet *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEQosMapSet) *
+ countOffset));
+ break;
+ case SigIeQuiet:
+ status |=
+ dot11f_unpack_ie_quiet(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEQuiet *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEQuiet) *
+ countOffset));
+ break;
+ case SigIeRCPIIE:
+ status |=
+ dot11f_unpack_ie_rcpiie(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERCPIIE *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERCPIIE) *
+ countOffset));
+ break;
+ case SigIeRICDataDesc:
+ /* reset the pointers back since this is a container IE and it doesnt have its own EID and Len. */
+ pBufRemaining -= 2;
+ nBufRemaining += 2;
+ if (pIe && pIe->noui) {
+ pBufRemaining -= pIe->noui;
+ nBufRemaining += pIe->noui;
+ len += pIe->noui;
+ }
+ status |= get_container_ies_len(pCtx, pBufRemaining, nBufRemaining, &len, IES_RICDataDesc);
+ if (status != DOT11F_PARSE_SUCCESS && status != DOT11F_UNKNOWN_IES)
+ break;
+ status |=
+ dot11f_unpack_ie_ric_data_desc(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERICDataDesc *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERICDataDesc) *
+ countOffset));
+ break;
+ case SigIeRSN:
+ status |=
+ dot11f_unpack_ie_rsn(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERSN *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERSN) *
+ countOffset));
+ break;
+ case SigIeRSNIIE:
+ status |=
+ dot11f_unpack_ie_rsniie(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERSNIIE *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERSNIIE) *
+ countOffset));
+ break;
+ case SigIeRSNOpaque:
+ status |=
+ dot11f_unpack_ie_rsn_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIERSNOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIERSNOpaque) *
+ countOffset));
+ break;
+ case SigIeSuppChannels:
+ status |=
+ dot11f_unpack_ie_supp_channels(
+ pCtx, pBufRemaining, len,
+ (tDot11fIESuppChannels *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIESuppChannels) *
+ countOffset));
+ break;
+ case SigIeSuppOperatingClasses:
+ status |=
+ dot11f_unpack_ie_supp_operating_classes(
+ pCtx, pBufRemaining, len,
+ (tDot11fIESuppOperatingClasses *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIESuppOperatingClasses) *
+ countOffset));
+ break;
+ case SigIeSuppRates:
+ status |=
+ dot11f_unpack_ie_supp_rates(
+ pCtx, pBufRemaining, len,
+ (tDot11fIESuppRates *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIESuppRates) *
+ countOffset));
+ break;
+ case SigIeTIM:
+ status |=
+ dot11f_unpack_ie_tim(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETIM *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETIM) *
+ countOffset));
+ break;
+ case SigIeTPCReport:
+ status |=
+ dot11f_unpack_ie_tpc_report(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETPCReport *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETPCReport) *
+ countOffset));
+ break;
+ case SigIeTPCRequest:
+ status |=
+ dot11f_unpack_ie_tpc_request(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETPCRequest *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETPCRequest) *
+ countOffset));
+ break;
+ case SigIeTimeAdvertisement:
+ status |=
+ dot11f_unpack_ie_time_advertisement(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETimeAdvertisement *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETimeAdvertisement) *
+ countOffset));
+ break;
+ case SigIeTimeoutInterval:
+ status |=
+ dot11f_unpack_ie_timeout_interval(
+ pCtx, pBufRemaining, len,
+ (tDot11fIETimeoutInterval *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIETimeoutInterval) *
+ countOffset));
+ break;
+ case SigIeVHTExtBssLoad:
+ status |=
+ dot11f_unpack_ie_vht_ext_bss_load(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEVHTExtBssLoad *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEVHTExtBssLoad) *
+ countOffset));
+ break;
+ case SigIeVendor1IE:
+ status |=
+ dot11f_unpack_ie_vendor1_ie(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEVendor1IE *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEVendor1IE) *
+ countOffset));
+ break;
+ case SigIeVendor3IE:
+ status |=
+ dot11f_unpack_ie_vendor3_ie(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEVendor3IE *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEVendor3IE) *
+ countOffset));
+ break;
+ case SigIeWAPI:
+ status |=
+ dot11f_unpack_ie_wapi(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWAPI *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWAPI) *
+ countOffset));
+ break;
+ case SigIeWAPIOpaque:
+ status |=
+ dot11f_unpack_ie_wapi_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWAPIOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWAPIOpaque) *
+ countOffset));
+ break;
+ case SigIeWFATPC:
+ status |=
+ dot11f_unpack_ie_wfatpc(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWFATPC *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWFATPC) *
+ countOffset));
+ break;
+ case SigIeWFDIEOpaque:
+ status |=
+ dot11f_unpack_ie_wfdie_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWFDIEOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWFDIEOpaque) *
+ countOffset));
+ break;
+ case SigIeWMMCaps:
+ status |=
+ dot11f_unpack_ie_wmm_caps(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMCaps *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMCaps) *
+ countOffset));
+ break;
+ case SigIeWMMInfoAp:
+ status |=
+ dot11f_unpack_ie_wmm_info_ap(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMInfoAp *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMInfoAp) *
+ countOffset));
+ break;
+ case SigIeWMMInfoStation:
+ status |=
+ dot11f_unpack_ie_wmm_info_station(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMInfoStation *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMInfoStation) *
+ countOffset));
+ break;
+ case SigIeWMMParams:
+ status |=
+ dot11f_unpack_ie_wmm_params(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWMMParams *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWMMParams) *
+ countOffset));
+ break;
+ case SigIeWPA:
+ status |=
+ dot11f_unpack_ie_wpa(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWPA *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWPA) *
+ countOffset));
+ break;
+ case SigIeWPAOpaque:
+ status |=
+ dot11f_unpack_ie_wpa_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWPAOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWPAOpaque) *
+ countOffset));
+ break;
+ case SigIeWSC:
+ status |=
+ dot11f_unpack_ie_wsc(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWSC *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWSC) *
+ countOffset));
+ break;
+ case SigIeWscAssocReq:
+ status |=
+ dot11f_unpack_ie_wsc_assoc_req(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscAssocReq *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscAssocReq) *
+ countOffset));
+ break;
+ case SigIeWscAssocRes:
+ status |=
+ dot11f_unpack_ie_wsc_assoc_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscAssocRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscAssocRes) *
+ countOffset));
+ break;
+ case SigIeWscBeacon:
+ status |=
+ dot11f_unpack_ie_wsc_beacon(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscBeacon *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscBeacon) *
+ countOffset));
+ break;
+ case SigIeWscBeaconProbeRes:
+ status |=
+ dot11f_unpack_ie_wsc_beacon_probe_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscBeaconProbeRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscBeaconProbeRes) *
+ countOffset));
+ break;
+ case SigIeWscIEOpaque:
+ status |=
+ dot11f_unpack_ie_wsc_ie_opaque(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscIEOpaque *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscIEOpaque) *
+ countOffset));
+ break;
+ case SigIeWscProbeReq:
+ status |=
+ dot11f_unpack_ie_wsc_probe_req(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscProbeReq *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscProbeReq) *
+ countOffset));
+ break;
+ case SigIeWscProbeRes:
+ status |=
+ dot11f_unpack_ie_wsc_probe_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscProbeRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscProbeRes) *
+ countOffset));
+ break;
+ case SigIeWscReassocRes:
+ status |=
+ dot11f_unpack_ie_wsc_reassoc_res(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEWscReassocRes *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEWscReassocRes) *
+ countOffset));
+ break;
+ case SigIeext_chan_switch_ann:
+ status |=
+ dot11f_unpack_ie_ext_chan_switch_ann(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEext_chan_switch_ann *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEext_chan_switch_ann) *
+ countOffset));
+ break;
+ case SigIeht2040_bss_coexistence:
+ status |=
+ dot11f_unpack_ie_ht2040_bss_coexistence(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEht2040_bss_coexistence *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEht2040_bss_coexistence) *
+ countOffset));
+ break;
+ case SigIeht2040_bss_intolerant_report:
+ status |=
+ dot11f_unpack_ie_ht2040_bss_intolerant_report(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEht2040_bss_intolerant_report *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEht2040_bss_intolerant_report) *
+ countOffset));
+ break;
+ case SigIesec_chan_offset_ele:
+ status |=
+ dot11f_unpack_ie_sec_chan_offset_ele(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEsec_chan_offset_ele *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEsec_chan_offset_ele) *
+ countOffset));
+ break;
+ case SigIevendor2_ie:
+ status |=
+ dot11f_unpack_ie_vendor2_ie(
+ pCtx, pBufRemaining, len,
+ (tDot11fIEvendor2_ie *)
+ (pFrm + pIe->offset +
+ sizeof(tDot11fIEvendor2_ie) *
+ countOffset));
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR"
+ ": I don't know about the IE signature %d"
+ "-- this is most likely a 'framesc' bug.\n"),
+ pIe->sig);
+ FRAMES_DBG_BREAK();
+ return DOT11F_INTERNAL_ERROR;
+ }
+ if (pIe->arraybound)
+ (++(*(uint16_t *)(pFrm + pIe->countOffset)));
+ }
+ } else {
+ FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown IE %d"
+ " (length %d)\n"), eid, len);
+ FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - 2, len);
+ status |= DOT11F_UNKNOWN_IES;
+ }
+
+ pBufRemaining += len;
+
+ if (len > nBufRemaining) {
+ FRAMES_LOG0(pCtx, FRLOGW, FRFL("This IE extends past "
+ "the buffer as it was defined to us. This could"
+ "mean a corrupt frame, or just an incorrect leng"
+ "th parameter.\n"));
+ FRAMES_DBG_BREAK();
+ status |= DOT11F_LAST_IE_TOO_LONG;
+ goto MandatoryCheck;
+ }
+
+ nBufRemaining -= len;
+
+ }
+
+MandatoryCheck:
+ pIe = &IEs[0];
+ while (0xff != pIe->eid) {
+ if (pIe->fMandatory) {
+ pfFound = (tFRAMES_BOOL *)(pFrm + pIe->offset +
+ pIe->presenceOffset);
+ if (!*pfFound) {
+ FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandato"
+ "ry IE %s wasn't seen.\n"),
+ pIe->name);
+ FRAMES_DBG_BREAK();
+ status |= DOT11F_MANDATORY_IE_MISSING;
+ }
+ }
+ ++pIe;
+ }
+
+ return status;
+} /* End unpack_core. */
+
+static uint32_t unpack_tlv_core(tpAniSirGlobal pCtx,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ const tTLVDefn TLVs[],
+ uint8_t *pFrm,
+ size_t nFrm)
+{
+ const tTLVDefn *pTlv;
+ uint32_t nBufRemaining, status, npec;
+ uint16_t id, len;
+ uint8_t *pBufRemaining, *pfFound;
+
+ (void)pCtx; /* Shutup the compiler */
+ (void)nFrm;
+ status = DOT11F_PARSE_SUCCESS;
+ pBufRemaining = pBuf;
+ nBufRemaining = nBuf;
+
+ /* While we have data... */
+ while (nBufRemaining) {
+ if (3 > nBufRemaining) {
+ FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+ "fewer three byte(s) remaining.\n"));
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+
+ npec = 0U;
+
+ /* Look for a matching TLV definition, */
+ pTlv = find_tlv_defn(pCtx, pBufRemaining, nBufRemaining, TLVs);
+ /* consume the type, */
+ if (pTlv) {
+ if (pTlv->sType == 2) {
+ framesntohs(pCtx, &id, pBufRemaining, pTlv->fMsb);
+ pBufRemaining += 2;
+ nBufRemaining -= 2;
+ } else {
+ id = *pBufRemaining;
+ pBufRemaining += 1;
+ nBufRemaining -= 1;
+ }
+ /* & length, */
+ if (pTlv->sLen == 2) {
+ framesntohs(pCtx, &len, pBufRemaining, pTlv->fMsb);
+ if (2 > nBufRemaining) {
+ FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+ "fewer two byte(s) remaining.\n"));
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+ pBufRemaining += 2;
+ nBufRemaining -= 2;
+ } else {
+ len = *pBufRemaining;
+ pBufRemaining += 1;
+ nBufRemaining -= 1;
+ }
+ } else {
+ pBufRemaining += TLVs[0].sType;
+ nBufRemaining -= TLVs[0].sType;
+ framesntohs(pCtx, &len, pBufRemaining, (TLVs[0].sType == 2));
+ if (2 > nBufRemaining) {
+ FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports "
+ "fewer two byte(s) remaining.\n"));
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+ pBufRemaining += 2;
+ nBufRemaining -= 2;
+ }
+
+ if (pTlv && pTlv->pec) {
+ npec = 3U;
+ if (3 > nBufRemaining) {
+ FRAMES_LOG2(pCtx, FRLOGW, FRFL("TLV %d reports length"
+ "%d, but it has a Private Enterprise Code (3 byte"
+ "s.\n"), id, len);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes"
+ "of this buffer, and show %d left.\n"),
+ pBufRemaining - pBuf, nBufRemaining);
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+ pBufRemaining += 3;
+ nBufRemaining -= 3;
+ len -= 3;
+ }
+
+ /* Whether we found a hit or not, we can validate the reported */
+ /* length of this TLV: */
+ if (len > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGW, FRFL("TLV %d reports length %"
+ "d, but there are only %d bytes remaining in this f"
+ "rame.\n"), id, len, nBufRemaining);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes"
+ " of this buffer, and show %d left.\n"),
+ pBufRemaining - pBuf, nBufRemaining);
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+
+ /* Now, *if* we found a hit... */
+ if (pTlv) {
+ if (len < pTlv->minSize - npec) {
+ FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be "
+ "at least %d bytes in size, but the size is only "
+ "%d bytes.\n"),
+ pTlv->name, pTlv->minSize, len);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ }
+ if (nBufRemaining < pTlv->minSize - npec - (pTlv->sType + pTlv->sLen)) {
+ FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be "
+ "at least %d bytes in size, but there are only "
+ "%d bytes remaining in this frame.\n"),
+ pTlv->name, pTlv->minSize, nBufRemaining);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ status |= DOT11F_INCOMPLETE_TLV;
+ FRAMES_DBG_BREAK();
+ goto MandatoryCheck;
+ } else if (len > pTlv->maxSize - npec - (pTlv->sType + pTlv->sLen)) {
+ FRAMES_LOG1(pCtx, FRLOGW, FRFL("The TLV %s reports "
+ "an illegally large size; this TLV is presumably"
+ "corrupt or otherwise invalid & will be skipped "
+ "ipped.\n"), pTlv->name);
+ FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf);
+ FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by"
+ "tes of this buffer, and show %d left.\n"),
+ pBufRemaining - pBuf, nBufRemaining);
+ FRAMES_DBG_BREAK();
+ status |= DOT11F_SKIPPED_BAD_TLV;
+ } else {
+ switch (pTlv->sig) {
+ case SigTlvAuthorizedMACs:
+ status |=
+ dot11f_unpack_tlv_authorized_ma_cs(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVAuthorizedMACs *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvRequestToEnroll:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVRequestToEnroll *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVRequestToEnroll *)
+ (pFrm + pTlv->offset))->req));
+ break;
+ case SigTlvVersion2:
+ status |=
+ dot11f_unpack_tlv_version2(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVVersion2 *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvAPSetupLocked:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVAPSetupLocked *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVAPSetupLocked *)
+ (pFrm + pTlv->offset))->fLocked));
+ break;
+ case SigTlvAssociationState:
+ status |=
+ dot11f_unpack_tlv_common_func2(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVAssociationState *)
+ (pFrm + pTlv->offset))->present),
+ (uint16_t *)&(((tDot11fTLVAssociationState *)
+ (pFrm + pTlv->offset))->state));
+ break;
+ case SigTlvConfigMethods:
+ status |=
+ dot11f_unpack_tlv_common_func2(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVConfigMethods *)
+ (pFrm + pTlv->offset))->present),
+ (uint16_t *)&(((tDot11fTLVConfigMethods *)
+ (pFrm + pTlv->offset))->methods));
+ break;
+ case SigTlvConfigurationError:
+ status |=
+ dot11f_unpack_tlv_common_func2(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVConfigurationError *)
+ (pFrm + pTlv->offset))->present),
+ (uint16_t *)&(((tDot11fTLVConfigurationError *)
+ (pFrm + pTlv->offset))->error));
+ break;
+ case SigTlvDeviceName:
+ status |=
+ dot11f_unpack_tlv_device_name(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVDeviceName *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvDevicePasswordID:
+ status |=
+ dot11f_unpack_tlv_common_func2(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVDevicePasswordID *)
+ (pFrm + pTlv->offset))->present),
+ (uint16_t *)&(((tDot11fTLVDevicePasswordID *)
+ (pFrm + pTlv->offset))->id));
+ break;
+ case SigTlvExtendedListenTiming:
+ status |=
+ dot11f_unpack_tlv_extended_listen_timing(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVExtendedListenTiming *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvListenChannel:
+ status |=
+ dot11f_unpack_tlv_listen_channel(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVListenChannel *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvManufacturer:
+ status |=
+ dot11f_unpack_tlv_manufacturer(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVManufacturer *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvMinorReasonCode:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVMinorReasonCode *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVMinorReasonCode *)
+ (pFrm + pTlv->offset))->minorReasonCode));
+ break;
+ case SigTlvModelName:
+ status |=
+ dot11f_unpack_tlv_model_name(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVModelName *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvModelNumber:
+ status |=
+ dot11f_unpack_tlv_model_number(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVModelNumber *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvNoticeOfAbsence:
+ status |=
+ dot11f_unpack_tlv_notice_of_absence(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVNoticeOfAbsence *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvOperatingChannel:
+ status |=
+ dot11f_unpack_tlv_operating_channel(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVOperatingChannel *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvP2PCapability:
+ status |=
+ dot11f_unpack_tlv_p2_p_capability(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVP2PCapability *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvP2PDeviceId:
+ status |=
+ dot11f_unpack_tlv_p2_p_device_id(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVP2PDeviceId *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvP2PDeviceInfo:
+ status |=
+ dot11f_unpack_tlv_p2_p_device_info(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVP2PDeviceInfo *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvP2PGroupInfo:
+ status |=
+ dot11f_unpack_tlv_p2_p_group_info(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVP2PGroupInfo *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvP2PStatus:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVP2PStatus *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVP2PStatus *)
+ (pFrm + pTlv->offset))->status));
+ break;
+ case SigTlvPrimaryDeviceType:
+ status |=
+ dot11f_unpack_tlv_primary_device_type(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVPrimaryDeviceType *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvRFBands:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVRFBands *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVRFBands *)
+ (pFrm + pTlv->offset))->bands));
+ break;
+ case SigTlvRequestDeviceType:
+ status |=
+ dot11f_unpack_tlv_request_device_type(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVRequestDeviceType *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvRequestType:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVRequestType *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVRequestType *)
+ (pFrm + pTlv->offset))->reqType));
+ break;
+ case SigTlvResponseType:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVResponseType *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVResponseType *)
+ (pFrm + pTlv->offset))->resType));
+ break;
+ case SigTlvSelectedRegistrar:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVSelectedRegistrar *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVSelectedRegistrar *)
+ (pFrm + pTlv->offset))->selected));
+ break;
+ case SigTlvSelectedRegistrarConfigMethods:
+ status |=
+ dot11f_unpack_tlv_common_func2(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVSelectedRegistrarConfigMethods *)
+ (pFrm + pTlv->offset))->present),
+ (uint16_t *)&(((tDot11fTLVSelectedRegistrarConfigMethods *)
+ (pFrm + pTlv->offset))->methods));
+ break;
+ case SigTlvSerialNumber:
+ status |=
+ dot11f_unpack_tlv_serial_number(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVSerialNumber *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvUUID_E:
+ status |=
+ dot11f_unpack_tlv_uuid_e(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVUUID_E *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvUUID_R:
+ status |=
+ dot11f_unpack_tlv_uuid_r(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVUUID_R *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvVendorExtension:
+ status |=
+ dot11f_unpack_tlv_vendor_extension(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVVendorExtension *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvVersion:
+ status |=
+ dot11f_unpack_tlv_version(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVVersion *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvWPSState:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVWPSState *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVWPSState *)
+ (pFrm + pTlv->offset))->state));
+ break;
+ case SigTlvP2PInterface:
+ status |=
+ dot11f_unpack_tlv_p2_p_interface(pCtx,
+ pBufRemaining, len,
+ (tDot11fTLVP2PInterface *)
+ (pFrm + pTlv->offset));
+ break;
+ case SigTlvP2PManageability:
+ status |=
+ dot11f_unpack_tlv_common_func(pCtx,
+ pBufRemaining, len,
+ (uint8_t *)&(((tDot11fTLVP2PManageability *)
+ (pFrm + pTlv->offset))->present),
+ (uint8_t *)&(((tDot11fTLVP2PManageability *)
+ (pFrm + pTlv->offset))->manageability));
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I"
+ " don't know about the TLV signature %d-- thi"
+ "s is most likely a 'framesc' bug.\n"),
+ pTlv->sig);
+ FRAMES_DBG_BREAK();
+ return DOT11F_INTERNAL_ERROR;
+ } /* End switch on sig. */
+ } /* End if on length check. */
+
+ } else {
+ FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown TLV %d ("
+ "length %d)\n"), id, len);
+ FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - (pTlv->sType + pTlv->sLen), len);
+ status |= DOT11F_UNKNOWN_TLVS;
+ }
+
+ /* Advance to the next TLV */
+ pBufRemaining += len;
+
+ if (len > nBufRemaining) {
+ FRAMES_LOG0(pCtx, FRLOGW, FRFL("This TLV extends past th"
+ "e buffer as it was defined to us. This could mean "
+ "a corrupt frame, or just an incorrect length parame"
+ "ter.\n"));
+ FRAMES_DBG_BREAK();
+ status |= DOT11F_LAST_TLV_TOO_LONG;
+ goto MandatoryCheck;
+ }
+
+ nBufRemaining -= len;
+
+ } /* End iteration over TLVs.*/
+
+MandatoryCheck:
+ pTlv = &TLVs[0];
+ while (0xffff != pTlv->id) {
+ if (pTlv->fMandatory) {
+ pfFound = (uint8_t *)(pFrm + pTlv->offset +
+ pTlv->presenceOffset);
+ if (!*pfFound) {
+ FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandatory "
+ "TLV %s wasn't seen.\n"),
+ pTlv->name);
+ FRAMES_DBG_BREAK();
+ status |= DOT11F_MANDATORY_TLV_MISSING;
+ }
+
+ }
+ ++pTlv;
+ }
+
+ return status;
+} /* End UnpacTlvkCore. */
+uint32_t dot11f_get_packed_ietclas(tpAniSirGlobal pCtx,
+ tDot11fIETCLAS *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ switch (pIe->classifier_type) {
+ case 0:
+ *pnNeeded += 6;
+ *pnNeeded += 6;
+ *pnNeeded += 2;
+ break;
+ case 1:
+ *pnNeeded += 1;
+ switch (pIe->info.IpParams.version) {
+ case 4:
+ *pnNeeded += 4;
+ *pnNeeded += 4;
+ *pnNeeded += 2;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ break;
+ case 6:
+ *pnNeeded += 16;
+ *pnNeeded += 16;
+ *pnNeeded += 2;
+ *pnNeeded += 2;
+ *pnNeeded += 3;
+ break;
+ }
+ break;
+ case 2:
+ *pnNeeded += 2;
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ietclas. */
+
+uint32_t dot11f_get_packed_iewmmtclas(tpAniSirGlobal pCtx,
+ tDot11fIEWMMTCLAS *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ switch (pIe->classifier_type) {
+ case 0:
+ *pnNeeded += 6;
+ *pnNeeded += 6;
+ *pnNeeded += 2;
+ break;
+ case 1:
+ *pnNeeded += 1;
+ switch (pIe->info.IpParams.version) {
+ case 4:
+ *pnNeeded += 4;
+ *pnNeeded += 4;
+ *pnNeeded += 2;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ break;
+ case 6:
+ *pnNeeded += 16;
+ *pnNeeded += 16;
+ *pnNeeded += 2;
+ *pnNeeded += 2;
+ *pnNeeded += 3;
+ break;
+ }
+ break;
+ case 2:
+ *pnNeeded += 2;
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iewmmtclas. */
+
+uint32_t dot11f_get_packed_ie_channel_switch_wrapper(tpAniSirGlobal pCtx,
+ tDot11fIEChannelSwitchWrapper *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ IES_ChannelSwitchWrapper);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_channel_switch_wrapper. */
+
+uint32_t dot11f_get_packed_ie_country(tpAniSirGlobal pCtx,
+ tDot11fIECountry *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 3;
+ if (pIe->num_triplets) {
+ *pnNeeded += (pIe->num_triplets * 3);
+ } else {
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_country. */
+
+uint32_t dot11f_get_packed_ieft_info(tpAniSirGlobal pCtx,
+ tDot11fIEFTInfo *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 2;
+ *pnNeeded += 16;
+ *pnNeeded += 32;
+ *pnNeeded += 32;
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ IES_FTInfo);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ieft_info. */
+
+uint32_t dot11f_get_packed_ie_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fIEMeasurementReport *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ if (pIe->type) {
+ switch (pIe->type) {
+ case 0:
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ break;
+ case 1:
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ break;
+ case 2:
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ break;
+ case 5:
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 6;
+ *pnNeeded += 1;
+ *pnNeeded += 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded, IES_reportBeacon);
+ break;
+ }
+ } else {
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_measurement_report. */
+
+uint32_t dot11f_get_packed_ie_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fIEMeasurementRequest *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ switch (pIe->measurement_type) {
+ case 0:
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ break;
+ case 1:
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ break;
+ case 2:
+ *pnNeeded += 1;
+ *pnNeeded += 8;
+ *pnNeeded += 2;
+ break;
+ case 5:
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 2;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ *pnNeeded += 6;
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded, IES_measurement_requestBeacon);
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_measurement_request. */
+
+uint32_t dot11f_get_packed_ie_neighbor_report(tpAniSirGlobal pCtx,
+ tDot11fIENeighborReport *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 6;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 2;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ IES_NeighborReport);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_neighbor_report. */
+
+uint32_t dot11f_get_packed_iep2_p_assoc_req(tpAniSirGlobal pCtx,
+ tDot11fIEP2PAssocReq *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PAssocReq);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_assoc_req. */
+
+uint32_t dot11f_get_packed_iep2_p_assoc_res(tpAniSirGlobal pCtx,
+ tDot11fIEP2PAssocRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PAssocRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_assoc_res. */
+
+uint32_t dot11f_get_packed_iep2_p_beacon(tpAniSirGlobal pCtx,
+ tDot11fIEP2PBeacon *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PBeacon);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_beacon. */
+
+uint32_t dot11f_get_packed_iep2_p_beacon_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEP2PBeaconProbeRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PBeaconProbeRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_beacon_probe_res. */
+
+uint32_t dot11f_get_packed_iep2_p_de_auth(tpAniSirGlobal pCtx,
+ tDot11fIEP2PDeAuth *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PDeAuth);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_de_auth. */
+
+uint32_t dot11f_get_packed_iep2_p_dis_assoc(tpAniSirGlobal pCtx,
+ tDot11fIEP2PDisAssoc *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PDisAssoc);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_dis_assoc. */
+
+uint32_t dot11f_get_packed_iep2_p_probe_req(tpAniSirGlobal pCtx,
+ tDot11fIEP2PProbeReq *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PProbeReq);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_probe_req. */
+
+uint32_t dot11f_get_packed_iep2_p_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEP2PProbeRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_P2PProbeRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iep2_p_probe_res. */
+
+uint32_t dot11f_get_packed_ieric_data_desc(tpAniSirGlobal pCtx,
+ tDot11fIERICDataDesc *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ IES_RICDataDesc);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ieric_data_desc. */
+
+uint32_t dot11f_get_packed_iersn(tpAniSirGlobal pCtx,
+ tDot11fIERSN *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 2;
+ *pnNeeded += 4;
+ if (pIe->pwise_cipher_suite_count) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ *pnNeeded += (pIe->pwise_cipher_suite_count * 4);
+ if (pIe->akm_suite_count) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ *pnNeeded += (pIe->akm_suite_count * 4);
+ if (pIe->RSN_Cap) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ if (pIe->pmkid_count) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ *pnNeeded += (pIe->pmkid_count * 16);
+ if (pIe->gp_mgmt_cipher_suite) {
+ *pnNeeded += 4;
+ } else {
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iersn. */
+
+uint32_t dot11f_get_packed_iewapi(tpAniSirGlobal pCtx,
+ tDot11fIEWAPI *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 2;
+ *pnNeeded += 2;
+ *pnNeeded += (pIe->akm_suite_count * 4);
+ *pnNeeded += 2;
+ *pnNeeded += (pIe->unicast_cipher_suite_count * 4);
+ *pnNeeded += 4;
+ *pnNeeded += 2;
+ if (pIe->bkid_count) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ *pnNeeded += (pIe->bkid_count * 16);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iewapi. */
+
+uint32_t dot11f_get_packed_iewpa(tpAniSirGlobal pCtx,
+ tDot11fIEWPA *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 2;
+ if (pIe->multicast_cipher_present) {
+
+ *pnNeeded += 4;
+ } else {
+ break;
+ }
+ if (pIe->unicast_cipher_count) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ *pnNeeded += (pIe->unicast_cipher_count * 4);
+ if (pIe->auth_suite_count) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ *pnNeeded += (pIe->auth_suite_count * 4);
+ if (pIe->caps) {
+ *pnNeeded += 2;
+ } else {
+ break;
+ }
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iewpa. */
+
+uint32_t dot11f_get_packed_iewsc(tpAniSirGlobal pCtx,
+ tDot11fIEWSC *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WSC);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_iewsc. */
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_req(tpAniSirGlobal pCtx,
+ tDot11fIEWscAssocReq *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscAssocReq);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_assoc_req. */
+
+uint32_t dot11f_get_packed_ie_wsc_assoc_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscAssocRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscAssocRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_assoc_res. */
+
+uint32_t dot11f_get_packed_ie_wsc_beacon(tpAniSirGlobal pCtx,
+ tDot11fIEWscBeacon *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscBeacon);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_beacon. */
+
+uint32_t dot11f_get_packed_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscBeaconProbeRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscBeaconProbeRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_beacon_probe_res. */
+
+uint32_t dot11f_get_packed_ie_wsc_probe_req(tpAniSirGlobal pCtx,
+ tDot11fIEWscProbeReq *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscProbeReq);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_probe_req. */
+
+uint32_t dot11f_get_packed_ie_wsc_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscProbeRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscProbeRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_probe_res. */
+
+uint32_t dot11f_get_packed_ie_wsc_reassoc_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscReassocRes *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ TLVS_WscReassocRes);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_wsc_reassoc_res. */
+
+uint32_t dot11f_get_packed_ie_vendor2_ie(tpAniSirGlobal pCtx,
+ tDot11fIEvendor2_ie *pIe, uint32_t *pnNeeded)
+{
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ (void)pCtx;
+ while (pIe->present) {
+ *pnNeeded += 1;
+ *pnNeeded += 1;
+ status = get_packed_size_core(pCtx, (uint8_t *)pIe, pnNeeded,
+ IES_vendor2_ie);
+ break;
+ }
+ return status;
+} /* End dot11f_get_packed_ie_vendor2_ie. */
+
+uint32_t dot11f_get_packed_add_ts_request_size(tpAniSirGlobal pCtx,
+ tDot11fAddTSRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_AddTSRequest);
+ return status;
+} /* End dot11f_get_packed_add_ts_request_size. */
+
+uint32_t dot11f_get_packed_add_ts_response_size(tpAniSirGlobal pCtx,
+ tDot11fAddTSResponse *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 5;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_AddTSResponse);
+ return status;
+} /* End dot11f_get_packed_add_ts_response_size. */
+
+uint32_t dot11f_get_packed_assoc_request_size(tpAniSirGlobal pCtx,
+ tDot11fAssocRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_AssocRequest);
+ return status;
+} /* End dot11f_get_packed_assoc_request_size. */
+
+uint32_t dot11f_get_packed_assoc_response_size(tpAniSirGlobal pCtx,
+ tDot11fAssocResponse *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 6;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_AssocResponse);
+ return status;
+} /* End dot11f_get_packed_assoc_response_size. */
+
+uint32_t dot11f_get_packed_authentication_size(tpAniSirGlobal pCtx,
+ tDot11fAuthentication *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 6;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_Authentication);
+ return status;
+} /* End dot11f_get_packed_authentication_size. */
+
+uint32_t dot11f_get_packed_beacon_size(tpAniSirGlobal pCtx,
+ tDot11fBeacon *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 12;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_Beacon);
+ return status;
+} /* End dot11f_get_packed_beacon_size. */
+
+uint32_t dot11f_get_packed_beacon1_size(tpAniSirGlobal pCtx,
+ tDot11fBeacon1 *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 12;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_Beacon1);
+ return status;
+} /* End dot11f_get_packed_beacon1_size. */
+
+uint32_t dot11f_get_packed_beacon2_size(tpAniSirGlobal pCtx,
+ tDot11fBeacon2 *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 0;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_Beacon2);
+ return status;
+} /* End dot11f_get_packed_beacon2_size. */
+
+uint32_t dot11f_get_packed_beacon_i_es_size(tpAniSirGlobal pCtx,
+ tDot11fBeaconIEs *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 0;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_BeaconIEs);
+ return status;
+} /* End dot11f_get_packed_beacon_i_es_size. */
+
+uint32_t dot11f_get_packed_channel_switch_size(tpAniSirGlobal pCtx,
+ tDot11fChannelSwitch *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 2;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_ChannelSwitch);
+ return status;
+} /* End dot11f_get_packed_channel_switch_size. */
+
+uint32_t dot11f_get_packed_de_auth_size(tpAniSirGlobal pCtx,
+ tDot11fDeAuth *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 2;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_DeAuth);
+ return status;
+} /* End dot11f_get_packed_de_auth_size. */
+
+uint32_t dot11f_get_packed_del_ts_size(tpAniSirGlobal pCtx,
+ tDot11fDelTS *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 7;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_DelTS);
+ return status;
+} /* End dot11f_get_packed_del_ts_size. */
+
+uint32_t dot11f_get_packed_disassociation_size(tpAniSirGlobal pCtx,
+ tDot11fDisassociation *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 2;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_Disassociation);
+ return status;
+} /* End dot11f_get_packed_disassociation_size. */
+
+uint32_t dot11f_get_packed_link_measurement_report_size(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementReport *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 11;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_LinkMeasurementReport);
+ return status;
+} /* End dot11f_get_packed_link_measurement_report_size. */
+
+uint32_t dot11f_get_packed_link_measurement_request_size(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 5;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_LinkMeasurementRequest);
+ return status;
+} /* End dot11f_get_packed_link_measurement_request_size. */
+
+uint32_t dot11f_get_packed_measurement_report_size(tpAniSirGlobal pCtx,
+ tDot11fMeasurementReport *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_MeasurementReport);
+ return status;
+} /* End dot11f_get_packed_measurement_report_size. */
+
+uint32_t dot11f_get_packed_measurement_request_size(tpAniSirGlobal pCtx,
+ tDot11fMeasurementRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_MeasurementRequest);
+ return status;
+} /* End dot11f_get_packed_measurement_request_size. */
+
+uint32_t dot11f_get_packed_neighbor_report_request_size(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_NeighborReportRequest);
+ return status;
+} /* End dot11f_get_packed_neighbor_report_request_size. */
+
+uint32_t dot11f_get_packed_neighbor_report_response_size(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportResponse *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_NeighborReportResponse);
+ return status;
+} /* End dot11f_get_packed_neighbor_report_response_size. */
+
+uint32_t dot11f_get_packed_operating_mode_size(tpAniSirGlobal pCtx,
+ tDot11fOperatingMode *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_OperatingMode);
+ return status;
+} /* End dot11f_get_packed_operating_mode_size. */
+
+uint32_t dot11f_get_packed_probe_request_size(tpAniSirGlobal pCtx,
+ tDot11fProbeRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 0;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_ProbeRequest);
+ return status;
+} /* End dot11f_get_packed_probe_request_size. */
+
+uint32_t dot11f_get_packed_probe_response_size(tpAniSirGlobal pCtx,
+ tDot11fProbeResponse *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 12;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_ProbeResponse);
+ return status;
+} /* End dot11f_get_packed_probe_response_size. */
+
+uint32_t dot11f_get_packed_qos_map_configure_size(tpAniSirGlobal pCtx,
+ tDot11fQosMapConfigure *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 2;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_QosMapConfigure);
+ return status;
+} /* End dot11f_get_packed_qos_map_configure_size. */
+
+uint32_t dot11f_get_packed_radio_measurement_report_size(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementReport *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_RadioMeasurementReport);
+ return status;
+} /* End dot11f_get_packed_radio_measurement_report_size. */
+
+uint32_t dot11f_get_packed_radio_measurement_request_size(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 5;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_RadioMeasurementRequest);
+ return status;
+} /* End dot11f_get_packed_radio_measurement_request_size. */
+
+uint32_t dot11f_get_packed_re_assoc_request_size(tpAniSirGlobal pCtx,
+ tDot11fReAssocRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 10;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_ReAssocRequest);
+ return status;
+} /* End dot11f_get_packed_re_assoc_request_size. */
+
+uint32_t dot11f_get_packed_re_assoc_response_size(tpAniSirGlobal pCtx,
+ tDot11fReAssocResponse *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 6;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_ReAssocResponse);
+ return status;
+} /* End dot11f_get_packed_re_assoc_response_size. */
+
+uint32_t dot11f_get_packed_sm_power_save_size(tpAniSirGlobal pCtx,
+ tDot11fSMPowerSave *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_SMPowerSave);
+ return status;
+} /* End dot11f_get_packed_sm_power_save_size. */
+
+uint32_t dot11f_get_packed_sa_query_req_size(tpAniSirGlobal pCtx,
+ tDot11fSaQueryReq *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_SaQueryReq);
+ return status;
+} /* End dot11f_get_packed_sa_query_req_size. */
+
+uint32_t dot11f_get_packed_sa_query_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fSaQueryRsp *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_SaQueryRsp);
+ return status;
+} /* End dot11f_get_packed_sa_query_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_dis_req_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisReq *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSDisReq);
+ return status;
+} /* End dot11f_get_packed_tdls_dis_req_size. */
+
+uint32_t dot11f_get_packed_tdls_dis_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisRsp *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 5;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSDisRsp);
+ return status;
+} /* End dot11f_get_packed_tdls_dis_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_peer_traffic_ind_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficInd *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSPeerTrafficInd);
+ return status;
+} /* End dot11f_get_packed_tdls_peer_traffic_ind_size. */
+
+uint32_t dot11f_get_packed_tdls_peer_traffic_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficRsp *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSPeerTrafficRsp);
+ return status;
+} /* End dot11f_get_packed_tdls_peer_traffic_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_setup_cnf_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupCnf *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 5;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSSetupCnf);
+ return status;
+} /* End dot11f_get_packed_tdls_setup_cnf_size. */
+
+uint32_t dot11f_get_packed_tdls_setup_req_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupReq *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 5;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSSetupReq);
+ return status;
+} /* End dot11f_get_packed_tdls_setup_req_size. */
+
+uint32_t dot11f_get_packed_tdls_setup_rsp_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupRsp *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 7;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSSetupRsp);
+ return status;
+} /* End dot11f_get_packed_tdls_setup_rsp_size. */
+
+uint32_t dot11f_get_packed_tdls_teardown_size(tpAniSirGlobal pCtx,
+ tDot11fTDLSTeardown *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TDLSTeardown);
+ return status;
+} /* End dot11f_get_packed_tdls_teardown_size. */
+
+uint32_t dot11f_get_packed_tpc_report_size(tpAniSirGlobal pCtx,
+ tDot11fTPCReport *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TPCReport);
+ return status;
+} /* End dot11f_get_packed_tpc_report_size. */
+
+uint32_t dot11f_get_packed_tpc_request_size(tpAniSirGlobal pCtx,
+ tDot11fTPCRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 3;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TPCRequest);
+ return status;
+} /* End dot11f_get_packed_tpc_request_size. */
+
+uint32_t dot11f_get_packed_timing_advertisement_frame_size(tpAniSirGlobal pCtx,
+ tDot11fTimingAdvertisementFrame *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 10;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_TimingAdvertisementFrame);
+ return status;
+} /* End dot11f_get_packed_timing_advertisement_frame_size. */
+
+uint32_t dot11f_get_packed_vht_gid_management_action_frame_size(tpAniSirGlobal pCtx,
+ tDot11fVHTGidManagementActionFrame *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 26;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_VHTGidManagementActionFrame);
+ return status;
+} /* End dot11f_get_packed_vht_gid_management_action_frame_size. */
+
+uint32_t dot11f_get_packed_wmm_add_ts_request_size(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSRequest *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_WMMAddTSRequest);
+ return status;
+} /* End dot11f_get_packed_wmm_add_ts_request_size. */
+
+uint32_t dot11f_get_packed_wmm_add_ts_response_size(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSResponse *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_WMMAddTSResponse);
+ return status;
+} /* End dot11f_get_packed_wmm_add_ts_response_size. */
+
+uint32_t dot11f_get_packed_wmm_del_ts_size(tpAniSirGlobal pCtx,
+ tDot11fWMMDelTS *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 4;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_WMMDelTS);
+ return status;
+} /* End dot11f_get_packed_wmm_del_ts_size. */
+
+uint32_t dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize(tpAniSirGlobal pCtx,
+ tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm, uint32_t *pnNeeded)
+{
+ uint32_t status = 0;
+ *pnNeeded = 2;
+ status = get_packed_size_core(pCtx, (uint8_t *)pFrm, pnNeeded,
+ IES_ht2040_bss_coexistence_mgmt_action_frame);
+ return status;
+} /* End dot11f_get_packed_ht2040_bss_coexistence_mgmt_action_frameSize. */
+
+static uint32_t get_packed_size_core(tpAniSirGlobal pCtx,
+ uint8_t *pFrm,
+ uint32_t *pnNeeded,
+ const tIEDefn IEs[])
+{
+ const tIEDefn *pIe;
+ uint16_t i, n;
+ uint32_t status;
+ tFRAMES_BOOL *pfFound;
+ uint32_t countOffset = 0;
+ uint32_t byteCount = 0;
+ uint8_t pIePresent = 0;
+ uint32_t offset = 0;
+
+ status = DOT11F_PARSE_SUCCESS;
+
+ (void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */
+ i = 0;
+ n = 0;
+ pIe = &(IEs[0]);
+ while (0xff != pIe->eid) {
+ pfFound = (tFRAMES_BOOL *)(pFrm + pIe->offset +
+ pIe->presenceOffset);
+ if (*pfFound) {
+ countOffset = ((0 == pIe->arraybound) ? 1 : (*(uint16_t *)(pFrm + pIe->countOffset)));
+ for (i = 0U; i < countOffset; ++i) {
+ *pnNeeded += 2U + pIe->noui;
+ byteCount = 0;
+ switch (pIe->sig) {
+ case SigIeCondensedCountryStr:
+ offset = sizeof(tDot11fIECondensedCountryStr);
+ byteCount = 2;
+ pIePresent = ((tDot11fIECondensedCountryStr *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeGTK:
+ offset = sizeof(tDot11fIEGTK);
+ byteCount = ((tDot11fIEGTK *)
+ (pFrm + pIe->offset + offset * i))->
+ num_key + 11;
+ pIePresent = ((tDot11fIEGTK *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeIGTK:
+ offset = sizeof(tDot11fIEIGTK);
+ byteCount = 33;
+ pIePresent = ((tDot11fIEIGTK *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeR0KH_ID:
+ offset = sizeof(tDot11fIER0KH_ID);
+ byteCount = ((tDot11fIER0KH_ID *)
+ (pFrm + pIe->offset + offset * i))->
+ num_PMK_R0_ID;
+ pIePresent = ((tDot11fIER0KH_ID *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeR1KH_ID:
+ offset = sizeof(tDot11fIER1KH_ID);
+ byteCount = 6;
+ pIePresent = ((tDot11fIER1KH_ID *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTSFInfo:
+ offset = sizeof(tDot11fIETSFInfo);
+ byteCount = 4;
+ pIePresent = ((tDot11fIETSFInfo *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeAPChannelReport:
+ offset = sizeof(tDot11fIEAPChannelReport);
+ byteCount = ((tDot11fIEAPChannelReport *)
+ (pFrm + pIe->offset + offset * i))->
+ num_channelList + 1;
+ pIePresent = ((tDot11fIEAPChannelReport *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeBcnReportingDetail:
+ offset = sizeof(tDot11fIEBcnReportingDetail);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEBcnReportingDetail *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeBeaconReportFrmBody:
+ offset = sizeof(tDot11fIEBeaconReportFrmBody);
+ byteCount = ((tDot11fIEBeaconReportFrmBody *)
+ (pFrm + pIe->offset + offset * i))->
+ num_reportedFields;
+ pIePresent = ((tDot11fIEBeaconReportFrmBody *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeBeaconReporting:
+ offset = sizeof(tDot11fIEBeaconReporting);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEBeaconReporting *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeMeasurementPilot:
+ offset = sizeof(tDot11fIEMeasurementPilot);
+ byteCount = ((tDot11fIEMeasurementPilot *)
+ (pFrm + pIe->offset + offset * i))->
+ num_vendorSpecific + 1;
+ pIePresent = ((tDot11fIEMeasurementPilot *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeMultiBssid:
+ offset = sizeof(tDot11fIEMultiBssid);
+ byteCount = ((tDot11fIEMultiBssid *)
+ (pFrm + pIe->offset + offset * i))->
+ num_vendorSpecific + 1;
+ pIePresent = ((tDot11fIEMultiBssid *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRICData:
+ offset = sizeof(tDot11fIERICData);
+ byteCount = 4;
+ pIePresent = ((tDot11fIERICData *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRICDescriptor:
+ offset = sizeof(tDot11fIERICDescriptor);
+ byteCount = ((tDot11fIERICDescriptor *)
+ (pFrm + pIe->offset + offset * i))->
+ num_variableData + 1;
+ pIePresent = ((tDot11fIERICDescriptor *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRRMEnabledCap:
+ offset = sizeof(tDot11fIERRMEnabledCap);
+ byteCount = 5;
+ pIePresent = ((tDot11fIERRMEnabledCap *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRequestedInfo:
+ offset = sizeof(tDot11fIERequestedInfo);
+ byteCount = ((tDot11fIERequestedInfo *)
+ (pFrm + pIe->offset + offset * i))->
+ num_requested_eids;
+ pIePresent = ((tDot11fIERequestedInfo *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeSSID:
+ offset = sizeof(tDot11fIESSID);
+ byteCount = ((tDot11fIESSID *)
+ (pFrm + pIe->offset + offset * i))->
+ num_ssid;
+ pIePresent = ((tDot11fIESSID *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeSchedule:
+ offset = sizeof(tDot11fIESchedule);
+ byteCount = 14;
+ pIePresent = ((tDot11fIESchedule *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTCLAS:
+ offset = sizeof(tDot11fIETCLAS);
+ status |=
+ dot11f_get_packed_ietclas(
+ pCtx, (tDot11fIETCLAS *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeTCLASSPROC:
+ offset = sizeof(tDot11fIETCLASSPROC);
+ byteCount = 1;
+ pIePresent = ((tDot11fIETCLASSPROC *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTSDelay:
+ offset = sizeof(tDot11fIETSDelay);
+ byteCount = 4;
+ pIePresent = ((tDot11fIETSDelay *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTSPEC:
+ offset = sizeof(tDot11fIETSPEC);
+ byteCount = 55;
+ pIePresent = ((tDot11fIETSPEC *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeVHTCaps:
+ offset = sizeof(tDot11fIEVHTCaps);
+ byteCount = 12;
+ pIePresent = ((tDot11fIEVHTCaps *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeVHTOperation:
+ offset = sizeof(tDot11fIEVHTOperation);
+ byteCount = 5;
+ pIePresent = ((tDot11fIEVHTOperation *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMSchedule:
+ offset = sizeof(tDot11fIEWMMSchedule);
+ byteCount = 15;
+ pIePresent = ((tDot11fIEWMMSchedule *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMTCLAS:
+ offset = sizeof(tDot11fIEWMMTCLAS);
+ status |=
+ dot11f_get_packed_iewmmtclas(
+ pCtx, (tDot11fIEWMMTCLAS *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWMMTCLASPROC:
+ offset = sizeof(tDot11fIEWMMTCLASPROC);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEWMMTCLASPROC *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMTSDelay:
+ offset = sizeof(tDot11fIEWMMTSDelay);
+ byteCount = 5;
+ pIePresent = ((tDot11fIEWMMTSDelay *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMTSPEC:
+ offset = sizeof(tDot11fIEWMMTSPEC);
+ byteCount = 56;
+ pIePresent = ((tDot11fIEWMMTSPEC *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWiderBWChanSwitchAnn:
+ offset = sizeof(tDot11fIEWiderBWChanSwitchAnn);
+ byteCount = 3;
+ pIePresent = ((tDot11fIEWiderBWChanSwitchAnn *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeAID:
+ offset = sizeof(tDot11fIEAID);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEAID *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeCFParams:
+ offset = sizeof(tDot11fIECFParams);
+ byteCount = 6;
+ pIePresent = ((tDot11fIECFParams *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeChallengeText:
+ offset = sizeof(tDot11fIEChallengeText);
+ byteCount = ((tDot11fIEChallengeText *)
+ (pFrm + pIe->offset + offset * i))->
+ num_text;
+ pIePresent = ((tDot11fIEChallengeText *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeChanSwitchAnn:
+ offset = sizeof(tDot11fIEChanSwitchAnn);
+ byteCount = 3;
+ pIePresent = ((tDot11fIEChanSwitchAnn *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeChannelSwitchWrapper:
+ offset = sizeof(tDot11fIEChannelSwitchWrapper);
+ status |=
+ dot11f_get_packed_ie_channel_switch_wrapper(
+ pCtx, (tDot11fIEChannelSwitchWrapper *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeCountry:
+ offset = sizeof(tDot11fIECountry);
+ status |=
+ dot11f_get_packed_ie_country(
+ pCtx, (tDot11fIECountry *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeDSParams:
+ offset = sizeof(tDot11fIEDSParams);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEDSParams *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeEDCAParamSet:
+ offset = sizeof(tDot11fIEEDCAParamSet);
+ byteCount = 18;
+ pIePresent = ((tDot11fIEEDCAParamSet *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeERPInfo:
+ offset = sizeof(tDot11fIEERPInfo);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEERPInfo *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeESECckmOpaque:
+ offset = sizeof(tDot11fIEESECckmOpaque);
+ byteCount = ((tDot11fIEESECckmOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIEESECckmOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeESERadMgmtCap:
+ offset = sizeof(tDot11fIEESERadMgmtCap);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEESERadMgmtCap *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeESETrafStrmMet:
+ offset = sizeof(tDot11fIEESETrafStrmMet);
+ byteCount = 4;
+ pIePresent = ((tDot11fIEESETrafStrmMet *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeESETrafStrmRateSet:
+ offset = sizeof(tDot11fIEESETrafStrmRateSet);
+ byteCount = ((tDot11fIEESETrafStrmRateSet *)
+ (pFrm + pIe->offset + offset * i))->
+ num_tsrates + 1;
+ pIePresent = ((tDot11fIEESETrafStrmRateSet *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeESETxmitPower:
+ offset = sizeof(tDot11fIEESETxmitPower);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEESETxmitPower *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeESEVersion:
+ offset = sizeof(tDot11fIEESEVersion);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEESEVersion *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeExtCap:
+ offset = sizeof(tDot11fIEExtCap);
+ byteCount = ((tDot11fIEExtCap *)
+ (pFrm + pIe->offset + offset * i))->
+ num_bytes;
+ pIePresent = ((tDot11fIEExtCap *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeExtSuppRates:
+ offset = sizeof(tDot11fIEExtSuppRates);
+ byteCount = ((tDot11fIEExtSuppRates *)
+ (pFrm + pIe->offset + offset * i))->
+ num_rates;
+ pIePresent = ((tDot11fIEExtSuppRates *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeFHParamSet:
+ offset = sizeof(tDot11fIEFHParamSet);
+ byteCount = 5;
+ pIePresent = ((tDot11fIEFHParamSet *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeFHParams:
+ offset = sizeof(tDot11fIEFHParams);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEFHParams *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeFHPattTable:
+ offset = sizeof(tDot11fIEFHPattTable);
+ byteCount = ((tDot11fIEFHPattTable *)
+ (pFrm + pIe->offset + offset * i))->
+ num_randtable + 4;
+ pIePresent = ((tDot11fIEFHPattTable *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeFTInfo:
+ offset = sizeof(tDot11fIEFTInfo);
+ status |=
+ dot11f_get_packed_ieft_info(
+ pCtx, (tDot11fIEFTInfo *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeHTCaps:
+ offset = sizeof(tDot11fIEHTCaps);
+ byteCount = ((tDot11fIEHTCaps *)
+ (pFrm + pIe->offset + offset * i))->
+ num_rsvd + 26;
+ pIePresent = ((tDot11fIEHTCaps *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeHTInfo:
+ offset = sizeof(tDot11fIEHTInfo);
+ byteCount = ((tDot11fIEHTInfo *)
+ (pFrm + pIe->offset + offset * i))->
+ num_rsvd + 22;
+ pIePresent = ((tDot11fIEHTInfo *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeIBSSParams:
+ offset = sizeof(tDot11fIEIBSSParams);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEIBSSParams *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeLinkIdentifier:
+ offset = sizeof(tDot11fIELinkIdentifier);
+ byteCount = 18;
+ pIePresent = ((tDot11fIELinkIdentifier *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeMeasurementReport:
+ offset = sizeof(tDot11fIEMeasurementReport);
+ status |=
+ dot11f_get_packed_ie_measurement_report(
+ pCtx, (tDot11fIEMeasurementReport *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeMeasurementRequest:
+ offset = sizeof(tDot11fIEMeasurementRequest);
+ status |=
+ dot11f_get_packed_ie_measurement_request(
+ pCtx, (tDot11fIEMeasurementRequest *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeMobilityDomain:
+ offset = sizeof(tDot11fIEMobilityDomain);
+ byteCount = 3;
+ pIePresent = ((tDot11fIEMobilityDomain *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeNeighborReport:
+ offset = sizeof(tDot11fIENeighborReport);
+ status |=
+ dot11f_get_packed_ie_neighbor_report(
+ pCtx, (tDot11fIENeighborReport *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeOBSSScanParameters:
+ offset = sizeof(tDot11fIEOBSSScanParameters);
+ byteCount = 14;
+ pIePresent = ((tDot11fIEOBSSScanParameters *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeOperatingMode:
+ offset = sizeof(tDot11fIEOperatingMode);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEOperatingMode *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeP2PAssocReq:
+ offset = sizeof(tDot11fIEP2PAssocReq);
+ status |=
+ dot11f_get_packed_iep2_p_assoc_req(
+ pCtx, (tDot11fIEP2PAssocReq *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PAssocRes:
+ offset = sizeof(tDot11fIEP2PAssocRes);
+ status |=
+ dot11f_get_packed_iep2_p_assoc_res(
+ pCtx, (tDot11fIEP2PAssocRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PBeacon:
+ offset = sizeof(tDot11fIEP2PBeacon);
+ status |=
+ dot11f_get_packed_iep2_p_beacon(
+ pCtx, (tDot11fIEP2PBeacon *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PBeaconProbeRes:
+ offset = sizeof(tDot11fIEP2PBeaconProbeRes);
+ status |=
+ dot11f_get_packed_iep2_p_beacon_probe_res(
+ pCtx, (tDot11fIEP2PBeaconProbeRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PDeAuth:
+ offset = sizeof(tDot11fIEP2PDeAuth);
+ status |=
+ dot11f_get_packed_iep2_p_de_auth(
+ pCtx, (tDot11fIEP2PDeAuth *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PDisAssoc:
+ offset = sizeof(tDot11fIEP2PDisAssoc);
+ status |=
+ dot11f_get_packed_iep2_p_dis_assoc(
+ pCtx, (tDot11fIEP2PDisAssoc *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PIEOpaque:
+ offset = sizeof(tDot11fIEP2PIEOpaque);
+ byteCount = ((tDot11fIEP2PIEOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIEP2PIEOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeP2PProbeReq:
+ offset = sizeof(tDot11fIEP2PProbeReq);
+ status |=
+ dot11f_get_packed_iep2_p_probe_req(
+ pCtx, (tDot11fIEP2PProbeReq *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeP2PProbeRes:
+ offset = sizeof(tDot11fIEP2PProbeRes);
+ status |=
+ dot11f_get_packed_iep2_p_probe_res(
+ pCtx, (tDot11fIEP2PProbeRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIePTIControl:
+ offset = sizeof(tDot11fIEPTIControl);
+ byteCount = 3;
+ pIePresent = ((tDot11fIEPTIControl *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIePUBufferStatus:
+ offset = sizeof(tDot11fIEPUBufferStatus);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEPUBufferStatus *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIePowerCaps:
+ offset = sizeof(tDot11fIEPowerCaps);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEPowerCaps *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIePowerConstraints:
+ offset = sizeof(tDot11fIEPowerConstraints);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEPowerConstraints *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeQBSSLoad:
+ offset = sizeof(tDot11fIEQBSSLoad);
+ byteCount = 5;
+ pIePresent = ((tDot11fIEQBSSLoad *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeQComVendorIE:
+ offset = sizeof(tDot11fIEQComVendorIE);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEQComVendorIE *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeQOSCapsAp:
+ offset = sizeof(tDot11fIEQOSCapsAp);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEQOSCapsAp *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeQOSCapsStation:
+ offset = sizeof(tDot11fIEQOSCapsStation);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEQOSCapsStation *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeQosMapSet:
+ offset = sizeof(tDot11fIEQosMapSet);
+ byteCount = ((tDot11fIEQosMapSet *)
+ (pFrm + pIe->offset + offset * i))->
+ num_dscp_exceptions;
+ pIePresent = ((tDot11fIEQosMapSet *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeQuiet:
+ offset = sizeof(tDot11fIEQuiet);
+ byteCount = 6;
+ pIePresent = ((tDot11fIEQuiet *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRCPIIE:
+ offset = sizeof(tDot11fIERCPIIE);
+ byteCount = 1;
+ pIePresent = ((tDot11fIERCPIIE *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRICDataDesc:
+ offset = sizeof(tDot11fIERICDataDesc);
+ pnNeeded -= 2 ; /* Subtract the length and Oui as this is our container IE to group Ies and it doesnt have its own length and OUI. */
+ status |=
+ dot11f_get_packed_ieric_data_desc(
+ pCtx, (tDot11fIERICDataDesc *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeRSN:
+ offset = sizeof(tDot11fIERSN);
+ status |=
+ dot11f_get_packed_iersn(
+ pCtx, (tDot11fIERSN *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeRSNIIE:
+ offset = sizeof(tDot11fIERSNIIE);
+ byteCount = 1;
+ pIePresent = ((tDot11fIERSNIIE *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeRSNOpaque:
+ offset = sizeof(tDot11fIERSNOpaque);
+ byteCount = ((tDot11fIERSNOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIERSNOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeSuppChannels:
+ offset = sizeof(tDot11fIESuppChannels);
+ byteCount = ((tDot11fIESuppChannels *)
+ (pFrm + pIe->offset + offset * i))->
+ num_bands * 2;
+ pIePresent = ((tDot11fIESuppChannels *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeSuppOperatingClasses:
+ offset = sizeof(tDot11fIESuppOperatingClasses);
+ byteCount = ((tDot11fIESuppOperatingClasses *)
+ (pFrm + pIe->offset + offset * i))->
+ num_classes;
+ pIePresent = ((tDot11fIESuppOperatingClasses *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeSuppRates:
+ offset = sizeof(tDot11fIESuppRates);
+ byteCount = ((tDot11fIESuppRates *)
+ (pFrm + pIe->offset + offset * i))->
+ num_rates;
+ pIePresent = ((tDot11fIESuppRates *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTIM:
+ offset = sizeof(tDot11fIETIM);
+ byteCount = ((tDot11fIETIM *)
+ (pFrm + pIe->offset + offset * i))->
+ num_vbmp + 3;
+ pIePresent = ((tDot11fIETIM *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTPCReport:
+ offset = sizeof(tDot11fIETPCReport);
+ byteCount = 2;
+ pIePresent = ((tDot11fIETPCReport *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTPCRequest:
+ offset = sizeof(tDot11fIETPCRequest);
+ byteCount = 0;
+ pIePresent = ((tDot11fIETPCRequest *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTimeAdvertisement:
+ offset = sizeof(tDot11fIETimeAdvertisement);
+ byteCount = 16;
+ pIePresent = ((tDot11fIETimeAdvertisement *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeTimeoutInterval:
+ offset = sizeof(tDot11fIETimeoutInterval);
+ byteCount = 5;
+ pIePresent = ((tDot11fIETimeoutInterval *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeVHTExtBssLoad:
+ offset = sizeof(tDot11fIEVHTExtBssLoad);
+ byteCount = 5;
+ pIePresent = ((tDot11fIEVHTExtBssLoad *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeVendor1IE:
+ offset = sizeof(tDot11fIEVendor1IE);
+ byteCount = 0;
+ pIePresent = ((tDot11fIEVendor1IE *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeVendor3IE:
+ offset = sizeof(tDot11fIEVendor3IE);
+ byteCount = 0;
+ pIePresent = ((tDot11fIEVendor3IE *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWAPI:
+ offset = sizeof(tDot11fIEWAPI);
+ status |=
+ dot11f_get_packed_iewapi(
+ pCtx, (tDot11fIEWAPI *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWAPIOpaque:
+ offset = sizeof(tDot11fIEWAPIOpaque);
+ byteCount = ((tDot11fIEWAPIOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIEWAPIOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWFATPC:
+ offset = sizeof(tDot11fIEWFATPC);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEWFATPC *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWFDIEOpaque:
+ offset = sizeof(tDot11fIEWFDIEOpaque);
+ byteCount = ((tDot11fIEWFDIEOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIEWFDIEOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMCaps:
+ offset = sizeof(tDot11fIEWMMCaps);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEWMMCaps *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMInfoAp:
+ offset = sizeof(tDot11fIEWMMInfoAp);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEWMMInfoAp *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMInfoStation:
+ offset = sizeof(tDot11fIEWMMInfoStation);
+ byteCount = 2;
+ pIePresent = ((tDot11fIEWMMInfoStation *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWMMParams:
+ offset = sizeof(tDot11fIEWMMParams);
+ byteCount = 19;
+ pIePresent = ((tDot11fIEWMMParams *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWPA:
+ offset = sizeof(tDot11fIEWPA);
+ status |=
+ dot11f_get_packed_iewpa(
+ pCtx, (tDot11fIEWPA *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWPAOpaque:
+ offset = sizeof(tDot11fIEWPAOpaque);
+ byteCount = ((tDot11fIEWPAOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIEWPAOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWSC:
+ offset = sizeof(tDot11fIEWSC);
+ status |=
+ dot11f_get_packed_iewsc(
+ pCtx, (tDot11fIEWSC *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscAssocReq:
+ offset = sizeof(tDot11fIEWscAssocReq);
+ status |=
+ dot11f_get_packed_ie_wsc_assoc_req(
+ pCtx, (tDot11fIEWscAssocReq *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscAssocRes:
+ offset = sizeof(tDot11fIEWscAssocRes);
+ status |=
+ dot11f_get_packed_ie_wsc_assoc_res(
+ pCtx, (tDot11fIEWscAssocRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscBeacon:
+ offset = sizeof(tDot11fIEWscBeacon);
+ status |=
+ dot11f_get_packed_ie_wsc_beacon(
+ pCtx, (tDot11fIEWscBeacon *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscBeaconProbeRes:
+ offset = sizeof(tDot11fIEWscBeaconProbeRes);
+ status |=
+ dot11f_get_packed_ie_wsc_beacon_probe_res(
+ pCtx, (tDot11fIEWscBeaconProbeRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscIEOpaque:
+ offset = sizeof(tDot11fIEWscIEOpaque);
+ byteCount = ((tDot11fIEWscIEOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ num_data;
+ pIePresent = ((tDot11fIEWscIEOpaque *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeWscProbeReq:
+ offset = sizeof(tDot11fIEWscProbeReq);
+ status |=
+ dot11f_get_packed_ie_wsc_probe_req(
+ pCtx, (tDot11fIEWscProbeReq *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscProbeRes:
+ offset = sizeof(tDot11fIEWscProbeRes);
+ status |=
+ dot11f_get_packed_ie_wsc_probe_res(
+ pCtx, (tDot11fIEWscProbeRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeWscReassocRes:
+ offset = sizeof(tDot11fIEWscReassocRes);
+ status |=
+ dot11f_get_packed_ie_wsc_reassoc_res(
+ pCtx, (tDot11fIEWscReassocRes *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ case SigIeext_chan_switch_ann:
+ offset = sizeof(tDot11fIEext_chan_switch_ann);
+ byteCount = 4;
+ pIePresent = ((tDot11fIEext_chan_switch_ann *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeht2040_bss_coexistence:
+ offset = sizeof(tDot11fIEht2040_bss_coexistence);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEht2040_bss_coexistence *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIeht2040_bss_intolerant_report:
+ offset = sizeof(tDot11fIEht2040_bss_intolerant_report);
+ byteCount = ((tDot11fIEht2040_bss_intolerant_report *)
+ (pFrm + pIe->offset + offset * i))->
+ num_channel_list + 1;
+ pIePresent = ((tDot11fIEht2040_bss_intolerant_report *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIesec_chan_offset_ele:
+ offset = sizeof(tDot11fIEsec_chan_offset_ele);
+ byteCount = 1;
+ pIePresent = ((tDot11fIEsec_chan_offset_ele *)
+ (pFrm + pIe->offset + offset * i))->
+ present;
+ break;
+ case SigIevendor2_ie:
+ offset = sizeof(tDot11fIEvendor2_ie);
+ status |=
+ dot11f_get_packed_ie_vendor2_ie(
+ pCtx, (tDot11fIEvendor2_ie *)
+ (pFrm + pIe->offset + offset * i),
+ pnNeeded);
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+ "'t know about the IE signature %d; this is most l"
+ "ikely a bug in 'framesc'.\n"), pIe->sig);
+ return DOT11F_INTERNAL_ERROR;
+ } /*End of switch Case*/
+
+ if (byteCount && pIePresent)
+ *pnNeeded += byteCount;
+ } /*End of for loop*/
+ }
+ ++pIe;
+ }
+ return status;
+
+}
+
+static uint32_t get_packed_size_tlv_core(tpAniSirGlobal pCtx,
+ uint8_t *pFrm,
+ uint32_t *pnNeeded,
+ const tTLVDefn TLVs[])
+{
+ const tTLVDefn *pTlv;
+ uint32_t status;
+ tFRAMES_BOOL *pfFound;
+ uint32_t byteCount = 0;
+ uint8_t pTlvPresent = 0;
+
+ status = DOT11F_PARSE_SUCCESS;
+
+ pTlv = &(TLVs[0]);
+ while (0xffff != pTlv->id) {
+ pfFound = (tFRAMES_BOOL *)(pFrm + pTlv->offset +
+ pTlv->presenceOffset);
+ if (*pfFound) {
+ *pnNeeded += (pTlv->sType + pTlv->sLen);
+ if (pTlv->pec)
+ *pnNeeded += 3U;
+ switch (pTlv->sig) {
+ case SigTlvAuthorizedMACs:
+ byteCount = 6;
+ pTlvPresent = ((tDot11fTLVAuthorizedMACs *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvRequestToEnroll:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVRequestToEnroll *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvVersion2:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVVersion2 *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvAPSetupLocked:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVAPSetupLocked *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvAssociationState:
+ byteCount = 2;
+ pTlvPresent = ((tDot11fTLVAssociationState *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvConfigMethods:
+ byteCount = 2;
+ pTlvPresent = ((tDot11fTLVConfigMethods *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvConfigurationError:
+ byteCount = 2;
+ pTlvPresent = ((tDot11fTLVConfigurationError *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvDeviceName:
+ byteCount = ((tDot11fTLVDeviceName *)(pFrm + pTlv->offset))->num_text;
+ pTlvPresent = ((tDot11fTLVDeviceName *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvDevicePasswordID:
+ byteCount = 2;
+ pTlvPresent = ((tDot11fTLVDevicePasswordID *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvExtendedListenTiming:
+ byteCount = 4;
+ pTlvPresent = ((tDot11fTLVExtendedListenTiming *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvListenChannel:
+ byteCount = 5;
+ pTlvPresent = ((tDot11fTLVListenChannel *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvManufacturer:
+ byteCount = ((tDot11fTLVManufacturer *)(pFrm + pTlv->offset))->num_name;
+ pTlvPresent = ((tDot11fTLVManufacturer *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvMinorReasonCode:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVMinorReasonCode *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvModelName:
+ byteCount = ((tDot11fTLVModelName *)(pFrm + pTlv->offset))->num_text;
+ pTlvPresent = ((tDot11fTLVModelName *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvModelNumber:
+ byteCount = ((tDot11fTLVModelNumber *)(pFrm + pTlv->offset))->num_text;
+ pTlvPresent = ((tDot11fTLVModelNumber *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvNoticeOfAbsence:
+ byteCount = ((tDot11fTLVNoticeOfAbsence *)(pFrm + pTlv->offset))->num_NoADesc+2;
+ pTlvPresent = ((tDot11fTLVNoticeOfAbsence *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvOperatingChannel:
+ byteCount = 5;
+ pTlvPresent = ((tDot11fTLVOperatingChannel *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PCapability:
+ byteCount = 2;
+ pTlvPresent = ((tDot11fTLVP2PCapability *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PDeviceId:
+ byteCount = 6;
+ pTlvPresent = ((tDot11fTLVP2PDeviceId *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PDeviceInfo:
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pFrm + pTlv->offset, pnNeeded, TLVS_P2PDeviceInfo);
+ byteCount = 16;
+ pTlvPresent = ((tDot11fTLVP2PDeviceInfo *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PGroupInfo:
+ byteCount = ((tDot11fTLVP2PGroupInfo *)(pFrm + pTlv->offset))->num_P2PClientInfoDesc;
+ pTlvPresent = ((tDot11fTLVP2PGroupInfo *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PStatus:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVP2PStatus *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvPrimaryDeviceType:
+ byteCount = 8;
+ pTlvPresent = ((tDot11fTLVPrimaryDeviceType *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvRFBands:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVRFBands *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvRequestDeviceType:
+ byteCount = 8;
+ pTlvPresent = ((tDot11fTLVRequestDeviceType *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvRequestType:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVRequestType *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvResponseType:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVResponseType *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvSelectedRegistrar:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVSelectedRegistrar *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvSelectedRegistrarConfigMethods:
+ byteCount = 2;
+ pTlvPresent = ((tDot11fTLVSelectedRegistrarConfigMethods *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvSerialNumber:
+ byteCount = ((tDot11fTLVSerialNumber *)(pFrm + pTlv->offset))->num_text;
+ pTlvPresent = ((tDot11fTLVSerialNumber *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvUUID_E:
+ byteCount = 16;
+ pTlvPresent = ((tDot11fTLVUUID_E *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvUUID_R:
+ byteCount = 16;
+ pTlvPresent = ((tDot11fTLVUUID_R *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvVendorExtension:
+ status = get_packed_size_tlv_core(pCtx, (uint8_t *)pFrm + pTlv->offset, pnNeeded, TLVS_VendorExtension);
+ byteCount = 3;
+ pTlvPresent = ((tDot11fTLVVendorExtension *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvVersion:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVVersion *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvWPSState:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVWPSState *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PInterface:
+ byteCount = 6;
+ pTlvPresent = ((tDot11fTLVP2PInterface *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ case SigTlvP2PManageability:
+ byteCount = 1;
+ pTlvPresent = ((tDot11fTLVP2PManageability *)
+ (pFrm + pTlv->offset))->present;
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+ "'t know about the TLV signature %d; this is most l"
+ "ikely a bug in 'framesc'.\n"), pTlv->sig);
+ return DOT11F_INTERNAL_ERROR;
+ }
+ if (pTlvPresent) {
+ *pnNeeded += byteCount;
+ }
+ }
+ ++pTlv;
+ }
+ return status;
+}
+void dot11f_pack_ff_aid(tpAniSirGlobal pCtx,
+ tDot11fFfAID *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->associd, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_aid. */
+
+void dot11f_pack_ff_action(tpAniSirGlobal pCtx,
+ tDot11fFfAction *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->action;
+ (void)pCtx;
+} /* End dot11f_pack_ff_action. */
+
+void dot11f_pack_ff_auth_algo(tpAniSirGlobal pCtx,
+ tDot11fFfAuthAlgo *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->algo, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_auth_algo. */
+
+void dot11f_pack_ff_auth_seq_no(tpAniSirGlobal pCtx,
+ tDot11fFfAuthSeqNo *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->no, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_auth_seq_no. */
+
+void dot11f_pack_ff_beacon_interval(tpAniSirGlobal pCtx,
+ tDot11fFfBeaconInterval *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->interval, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_beacon_interval. */
+
+void dot11f_pack_ff_capabilities(tpAniSirGlobal pCtx,
+ tDot11fFfCapabilities *pSrc,
+ uint8_t *pBuf)
+{
+ uint16_t tmp66__;
+ tmp66__ = 0U;
+ tmp66__ |= (pSrc->ess << 0);
+ tmp66__ |= (pSrc->ibss << 1);
+ tmp66__ |= (pSrc->cfPollable << 2);
+ tmp66__ |= (pSrc->cfPollReq << 3);
+ tmp66__ |= (pSrc->privacy << 4);
+ tmp66__ |= (pSrc->shortPreamble << 5);
+ tmp66__ |= (pSrc->pbcc << 6);
+ tmp66__ |= (pSrc->channelAgility << 7);
+ tmp66__ |= (pSrc->spectrumMgt << 8);
+ tmp66__ |= (pSrc->qos << 9);
+ tmp66__ |= (pSrc->shortSlotTime << 10);
+ tmp66__ |= (pSrc->apsd << 11);
+ tmp66__ |= (pSrc->rrm << 12);
+ tmp66__ |= (pSrc->dsssOfdm << 13);
+ tmp66__ |= (pSrc->delayedBA << 14);
+ tmp66__ |= (pSrc->immediateBA << 15);
+ frameshtons(pCtx, pBuf, tmp66__, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_capabilities. */
+
+void dot11f_pack_ff_category(tpAniSirGlobal pCtx,
+ tDot11fFfCategory *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->category;
+ (void)pCtx;
+} /* End dot11f_pack_ff_category. */
+
+void dot11f_pack_ff_current_ap_address(tpAniSirGlobal pCtx,
+ tDot11fFfCurrentAPAddress *pSrc,
+ uint8_t *pBuf)
+{
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6);
+ (void)pCtx;
+} /* End dot11f_pack_ff_current_ap_address. */
+
+void dot11f_pack_ff_dialog_token(tpAniSirGlobal pCtx,
+ tDot11fFfDialogToken *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->token;
+ (void)pCtx;
+} /* End dot11f_pack_ff_dialog_token. */
+
+void dot11f_pack_ff_link_margin(tpAniSirGlobal pCtx,
+ tDot11fFfLinkMargin *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->linkMargin;
+ (void)pCtx;
+} /* End dot11f_pack_ff_link_margin. */
+
+void dot11f_pack_ff_listen_interval(tpAniSirGlobal pCtx,
+ tDot11fFfListenInterval *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->interval, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_listen_interval. */
+
+void dot11f_pack_ff_max_tx_power(tpAniSirGlobal pCtx,
+ tDot11fFfMaxTxPower *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->maxTxPower;
+ (void)pCtx;
+} /* End dot11f_pack_ff_max_tx_power. */
+
+void dot11f_pack_ff_num_of_repetitions(tpAniSirGlobal pCtx,
+ tDot11fFfNumOfRepetitions *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->repetitions, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_num_of_repetitions. */
+
+void dot11f_pack_ff_operating_mode(tpAniSirGlobal pCtx,
+ tDot11fFfOperatingMode *pSrc,
+ uint8_t *pBuf)
+{
+ uint8_t tmp67__;
+ tmp67__ = 0U;
+ tmp67__ |= (pSrc->chanWidth << 0);
+ tmp67__ |= (pSrc->reserved << 2);
+ tmp67__ |= (pSrc->rxNSS << 4);
+ tmp67__ |= (pSrc->rxNSSType << 7);
+ *pBuf = tmp67__;
+ (void)pCtx;
+} /* End dot11f_pack_ff_operating_mode. */
+
+void dot11f_pack_ff_rcpi(tpAniSirGlobal pCtx,
+ tDot11fFfRCPI *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->rcpi;
+ (void)pCtx;
+} /* End dot11f_pack_ff_rcpi. */
+
+void dot11f_pack_ff_rsni(tpAniSirGlobal pCtx,
+ tDot11fFfRSNI *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->rsni;
+ (void)pCtx;
+} /* End dot11f_pack_ff_rsni. */
+
+void dot11f_pack_ff_reason(tpAniSirGlobal pCtx,
+ tDot11fFfReason *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->code, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_reason. */
+
+void dot11f_pack_ff_rx_antenna_id(tpAniSirGlobal pCtx,
+ tDot11fFfRxAntennaId *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->antennaId;
+ (void)pCtx;
+} /* End dot11f_pack_ff_rx_antenna_id. */
+
+void dot11f_pack_ff_sm_power_mode_set(tpAniSirGlobal pCtx,
+ tDot11fFfSMPowerModeSet *pSrc,
+ uint8_t *pBuf)
+{
+ uint8_t tmp68__;
+ tmp68__ = 0U;
+ tmp68__ |= (pSrc->PowerSave_En << 0);
+ tmp68__ |= (pSrc->Mode << 1);
+ tmp68__ |= (pSrc->reserved << 2);
+ *pBuf = tmp68__;
+ (void)pCtx;
+} /* End dot11f_pack_ff_sm_power_mode_set. */
+
+void dot11f_pack_ff_status(tpAniSirGlobal pCtx,
+ tDot11fFfStatus *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtons(pCtx, pBuf, pSrc->status, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_status. */
+
+void dot11f_pack_ff_status_code(tpAniSirGlobal pCtx,
+ tDot11fFfStatusCode *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->statusCode;
+ (void)pCtx;
+} /* End dot11f_pack_ff_status_code. */
+
+void dot11f_pack_ff_tpc_ele_id(tpAniSirGlobal pCtx,
+ tDot11fFfTPCEleID *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->TPCId;
+ (void)pCtx;
+} /* End dot11f_pack_ff_tpc_ele_id. */
+
+void dot11f_pack_ff_tpc_ele_len(tpAniSirGlobal pCtx,
+ tDot11fFfTPCEleLen *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->TPCLen;
+ (void)pCtx;
+} /* End dot11f_pack_ff_tpc_ele_len. */
+
+void dot11f_pack_ff_ts_info(tpAniSirGlobal pCtx,
+ tDot11fFfTSInfo *pSrc,
+ uint8_t *pBuf)
+{
+ uint32_t tmp69__;
+ tmp69__ = 0U;
+ tmp69__ |= (pSrc->traffic_type << 0);
+ tmp69__ |= (pSrc->tsid << 1);
+ tmp69__ |= (pSrc->direction << 5);
+ tmp69__ |= (pSrc->access_policy << 7);
+ tmp69__ |= (pSrc->aggregation << 9);
+ tmp69__ |= (pSrc->psb << 10);
+ tmp69__ |= (pSrc->user_priority << 11);
+ tmp69__ |= (pSrc->tsinfo_ack_pol << 14);
+ tmp69__ |= (pSrc->schedule << 16);
+ tmp69__ |= (pSrc->unused << 17);
+ frameshtonl(pCtx, pBuf, tmp69__, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_ts_info. */
+
+void dot11f_pack_ff_time_stamp(tpAniSirGlobal pCtx,
+ tDot11fFfTimeStamp *pSrc,
+ uint8_t *pBuf)
+{
+ frameshtonq(pCtx, pBuf, pSrc->timestamp, 0);
+ (void)pCtx;
+} /* End dot11f_pack_ff_time_stamp. */
+
+void dot11f_pack_ff_transaction_id(tpAniSirGlobal pCtx,
+ tDot11fFfTransactionId *pSrc,
+ uint8_t *pBuf)
+{
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->transId, 2);
+ (void)pCtx;
+} /* End dot11f_pack_ff_transaction_id. */
+
+void dot11f_pack_ff_tx_antenna_id(tpAniSirGlobal pCtx,
+ tDot11fFfTxAntennaId *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->antennaId;
+ (void)pCtx;
+} /* End dot11f_pack_ff_tx_antenna_id. */
+
+void dot11f_pack_ff_tx_power(tpAniSirGlobal pCtx,
+ tDot11fFfTxPower *pSrc,
+ uint8_t *pBuf)
+{
+ *pBuf = pSrc->txPower;
+ (void)pCtx;
+} /* End dot11f_pack_ff_tx_power. */
+
+void dot11f_pack_ff_vht_membership_status_array(tpAniSirGlobal pCtx,
+ tDot11fFfVhtMembershipStatusArray *pSrc,
+ uint8_t *pBuf)
+{
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->membershipStatusArray, 8);
+ (void)pCtx;
+} /* End dot11f_pack_ff_vht_membership_status_array. */
+
+void dot11f_pack_ff_vht_user_position_array(tpAniSirGlobal pCtx,
+ tDot11fFfVhtUserPositionArray *pSrc,
+ uint8_t *pBuf)
+{
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->userPositionArray, 16);
+ (void)pCtx;
+} /* End dot11f_pack_ff_vht_user_position_array. */
+
+uint32_t dot11f_pack_tlv_authorized_ma_cs(tpAniSirGlobal pCtx,
+ tDot11fTLVAuthorizedMACs *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 8;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 1;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 1; *pnConsumed += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ *pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_authorized_ma_cs. */
+
+uint32_t dot11f_pack_tlv_request_to_enroll(tpAniSirGlobal pCtx,
+ tDot11fTLVRequestToEnroll *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 3;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 3;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 1; *pnConsumed += 1;
+ *pBuf = pSrc->req;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ *pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_request_to_enroll. */
+
+uint32_t dot11f_pack_tlv_version2(tpAniSirGlobal pCtx,
+ tDot11fTLVVersion2 *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp70__;
+ nNeeded += 3;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 0;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 1; *pnConsumed += 1;
+ tmp70__ = 0U;
+ tmp70__ |= (pSrc->minor << 0);
+ tmp70__ |= (pSrc->major << 4);
+ *pBuf = tmp70__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ *pTlvLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_version2. */
+
+uint32_t dot11f_pack_tlv_ap_setup_locked(tpAniSirGlobal pCtx,
+ tDot11fTLVAPSetupLocked *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4183, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->fLocked;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_ap_setup_locked. */
+
+uint32_t dot11f_pack_tlv_association_state(tpAniSirGlobal pCtx,
+ tDot11fTLVAssociationState *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4098, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->state, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_association_state. */
+
+uint32_t dot11f_pack_tlv_config_methods(tpAniSirGlobal pCtx,
+ tDot11fTLVConfigMethods *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4104, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->methods, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_config_methods. */
+
+uint32_t dot11f_pack_tlv_configuration_error(tpAniSirGlobal pCtx,
+ tDot11fTLVConfigurationError *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4105, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->error, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_configuration_error. */
+
+uint32_t dot11f_pack_tlv_device_name(tpAniSirGlobal pCtx,
+ tDot11fTLVDeviceName *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_text + 4) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4113, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+ *pnConsumed += pSrc->num_text;
+ pBuf += pSrc->num_text;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_device_name. */
+
+uint32_t dot11f_pack_tlv_device_password_id(tpAniSirGlobal pCtx,
+ tDot11fTLVDevicePasswordID *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4114, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->id, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_device_password_id. */
+
+uint32_t dot11f_pack_tlv_extended_listen_timing(tpAniSirGlobal pCtx,
+ tDot11fTLVExtendedListenTiming *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 7;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 8;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->availibilityPeriod, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->availibilityInterval, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_extended_listen_timing. */
+
+uint32_t dot11f_pack_tlv_listen_channel(tpAniSirGlobal pCtx,
+ tDot11fTLVListenChannel *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 8;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 6;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3);
+ *pnConsumed += 3;
+ pBuf += 3;
+ *pBuf = pSrc->regulatoryClass;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_listen_channel. */
+
+uint32_t dot11f_pack_tlv_manufacturer(tpAniSirGlobal pCtx,
+ tDot11fTLVManufacturer *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_name + 4) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4129, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->name), pSrc->num_name);
+ *pnConsumed += pSrc->num_name;
+ pBuf += pSrc->num_name;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_manufacturer. */
+
+uint32_t dot11f_pack_tlv_minor_reason_code(tpAniSirGlobal pCtx,
+ tDot11fTLVMinorReasonCode *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 1;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->minorReasonCode;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_minor_reason_code. */
+
+uint32_t dot11f_pack_tlv_model_name(tpAniSirGlobal pCtx,
+ tDot11fTLVModelName *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_text + 4) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4131, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+ *pnConsumed += pSrc->num_text;
+ pBuf += pSrc->num_text;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_model_name. */
+
+uint32_t dot11f_pack_tlv_model_number(tpAniSirGlobal pCtx,
+ tDot11fTLVModelNumber *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_text + 4) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4132, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+ *pnConsumed += pSrc->num_text;
+ pBuf += pSrc->num_text;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_model_number. */
+
+uint32_t dot11f_pack_tlv_notice_of_absence(tpAniSirGlobal pCtx,
+ tDot11fTLVNoticeOfAbsence *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_NoADesc + 5) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 12;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->index;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->CTSWindowOppPS;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->NoADesc), pSrc->num_NoADesc);
+ *pnConsumed += pSrc->num_NoADesc;
+ pBuf += pSrc->num_NoADesc;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_notice_of_absence. */
+
+uint32_t dot11f_pack_tlv_operating_channel(tpAniSirGlobal pCtx,
+ tDot11fTLVOperatingChannel *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 8;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 17;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3);
+ *pnConsumed += 3;
+ pBuf += 3;
+ *pBuf = pSrc->regulatoryClass;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_operating_channel. */
+
+uint32_t dot11f_pack_tlv_p2_p_capability(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PCapability *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 2;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->deviceCapability;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->groupCapability;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_capability. */
+
+uint32_t dot11f_pack_tlv_p2_p_device_id(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PDeviceId *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 9;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 3;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_device_id. */
+
+uint32_t dot11f_pack_tlv_p2_p_device_info(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PDeviceInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ uint32_t idx = 0;
+ nNeeded += 19;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 13;
+ pBuf += 1; nBuf -= 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; nBuf -= 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ frameshtons(pCtx, pBuf, pSrc->configMethod, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->primaryDeviceType, 8);
+ *pnConsumed += 8;
+ pBuf += 8;
+ status |= pack_tlv_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ TLVS_P2PDeviceInfo, &idx);
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return status;
+} /* End dot11f_pack_tlv_p2_p_device_info. */
+
+uint32_t dot11f_pack_tlv_p2_p_group_info(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PGroupInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_P2PClientInfoDesc + 3) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 14;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->P2PClientInfoDesc), pSrc->num_P2PClientInfoDesc);
+ *pnConsumed += pSrc->num_P2PClientInfoDesc;
+ pBuf += pSrc->num_P2PClientInfoDesc;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_group_info. */
+
+uint32_t dot11f_pack_tlv_p2_p_status(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PStatus *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 0;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->status;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_status. */
+
+uint32_t dot11f_pack_tlv_primary_device_type(tpAniSirGlobal pCtx,
+ tDot11fTLVPrimaryDeviceType *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 12;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4180, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->primary_category, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->sub_category, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_primary_device_type. */
+
+uint32_t dot11f_pack_tlv_rf_bands(tpAniSirGlobal pCtx,
+ tDot11fTLVRFBands *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4156, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->bands;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_rf_bands. */
+
+uint32_t dot11f_pack_tlv_request_device_type(tpAniSirGlobal pCtx,
+ tDot11fTLVRequestDeviceType *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 12;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4202, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->primary_category, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->sub_category, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_request_device_type. */
+
+uint32_t dot11f_pack_tlv_request_type(tpAniSirGlobal pCtx,
+ tDot11fTLVRequestType *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4154, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->reqType;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_request_type. */
+
+uint32_t dot11f_pack_tlv_response_type(tpAniSirGlobal pCtx,
+ tDot11fTLVResponseType *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4155, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->resType;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_response_type. */
+
+uint32_t dot11f_pack_tlv_selected_registrar(tpAniSirGlobal pCtx,
+ tDot11fTLVSelectedRegistrar *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4161, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->selected;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_selected_registrar. */
+
+uint32_t dot11f_pack_tlv_selected_registrar_config_methods(tpAniSirGlobal pCtx,
+ tDot11fTLVSelectedRegistrarConfigMethods *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4179, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ frameshtons(pCtx, pBuf, pSrc->methods, 1);
+ *pnConsumed += 2;
+ pBuf += 2;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_selected_registrar_config_methods. */
+
+uint32_t dot11f_pack_tlv_serial_number(tpAniSirGlobal pCtx,
+ tDot11fTLVSerialNumber *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_text + 4) ;
+
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4162, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+ *pnConsumed += pSrc->num_text;
+ pBuf += pSrc->num_text;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_serial_number. */
+
+uint32_t dot11f_pack_tlv_uuid_e(tpAniSirGlobal pCtx,
+ tDot11fTLVUUID_E *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 20;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4167, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_uuid_e. */
+
+uint32_t dot11f_pack_tlv_uuid_r(tpAniSirGlobal pCtx,
+ tDot11fTLVUUID_R *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 20;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4168, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_uuid_r. */
+
+uint32_t dot11f_pack_tlv_vendor_extension(tpAniSirGlobal pCtx,
+ tDot11fTLVVendorExtension *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ uint32_t idx = 0;
+ nNeeded += 7;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4169, 1);
+ pBuf += 2; nBuf -= 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; nBuf -= 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->vendorId, 3);
+ *pnConsumed += 3;
+ pBuf += 3;
+ status |= pack_tlv_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ TLVS_VendorExtension, &idx);
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return status;
+} /* End dot11f_pack_tlv_vendor_extension. */
+
+uint32_t dot11f_pack_tlv_version(tpAniSirGlobal pCtx,
+ tDot11fTLVVersion *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp71__;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4170, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ tmp71__ = 0U;
+ tmp71__ |= (pSrc->minor << 0);
+ tmp71__ |= (pSrc->major << 4);
+ *pBuf = tmp71__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_version. */
+
+uint32_t dot11f_pack_tlv_wps_state(tpAniSirGlobal pCtx,
+ tDot11fTLVWPSState *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ frameshtons(pCtx, pBuf, 4164, 1);
+ pBuf += 2; *pnConsumed += 2;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->state;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_wps_state. */
+
+uint32_t dot11f_pack_tlv_p2_p_interface(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PInterface *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 9;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 16;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_interface. */
+
+uint32_t dot11f_pack_tlv_p2_p_manageability(tpAniSirGlobal pCtx,
+ tDot11fTLVP2PManageability *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pTlvLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ while (pSrc->present) {
+ *pBuf = 10;
+ pBuf += 1; *pnConsumed += 1;
+ pTlvLen = pBuf;
+ pBuf += 2; *pnConsumed += 2;
+ *pBuf = pSrc->manageability;
+ *pnConsumed += 1;
+ pBuf += 1;
+ break;
+ }
+ (void)pCtx;
+ if (pTlvLen) {
+ frameshtons(pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0);
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_tlv_p2_p_manageability. */
+
+uint32_t dot11f_pack_ie_condensed_country_str(tpAniSirGlobal pCtx,
+ tDot11fIECondensedCountryStr *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 2;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryStr, 2);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_condensed_country_str. */
+
+uint32_t dot11f_pack_ie_gtk(tpAniSirGlobal pCtx,
+ tDot11fIEGTK *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp72__;
+ nNeeded += (pSrc->num_key + 11);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 2;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp72__ = 0U;
+ tmp72__ |= (pSrc->keyId << 0);
+ tmp72__ |= (pSrc->reserved << 2);
+ frameshtons(pCtx, pBuf, tmp72__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ *pBuf = pSrc->keyLength;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSC, 8);
+ *pnConsumed += 8;
+ pBuf += 8;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->key), pSrc->num_key);
+ *pnConsumed += pSrc->num_key;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_gtk. */
+
+uint32_t dot11f_pack_ie_igtk(tpAniSirGlobal pCtx,
+ tDot11fIEIGTK *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 33;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 4;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->keyID, 2);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->IPN, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ *pBuf = pSrc->keyLength;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->key, 24);
+ *pnConsumed += 24;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_igtk. */
+
+uint32_t dot11f_pack_ie_r0_kh_id(tpAniSirGlobal pCtx,
+ tDot11fIER0KH_ID *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_PMK_R0_ID;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 3;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->PMK_R0_ID), pSrc->num_PMK_R0_ID);
+ *pnConsumed += pSrc->num_PMK_R0_ID;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_r0_kh_id. */
+
+uint32_t dot11f_pack_ie_r1_kh_id(tpAniSirGlobal pCtx,
+ tDot11fIER1KH_ID *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 1;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->PMK_R1_ID, 6);
+ *pnConsumed += 6;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_r1_kh_id. */
+
+uint32_t dot11f_pack_ie_tsf_info(tpAniSirGlobal pCtx,
+ tDot11fIETSFInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 1;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->TsfOffset, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->BeaconIntvl, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tsf_info. */
+
+uint32_t dot11f_pack_ie_ap_channel_report(tpAniSirGlobal pCtx,
+ tDot11fIEAPChannelReport *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_channelList + 1);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 51;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->regulatoryClass;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->channelList), pSrc->num_channelList);
+ *pnConsumed += pSrc->num_channelList;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ap_channel_report. */
+
+uint32_t dot11f_pack_ie_bcn_reporting_detail(tpAniSirGlobal pCtx,
+ tDot11fIEBcnReportingDetail *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 2;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->reportingDetail;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_bcn_reporting_detail. */
+
+uint32_t dot11f_pack_ie_beacon_report_frm_body(tpAniSirGlobal pCtx,
+ tDot11fIEBeaconReportFrmBody *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_reportedFields;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 1;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->reportedFields), pSrc->num_reportedFields);
+ *pnConsumed += pSrc->num_reportedFields;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_beacon_report_frm_body. */
+
+uint32_t dot11f_pack_ie_beacon_reporting(tpAniSirGlobal pCtx,
+ tDot11fIEBeaconReporting *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 1;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->reportingCondition;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->threshold;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_beacon_reporting. */
+
+uint32_t dot11f_pack_ie_measurement_pilot(tpAniSirGlobal pCtx,
+ tDot11fIEMeasurementPilot *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_vendorSpecific + 1);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 66;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->measurementPilot;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->vendorSpecific), pSrc->num_vendorSpecific);
+ *pnConsumed += pSrc->num_vendorSpecific;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_measurement_pilot. */
+
+uint32_t dot11f_pack_ie_multi_bssid(tpAniSirGlobal pCtx,
+ tDot11fIEMultiBssid *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_vendorSpecific + 1);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 71;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->maxBSSIDIndicator;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->vendorSpecific), pSrc->num_vendorSpecific);
+ *pnConsumed += pSrc->num_vendorSpecific;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_multi_bssid. */
+
+uint32_t dot11f_pack_ie_ric_data(tpAniSirGlobal pCtx,
+ tDot11fIERICData *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 57;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->Identifier;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->resourceDescCount;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->statusCode, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ric_data. */
+
+uint32_t dot11f_pack_ie_ric_descriptor(tpAniSirGlobal pCtx,
+ tDot11fIERICDescriptor *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_variableData + 1);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 75;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->resourceType;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->variableData), pSrc->num_variableData);
+ *pnConsumed += pSrc->num_variableData;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ric_descriptor. */
+
+uint32_t dot11f_pack_ie_rrm_enabled_cap(tpAniSirGlobal pCtx,
+ tDot11fIERRMEnabledCap *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp73__;
+ uint8_t tmp74__;
+ uint8_t tmp75__;
+ uint8_t tmp76__;
+ uint8_t tmp77__;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 70;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp73__ = 0U;
+ tmp73__ |= (pSrc->LinkMeasurement << 0);
+ tmp73__ |= (pSrc->NeighborRpt << 1);
+ tmp73__ |= (pSrc->parallel << 2);
+ tmp73__ |= (pSrc->repeated << 3);
+ tmp73__ |= (pSrc->BeaconPassive << 4);
+ tmp73__ |= (pSrc->BeaconActive << 5);
+ tmp73__ |= (pSrc->BeaconTable << 6);
+ tmp73__ |= (pSrc->BeaconRepCond << 7);
+ *pBuf = tmp73__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp74__ = 0U;
+ tmp74__ |= (pSrc->FrameMeasurement << 0);
+ tmp74__ |= (pSrc->ChannelLoad << 1);
+ tmp74__ |= (pSrc->NoiseHistogram << 2);
+ tmp74__ |= (pSrc->statistics << 3);
+ tmp74__ |= (pSrc->LCIMeasurement << 4);
+ tmp74__ |= (pSrc->LCIAzimuth << 5);
+ tmp74__ |= (pSrc->TCMCapability << 6);
+ tmp74__ |= (pSrc->triggeredTCM << 7);
+ *pBuf = tmp74__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp75__ = 0U;
+ tmp75__ |= (pSrc->APChanReport << 0);
+ tmp75__ |= (pSrc->RRMMIBEnabled << 1);
+ tmp75__ |= (pSrc->operatingChanMax << 2);
+ tmp75__ |= (pSrc->nonOperatinChanMax << 5);
+ *pBuf = tmp75__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp76__ = 0U;
+ tmp76__ |= (pSrc->MeasurementPilot << 0);
+ tmp76__ |= (pSrc->MeasurementPilotEnabled << 3);
+ tmp76__ |= (pSrc->NeighborTSFOffset << 4);
+ tmp76__ |= (pSrc->RCPIMeasurement << 5);
+ tmp76__ |= (pSrc->RSNIMeasurement << 6);
+ tmp76__ |= (pSrc->BssAvgAccessDelay << 7);
+ *pBuf = tmp76__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp77__ = 0U;
+ tmp77__ |= (pSrc->BSSAvailAdmission << 0);
+ tmp77__ |= (pSrc->AntennaInformation << 1);
+ tmp77__ |= (pSrc->fine_time_meas_rpt << 2);
+ tmp77__ |= (pSrc->lci_capability << 3);
+ tmp77__ |= (pSrc->reserved << 4);
+ *pBuf = tmp77__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rrm_enabled_cap. */
+
+uint32_t dot11f_pack_ie_requested_info(tpAniSirGlobal pCtx,
+ tDot11fIERequestedInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_requested_eids;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 10;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->requested_eids), pSrc->num_requested_eids);
+ *pnConsumed += pSrc->num_requested_eids;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_requested_info. */
+
+uint32_t dot11f_pack_ie_ssid(tpAniSirGlobal pCtx,
+ tDot11fIESSID *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_ssid;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 0;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->ssid), pSrc->num_ssid);
+ *pnConsumed += pSrc->num_ssid;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ssid. */
+
+uint32_t dot11f_pack_ie_schedule(tpAniSirGlobal pCtx,
+ tDot11fIESchedule *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp78__;
+ nNeeded += 14;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 15;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp78__ = 0U;
+ tmp78__ |= (pSrc->aggregation << 0);
+ tmp78__ |= (pSrc->tsid << 1);
+ tmp78__ |= (pSrc->direction << 5);
+ tmp78__ |= (pSrc->reserved << 7);
+ frameshtons(pCtx, pBuf, tmp78__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->service_interval, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->spec_interval, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_schedule. */
+
+uint32_t dot11f_pack_ie_tclas(tpAniSirGlobal pCtx,
+ tDot11fIETCLAS *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ietclas(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 14;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->user_priority;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->classifier_type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->classifier_mask;
+ *pnConsumed += 1;
+ pBuf += 1;
+ switch (pSrc->classifier_type) {
+ case 0:
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 1:
+ *pBuf = pSrc->info.IpParams.version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ switch (pSrc->info.IpParams.version) {
+ case 4:
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->info.IpParams.params.IpV4Params.proto;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->info.IpParams.params.IpV4Params.reserved;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 6:
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3);
+ *pnConsumed += 3;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ break;
+ case 2:
+ frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_tclas. */
+
+uint32_t dot11f_pack_ie_tclassproc(tpAniSirGlobal pCtx,
+ tDot11fIETCLASSPROC *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 44;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->processing;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tclassproc. */
+
+uint32_t dot11f_pack_ie_ts_delay(tpAniSirGlobal pCtx,
+ tDot11fIETSDelay *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 43;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtonl(pCtx, pBuf, pSrc->delay, 0);
+ *pnConsumed += 4;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ts_delay. */
+
+uint32_t dot11f_pack_ie_tspec(tpAniSirGlobal pCtx,
+ tDot11fIETSPEC *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp79__;
+ uint8_t tmp80__;
+ uint16_t tmp81__;
+ nNeeded += 55;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 13;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp79__ = 0U;
+ tmp79__ |= (pSrc->traffic_type << 0);
+ tmp79__ |= (pSrc->tsid << 1);
+ tmp79__ |= (pSrc->direction << 5);
+ tmp79__ |= (pSrc->access_policy << 7);
+ tmp79__ |= (pSrc->aggregation << 9);
+ tmp79__ |= (pSrc->psb << 10);
+ tmp79__ |= (pSrc->user_priority << 11);
+ tmp79__ |= (pSrc->tsinfo_ack_pol << 14);
+ frameshtons(pCtx, pBuf, tmp79__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ tmp80__ = 0U;
+ tmp80__ |= (pSrc->schedule << 0);
+ tmp80__ |= (pSrc->unused << 1);
+ *pBuf = tmp80__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp81__ = 0U;
+ tmp81__ |= (pSrc->size << 0);
+ tmp81__ |= (pSrc->fixed << 15);
+ frameshtons(pCtx, pBuf, tmp81__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->burst_size, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->medium_time, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tspec. */
+
+uint32_t dot11f_pack_ie_vht_caps(tpAniSirGlobal pCtx,
+ tDot11fIEVHTCaps *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t tmp82__;
+ uint16_t tmp83__;
+ uint16_t tmp84__;
+ nNeeded += 12;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 191;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp82__ = 0U;
+ tmp82__ |= (pSrc->maxMPDULen << 0);
+ tmp82__ |= (pSrc->supportedChannelWidthSet << 2);
+ tmp82__ |= (pSrc->ldpcCodingCap << 4);
+ tmp82__ |= (pSrc->shortGI80MHz << 5);
+ tmp82__ |= (pSrc->shortGI160and80plus80MHz << 6);
+ tmp82__ |= (pSrc->txSTBC << 7);
+ tmp82__ |= (pSrc->rxSTBC << 8);
+ tmp82__ |= (pSrc->suBeamFormerCap << 11);
+ tmp82__ |= (pSrc->suBeamformeeCap << 12);
+ tmp82__ |= (pSrc->csnofBeamformerAntSup << 13);
+ tmp82__ |= (pSrc->numSoundingDim << 16);
+ tmp82__ |= (pSrc->muBeamformerCap << 19);
+ tmp82__ |= (pSrc->muBeamformeeCap << 20);
+ tmp82__ |= (pSrc->vhtTXOPPS << 21);
+ tmp82__ |= (pSrc->htcVHTCap << 22);
+ tmp82__ |= (pSrc->maxAMPDULenExp << 23);
+ tmp82__ |= (pSrc->vhtLinkAdaptCap << 26);
+ tmp82__ |= (pSrc->rxAntPattern << 28);
+ tmp82__ |= (pSrc->txAntPattern << 29);
+ tmp82__ |= (pSrc->reserved1 << 30);
+ frameshtonl(pCtx, pBuf, tmp82__, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ nBuf -= 4 ;
+ frameshtons(pCtx, pBuf, pSrc->rxMCSMap, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp83__ = 0U;
+ tmp83__ |= (pSrc->rxHighSupDataRate << 0);
+ tmp83__ |= (pSrc->reserved2 << 13);
+ frameshtons(pCtx, pBuf, tmp83__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ frameshtons(pCtx, pBuf, pSrc->txMCSMap, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp84__ = 0U;
+ tmp84__ |= (pSrc->txSupDataRate << 0);
+ tmp84__ |= (pSrc->reserved3 << 13);
+ frameshtons(pCtx, pBuf, tmp84__, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 2 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_caps. */
+
+uint32_t dot11f_pack_ie_vht_operation(tpAniSirGlobal pCtx,
+ tDot11fIEVHTOperation *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 192;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->chanWidth;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->chanCenterFreqSeg1;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->chanCenterFreqSeg2;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->basicMCSSet, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_operation. */
+
+uint32_t dot11f_pack_ie_wmm_schedule(tpAniSirGlobal pCtx,
+ tDot11fIEWMMSchedule *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp85__;
+ nNeeded += 15;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp85__ = 0U;
+ tmp85__ |= (pSrc->aggregation << 0);
+ tmp85__ |= (pSrc->tsid << 1);
+ tmp85__ |= (pSrc->direction << 5);
+ tmp85__ |= (pSrc->reserved << 7);
+ frameshtons(pCtx, pBuf, tmp85__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->service_interval, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->spec_interval, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_schedule. */
+
+uint32_t dot11f_pack_ie_wmmtclas(tpAniSirGlobal pCtx,
+ tDot11fIEWMMTCLAS *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_iewmmtclas(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x6;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->user_priority;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->classifier_type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->classifier_mask;
+ *pnConsumed += 1;
+ pBuf += 1;
+ switch (pSrc->classifier_type) {
+ case 0:
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 1:
+ *pBuf = pSrc->info.IpParams.version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ switch (pSrc->info.IpParams.version) {
+ case 4:
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->info.IpParams.params.IpV4Params.proto;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->info.IpParams.params.IpV4Params.reserved;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 6:
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 10);
+ *pnConsumed += 10;
+ pBuf += 10;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 10);
+ *pnConsumed += 10;
+ pBuf += 10;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3);
+ *pnConsumed += 3;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ break;
+ case 2:
+ frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_wmmtclas. */
+
+uint32_t dot11f_pack_ie_wmmtclasproc(tpAniSirGlobal pCtx,
+ tDot11fIEWMMTCLASPROC *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x7;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->processing;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmmtclasproc. */
+
+uint32_t dot11f_pack_ie_wmmts_delay(tpAniSirGlobal pCtx,
+ tDot11fIEWMMTSDelay *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x8;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonl(pCtx, pBuf, pSrc->delay, 0);
+ *pnConsumed += 4;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmmts_delay. */
+
+uint32_t dot11f_pack_ie_wmmtspec(tpAniSirGlobal pCtx,
+ tDot11fIEWMMTSPEC *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp86__;
+ uint8_t tmp87__;
+ uint16_t tmp88__;
+ nNeeded += 38;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp86__ = 0U;
+ tmp86__ |= (pSrc->traffic_type << 0);
+ tmp86__ |= (pSrc->tsid << 1);
+ tmp86__ |= (pSrc->direction << 5);
+ tmp86__ |= (pSrc->access_policy << 7);
+ tmp86__ |= (pSrc->aggregation << 9);
+ tmp86__ |= (pSrc->psb << 10);
+ tmp86__ |= (pSrc->user_priority << 11);
+ tmp86__ |= (pSrc->tsinfo_ack_pol << 14);
+ frameshtons(pCtx, pBuf, tmp86__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ tmp87__ = 0U;
+ tmp87__ |= (pSrc->tsinfo_rsvd << 0);
+ tmp87__ |= (pSrc->burst_size_defn << 7);
+ *pBuf = tmp87__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp88__ = 0U;
+ tmp88__ |= (pSrc->size << 0);
+ tmp88__ |= (pSrc->fixed << 15);
+ frameshtons(pCtx, pBuf, tmp88__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->burst_size, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->medium_time, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmmtspec. */
+
+uint32_t dot11f_pack_ie_wider_bw_chan_switch_ann(tpAniSirGlobal pCtx,
+ tDot11fIEWiderBWChanSwitchAnn *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 3;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 194;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->newChanWidth;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->newCenterChanFreq0;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->newCenterChanFreq1;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wider_bw_chan_switch_ann. */
+
+uint32_t dot11f_pack_ie_aid(tpAniSirGlobal pCtx,
+ tDot11fIEAID *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 197;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->assocId, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_aid. */
+
+uint32_t dot11f_pack_ie_cf_params(tpAniSirGlobal pCtx,
+ tDot11fIECFParams *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 4;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->cfp_count;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->cfp_period;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->cfp_maxduration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->cfp_durremaining, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_cf_params. */
+
+uint32_t dot11f_pack_ie_challenge_text(tpAniSirGlobal pCtx,
+ tDot11fIEChallengeText *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_text;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 16;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->text), pSrc->num_text);
+ *pnConsumed += pSrc->num_text;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_challenge_text. */
+
+uint32_t dot11f_pack_ie_chan_switch_ann(tpAniSirGlobal pCtx,
+ tDot11fIEChanSwitchAnn *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 3;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 37;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->switchMode;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->newChannel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->switchCount;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_chan_switch_ann. */
+
+uint32_t dot11f_pack_ie_channel_switch_wrapper(tpAniSirGlobal pCtx,
+ tDot11fIEChannelSwitchWrapper *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ie_channel_switch_wrapper(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 196;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_ChannelSwitchWrapper,
+ IES_ChannelSwitchWrapper);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_channel_switch_wrapper. */
+
+uint32_t dot11f_pack_ie_country(tpAniSirGlobal pCtx,
+ tDot11fIECountry *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ie_country(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 7;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->country, 3);
+ *pnConsumed += 3;
+ pBuf += 3;
+ if (pSrc->num_triplets) {
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->triplets), (pSrc->num_triplets * 3));
+ *pnConsumed += (pSrc->num_triplets * 3);
+ /* fieldsEndFlag = 1 */
+ } else {
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_country. */
+
+uint32_t dot11f_pack_ie_ds_params(tpAniSirGlobal pCtx,
+ tDot11fIEDSParams *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 3;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->curr_channel;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ds_params. */
+
+uint32_t dot11f_pack_ie_edca_param_set(tpAniSirGlobal pCtx,
+ tDot11fIEEDCAParamSet *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp89__;
+ uint8_t tmp90__;
+ uint8_t tmp91__;
+ uint8_t tmp92__;
+ uint8_t tmp93__;
+ uint8_t tmp94__;
+ uint8_t tmp95__;
+ uint8_t tmp96__;
+ nNeeded += 18;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 12;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->qos;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->reserved;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp89__ = 0U;
+ tmp89__ |= (pSrc->acbe_aifsn << 0);
+ tmp89__ |= (pSrc->acbe_acm << 4);
+ tmp89__ |= (pSrc->acbe_aci << 5);
+ tmp89__ |= (pSrc->unused1 << 7);
+ *pBuf = tmp89__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp90__ = 0U;
+ tmp90__ |= (pSrc->acbe_acwmin << 0);
+ tmp90__ |= (pSrc->acbe_acwmax << 4);
+ *pBuf = tmp90__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp91__ = 0U;
+ tmp91__ |= (pSrc->acbk_aifsn << 0);
+ tmp91__ |= (pSrc->acbk_acm << 4);
+ tmp91__ |= (pSrc->acbk_aci << 5);
+ tmp91__ |= (pSrc->unused2 << 7);
+ *pBuf = tmp91__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp92__ = 0U;
+ tmp92__ |= (pSrc->acbk_acwmin << 0);
+ tmp92__ |= (pSrc->acbk_acwmax << 4);
+ *pBuf = tmp92__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp93__ = 0U;
+ tmp93__ |= (pSrc->acvi_aifsn << 0);
+ tmp93__ |= (pSrc->acvi_acm << 4);
+ tmp93__ |= (pSrc->acvi_aci << 5);
+ tmp93__ |= (pSrc->unused3 << 7);
+ *pBuf = tmp93__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp94__ = 0U;
+ tmp94__ |= (pSrc->acvi_acwmin << 0);
+ tmp94__ |= (pSrc->acvi_acwmax << 4);
+ *pBuf = tmp94__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp95__ = 0U;
+ tmp95__ |= (pSrc->acvo_aifsn << 0);
+ tmp95__ |= (pSrc->acvo_acm << 4);
+ tmp95__ |= (pSrc->acvo_aci << 5);
+ tmp95__ |= (pSrc->unused4 << 7);
+ *pBuf = tmp95__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp96__ = 0U;
+ tmp96__ |= (pSrc->acvo_acwmin << 0);
+ tmp96__ |= (pSrc->acvo_acwmax << 4);
+ *pBuf = tmp96__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_edca_param_set. */
+
+uint32_t dot11f_pack_ie_erp_info(tpAniSirGlobal pCtx,
+ tDot11fIEERPInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp97__;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 42;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp97__ = 0U;
+ tmp97__ |= (pSrc->non_erp_present << 0);
+ tmp97__ |= (pSrc->use_prot << 1);
+ tmp97__ |= (pSrc->barker_preamble << 2);
+ tmp97__ |= (pSrc->unused << 3);
+ *pBuf = tmp97__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_erp_info. */
+
+uint32_t dot11f_pack_ie_ese_cckm_opaque(tpAniSirGlobal pCtx,
+ tDot11fIEESECckmOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 156;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x40;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x96;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_cckm_opaque. */
+
+uint32_t dot11f_pack_ie_ese_rad_mgmt_cap(tpAniSirGlobal pCtx,
+ tDot11fIEESERadMgmtCap *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp98__;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x40;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x96;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x1;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->mgmt_state;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp98__ = 0U;
+ tmp98__ |= (pSrc->mbssid_mask << 0);
+ tmp98__ |= (pSrc->reserved << 3);
+ *pBuf = tmp98__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_rad_mgmt_cap. */
+
+uint32_t dot11f_pack_ie_ese_traf_strm_met(tpAniSirGlobal pCtx,
+ tDot11fIEESETrafStrmMet *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x40;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x96;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x7;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->tsid;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->state;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->msmt_interval, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_traf_strm_met. */
+
+uint32_t dot11f_pack_ie_ese_traf_strm_rate_set(tpAniSirGlobal pCtx,
+ tDot11fIEESETrafStrmRateSet *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_tsrates + 1);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x40;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x96;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x8;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->tsid;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->tsrates), pSrc->num_tsrates);
+ *pnConsumed += pSrc->num_tsrates;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_traf_strm_rate_set. */
+
+uint32_t dot11f_pack_ie_ese_txmit_power(tpAniSirGlobal pCtx,
+ tDot11fIEESETxmitPower *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 150;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x40;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x96;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->power_limit;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->reserved;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_txmit_power. */
+
+uint32_t dot11f_pack_ie_ese_version(tpAniSirGlobal pCtx,
+ tDot11fIEESEVersion *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x40;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x96;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x3;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ese_version. */
+
+uint32_t dot11f_pack_ie_ext_cap(tpAniSirGlobal pCtx,
+ tDot11fIEExtCap *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_bytes;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 127;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bytes), pSrc->num_bytes);
+ *pnConsumed += pSrc->num_bytes;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ext_cap. */
+
+uint32_t dot11f_pack_ie_ext_supp_rates(tpAniSirGlobal pCtx,
+ tDot11fIEExtSuppRates *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_rates;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 50;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rates), pSrc->num_rates);
+ *pnConsumed += pSrc->num_rates;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ext_supp_rates. */
+
+uint32_t dot11f_pack_ie_fh_param_set(tpAniSirGlobal pCtx,
+ tDot11fIEFHParamSet *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 2;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->dwell_time, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->hop_set;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->hop_pattern;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->hop_index;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fh_param_set. */
+
+uint32_t dot11f_pack_ie_fh_params(tpAniSirGlobal pCtx,
+ tDot11fIEFHParams *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 8;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->radix;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->nchannels;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fh_params. */
+
+uint32_t dot11f_pack_ie_fh_patt_table(tpAniSirGlobal pCtx,
+ tDot11fIEFHPattTable *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_randtable + 4);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 9;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->flag;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->nsets;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->modulus;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->offset;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->randtable), pSrc->num_randtable);
+ *pnConsumed += pSrc->num_randtable;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_fh_patt_table. */
+
+uint32_t dot11f_pack_ie_ft_info(tpAniSirGlobal pCtx,
+ tDot11fIEFTInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp99__;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ieft_info(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 55;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ tmp99__ = 0U;
+ tmp99__ |= (pSrc->reserved << 0);
+ tmp99__ |= (pSrc->IECount << 8);
+ frameshtons(pCtx, pBuf, tmp99__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->MIC, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->Anonce, 32);
+ *pnConsumed += 32;
+ pBuf += 32;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->Snonce, 32);
+ *pnConsumed += 32;
+ pBuf += 32;
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_FTInfo,
+ IES_FTInfo);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_ft_info. */
+
+uint32_t dot11f_pack_ie_ht_caps(tpAniSirGlobal pCtx,
+ tDot11fIEHTCaps *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp100__;
+ uint8_t tmp101__;
+ uint16_t tmp102__;
+ uint32_t tmp103__;
+ uint8_t tmp104__;
+ nNeeded += (pSrc->num_rsvd + 26);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 45;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp100__ = 0U;
+ tmp100__ |= (pSrc->advCodingCap << 0);
+ tmp100__ |= (pSrc->supportedChannelWidthSet << 1);
+ tmp100__ |= (pSrc->mimoPowerSave << 2);
+ tmp100__ |= (pSrc->greenField << 4);
+ tmp100__ |= (pSrc->shortGI20MHz << 5);
+ tmp100__ |= (pSrc->shortGI40MHz << 6);
+ tmp100__ |= (pSrc->txSTBC << 7);
+ tmp100__ |= (pSrc->rxSTBC << 8);
+ tmp100__ |= (pSrc->delayedBA << 10);
+ tmp100__ |= (pSrc->maximalAMSDUsize << 11);
+ tmp100__ |= (pSrc->dsssCckMode40MHz << 12);
+ tmp100__ |= (pSrc->psmp << 13);
+ tmp100__ |= (pSrc->stbcControlFrame << 14);
+ tmp100__ |= (pSrc->lsigTXOPProtection << 15);
+ frameshtons(pCtx, pBuf, tmp100__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ tmp101__ = 0U;
+ tmp101__ |= (pSrc->maxRxAMPDUFactor << 0);
+ tmp101__ |= (pSrc->mpduDensity << 2);
+ tmp101__ |= (pSrc->reserved1 << 5);
+ *pBuf = tmp101__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->supportedMCSSet, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ tmp102__ = 0U;
+ tmp102__ |= (pSrc->pco << 0);
+ tmp102__ |= (pSrc->transitionTime << 1);
+ tmp102__ |= (pSrc->reserved2 << 3);
+ tmp102__ |= (pSrc->mcsFeedback << 8);
+ tmp102__ |= (pSrc->reserved3 << 10);
+ frameshtons(pCtx, pBuf, tmp102__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ tmp103__ = 0U;
+ tmp103__ |= (pSrc->txBF << 0);
+ tmp103__ |= (pSrc->rxStaggeredSounding << 1);
+ tmp103__ |= (pSrc->txStaggeredSounding << 2);
+ tmp103__ |= (pSrc->rxZLF << 3);
+ tmp103__ |= (pSrc->txZLF << 4);
+ tmp103__ |= (pSrc->implicitTxBF << 5);
+ tmp103__ |= (pSrc->calibration << 6);
+ tmp103__ |= (pSrc->explicitCSITxBF << 8);
+ tmp103__ |= (pSrc->explicitUncompressedSteeringMatrix << 9);
+ tmp103__ |= (pSrc->explicitBFCSIFeedback << 10);
+ tmp103__ |= (pSrc->explicitUncompressedSteeringMatrixFeedback << 13);
+ tmp103__ |= (pSrc->explicitCompressedSteeringMatrixFeedback << 16);
+ tmp103__ |= (pSrc->csiNumBFAntennae << 19);
+ tmp103__ |= (pSrc->uncompressedSteeringMatrixBFAntennae << 21);
+ tmp103__ |= (pSrc->compressedSteeringMatrixBFAntennae << 23);
+ tmp103__ |= (pSrc->reserved4 << 25);
+ frameshtonl(pCtx, pBuf, tmp103__, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ nBuf -= 4 ;
+ tmp104__ = 0U;
+ tmp104__ |= (pSrc->antennaSelection << 0);
+ tmp104__ |= (pSrc->explicitCSIFeedbackTx << 1);
+ tmp104__ |= (pSrc->antennaIndicesFeedbackTx << 2);
+ tmp104__ |= (pSrc->explicitCSIFeedback << 3);
+ tmp104__ |= (pSrc->antennaIndicesFeedback << 4);
+ tmp104__ |= (pSrc->rxAS << 5);
+ tmp104__ |= (pSrc->txSoundingPPDUs << 6);
+ tmp104__ |= (pSrc->reserved5 << 7);
+ *pBuf = tmp104__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rsvd), pSrc->num_rsvd);
+ *pnConsumed += pSrc->num_rsvd;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht_caps. */
+
+uint32_t dot11f_pack_ie_ht_info(tpAniSirGlobal pCtx,
+ tDot11fIEHTInfo *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp105__;
+ uint16_t tmp106__;
+ uint16_t tmp107__;
+ nNeeded += (pSrc->num_rsvd + 22);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 61;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->primaryChannel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp105__ = 0U;
+ tmp105__ |= (pSrc->secondaryChannelOffset << 0);
+ tmp105__ |= (pSrc->recommendedTxWidthSet << 2);
+ tmp105__ |= (pSrc->rifsMode << 3);
+ tmp105__ |= (pSrc->controlledAccessOnly << 4);
+ tmp105__ |= (pSrc->serviceIntervalGranularity << 5);
+ *pBuf = tmp105__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp106__ = 0U;
+ tmp106__ |= (pSrc->opMode << 0);
+ tmp106__ |= (pSrc->nonGFDevicesPresent << 2);
+ tmp106__ |= (pSrc->transmitBurstLimit << 3);
+ tmp106__ |= (pSrc->obssNonHTStaPresent << 4);
+ tmp106__ |= (pSrc->reserved << 5);
+ frameshtons(pCtx, pBuf, tmp106__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ tmp107__ = 0U;
+ tmp107__ |= (pSrc->basicSTBCMCS << 0);
+ tmp107__ |= (pSrc->dualCTSProtection << 7);
+ tmp107__ |= (pSrc->secondaryBeacon << 8);
+ tmp107__ |= (pSrc->lsigTXOPProtectionFullSupport << 9);
+ tmp107__ |= (pSrc->pcoActive << 10);
+ tmp107__ |= (pSrc->pcoPhase << 11);
+ tmp107__ |= (pSrc->reserved2 << 12);
+ frameshtons(pCtx, pBuf, tmp107__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->basicMCSSet, 16);
+ *pnConsumed += 16;
+ pBuf += 16;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rsvd), pSrc->num_rsvd);
+ *pnConsumed += pSrc->num_rsvd;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht_info. */
+
+uint32_t dot11f_pack_ie_ibss_params(tpAniSirGlobal pCtx,
+ tDot11fIEIBSSParams *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 6;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->atim, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ibss_params. */
+
+uint32_t dot11f_pack_ie_link_identifier(tpAniSirGlobal pCtx,
+ tDot11fIELinkIdentifier *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 18;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 101;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->InitStaAddr, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->RespStaAddr, 6);
+ *pnConsumed += 6;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_link_identifier. */
+
+uint32_t dot11f_pack_ie_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fIEMeasurementReport *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp108__;
+ uint8_t tmp109__;
+ uint8_t tmp110__;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ie_measurement_report(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 39;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->token;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp108__ = 0U;
+ tmp108__ |= (pSrc->late << 0);
+ tmp108__ |= (pSrc->incapable << 1);
+ tmp108__ |= (pSrc->refused << 2);
+ tmp108__ |= (pSrc->unused << 3);
+ *pBuf = tmp108__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ *pBuf = pSrc->type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ if (pSrc->type) {
+ switch (pSrc->type) {
+ case 0:
+ *pBuf = pSrc->report.Basic.channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonq(pCtx, pBuf, pSrc->report.Basic.meas_start_time, 0);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->report.Basic.meas_duration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp109__ = 0U;
+ tmp109__ |= (pSrc->report.Basic.bss << 0);
+ tmp109__ |= (pSrc->report.Basic.ofdm_preamble << 1);
+ tmp109__ |= (pSrc->report.Basic.unid_signal << 2);
+ tmp109__ |= (pSrc->report.Basic.rader << 3);
+ tmp109__ |= (pSrc->report.Basic.unmeasured << 4);
+ tmp109__ |= (pSrc->report.Basic.unused << 5);
+ *pBuf = tmp109__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ case 1:
+ *pBuf = pSrc->report.CCA.channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonq(pCtx, pBuf, pSrc->report.CCA.meas_start_time, 0);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->report.CCA.meas_duration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->report.CCA.cca_busy_fraction;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 2:
+ *pBuf = pSrc->report.RPIHistogram.channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonq(pCtx, pBuf, pSrc->report.RPIHistogram.meas_start_time, 0);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->report.RPIHistogram.meas_duration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->report.RPIHistogram.rpi0_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi1_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi2_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi3_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi4_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi5_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi6_density;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.RPIHistogram.rpi7_density;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 5:
+ *pBuf = pSrc->report.Beacon.regClass;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.Beacon.channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonq(pCtx, pBuf, pSrc->report.Beacon.meas_start_time, 0);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->report.Beacon.meas_duration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp110__ = 0U;
+ tmp110__ |= (pSrc->report.Beacon.condensed_PHY << 0);
+ tmp110__ |= (pSrc->report.Beacon.reported_frame_type << 7);
+ *pBuf = tmp110__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ *pBuf = pSrc->report.Beacon.RCPI;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->report.Beacon.RSNI;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->report.Beacon.BSSID, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ *pBuf = pSrc->report.Beacon.antenna_id;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonl(pCtx, pBuf, pSrc->report.Beacon.parent_TSF, 0);
+ *pnConsumed += 4;
+ pBuf += 4;
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_reportBeacon,
+ IES_reportBeacon);
+ break;
+ }
+ } else {
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_measurement_report. */
+
+uint32_t dot11f_pack_ie_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fIEMeasurementRequest *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp111__;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ie_measurement_request(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 38;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->measurement_token;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp111__ = 0U;
+ tmp111__ |= (pSrc->parallel << 0);
+ tmp111__ |= (pSrc->enable << 1);
+ tmp111__ |= (pSrc->request << 2);
+ tmp111__ |= (pSrc->report << 3);
+ tmp111__ |= (pSrc->durationMandatory << 4);
+ tmp111__ |= (pSrc->unused << 5);
+ *pBuf = tmp111__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ *pBuf = pSrc->measurement_type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ switch (pSrc->measurement_type) {
+ case 0:
+ *pBuf = pSrc->measurement_request.Basic.channel_no;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Basic.meas_start_time, 8);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->measurement_request.Basic.meas_duration, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 1:
+ *pBuf = pSrc->measurement_request.CCA.channel_no;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.CCA.meas_start_time, 8);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->measurement_request.CCA.meas_duration, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 2:
+ *pBuf = pSrc->measurement_request.RPIHistogram.channel_no;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_start_time, 8);
+ *pnConsumed += 8;
+ pBuf += 8;
+ frameshtons(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_duration, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ case 5:
+ *pBuf = pSrc->measurement_request.Beacon.regClass;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->measurement_request.Beacon.channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.randomization, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.meas_duration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->measurement_request.Beacon.meas_mode;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Beacon.BSSID, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_measurement_requestBeacon,
+ IES_measurement_requestBeacon);
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_measurement_request. */
+
+uint32_t dot11f_pack_ie_mobility_domain(tpAniSirGlobal pCtx,
+ tDot11fIEMobilityDomain *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp112__;
+ nNeeded += 3;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 54;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->MDID, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp112__ = 0U;
+ tmp112__ |= (pSrc->overDSCap << 0);
+ tmp112__ |= (pSrc->resourceReqCap << 1);
+ tmp112__ |= (pSrc->reserved << 2);
+ *pBuf = tmp112__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_mobility_domain. */
+
+uint32_t dot11f_pack_ie_neighbor_report(tpAniSirGlobal pCtx,
+ tDot11fIENeighborReport *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp113__;
+ uint8_t tmp114__;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ie_neighbor_report(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 52;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6);
+ *pnConsumed += 6;
+ pBuf += 6;
+ tmp113__ = 0U;
+ tmp113__ |= (pSrc->APReachability << 0);
+ tmp113__ |= (pSrc->Security << 2);
+ tmp113__ |= (pSrc->KeyScope << 3);
+ tmp113__ |= (pSrc->SpecMgmtCap << 4);
+ tmp113__ |= (pSrc->QosCap << 5);
+ tmp113__ |= (pSrc->apsd << 6);
+ tmp113__ |= (pSrc->rrm << 7);
+ *pBuf = tmp113__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp114__ = 0U;
+ tmp114__ |= (pSrc->DelayedBA << 0);
+ tmp114__ |= (pSrc->ImmBA << 1);
+ tmp114__ |= (pSrc->MobilityDomain << 2);
+ tmp114__ |= (pSrc->reserved << 3);
+ *pBuf = tmp114__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->reserved1, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->regulatoryClass;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->PhyType;
+ *pnConsumed += 1;
+ pBuf += 1;
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_NeighborReport,
+ IES_NeighborReport);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_neighbor_report. */
+
+uint32_t dot11f_pack_ie_obss_scan_parameters(tpAniSirGlobal pCtx,
+ tDot11fIEOBSSScanParameters *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 14;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 74;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->obssScanPassiveDwell, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->obssScanActiveDwell, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->bssChannelWidthTriggerScanInterval, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->obssScanPassiveTotalPerChannel, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->obssScanActiveTotalPerChannel, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->bssWidthChannelTransitionDelayFactor, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->obssScanActivityThreshold, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_obss_scan_parameters. */
+
+uint32_t dot11f_pack_ie_operating_mode(tpAniSirGlobal pCtx,
+ tDot11fIEOperatingMode *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp115__;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 199;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp115__ = 0U;
+ tmp115__ |= (pSrc->chanWidth << 0);
+ tmp115__ |= (pSrc->reserved << 2);
+ tmp115__ |= (pSrc->rxNSS << 4);
+ tmp115__ |= (pSrc->rxNSSType << 7);
+ *pBuf = tmp115__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_operating_mode. */
+
+uint32_t dot11f_pack_ie_p2_p_assoc_req(tpAniSirGlobal pCtx,
+ tDot11fIEP2PAssocReq *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_assoc_req(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PAssocReq +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_assoc_req. */
+
+uint32_t dot11f_pack_ie_p2_p_assoc_res(tpAniSirGlobal pCtx,
+ tDot11fIEP2PAssocRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_assoc_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PAssocRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_assoc_res. */
+
+uint32_t dot11f_pack_ie_p2_p_beacon(tpAniSirGlobal pCtx,
+ tDot11fIEP2PBeacon *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_beacon(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PBeacon +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_beacon. */
+
+uint32_t dot11f_pack_ie_p2_p_beacon_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEP2PBeaconProbeRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_beacon_probe_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PBeaconProbeRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_beacon_probe_res. */
+
+uint32_t dot11f_pack_ie_p2_p_de_auth(tpAniSirGlobal pCtx,
+ tDot11fIEP2PDeAuth *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_de_auth(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PDeAuth +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_de_auth. */
+
+uint32_t dot11f_pack_ie_p2_p_dis_assoc(tpAniSirGlobal pCtx,
+ tDot11fIEP2PDisAssoc *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_dis_assoc(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PDisAssoc +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_dis_assoc. */
+
+uint32_t dot11f_pack_ie_p2_pie_opaque(tpAniSirGlobal pCtx,
+ tDot11fIEP2PIEOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_p2_pie_opaque. */
+
+uint32_t dot11f_pack_ie_p2_p_probe_req(tpAniSirGlobal pCtx,
+ tDot11fIEP2PProbeReq *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_probe_req(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PProbeReq +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_probe_req. */
+
+uint32_t dot11f_pack_ie_p2_p_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEP2PProbeRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iep2_p_probe_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x9;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_P2PProbeRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_p2_p_probe_res. */
+
+uint32_t dot11f_pack_ie_pti_control(tpAniSirGlobal pCtx,
+ tDot11fIEPTIControl *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 3;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 105;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->tid;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->sequence_control, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_pti_control. */
+
+uint32_t dot11f_pack_ie_pu_buffer_status(tpAniSirGlobal pCtx,
+ tDot11fIEPUBufferStatus *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp116__;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 106;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp116__ = 0U;
+ tmp116__ |= (pSrc->ac_bk_traffic_aval << 0);
+ tmp116__ |= (pSrc->ac_be_traffic_aval << 1);
+ tmp116__ |= (pSrc->ac_vi_traffic_aval << 2);
+ tmp116__ |= (pSrc->ac_vo_traffic_aval << 3);
+ tmp116__ |= (pSrc->reserved << 4);
+ *pBuf = tmp116__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_pu_buffer_status. */
+
+uint32_t dot11f_pack_ie_power_caps(tpAniSirGlobal pCtx,
+ tDot11fIEPowerCaps *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 33;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->minTxPower;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->maxTxPower;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_power_caps. */
+
+uint32_t dot11f_pack_ie_power_constraints(tpAniSirGlobal pCtx,
+ tDot11fIEPowerConstraints *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 32;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->localPowerConstraints;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_power_constraints. */
+
+uint32_t dot11f_pack_ie_qbss_load(tpAniSirGlobal pCtx,
+ tDot11fIEQBSSLoad *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 11;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->stacount, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ *pBuf = pSrc->chautil;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->avail, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qbss_load. */
+
+uint32_t dot11f_pack_ie_QComVendorIE(tpAniSirGlobal pCtx,
+ tDot11fIEQComVendorIE *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xa0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xc6;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->channel;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_QComVendorIE. */
+
+uint32_t dot11f_pack_ie_qos_caps_ap(tpAniSirGlobal pCtx,
+ tDot11fIEQOSCapsAp *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp117__;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 46;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp117__ = 0U;
+ tmp117__ |= (pSrc->count << 0);
+ tmp117__ |= (pSrc->qack << 4);
+ tmp117__ |= (pSrc->qreq << 5);
+ tmp117__ |= (pSrc->txopreq << 6);
+ tmp117__ |= (pSrc->reserved << 7);
+ *pBuf = tmp117__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qos_caps_ap. */
+
+uint32_t dot11f_pack_ie_qos_caps_station(tpAniSirGlobal pCtx,
+ tDot11fIEQOSCapsStation *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp118__;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 46;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp118__ = 0U;
+ tmp118__ |= (pSrc->acvo_uapsd << 0);
+ tmp118__ |= (pSrc->acvi_uapsd << 1);
+ tmp118__ |= (pSrc->acbk_uapsd << 2);
+ tmp118__ |= (pSrc->acbe_uapsd << 3);
+ tmp118__ |= (pSrc->qack << 4);
+ tmp118__ |= (pSrc->max_sp_length << 5);
+ tmp118__ |= (pSrc->more_data_ack << 7);
+ *pBuf = tmp118__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qos_caps_station. */
+
+uint32_t dot11f_pack_ie_qos_map_set(tpAniSirGlobal pCtx,
+ tDot11fIEQosMapSet *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_dscp_exceptions;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 110;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->dscp_exceptions), pSrc->num_dscp_exceptions);
+ *pnConsumed += pSrc->num_dscp_exceptions;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_qos_map_set. */
+
+uint32_t dot11f_pack_ie_quiet(tpAniSirGlobal pCtx,
+ tDot11fIEQuiet *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 6;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 40;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->count;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->period;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtons(pCtx, pBuf, pSrc->duration, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->offset, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_quiet. */
+
+uint32_t dot11f_pack_ie_rcpiie(tpAniSirGlobal pCtx,
+ tDot11fIERCPIIE *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 53;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->rcpi;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rcpiie. */
+
+uint32_t dot11f_pack_ie_ric_data_desc(tpAniSirGlobal pCtx,
+ tDot11fIERICDataDesc *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ieric_data_desc(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_RICDataDesc,
+ IES_RICDataDesc);
+ break;
+ }
+ (void)pCtx;
+ return status;
+} /* End dot11f_pack_ie_ric_data_desc. */
+
+uint32_t dot11f_pack_ie_rsn(tpAniSirGlobal pCtx,
+ tDot11fIERSN *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_iersn(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 48;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->version, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_cipher_suite, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ if (pSrc->pwise_cipher_suite_count) {
+ frameshtons(pCtx, pBuf, pSrc->pwise_cipher_suite_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->pwise_cipher_suites), (pSrc->pwise_cipher_suite_count * 4));
+ *pnConsumed += (pSrc->pwise_cipher_suite_count * 4);
+ pBuf += (pSrc->pwise_cipher_suite_count * 4);
+ if (pSrc->akm_suite_count) {
+ frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->akm_suites), (pSrc->akm_suite_count * 4));
+ *pnConsumed += (pSrc->akm_suite_count * 4);
+ pBuf += (pSrc->akm_suite_count * 4);
+ if (pSrc->RSN_Cap) {
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSN_Cap, 2);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ if (pSrc->pmkid_count) {
+ frameshtons(pCtx, pBuf, pSrc->pmkid_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->pmkid), (pSrc->pmkid_count * 16));
+ *pnConsumed += (pSrc->pmkid_count * 16);
+ pBuf += (pSrc->pmkid_count * 16);
+ if (pSrc->gp_mgmt_cipher_suite) {
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_mgmt_cipher_suite, 4);
+ *pnConsumed += 4;
+ /* fieldsEndFlag = 1 */
+ } else {
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_rsn. */
+
+uint32_t dot11f_pack_ie_rsniie(tpAniSirGlobal pCtx,
+ tDot11fIERSNIIE *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 65;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->rsni;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rsniie. */
+
+uint32_t dot11f_pack_ie_rsn_opaque(tpAniSirGlobal pCtx,
+ tDot11fIERSNOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 48;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_rsn_opaque. */
+
+uint32_t dot11f_pack_ie_supp_channels(tpAniSirGlobal pCtx,
+ tDot11fIESuppChannels *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_bands * 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 36;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bands), (pSrc->num_bands * 2));
+ *pnConsumed += (pSrc->num_bands * 2);
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_supp_channels. */
+
+uint32_t dot11f_pack_ie_supp_operating_classes(tpAniSirGlobal pCtx,
+ tDot11fIESuppOperatingClasses *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_classes;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 59;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->classes), pSrc->num_classes);
+ *pnConsumed += pSrc->num_classes;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_supp_operating_classes. */
+
+uint32_t dot11f_pack_ie_supp_rates(tpAniSirGlobal pCtx,
+ tDot11fIESuppRates *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_rates;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 1;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->rates), pSrc->num_rates);
+ *pnConsumed += pSrc->num_rates;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_supp_rates. */
+
+uint32_t dot11f_pack_ie_tim(tpAniSirGlobal pCtx,
+ tDot11fIETIM *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_vbmp + 3);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 5;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->dtim_count;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->dtim_period;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->bmpctl;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->vbmp), pSrc->num_vbmp);
+ *pnConsumed += pSrc->num_vbmp;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tim. */
+
+uint32_t dot11f_pack_ie_tpc_report(tpAniSirGlobal pCtx,
+ tDot11fIETPCReport *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 35;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->tx_power;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->link_margin;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tpc_report. */
+
+uint32_t dot11f_pack_ie_tpc_request(tpAniSirGlobal pCtx,
+ tDot11fIETPCRequest *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 0;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 34;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_tpc_request. */
+
+uint32_t dot11f_pack_ie_time_advertisement(tpAniSirGlobal pCtx,
+ tDot11fIETimeAdvertisement *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 16;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 69;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->timing_capabilities;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->time_value, 10);
+ *pnConsumed += 10;
+ pBuf += 10;
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->time_error, 5);
+ *pnConsumed += 5;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_time_advertisement. */
+
+uint32_t dot11f_pack_ie_timeout_interval(tpAniSirGlobal pCtx,
+ tDot11fIETimeoutInterval *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 56;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->timeoutType;
+ *pnConsumed += 1;
+ pBuf += 1;
+ frameshtonl(pCtx, pBuf, pSrc->timeoutValue, 0);
+ *pnConsumed += 4;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_timeout_interval. */
+
+uint32_t dot11f_pack_ie_vht_ext_bss_load(tpAniSirGlobal pCtx,
+ tDot11fIEVHTExtBssLoad *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 5;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 193;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->muMIMOCapStaCount;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->ssUnderUtil;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->FortyMHzUtil;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->EightyMHzUtil;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->OneSixtyMHzUtil;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vht_ext_bss_load. */
+
+uint32_t dot11f_pack_ie_vendor1_ie(tpAniSirGlobal pCtx,
+ tDot11fIEVendor1IE *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 0;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x10;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x18;
+ ++pBuf; ++(*pnConsumed);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vendor1_ie. */
+
+uint32_t dot11f_pack_ie_vendor3_ie(tpAniSirGlobal pCtx,
+ tDot11fIEVendor3IE *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 0;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x16;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x32;
+ ++pBuf; ++(*pnConsumed);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_vendor3_ie. */
+
+uint32_t dot11f_pack_ie_wapi(tpAniSirGlobal pCtx,
+ tDot11fIEWAPI *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint16_t tmp119__;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_iewapi(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 68;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->version, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->akm_suites), (pSrc->akm_suite_count * 4));
+ *pnConsumed += (pSrc->akm_suite_count * 4);
+ pBuf += (pSrc->akm_suite_count * 4);
+ frameshtons(pCtx, pBuf, pSrc->unicast_cipher_suite_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->unicast_cipher_suites), (pSrc->unicast_cipher_suite_count * 4));
+ *pnConsumed += (pSrc->unicast_cipher_suite_count * 4);
+ pBuf += (pSrc->unicast_cipher_suite_count * 4);
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher_suite, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ tmp119__ = 0U;
+ tmp119__ |= (pSrc->preauth << 0);
+ tmp119__ |= (pSrc->reserved << 1);
+ frameshtons(pCtx, pBuf, tmp119__, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ nBuf -= 2 ;
+ if (pSrc->bkid_count) {
+ frameshtons(pCtx, pBuf, pSrc->bkid_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->bkid), (pSrc->bkid_count * 16));
+ *pnConsumed += (pSrc->bkid_count * 16);
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_wapi. */
+
+uint32_t dot11f_pack_ie_wapi_opaque(tpAniSirGlobal pCtx,
+ tDot11fIEWAPIOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 68;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wapi_opaque. */
+
+uint32_t dot11f_pack_ie_wfatpc(tpAniSirGlobal pCtx,
+ tDot11fIEWFATPC *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x8;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->txPower;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->linkMargin;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wfatpc. */
+
+uint32_t dot11f_pack_ie_wfdie_opaque(tpAniSirGlobal pCtx,
+ tDot11fIEWFDIEOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x6f;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x9a;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xa;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wfdie_opaque. */
+
+uint32_t dot11f_pack_ie_wmm_caps(tpAniSirGlobal pCtx,
+ tDot11fIEWMMCaps *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp120__;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x5;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp120__ = 0U;
+ tmp120__ |= (pSrc->reserved << 0);
+ tmp120__ |= (pSrc->qack << 4);
+ tmp120__ |= (pSrc->queue_request << 5);
+ tmp120__ |= (pSrc->txop_request << 6);
+ tmp120__ |= (pSrc->more_ack << 7);
+ *pBuf = tmp120__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_caps. */
+
+uint32_t dot11f_pack_ie_wmm_info_ap(tpAniSirGlobal pCtx,
+ tDot11fIEWMMInfoAp *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp121__;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp121__ = 0U;
+ tmp121__ |= (pSrc->param_set_count << 0);
+ tmp121__ |= (pSrc->reserved << 4);
+ tmp121__ |= (pSrc->uapsd << 7);
+ *pBuf = tmp121__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_info_ap. */
+
+uint32_t dot11f_pack_ie_wmm_info_station(tpAniSirGlobal pCtx,
+ tDot11fIEWMMInfoStation *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp122__;
+ nNeeded += 2;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp122__ = 0U;
+ tmp122__ |= (pSrc->acvo_uapsd << 0);
+ tmp122__ |= (pSrc->acvi_uapsd << 1);
+ tmp122__ |= (pSrc->acbk_uapsd << 2);
+ tmp122__ |= (pSrc->acbe_uapsd << 3);
+ tmp122__ |= (pSrc->reserved1 << 4);
+ tmp122__ |= (pSrc->max_sp_length << 5);
+ tmp122__ |= (pSrc->reserved2 << 7);
+ *pBuf = tmp122__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_info_station. */
+
+uint32_t dot11f_pack_ie_wmm_params(tpAniSirGlobal pCtx,
+ tDot11fIEWMMParams *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp123__;
+ uint8_t tmp124__;
+ uint8_t tmp125__;
+ uint8_t tmp126__;
+ uint8_t tmp127__;
+ uint8_t tmp128__;
+ uint8_t tmp129__;
+ uint8_t tmp130__;
+ nNeeded += 19;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x1;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->version;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->qosInfo;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->reserved2;
+ *pnConsumed += 1;
+ pBuf += 1;
+ tmp123__ = 0U;
+ tmp123__ |= (pSrc->acbe_aifsn << 0);
+ tmp123__ |= (pSrc->acbe_acm << 4);
+ tmp123__ |= (pSrc->acbe_aci << 5);
+ tmp123__ |= (pSrc->unused1 << 7);
+ *pBuf = tmp123__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp124__ = 0U;
+ tmp124__ |= (pSrc->acbe_acwmin << 0);
+ tmp124__ |= (pSrc->acbe_acwmax << 4);
+ *pBuf = tmp124__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp125__ = 0U;
+ tmp125__ |= (pSrc->acbk_aifsn << 0);
+ tmp125__ |= (pSrc->acbk_acm << 4);
+ tmp125__ |= (pSrc->acbk_aci << 5);
+ tmp125__ |= (pSrc->unused2 << 7);
+ *pBuf = tmp125__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp126__ = 0U;
+ tmp126__ |= (pSrc->acbk_acwmin << 0);
+ tmp126__ |= (pSrc->acbk_acwmax << 4);
+ *pBuf = tmp126__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp127__ = 0U;
+ tmp127__ |= (pSrc->acvi_aifsn << 0);
+ tmp127__ |= (pSrc->acvi_acm << 4);
+ tmp127__ |= (pSrc->acvi_aci << 5);
+ tmp127__ |= (pSrc->unused3 << 7);
+ *pBuf = tmp127__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp128__ = 0U;
+ tmp128__ |= (pSrc->acvi_acwmin << 0);
+ tmp128__ |= (pSrc->acvi_acwmax << 4);
+ *pBuf = tmp128__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ tmp129__ = 0U;
+ tmp129__ |= (pSrc->acvo_aifsn << 0);
+ tmp129__ |= (pSrc->acvo_acm << 4);
+ tmp129__ |= (pSrc->acvo_aci << 5);
+ tmp129__ |= (pSrc->unused4 << 7);
+ *pBuf = tmp129__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ tmp130__ = 0U;
+ tmp130__ |= (pSrc->acvo_acwmin << 0);
+ tmp130__ |= (pSrc->acvo_acwmax << 4);
+ *pBuf = tmp130__;
+ *pnConsumed += 1;
+ pBuf += 1;
+ nBuf -= 1 ;
+ frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wmm_params. */
+
+uint32_t dot11f_pack_ie_wpa(tpAniSirGlobal pCtx,
+ tDot11fIEWPA *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_iewpa(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x1;
+ ++pBuf; ++(*pnConsumed);
+ frameshtons(pCtx, pBuf, pSrc->version, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ if (pSrc->multicast_cipher_present) {
+ DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher, 4);
+ *pnConsumed += 4;
+ pBuf += 4;
+ } else {
+ break;
+ }
+ if (pSrc->unicast_cipher_count) {
+ frameshtons(pCtx, pBuf, pSrc->unicast_cipher_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->unicast_ciphers), (pSrc->unicast_cipher_count * 4));
+ *pnConsumed += (pSrc->unicast_cipher_count * 4);
+ pBuf += (pSrc->unicast_cipher_count * 4);
+ if (pSrc->auth_suite_count) {
+ frameshtons(pCtx, pBuf, pSrc->auth_suite_count, 0);
+ *pnConsumed += 2;
+ pBuf += 2;
+ } else {
+ break;
+ }
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->auth_suites), (pSrc->auth_suite_count * 4));
+ *pnConsumed += (pSrc->auth_suite_count * 4);
+ pBuf += (pSrc->auth_suite_count * 4);
+ if (pSrc->caps) {
+ frameshtons(pCtx, pBuf, pSrc->caps, 0);
+ *pnConsumed += 2;
+ /* fieldsEndFlag = 1 */
+ } else {
+ break;
+ }
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_wpa. */
+
+uint32_t dot11f_pack_ie_wpa_opaque(tpAniSirGlobal pCtx,
+ tDot11fIEWPAOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x1;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wpa_opaque. */
+
+uint32_t dot11f_pack_ie_wsc(tpAniSirGlobal pCtx,
+ tDot11fIEWSC *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_iewsc(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WSC +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc. */
+
+uint32_t dot11f_pack_ie_wsc_assoc_req(tpAniSirGlobal pCtx,
+ tDot11fIEWscAssocReq *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_assoc_req(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscAssocReq +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_assoc_req. */
+
+uint32_t dot11f_pack_ie_wsc_assoc_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscAssocRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_assoc_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscAssocRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_assoc_res. */
+
+uint32_t dot11f_pack_ie_wsc_beacon(tpAniSirGlobal pCtx,
+ tDot11fIEWscBeacon *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_beacon(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscBeacon +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_beacon. */
+
+uint32_t dot11f_pack_ie_wsc_beacon_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscBeaconProbeRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_beacon_probe_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscBeaconProbeRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_beacon_probe_res. */
+
+uint32_t dot11f_pack_ie_wsc_ie_opaque(tpAniSirGlobal pCtx,
+ tDot11fIEWscIEOpaque *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += pSrc->num_data;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; ++(*pnConsumed);
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->data), pSrc->num_data);
+ *pnConsumed += pSrc->num_data;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_wsc_ie_opaque. */
+
+uint32_t dot11f_pack_ie_wsc_probe_req(tpAniSirGlobal pCtx,
+ tDot11fIEWscProbeReq *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_probe_req(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscProbeReq +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_probe_req. */
+
+uint32_t dot11f_pack_ie_wsc_probe_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscProbeRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_probe_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscProbeRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_probe_res. */
+
+uint32_t dot11f_pack_ie_wsc_reassoc_res(tpAniSirGlobal pCtx,
+ tDot11fIEWscReassocRes *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t n, idx = 0, idxlast;
+ uint32_t nConsumedSoFar, nConsumedNow;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ uint32_t nNeeded = 0U;
+ status = dot11f_get_packed_ie_wsc_reassoc_res(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ (void)pCtx;
+ if (pSrc->present) {
+ do {
+ nConsumedSoFar = *pnConsumed;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x50;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0xf2;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ n = (255 - 4) < nBuf ? (255 - 4) : nBuf;
+ nConsumedNow = *pnConsumed;
+ idxlast = idx;
+ status = pack_tlv_core(pCtx, (uint8_t *)pSrc, pBuf, n,
+ pnConsumed,
+ TLVS_WscReassocRes +
+ idx, &idx);
+ nConsumedNow = *pnConsumed - nConsumedNow;
+ *pIeLen = *pnConsumed - nConsumedSoFar - 2;
+ pBuf += nConsumedNow;
+ nBuf -= nConsumedNow;
+ } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx);
+ }
+ return status;
+} /* End dot11f_pack_ie_wsc_reassoc_res. */
+
+uint32_t dot11f_pack_ie_ext_chan_switch_ann(tpAniSirGlobal pCtx,
+ tDot11fIEext_chan_switch_ann *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 4;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 60;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->switch_mode;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->new_reg_class;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->new_channel;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->switch_count;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ext_chan_switch_ann. */
+
+uint32_t dot11f_pack_ie_ht2040_bss_coexistence(tpAniSirGlobal pCtx,
+ tDot11fIEht2040_bss_coexistence *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint8_t tmp131__;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 72;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ tmp131__ = 0U;
+ tmp131__ |= (pSrc->info_request << 0);
+ tmp131__ |= (pSrc->forty_mhz_intolerant << 1);
+ tmp131__ |= (pSrc->twenty_mhz_bsswidth_req << 2);
+ tmp131__ |= (pSrc->obss_scan_exemption_req << 3);
+ tmp131__ |= (pSrc->obss_scan_exemption_grant << 4);
+ tmp131__ |= (pSrc->unused << 5);
+ *pBuf = tmp131__;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ nBuf -= 1 ;
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht2040_bss_coexistence. */
+
+uint32_t dot11f_pack_ie_ht2040_bss_intolerant_report(tpAniSirGlobal pCtx,
+ tDot11fIEht2040_bss_intolerant_report *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += (pSrc->num_channel_list + 1);
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 73;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->operating_class;
+ *pnConsumed += 1;
+ pBuf += 1;
+ DOT11F_MEMCPY(pCtx, pBuf, &(pSrc->channel_list), pSrc->num_channel_list);
+ *pnConsumed += pSrc->num_channel_list;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_ht2040_bss_intolerant_report. */
+
+uint32_t dot11f_pack_ie_sec_chan_offset_ele(tpAniSirGlobal pCtx,
+ tDot11fIEsec_chan_offset_ele *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ nNeeded += 1;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 62;
+ ++pBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; ++(*pnConsumed);
+ *pBuf = pSrc->secondaryChannelOffset;
+ *pnConsumed += 1;
+ /* fieldsEndFlag = 1 */
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return DOT11F_PARSE_SUCCESS;
+} /* End dot11f_pack_ie_sec_chan_offset_ele. */
+
+uint32_t dot11f_pack_ie_vendor2_ie(tpAniSirGlobal pCtx,
+ tDot11fIEvendor2_ie *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed)
+{
+ uint8_t *pIeLen = 0;
+ uint32_t nConsumedOnEntry = *pnConsumed;
+ uint32_t nNeeded = 0U;
+ uint32_t status = DOT11F_PARSE_SUCCESS;
+ status = dot11f_get_packed_ie_vendor2_ie(pCtx, pSrc, &nNeeded);
+ if (!DOT11F_SUCCEEDED(status))
+ return status;
+ while (pSrc->present) {
+ if (nNeeded > nBuf)
+ return DOT11F_BUFFER_OVERFLOW;
+ *pBuf = 221;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ pIeLen = pBuf;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x0;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x90;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = 0x4c;
+ ++pBuf; --nBuf; ++(*pnConsumed);
+ *pBuf = pSrc->type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ *pBuf = pSrc->sub_type;
+ *pnConsumed += 1;
+ pBuf += 1;
+ status = pack_core(pCtx,
+ (uint8_t *)pSrc,
+ pBuf,
+ nBuf,
+ pnConsumed,
+ FFS_vendor2_ie,
+ IES_vendor2_ie);
+ break;
+ }
+ (void)pCtx;
+ if (pIeLen) {
+ *pIeLen = *pnConsumed - nConsumedOnEntry - 2;
+ }
+ return status;
+} /* End dot11f_pack_ie_vendor2_ie. */
+
+uint32_t dot11f_pack_add_ts_request(tpAniSirGlobal pCtx,
+ tDot11fAddTSRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_AddTSRequest, IES_AddTSRequest);
+
+ return status;
+
+} /* End dot11f_unpack_add_ts_request. */
+
+uint32_t dot11f_pack_add_ts_response(tpAniSirGlobal pCtx,
+ tDot11fAddTSResponse *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_AddTSResponse, IES_AddTSResponse);
+
+ return status;
+
+} /* End dot11f_unpack_add_ts_response. */
+
+uint32_t dot11f_pack_assoc_request(tpAniSirGlobal pCtx,
+ tDot11fAssocRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_AssocRequest, IES_AssocRequest);
+
+ return status;
+
+} /* End dot11f_unpack_assoc_request. */
+
+uint32_t dot11f_pack_assoc_response(tpAniSirGlobal pCtx,
+ tDot11fAssocResponse *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_AssocResponse, IES_AssocResponse);
+
+ return status;
+
+} /* End dot11f_unpack_assoc_response. */
+
+uint32_t dot11f_pack_authentication(tpAniSirGlobal pCtx,
+ tDot11fAuthentication *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_Authentication, IES_Authentication);
+
+ return status;
+
+} /* End dot11f_unpack_authentication. */
+
+uint32_t dot11f_pack_beacon(tpAniSirGlobal pCtx,
+ tDot11fBeacon *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_Beacon, IES_Beacon);
+
+ return status;
+
+} /* End dot11f_unpack_beacon. */
+
+uint32_t dot11f_pack_beacon1(tpAniSirGlobal pCtx,
+ tDot11fBeacon1 *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_Beacon1, IES_Beacon1);
+
+ return status;
+
+} /* End dot11f_unpack_beacon1. */
+
+uint32_t dot11f_pack_beacon2(tpAniSirGlobal pCtx,
+ tDot11fBeacon2 *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_Beacon2, IES_Beacon2);
+
+ return status;
+
+} /* End dot11f_unpack_beacon2. */
+
+uint32_t dot11f_pack_beacon_i_es(tpAniSirGlobal pCtx,
+ tDot11fBeaconIEs *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_BeaconIEs, IES_BeaconIEs);
+
+ return status;
+
+} /* End dot11f_unpack_beacon_i_es. */
+
+uint32_t dot11f_pack_channel_switch(tpAniSirGlobal pCtx,
+ tDot11fChannelSwitch *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_ChannelSwitch, IES_ChannelSwitch);
+
+ return status;
+
+} /* End dot11f_unpack_channel_switch. */
+
+uint32_t dot11f_pack_de_auth(tpAniSirGlobal pCtx,
+ tDot11fDeAuth *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_DeAuth, IES_DeAuth);
+
+ return status;
+
+} /* End dot11f_unpack_de_auth. */
+
+uint32_t dot11f_pack_del_ts(tpAniSirGlobal pCtx,
+ tDot11fDelTS *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_DelTS, IES_DelTS);
+
+ return status;
+
+} /* End dot11f_unpack_del_ts. */
+
+uint32_t dot11f_pack_disassociation(tpAniSirGlobal pCtx,
+ tDot11fDisassociation *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_Disassociation, IES_Disassociation);
+
+ return status;
+
+} /* End dot11f_unpack_disassociation. */
+
+uint32_t dot11f_pack_link_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementReport *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_LinkMeasurementReport, IES_LinkMeasurementReport);
+
+ return status;
+
+} /* End dot11f_unpack_link_measurement_report. */
+
+uint32_t dot11f_pack_link_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fLinkMeasurementRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest);
+
+ return status;
+
+} /* End dot11f_unpack_link_measurement_request. */
+
+uint32_t dot11f_pack_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fMeasurementReport *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_MeasurementReport, IES_MeasurementReport);
+
+ return status;
+
+} /* End dot11f_unpack_measurement_report. */
+
+uint32_t dot11f_pack_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fMeasurementRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_MeasurementRequest, IES_MeasurementRequest);
+
+ return status;
+
+} /* End dot11f_unpack_measurement_request. */
+
+uint32_t dot11f_pack_neighbor_report_request(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_NeighborReportRequest, IES_NeighborReportRequest);
+
+ return status;
+
+} /* End dot11f_unpack_neighbor_report_request. */
+
+uint32_t dot11f_pack_neighbor_report_response(tpAniSirGlobal pCtx,
+ tDot11fNeighborReportResponse *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_NeighborReportResponse, IES_NeighborReportResponse);
+
+ return status;
+
+} /* End dot11f_unpack_neighbor_report_response. */
+
+uint32_t dot11f_pack_operating_mode(tpAniSirGlobal pCtx,
+ tDot11fOperatingMode *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_OperatingMode, IES_OperatingMode);
+
+ return status;
+
+} /* End dot11f_unpack_operating_mode. */
+
+uint32_t dot11f_pack_probe_request(tpAniSirGlobal pCtx,
+ tDot11fProbeRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_ProbeRequest, IES_ProbeRequest);
+
+ return status;
+
+} /* End dot11f_unpack_probe_request. */
+
+uint32_t dot11f_pack_probe_response(tpAniSirGlobal pCtx,
+ tDot11fProbeResponse *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_ProbeResponse, IES_ProbeResponse);
+
+ return status;
+
+} /* End dot11f_unpack_probe_response. */
+
+uint32_t dot11f_pack_qos_map_configure(tpAniSirGlobal pCtx,
+ tDot11fQosMapConfigure *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_QosMapConfigure, IES_QosMapConfigure);
+
+ return status;
+
+} /* End dot11f_unpack_qos_map_configure. */
+
+uint32_t dot11f_pack_radio_measurement_report(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementReport *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_RadioMeasurementReport, IES_RadioMeasurementReport);
+
+ return status;
+
+} /* End dot11f_unpack_radio_measurement_report. */
+
+uint32_t dot11f_pack_radio_measurement_request(tpAniSirGlobal pCtx,
+ tDot11fRadioMeasurementRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest);
+
+ return status;
+
+} /* End dot11f_unpack_radio_measurement_request. */
+
+uint32_t dot11f_pack_re_assoc_request(tpAniSirGlobal pCtx,
+ tDot11fReAssocRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_ReAssocRequest, IES_ReAssocRequest);
+
+ return status;
+
+} /* End dot11f_unpack_re_assoc_request. */
+
+uint32_t dot11f_pack_re_assoc_response(tpAniSirGlobal pCtx,
+ tDot11fReAssocResponse *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_ReAssocResponse, IES_ReAssocResponse);
+
+ return status;
+
+} /* End dot11f_unpack_re_assoc_response. */
+
+uint32_t dot11f_pack_sm_power_save(tpAniSirGlobal pCtx,
+ tDot11fSMPowerSave *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_SMPowerSave, IES_SMPowerSave);
+
+ return status;
+
+} /* End dot11f_unpack_sm_power_save. */
+
+uint32_t dot11f_pack_sa_query_req(tpAniSirGlobal pCtx,
+ tDot11fSaQueryReq *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_SaQueryReq, IES_SaQueryReq);
+
+ return status;
+
+} /* End dot11f_unpack_sa_query_req. */
+
+uint32_t dot11f_pack_sa_query_rsp(tpAniSirGlobal pCtx,
+ tDot11fSaQueryRsp *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_SaQueryRsp, IES_SaQueryRsp);
+
+ return status;
+
+} /* End dot11f_unpack_sa_query_rsp. */
+
+uint32_t dot11f_pack_tdls_dis_req(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisReq *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSDisReq, IES_TDLSDisReq);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_dis_req. */
+
+uint32_t dot11f_pack_tdls_dis_rsp(tpAniSirGlobal pCtx,
+ tDot11fTDLSDisRsp *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSDisRsp, IES_TDLSDisRsp);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_dis_rsp. */
+
+uint32_t dot11f_pack_tdls_peer_traffic_ind(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficInd *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_ind. */
+
+uint32_t dot11f_pack_tdls_peer_traffic_rsp(tpAniSirGlobal pCtx,
+ tDot11fTDLSPeerTrafficRsp *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_peer_traffic_rsp. */
+
+uint32_t dot11f_pack_tdls_setup_cnf(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupCnf *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSSetupCnf, IES_TDLSSetupCnf);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_setup_cnf. */
+
+uint32_t dot11f_pack_tdls_setup_req(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupReq *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSSetupReq, IES_TDLSSetupReq);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_setup_req. */
+
+uint32_t dot11f_pack_tdls_setup_rsp(tpAniSirGlobal pCtx,
+ tDot11fTDLSSetupRsp *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSSetupRsp, IES_TDLSSetupRsp);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_setup_rsp. */
+
+uint32_t dot11f_pack_tdls_teardown(tpAniSirGlobal pCtx,
+ tDot11fTDLSTeardown *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TDLSTeardown, IES_TDLSTeardown);
+
+ return status;
+
+} /* End dot11f_unpack_tdls_teardown. */
+
+uint32_t dot11f_pack_tpc_report(tpAniSirGlobal pCtx,
+ tDot11fTPCReport *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TPCReport, IES_TPCReport);
+
+ return status;
+
+} /* End dot11f_unpack_tpc_report. */
+
+uint32_t dot11f_pack_tpc_request(tpAniSirGlobal pCtx,
+ tDot11fTPCRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TPCRequest, IES_TPCRequest);
+
+ return status;
+
+} /* End dot11f_unpack_tpc_request. */
+
+uint32_t dot11f_pack_timing_advertisement_frame(tpAniSirGlobal pCtx,
+ tDot11fTimingAdvertisementFrame *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_TimingAdvertisementFrame, IES_TimingAdvertisementFrame);
+
+ return status;
+
+} /* End dot11f_unpack_timing_advertisement_frame. */
+
+uint32_t dot11f_pack_vht_gid_management_action_frame(tpAniSirGlobal pCtx,
+ tDot11fVHTGidManagementActionFrame *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame);
+
+ return status;
+
+} /* End dot11f_unpack_vht_gid_management_action_frame. */
+
+uint32_t dot11f_pack_wmm_add_ts_request(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSRequest *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_WMMAddTSRequest, IES_WMMAddTSRequest);
+
+ return status;
+
+} /* End dot11f_unpack_wmm_add_ts_request. */
+
+uint32_t dot11f_pack_wmm_add_ts_response(tpAniSirGlobal pCtx,
+ tDot11fWMMAddTSResponse *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_WMMAddTSResponse, IES_WMMAddTSResponse);
+
+ return status;
+
+} /* End dot11f_unpack_wmm_add_ts_response. */
+
+uint32_t dot11f_pack_wmm_del_ts(tpAniSirGlobal pCtx,
+ tDot11fWMMDelTS *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_WMMDelTS, IES_WMMDelTS);
+
+ return status;
+
+} /* End dot11f_unpack_wmm_del_ts. */
+
+uint32_t dot11f_pack_ht2040_bss_coexistence_mgmt_action_frame(tpAniSirGlobal pCtx,
+ tDot11fht2040_bss_coexistence_mgmt_action_frame *pFrm,
+ uint8_t *pBuf, uint32_t nBuf, uint32_t *pnConsumed)
+{
+ uint32_t i = 0;
+ uint32_t status = 0;
+ (void)i;
+ *pnConsumed = 0U;
+ status = pack_core(pCtx, (uint8_t *)pFrm, pBuf, nBuf, pnConsumed,
+ FFS_ht2040_bss_coexistence_mgmt_action_frame, IES_ht2040_bss_coexistence_mgmt_action_frame);
+
+ return status;
+
+} /* End dot11f_unpack_ht2040_bss_coexistence_mgmt_action_frame. */
+
+static uint32_t pack_core(tpAniSirGlobal pCtx,
+ uint8_t *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed,
+ const tFFDefn FFs[],
+ const tIEDefn IEs[])
+{
+ const tFFDefn *pFf;
+ const tIEDefn *pIe;
+ tFRAMES_BOOL *pfFound;
+ uint8_t *pBufRemaining;
+ uint16_t i;
+ uint32_t nBufRemaining, status, len;
+ uint32_t countOffset = 0;
+
+ (void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */
+ i = 0;
+
+ DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed);
+
+ status = DOT11F_PARSE_SUCCESS;
+ pBufRemaining = pBuf;
+ nBufRemaining = nBuf;
+
+ pFf = &(FFs[0]);
+ while (pFf->size) {
+ if (pFf->size > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGE, FRFL("The Fixed Field %s req"
+ "uires %d bytes, but there are only %d remaining.\n"),
+ pFf->name, pFf->size, nBufRemaining);
+ return DOT11F_BUFFER_OVERFLOW;
+ }
+
+ switch (pFf->sig) {
+ case SigFfAID:
+ dot11f_pack_ff_aid(
+ pCtx, (tDot11fFfAID *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfAction:
+ dot11f_pack_ff_action(
+ pCtx, (tDot11fFfAction *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfAuthAlgo:
+ dot11f_pack_ff_auth_algo(
+ pCtx, (tDot11fFfAuthAlgo *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfAuthSeqNo:
+ dot11f_pack_ff_auth_seq_no(
+ pCtx, (tDot11fFfAuthSeqNo *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfBeaconInterval:
+ dot11f_pack_ff_beacon_interval(
+ pCtx, (tDot11fFfBeaconInterval *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfCapabilities:
+ dot11f_pack_ff_capabilities(
+ pCtx, (tDot11fFfCapabilities *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfCategory:
+ dot11f_pack_ff_category(
+ pCtx, (tDot11fFfCategory *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfCurrentAPAddress:
+ dot11f_pack_ff_current_ap_address(
+ pCtx, (tDot11fFfCurrentAPAddress *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfDialogToken:
+ dot11f_pack_ff_dialog_token(
+ pCtx, (tDot11fFfDialogToken *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfLinkMargin:
+ dot11f_pack_ff_link_margin(
+ pCtx, (tDot11fFfLinkMargin *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfListenInterval:
+ dot11f_pack_ff_listen_interval(
+ pCtx, (tDot11fFfListenInterval *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfMaxTxPower:
+ dot11f_pack_ff_max_tx_power(
+ pCtx, (tDot11fFfMaxTxPower *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfNumOfRepetitions:
+ dot11f_pack_ff_num_of_repetitions(
+ pCtx, (tDot11fFfNumOfRepetitions *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfOperatingMode:
+ dot11f_pack_ff_operating_mode(
+ pCtx, (tDot11fFfOperatingMode *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfRCPI:
+ dot11f_pack_ff_rcpi(
+ pCtx, (tDot11fFfRCPI *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfRSNI:
+ dot11f_pack_ff_rsni(
+ pCtx, (tDot11fFfRSNI *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfReason:
+ dot11f_pack_ff_reason(
+ pCtx, (tDot11fFfReason *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfRxAntennaId:
+ dot11f_pack_ff_rx_antenna_id(
+ pCtx, (tDot11fFfRxAntennaId *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfSMPowerModeSet:
+ dot11f_pack_ff_sm_power_mode_set(
+ pCtx, (tDot11fFfSMPowerModeSet *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfStatus:
+ dot11f_pack_ff_status(
+ pCtx, (tDot11fFfStatus *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfStatusCode:
+ dot11f_pack_ff_status_code(
+ pCtx, (tDot11fFfStatusCode *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTPCEleID:
+ dot11f_pack_ff_tpc_ele_id(
+ pCtx, (tDot11fFfTPCEleID *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTPCEleLen:
+ dot11f_pack_ff_tpc_ele_len(
+ pCtx, (tDot11fFfTPCEleLen *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTSInfo:
+ dot11f_pack_ff_ts_info(
+ pCtx, (tDot11fFfTSInfo *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTimeStamp:
+ dot11f_pack_ff_time_stamp(
+ pCtx, (tDot11fFfTimeStamp *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTransactionId:
+ dot11f_pack_ff_transaction_id(
+ pCtx, (tDot11fFfTransactionId *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTxAntennaId:
+ dot11f_pack_ff_tx_antenna_id(
+ pCtx, (tDot11fFfTxAntennaId *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfTxPower:
+ dot11f_pack_ff_tx_power(
+ pCtx, (tDot11fFfTxPower *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfVhtMembershipStatusArray:
+ dot11f_pack_ff_vht_membership_status_array(
+ pCtx, (tDot11fFfVhtMembershipStatusArray *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ case SigFfVhtUserPositionArray:
+ dot11f_pack_ff_vht_user_position_array(
+ pCtx, (tDot11fFfVhtUserPositionArray *)
+ (pSrc + pFf->offset), pBufRemaining);
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+ "'t know about the Fixed Field %d; this is most l"
+ "ikely a bug in 'framesg'.\n"), pFf->sig);
+ return DOT11F_INTERNAL_ERROR;
+ }
+
+ pBufRemaining += pFf->size;
+ nBufRemaining -= pFf->size;
+ *pnConsumed += pFf->size;
+ ++pFf;
+
+ }
+
+ pIe = &(IEs[0]);
+ while (0xff != pIe->eid) {
+ pfFound = (tFRAMES_BOOL *)(pSrc + pIe->offset +
+ pIe->presenceOffset);
+ if (*pfFound && pIe->minSize > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGE, FRFL("The IE %s takes at le"
+ "ast %d bytes, but there are only %d left in the b"
+ "uffer.\n"), pIe->name, pIe->minSize, nBufRemaining);
+ return DOT11F_BUFFER_OVERFLOW;
+ }
+
+
+ countOffset = ((0 == pIe->arraybound) ? 1 : *(uint16_t *)(pSrc + pIe->countOffset));
+ for (i = 0; i < countOffset; ++i) {
+ len = 0U;
+ switch (pIe->sig) {
+ case SigIeCondensedCountryStr:
+ status |=
+ dot11f_pack_ie_condensed_country_str(
+ pCtx, (tDot11fIECondensedCountryStr *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIECondensedCountryStr) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeGTK:
+ status |=
+ dot11f_pack_ie_gtk(
+ pCtx, (tDot11fIEGTK *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEGTK) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeIGTK:
+ status |=
+ dot11f_pack_ie_igtk(
+ pCtx, (tDot11fIEIGTK *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEIGTK) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeR0KH_ID:
+ status |=
+ dot11f_pack_ie_r0_kh_id(
+ pCtx, (tDot11fIER0KH_ID *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIER0KH_ID) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeR1KH_ID:
+ status |=
+ dot11f_pack_ie_r1_kh_id(
+ pCtx, (tDot11fIER1KH_ID *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIER1KH_ID) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTSFInfo:
+ status |=
+ dot11f_pack_ie_tsf_info(
+ pCtx, (tDot11fIETSFInfo *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETSFInfo) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeAPChannelReport:
+ status |=
+ dot11f_pack_ie_ap_channel_report(
+ pCtx, (tDot11fIEAPChannelReport *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEAPChannelReport) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeBcnReportingDetail:
+ status |=
+ dot11f_pack_ie_bcn_reporting_detail(
+ pCtx, (tDot11fIEBcnReportingDetail *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEBcnReportingDetail) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeBeaconReportFrmBody:
+ status |=
+ dot11f_pack_ie_beacon_report_frm_body(
+ pCtx, (tDot11fIEBeaconReportFrmBody *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEBeaconReportFrmBody) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeBeaconReporting:
+ status |=
+ dot11f_pack_ie_beacon_reporting(
+ pCtx, (tDot11fIEBeaconReporting *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEBeaconReporting) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeMeasurementPilot:
+ status |=
+ dot11f_pack_ie_measurement_pilot(
+ pCtx, (tDot11fIEMeasurementPilot *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEMeasurementPilot) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeMultiBssid:
+ status |=
+ dot11f_pack_ie_multi_bssid(
+ pCtx, (tDot11fIEMultiBssid *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEMultiBssid) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRICData:
+ status |=
+ dot11f_pack_ie_ric_data(
+ pCtx, (tDot11fIERICData *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERICData) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRICDescriptor:
+ status |=
+ dot11f_pack_ie_ric_descriptor(
+ pCtx, (tDot11fIERICDescriptor *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERICDescriptor) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRRMEnabledCap:
+ status |=
+ dot11f_pack_ie_rrm_enabled_cap(
+ pCtx, (tDot11fIERRMEnabledCap *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERRMEnabledCap) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRequestedInfo:
+ status |=
+ dot11f_pack_ie_requested_info(
+ pCtx, (tDot11fIERequestedInfo *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERequestedInfo) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeSSID:
+ status |=
+ dot11f_pack_ie_ssid(
+ pCtx, (tDot11fIESSID *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIESSID) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeSchedule:
+ status |=
+ dot11f_pack_ie_schedule(
+ pCtx, (tDot11fIESchedule *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIESchedule) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTCLAS:
+ status |=
+ dot11f_pack_ie_tclas(
+ pCtx, (tDot11fIETCLAS *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETCLAS) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTCLASSPROC:
+ status |=
+ dot11f_pack_ie_tclassproc(
+ pCtx, (tDot11fIETCLASSPROC *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETCLASSPROC) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTSDelay:
+ status |=
+ dot11f_pack_ie_ts_delay(
+ pCtx, (tDot11fIETSDelay *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETSDelay) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTSPEC:
+ status |=
+ dot11f_pack_ie_tspec(
+ pCtx, (tDot11fIETSPEC *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETSPEC) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeVHTCaps:
+ status |=
+ dot11f_pack_ie_vht_caps(
+ pCtx, (tDot11fIEVHTCaps *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEVHTCaps) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeVHTOperation:
+ status |=
+ dot11f_pack_ie_vht_operation(
+ pCtx, (tDot11fIEVHTOperation *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEVHTOperation) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMSchedule:
+ status |=
+ dot11f_pack_ie_wmm_schedule(
+ pCtx, (tDot11fIEWMMSchedule *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMSchedule) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMTCLAS:
+ status |=
+ dot11f_pack_ie_wmmtclas(
+ pCtx, (tDot11fIEWMMTCLAS *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMTCLAS) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMTCLASPROC:
+ status |=
+ dot11f_pack_ie_wmmtclasproc(
+ pCtx, (tDot11fIEWMMTCLASPROC *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMTCLASPROC) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMTSDelay:
+ status |=
+ dot11f_pack_ie_wmmts_delay(
+ pCtx, (tDot11fIEWMMTSDelay *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMTSDelay) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMTSPEC:
+ status |=
+ dot11f_pack_ie_wmmtspec(
+ pCtx, (tDot11fIEWMMTSPEC *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMTSPEC) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWiderBWChanSwitchAnn:
+ status |=
+ dot11f_pack_ie_wider_bw_chan_switch_ann(
+ pCtx, (tDot11fIEWiderBWChanSwitchAnn *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWiderBWChanSwitchAnn) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeAID:
+ status |=
+ dot11f_pack_ie_aid(
+ pCtx, (tDot11fIEAID *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEAID) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeCFParams:
+ status |=
+ dot11f_pack_ie_cf_params(
+ pCtx, (tDot11fIECFParams *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIECFParams) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeChallengeText:
+ status |=
+ dot11f_pack_ie_challenge_text(
+ pCtx, (tDot11fIEChallengeText *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEChallengeText) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeChanSwitchAnn:
+ status |=
+ dot11f_pack_ie_chan_switch_ann(
+ pCtx, (tDot11fIEChanSwitchAnn *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEChanSwitchAnn) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeChannelSwitchWrapper:
+ status |=
+ dot11f_pack_ie_channel_switch_wrapper(
+ pCtx, (tDot11fIEChannelSwitchWrapper *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEChannelSwitchWrapper) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeCountry:
+ status |=
+ dot11f_pack_ie_country(
+ pCtx, (tDot11fIECountry *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIECountry) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeDSParams:
+ status |=
+ dot11f_pack_ie_ds_params(
+ pCtx, (tDot11fIEDSParams *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEDSParams) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeEDCAParamSet:
+ status |=
+ dot11f_pack_ie_edca_param_set(
+ pCtx, (tDot11fIEEDCAParamSet *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEEDCAParamSet) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeERPInfo:
+ status |=
+ dot11f_pack_ie_erp_info(
+ pCtx, (tDot11fIEERPInfo *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEERPInfo) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeESECckmOpaque:
+ status |=
+ dot11f_pack_ie_ese_cckm_opaque(
+ pCtx, (tDot11fIEESECckmOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEESECckmOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeESERadMgmtCap:
+ status |=
+ dot11f_pack_ie_ese_rad_mgmt_cap(
+ pCtx, (tDot11fIEESERadMgmtCap *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEESERadMgmtCap) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeESETrafStrmMet:
+ status |=
+ dot11f_pack_ie_ese_traf_strm_met(
+ pCtx, (tDot11fIEESETrafStrmMet *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEESETrafStrmMet) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeESETrafStrmRateSet:
+ status |=
+ dot11f_pack_ie_ese_traf_strm_rate_set(
+ pCtx, (tDot11fIEESETrafStrmRateSet *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEESETrafStrmRateSet) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeESETxmitPower:
+ status |=
+ dot11f_pack_ie_ese_txmit_power(
+ pCtx, (tDot11fIEESETxmitPower *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEESETxmitPower) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeESEVersion:
+ status |=
+ dot11f_pack_ie_ese_version(
+ pCtx, (tDot11fIEESEVersion *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEESEVersion) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeExtCap:
+ status |=
+ dot11f_pack_ie_ext_cap(
+ pCtx, (tDot11fIEExtCap *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEExtCap) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeExtSuppRates:
+ status |=
+ dot11f_pack_ie_ext_supp_rates(
+ pCtx, (tDot11fIEExtSuppRates *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEExtSuppRates) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeFHParamSet:
+ status |=
+ dot11f_pack_ie_fh_param_set(
+ pCtx, (tDot11fIEFHParamSet *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEFHParamSet) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeFHParams:
+ status |=
+ dot11f_pack_ie_fh_params(
+ pCtx, (tDot11fIEFHParams *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEFHParams) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeFHPattTable:
+ status |=
+ dot11f_pack_ie_fh_patt_table(
+ pCtx, (tDot11fIEFHPattTable *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEFHPattTable) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeFTInfo:
+ status |=
+ dot11f_pack_ie_ft_info(
+ pCtx, (tDot11fIEFTInfo *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEFTInfo) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeHTCaps:
+ status |=
+ dot11f_pack_ie_ht_caps(
+ pCtx, (tDot11fIEHTCaps *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEHTCaps) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeHTInfo:
+ status |=
+ dot11f_pack_ie_ht_info(
+ pCtx, (tDot11fIEHTInfo *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEHTInfo) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeIBSSParams:
+ status |=
+ dot11f_pack_ie_ibss_params(
+ pCtx, (tDot11fIEIBSSParams *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEIBSSParams) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeLinkIdentifier:
+ status |=
+ dot11f_pack_ie_link_identifier(
+ pCtx, (tDot11fIELinkIdentifier *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIELinkIdentifier) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeMeasurementReport:
+ status |=
+ dot11f_pack_ie_measurement_report(
+ pCtx, (tDot11fIEMeasurementReport *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEMeasurementReport) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeMeasurementRequest:
+ status |=
+ dot11f_pack_ie_measurement_request(
+ pCtx, (tDot11fIEMeasurementRequest *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEMeasurementRequest) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeMobilityDomain:
+ status |=
+ dot11f_pack_ie_mobility_domain(
+ pCtx, (tDot11fIEMobilityDomain *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEMobilityDomain) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeNeighborReport:
+ status |=
+ dot11f_pack_ie_neighbor_report(
+ pCtx, (tDot11fIENeighborReport *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIENeighborReport) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeOBSSScanParameters:
+ status |=
+ dot11f_pack_ie_obss_scan_parameters(
+ pCtx, (tDot11fIEOBSSScanParameters *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEOBSSScanParameters) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeOperatingMode:
+ status |=
+ dot11f_pack_ie_operating_mode(
+ pCtx, (tDot11fIEOperatingMode *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEOperatingMode) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PAssocReq:
+ status |=
+ dot11f_pack_ie_p2_p_assoc_req(
+ pCtx, (tDot11fIEP2PAssocReq *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PAssocReq) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PAssocRes:
+ status |=
+ dot11f_pack_ie_p2_p_assoc_res(
+ pCtx, (tDot11fIEP2PAssocRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PAssocRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PBeacon:
+ status |=
+ dot11f_pack_ie_p2_p_beacon(
+ pCtx, (tDot11fIEP2PBeacon *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PBeacon) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PBeaconProbeRes:
+ status |=
+ dot11f_pack_ie_p2_p_beacon_probe_res(
+ pCtx, (tDot11fIEP2PBeaconProbeRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PBeaconProbeRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PDeAuth:
+ status |=
+ dot11f_pack_ie_p2_p_de_auth(
+ pCtx, (tDot11fIEP2PDeAuth *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PDeAuth) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PDisAssoc:
+ status |=
+ dot11f_pack_ie_p2_p_dis_assoc(
+ pCtx, (tDot11fIEP2PDisAssoc *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PDisAssoc) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PIEOpaque:
+ status |=
+ dot11f_pack_ie_p2_pie_opaque(
+ pCtx, (tDot11fIEP2PIEOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PIEOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PProbeReq:
+ status |=
+ dot11f_pack_ie_p2_p_probe_req(
+ pCtx, (tDot11fIEP2PProbeReq *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PProbeReq) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeP2PProbeRes:
+ status |=
+ dot11f_pack_ie_p2_p_probe_res(
+ pCtx, (tDot11fIEP2PProbeRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEP2PProbeRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIePTIControl:
+ status |=
+ dot11f_pack_ie_pti_control(
+ pCtx, (tDot11fIEPTIControl *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEPTIControl) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIePUBufferStatus:
+ status |=
+ dot11f_pack_ie_pu_buffer_status(
+ pCtx, (tDot11fIEPUBufferStatus *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEPUBufferStatus) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIePowerCaps:
+ status |=
+ dot11f_pack_ie_power_caps(
+ pCtx, (tDot11fIEPowerCaps *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEPowerCaps) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIePowerConstraints:
+ status |=
+ dot11f_pack_ie_power_constraints(
+ pCtx, (tDot11fIEPowerConstraints *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEPowerConstraints) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeQBSSLoad:
+ status |=
+ dot11f_pack_ie_qbss_load(
+ pCtx, (tDot11fIEQBSSLoad *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEQBSSLoad) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeQComVendorIE:
+ status |=
+ dot11f_pack_ie_QComVendorIE(
+ pCtx, (tDot11fIEQComVendorIE *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEQComVendorIE) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeQOSCapsAp:
+ status |=
+ dot11f_pack_ie_qos_caps_ap(
+ pCtx, (tDot11fIEQOSCapsAp *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEQOSCapsAp) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeQOSCapsStation:
+ status |=
+ dot11f_pack_ie_qos_caps_station(
+ pCtx, (tDot11fIEQOSCapsStation *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEQOSCapsStation) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeQosMapSet:
+ status |=
+ dot11f_pack_ie_qos_map_set(
+ pCtx, (tDot11fIEQosMapSet *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEQosMapSet) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeQuiet:
+ status |=
+ dot11f_pack_ie_quiet(
+ pCtx, (tDot11fIEQuiet *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEQuiet) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRCPIIE:
+ status |=
+ dot11f_pack_ie_rcpiie(
+ pCtx, (tDot11fIERCPIIE *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERCPIIE) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRICDataDesc:
+ status |=
+ dot11f_pack_ie_ric_data_desc(
+ pCtx, (tDot11fIERICDataDesc *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERICDataDesc) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRSN:
+ status |=
+ dot11f_pack_ie_rsn(
+ pCtx, (tDot11fIERSN *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERSN) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRSNIIE:
+ status |=
+ dot11f_pack_ie_rsniie(
+ pCtx, (tDot11fIERSNIIE *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERSNIIE) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeRSNOpaque:
+ status |=
+ dot11f_pack_ie_rsn_opaque(
+ pCtx, (tDot11fIERSNOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIERSNOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeSuppChannels:
+ status |=
+ dot11f_pack_ie_supp_channels(
+ pCtx, (tDot11fIESuppChannels *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIESuppChannels) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeSuppOperatingClasses:
+ status |=
+ dot11f_pack_ie_supp_operating_classes(
+ pCtx, (tDot11fIESuppOperatingClasses *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIESuppOperatingClasses) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeSuppRates:
+ status |=
+ dot11f_pack_ie_supp_rates(
+ pCtx, (tDot11fIESuppRates *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIESuppRates) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTIM:
+ status |=
+ dot11f_pack_ie_tim(
+ pCtx, (tDot11fIETIM *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETIM) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTPCReport:
+ status |=
+ dot11f_pack_ie_tpc_report(
+ pCtx, (tDot11fIETPCReport *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETPCReport) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTPCRequest:
+ status |=
+ dot11f_pack_ie_tpc_request(
+ pCtx, (tDot11fIETPCRequest *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETPCRequest) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTimeAdvertisement:
+ status |=
+ dot11f_pack_ie_time_advertisement(
+ pCtx, (tDot11fIETimeAdvertisement *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETimeAdvertisement) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeTimeoutInterval:
+ status |=
+ dot11f_pack_ie_timeout_interval(
+ pCtx, (tDot11fIETimeoutInterval *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIETimeoutInterval) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeVHTExtBssLoad:
+ status |=
+ dot11f_pack_ie_vht_ext_bss_load(
+ pCtx, (tDot11fIEVHTExtBssLoad *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEVHTExtBssLoad) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeVendor1IE:
+ status |=
+ dot11f_pack_ie_vendor1_ie(
+ pCtx, (tDot11fIEVendor1IE *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEVendor1IE) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeVendor3IE:
+ status |=
+ dot11f_pack_ie_vendor3_ie(
+ pCtx, (tDot11fIEVendor3IE *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEVendor3IE) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWAPI:
+ status |=
+ dot11f_pack_ie_wapi(
+ pCtx, (tDot11fIEWAPI *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWAPI) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWAPIOpaque:
+ status |=
+ dot11f_pack_ie_wapi_opaque(
+ pCtx, (tDot11fIEWAPIOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWAPIOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWFATPC:
+ status |=
+ dot11f_pack_ie_wfatpc(
+ pCtx, (tDot11fIEWFATPC *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWFATPC) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWFDIEOpaque:
+ status |=
+ dot11f_pack_ie_wfdie_opaque(
+ pCtx, (tDot11fIEWFDIEOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWFDIEOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMCaps:
+ status |=
+ dot11f_pack_ie_wmm_caps(
+ pCtx, (tDot11fIEWMMCaps *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMCaps) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMInfoAp:
+ status |=
+ dot11f_pack_ie_wmm_info_ap(
+ pCtx, (tDot11fIEWMMInfoAp *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMInfoAp) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMInfoStation:
+ status |=
+ dot11f_pack_ie_wmm_info_station(
+ pCtx, (tDot11fIEWMMInfoStation *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMInfoStation) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWMMParams:
+ status |=
+ dot11f_pack_ie_wmm_params(
+ pCtx, (tDot11fIEWMMParams *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWMMParams) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWPA:
+ status |=
+ dot11f_pack_ie_wpa(
+ pCtx, (tDot11fIEWPA *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWPA) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWPAOpaque:
+ status |=
+ dot11f_pack_ie_wpa_opaque(
+ pCtx, (tDot11fIEWPAOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWPAOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWSC:
+ status |=
+ dot11f_pack_ie_wsc(
+ pCtx, (tDot11fIEWSC *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWSC) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscAssocReq:
+ status |=
+ dot11f_pack_ie_wsc_assoc_req(
+ pCtx, (tDot11fIEWscAssocReq *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscAssocReq) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscAssocRes:
+ status |=
+ dot11f_pack_ie_wsc_assoc_res(
+ pCtx, (tDot11fIEWscAssocRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscAssocRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscBeacon:
+ status |=
+ dot11f_pack_ie_wsc_beacon(
+ pCtx, (tDot11fIEWscBeacon *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscBeacon) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscBeaconProbeRes:
+ status |=
+ dot11f_pack_ie_wsc_beacon_probe_res(
+ pCtx, (tDot11fIEWscBeaconProbeRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscBeaconProbeRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscIEOpaque:
+ status |=
+ dot11f_pack_ie_wsc_ie_opaque(
+ pCtx, (tDot11fIEWscIEOpaque *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscIEOpaque) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscProbeReq:
+ status |=
+ dot11f_pack_ie_wsc_probe_req(
+ pCtx, (tDot11fIEWscProbeReq *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscProbeReq) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscProbeRes:
+ status |=
+ dot11f_pack_ie_wsc_probe_res(
+ pCtx, (tDot11fIEWscProbeRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscProbeRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeWscReassocRes:
+ status |=
+ dot11f_pack_ie_wsc_reassoc_res(
+ pCtx, (tDot11fIEWscReassocRes *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEWscReassocRes) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeext_chan_switch_ann:
+ status |=
+ dot11f_pack_ie_ext_chan_switch_ann(
+ pCtx, (tDot11fIEext_chan_switch_ann *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEext_chan_switch_ann) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeht2040_bss_coexistence:
+ status |=
+ dot11f_pack_ie_ht2040_bss_coexistence(
+ pCtx, (tDot11fIEht2040_bss_coexistence *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEht2040_bss_coexistence) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIeht2040_bss_intolerant_report:
+ status |=
+ dot11f_pack_ie_ht2040_bss_intolerant_report(
+ pCtx, (tDot11fIEht2040_bss_intolerant_report *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEht2040_bss_intolerant_report) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIesec_chan_offset_ele:
+ status |=
+ dot11f_pack_ie_sec_chan_offset_ele(
+ pCtx, (tDot11fIEsec_chan_offset_ele *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEsec_chan_offset_ele) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ case SigIevendor2_ie:
+ status |=
+ dot11f_pack_ie_vendor2_ie(
+ pCtx, (tDot11fIEvendor2_ie *)
+ (pSrc + pIe->offset +
+ sizeof(tDot11fIEvendor2_ie) * i),
+ pBufRemaining, nBufRemaining, &len);
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don"
+ "'t know about the IE %d; this is most likely a b"
+ "ug in 'framesc'.\n"), pFf->sig);
+ return DOT11F_INTERNAL_ERROR;
+ }
+
+ pBufRemaining += len;
+ nBufRemaining -= len;
+ *pnConsumed += len;
+ }
+
+ ++pIe;
+
+ }
+
+ return status;
+
+}
+
+static uint32_t pack_tlv_core(tpAniSirGlobal pCtx,
+ uint8_t *pSrc,
+ uint8_t *pBuf,
+ uint32_t nBuf,
+ uint32_t *pnConsumed,
+ const tTLVDefn TLVs[],
+ uint32_t *pidx)
+{
+ const tTLVDefn *pTlv;
+ tFRAMES_BOOL *pfFound;
+ uint8_t *pBufRemaining;
+ uint32_t nBufRemaining, status, len;
+
+ DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed);
+
+ (void)pCtx;
+ status = DOT11F_PARSE_SUCCESS;
+ pBufRemaining = pBuf;
+ nBufRemaining = nBuf;
+
+ pTlv = &(TLVs[0]);
+ while (0xffff != pTlv->id) {
+ pfFound = (tFRAMES_BOOL *)(pSrc + pTlv->offset +
+ pTlv->presenceOffset);
+ if (*pfFound && pTlv->minSize > nBufRemaining) {
+ FRAMES_LOG3(pCtx, FRLOGE, FRFL("The TLV %s takes at least"
+ " %d bytes, but there are only %d left in the buffer."
+ "\n"), pTlv->name, pTlv->minSize, nBufRemaining);
+ return DOT11F_BUFFER_OVERFLOW;
+ }
+
+ len = 0U;
+
+ if (*pfFound) {
+ switch (pTlv->sig) {
+ case SigTlvAuthorizedMACs:
+ status |=
+ dot11f_pack_tlv_authorized_ma_cs(
+ pCtx, (tDot11fTLVAuthorizedMACs *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvRequestToEnroll:
+ status |=
+ dot11f_pack_tlv_request_to_enroll(
+ pCtx, (tDot11fTLVRequestToEnroll *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvVersion2:
+ status |=
+ dot11f_pack_tlv_version2(
+ pCtx, (tDot11fTLVVersion2 *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvAPSetupLocked:
+ status |=
+ dot11f_pack_tlv_ap_setup_locked(
+ pCtx, (tDot11fTLVAPSetupLocked *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvAssociationState:
+ status |=
+ dot11f_pack_tlv_association_state(
+ pCtx, (tDot11fTLVAssociationState *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvConfigMethods:
+ status |=
+ dot11f_pack_tlv_config_methods(
+ pCtx, (tDot11fTLVConfigMethods *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvConfigurationError:
+ status |=
+ dot11f_pack_tlv_configuration_error(
+ pCtx, (tDot11fTLVConfigurationError *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvDeviceName:
+ status |=
+ dot11f_pack_tlv_device_name(
+ pCtx, (tDot11fTLVDeviceName *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvDevicePasswordID:
+ status |=
+ dot11f_pack_tlv_device_password_id(
+ pCtx, (tDot11fTLVDevicePasswordID *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvExtendedListenTiming:
+ status |=
+ dot11f_pack_tlv_extended_listen_timing(
+ pCtx, (tDot11fTLVExtendedListenTiming *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvListenChannel:
+ status |=
+ dot11f_pack_tlv_listen_channel(
+ pCtx, (tDot11fTLVListenChannel *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvManufacturer:
+ status |=
+ dot11f_pack_tlv_manufacturer(
+ pCtx, (tDot11fTLVManufacturer *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvMinorReasonCode:
+ status |=
+ dot11f_pack_tlv_minor_reason_code(
+ pCtx, (tDot11fTLVMinorReasonCode *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvModelName:
+ status |=
+ dot11f_pack_tlv_model_name(
+ pCtx, (tDot11fTLVModelName *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvModelNumber:
+ status |=
+ dot11f_pack_tlv_model_number(
+ pCtx, (tDot11fTLVModelNumber *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvNoticeOfAbsence:
+ status |=
+ dot11f_pack_tlv_notice_of_absence(
+ pCtx, (tDot11fTLVNoticeOfAbsence *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvOperatingChannel:
+ status |=
+ dot11f_pack_tlv_operating_channel(
+ pCtx, (tDot11fTLVOperatingChannel *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PCapability:
+ status |=
+ dot11f_pack_tlv_p2_p_capability(
+ pCtx, (tDot11fTLVP2PCapability *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PDeviceId:
+ status |=
+ dot11f_pack_tlv_p2_p_device_id(
+ pCtx, (tDot11fTLVP2PDeviceId *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PDeviceInfo:
+ status |=
+ dot11f_pack_tlv_p2_p_device_info(
+ pCtx, (tDot11fTLVP2PDeviceInfo *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PGroupInfo:
+ status |=
+ dot11f_pack_tlv_p2_p_group_info(
+ pCtx, (tDot11fTLVP2PGroupInfo *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PStatus:
+ status |=
+ dot11f_pack_tlv_p2_p_status(
+ pCtx, (tDot11fTLVP2PStatus *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvPrimaryDeviceType:
+ status |=
+ dot11f_pack_tlv_primary_device_type(
+ pCtx, (tDot11fTLVPrimaryDeviceType *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvRFBands:
+ status |=
+ dot11f_pack_tlv_rf_bands(
+ pCtx, (tDot11fTLVRFBands *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvRequestDeviceType:
+ status |=
+ dot11f_pack_tlv_request_device_type(
+ pCtx, (tDot11fTLVRequestDeviceType *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvRequestType:
+ status |=
+ dot11f_pack_tlv_request_type(
+ pCtx, (tDot11fTLVRequestType *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvResponseType:
+ status |=
+ dot11f_pack_tlv_response_type(
+ pCtx, (tDot11fTLVResponseType *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvSelectedRegistrar:
+ status |=
+ dot11f_pack_tlv_selected_registrar(
+ pCtx, (tDot11fTLVSelectedRegistrar *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvSelectedRegistrarConfigMethods:
+ status |=
+ dot11f_pack_tlv_selected_registrar_config_methods(
+ pCtx, (tDot11fTLVSelectedRegistrarConfigMethods *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvSerialNumber:
+ status |=
+ dot11f_pack_tlv_serial_number(
+ pCtx, (tDot11fTLVSerialNumber *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvUUID_E:
+ status |=
+ dot11f_pack_tlv_uuid_e(
+ pCtx, (tDot11fTLVUUID_E *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvUUID_R:
+ status |=
+ dot11f_pack_tlv_uuid_r(
+ pCtx, (tDot11fTLVUUID_R *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvVendorExtension:
+ status |=
+ dot11f_pack_tlv_vendor_extension(
+ pCtx, (tDot11fTLVVendorExtension *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvVersion:
+ status |=
+ dot11f_pack_tlv_version(
+ pCtx, (tDot11fTLVVersion *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvWPSState:
+ status |=
+ dot11f_pack_tlv_wps_state(
+ pCtx, (tDot11fTLVWPSState *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PInterface:
+ status |=
+ dot11f_pack_tlv_p2_p_interface(
+ pCtx, (tDot11fTLVP2PInterface *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ case SigTlvP2PManageability:
+ status |=
+ dot11f_pack_tlv_p2_p_manageability(
+ pCtx, (tDot11fTLVP2PManageability *)
+ (pSrc + pTlv->offset), pBufRemaining,
+ nBufRemaining, &len);
+ break;
+ default:
+ FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don't "
+ "know about the TLV %d; this is most likely a bug in "
+ "'framesc'.\n"), pTlv->sig);
+ return DOT11F_INTERNAL_ERROR;
+ }
+
+ } /* End if on *pfFound */
+ pBufRemaining += len;
+ nBufRemaining -= len;
+ *pnConsumed += len;
+ ++pTlv;
+ if (len)
+ ++*pidx;
+ }
+
+ return status;
+
+}
diff --git a/core/mac/src/sys/legacy/src/utils/src/log_api.c b/core/mac/src/sys/legacy/src/utils/src/log_api.c
new file mode 100644
index 0000000..8ec7b8c
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/log_api.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * log_api.cc - Handles log messages for all the modules.
+ * Author: Kevin Nguyen
+ * Date: 02/27/02
+ * History:-
+ * 02/11/02 Created.
+ * 03/12/02 Rearrange log_debug parameter list and add more params.
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include <sir_common.h>
+#include <sir_debug.h>
+#include <utils_api.h>
+#include <wma_types.h>
+
+#include <stdarg.h>
+#include "utils_global.h"
+#include "mac_init_api.h"
+
+#include "cdf_trace.h"
+
+#ifdef ANI_OS_TYPE_ANDROID
+#include <linux/kernel.h>
+#endif
+
+/* --------------------------------------------------------------------- */
+/**
+ * log_init()
+ *
+ * FUNCTION:
+ * This function is called to prepare the logging utility.
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param tpAniSirGlobal Sirius software parameter strucutre pointer
+ * @return None
+ */
+tSirRetStatus log_init(tpAniSirGlobal pMac)
+{
+ uint32_t i;
+
+ /* Add code to initialize debug level from CFG module */
+ /* For now, enable all logging */
+ for (i = 0; i < LOG_ENTRY_NUM; i++) {
+#ifdef SIR_DEBUG
+ pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] =
+ LOG1;
+#else
+ pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] =
+ LOGW;
+#endif
+ }
+ return eSIR_SUCCESS;
+
+} /*** log_init() ***/
+
+void log_deinit(tpAniSirGlobal pMac)
+{
+ return;
+}
+
+/**
+ * log_dbg()
+ *
+ ***FUNCTION:
+ * This function is called to log a debug message.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * None.
+ *
+ ***NOTE:
+ *
+ * @param tpAniSirGlobal Sirius software parameter strucutre pointer
+ * @param ModId 8-bit modID
+ * @param debugLevel debugging level for this message
+ * @param pStr string parameter pointer
+ * @return None
+ */
+
+void log_dbg(tpAniSirGlobal pMac, uint8_t modId, uint32_t debugLevel,
+ const char *pStr, ...)
+{
+#ifdef WLAN_DEBUG
+ if (debugLevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(modId)])
+ return;
+ else {
+ va_list marker;
+
+ va_start(marker, pStr); /* Initialize variable arguments. */
+
+ log_debug(pMac, modId, debugLevel, pStr, marker);
+
+ va_end(marker); /* Reset variable arguments. */
+ }
+#endif
+}
+
+CDF_TRACE_LEVEL get_vos_debug_level(uint32_t debugLevel)
+{
+ switch (debugLevel) {
+ case LOGP:
+ return CDF_TRACE_LEVEL_FATAL;
+ case LOGE:
+ return CDF_TRACE_LEVEL_ERROR;
+ case LOGW:
+ return CDF_TRACE_LEVEL_WARN;
+ case LOG1:
+ return CDF_TRACE_LEVEL_INFO;
+ case LOG2:
+ return CDF_TRACE_LEVEL_INFO_HIGH;
+ case LOG3:
+ return CDF_TRACE_LEVEL_INFO_MED;
+ case LOG4:
+ return CDF_TRACE_LEVEL_INFO_LOW;
+ default:
+ return CDF_TRACE_LEVEL_INFO_LOW;
+ }
+}
+
+static inline CDF_MODULE_ID get_vos_module_id(uint8_t modId)
+{
+ switch (modId) {
+ case SIR_HAL_MODULE_ID:
+ return CDF_MODULE_ID_WMA;
+
+ case SIR_LIM_MODULE_ID:
+ case SIR_SCH_MODULE_ID:
+ case SIR_CFG_MODULE_ID:
+ case SIR_MNT_MODULE_ID:
+ case SIR_DPH_MODULE_ID:
+ case SIR_DBG_MODULE_ID:
+ return CDF_MODULE_ID_PE;
+
+ case SIR_SYS_MODULE_ID:
+ return CDF_MODULE_ID_SYS;
+
+ case SIR_SMS_MODULE_ID:
+ return CDF_MODULE_ID_SME;
+
+ default:
+ return CDF_MODULE_ID_SYS;
+ }
+}
+
+#define LOG_SIZE 256
+void log_debug(tpAniSirGlobal pMac, uint8_t modId, uint32_t debugLevel,
+ const char *pStr, va_list marker)
+{
+ CDF_TRACE_LEVEL cdf_debug_level;
+ CDF_MODULE_ID cdf_module_id;
+ char logBuffer[LOG_SIZE];
+
+ cdf_debug_level = get_vos_debug_level(debugLevel);
+ cdf_module_id = get_vos_module_id(modId);
+
+ vsnprintf(logBuffer, LOG_SIZE - 1, pStr, marker);
+ CDF_TRACE(cdf_module_id, cdf_debug_level, "%s", logBuffer);
+
+ /* The caller must check loglevel */
+ CDF_ASSERT((debugLevel <=
+ pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(modId)])
+ && (LOGP != debugLevel));
+} /*** end log_debug() ***/
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
new file mode 100644
index 0000000..7d0d9ac
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -0,0 +1,759 @@
+/*
+ * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/**=========================================================================
+
+ \file mac_trace.c
+
+ \brief implementation for trace related APIs
+
+ \author Sunit Bhatia
+
+ ========================================================================*/
+
+/*--------------------------------------------------------------------------
+ Include Files
+ ------------------------------------------------------------------------*/
+
+#include "mac_trace.h"
+#include "wma_types.h"
+#include "csr_neighbor_roam.h"
+#include "csr_internal.h"
+#include "lim_global.h"
+#include "cdf_memory.h"
+#include "cdf_trace.h"
+#include "wma_if.h"
+
+#ifdef TRACE_RECORD
+/**
+ * mac_trace_get_neighbour_roam_state() - Get the neighbor roam state
+ * @neighbourroamstate: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_get_neighbour_roam_state(uint16_t neighbourroamstate)
+{
+ switch (neighbourroamstate) {
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CLOSED);
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_INIT);
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED);
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING);
+ CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+ CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX);
+
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_getcsr_roam_state() - Get the csr roam state
+ * @csr_roam_state: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_getcsr_roam_state(uint16_t csr_roam_state)
+{
+ switch (csr_roam_state) {
+ CASE_RETURN_STRING(eCSR_ROAMING_STATE_STOP);
+ CASE_RETURN_STRING(eCSR_ROAMING_STATE_IDLE);
+ CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINING);
+ CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINED);
+
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_getcsr_roam_sub_state() - Get the csr roam sub state
+ * @csr_roam_sub_state: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_getcsr_roam_sub_state(uint16_t csr_roam_sub_state)
+{
+ switch (csr_roam_sub_state) {
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_NONE);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_START_BSS_REQ);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOIN_REQ);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_REASSOC_REQ);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REQ);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_STOP_BSS_REQ);
+ CASE_RETURN_STRING
+ (eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_AUTH_REQ);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_CONFIG);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DEAUTH_REQ);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_FORCED);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC);
+ CASE_RETURN_STRING
+ (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC);
+ CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC);
+
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_lim_sme_state() - Get the lim sme state
+ * @lim_state: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_get_lim_sme_state(uint16_t lim_state)
+{
+ switch (lim_state) {
+ CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_IDLE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE);
+ CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE);
+ CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE);
+ CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE);
+ CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE);
+ CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE);
+ CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE);
+
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_lim_mlm_state() - Get the lim mlm state
+ * @mlmstate: State in numeric form
+ *
+ * This function will return a string equivalent of the state.
+ *
+ * Return: String equivalent of the state.
+ **/
+uint8_t *mac_trace_get_lim_mlm_state(uint16_t mlm_state)
+{
+ switch (mlm_state) {
+ CASE_RETURN_STRING(eLIM_MLM_OFFLINE_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_IDLE_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_PROBE_RESP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_PASSIVE_SCAN_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_JOIN_BEACON_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_JOINED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_BSS_STARTED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME2_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME3_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME4_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_AUTH_RSP_TIMEOUT_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_AUTHENTICATED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_REASSOC_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_ASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_REASSOCIATED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_LINK_ESTABLISHED_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_CNF_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_LEARN_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_DEL_BSS_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_ADD_STA_RSP_STATE);
+ CASE_RETURN_STRING(eLIM_MLM_WT_DEL_STA_RSP_STATE);
+
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_sme_msg_string() - Get the msg
+ * @sme_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg)
+{
+ switch (sme_msg) {
+ CASE_RETURN_STRING(eWNI_SME_SYS_READY_IND);
+ CASE_RETURN_STRING(eWNI_SME_SCAN_REQ);
+ CASE_RETURN_STRING(eWNI_SME_SCAN_ABORT_IND);
+ CASE_RETURN_STRING(eWNI_SME_SCAN_RSP);
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ CASE_RETURN_STRING(eWNI_SME_OEM_DATA_REQ);
+ CASE_RETURN_STRING(eWNI_SME_OEM_DATA_RSP);
+#endif
+ CASE_RETURN_STRING(eWNI_SME_JOIN_REQ);
+ CASE_RETURN_STRING(eWNI_SME_JOIN_RSP);
+ CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_REQ);
+ CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_RSP);
+ CASE_RETURN_STRING(eWNI_SME_REASSOC_REQ);
+ CASE_RETURN_STRING(eWNI_SME_REASSOC_RSP);
+ CASE_RETURN_STRING(eWNI_SME_DISASSOC_REQ);
+ CASE_RETURN_STRING(eWNI_SME_DISASSOC_RSP);
+ CASE_RETURN_STRING(eWNI_SME_DISASSOC_IND);
+ CASE_RETURN_STRING(eWNI_SME_DISASSOC_CNF);
+ CASE_RETURN_STRING(eWNI_SME_DEAUTH_REQ);
+ CASE_RETURN_STRING(eWNI_SME_DEAUTH_RSP);
+ CASE_RETURN_STRING(eWNI_SME_DEAUTH_IND);
+ CASE_RETURN_STRING(eWNI_SME_WM_STATUS_CHANGE_NTF);
+ CASE_RETURN_STRING(eWNI_SME_IBSS_NEW_PEER_IND);
+ CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_DEPARTED_IND);
+ CASE_RETURN_STRING(eWNI_SME_START_BSS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_START_BSS_RSP);
+ CASE_RETURN_STRING(eWNI_SME_ASSOC_IND);
+ CASE_RETURN_STRING(eWNI_SME_ASSOC_CNF);
+ CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_IND);
+ CASE_RETURN_STRING(eWNI_SME_STOP_BSS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_STOP_BSS_RSP);
+ CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_BSS_IND);
+ CASE_RETURN_STRING(eWNI_SME_DEAUTH_CNF);
+ CASE_RETURN_STRING(eWNI_SME_MIC_FAILURE_IND);
+ CASE_RETURN_STRING(eWNI_SME_ADDTS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_ADDTS_RSP);
+ CASE_RETURN_STRING(eWNI_SME_DELTS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_DELTS_RSP);
+ CASE_RETURN_STRING(eWNI_SME_DELTS_IND);
+ CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_RSP);
+ CASE_RETURN_STRING(eWNI_SME_GET_RSSI_REQ);
+ CASE_RETURN_STRING(eWNI_SME_GET_ASSOC_STAS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_TKIP_CNTR_MEAS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_UPDATE_APWPSIE_REQ);
+ CASE_RETURN_STRING(eWNI_SME_GET_WPSPBC_SESSION_REQ);
+ CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND);
+ CASE_RETURN_STRING(eWNI_SME_SET_APWPARSNIEs_REQ);
+ CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF);
+ CASE_RETURN_STRING(eWNI_SME_HIDE_SSID_REQ);
+ CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHANNEL_REQ);
+ CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_RSP);
+ CASE_RETURN_STRING(eWNI_SME_MGMT_FRM_IND);
+ CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_RDY_IND);
+ CASE_RETURN_STRING(eWNI_SME_SEND_ACTION_FRAME_IND);
+ CASE_RETURN_STRING(eWNI_SME_ACTION_FRAME_SEND_CNF);
+ CASE_RETURN_STRING(eWNI_SME_ABORT_REMAIN_ON_CHAN_IND);
+ CASE_RETURN_STRING(eWNI_SME_UPDATE_NOA);
+ CASE_RETURN_STRING(eWNI_SME_CLEAR_DFS_CHANNEL_LIST);
+ CASE_RETURN_STRING(eWNI_SME_GET_SNR_REQ);
+ CASE_RETURN_STRING(eWNI_SME_LINK_STATUS_IND);
+
+ CASE_RETURN_STRING(eWNI_PMC_MSG_TYPES_BEGIN);
+
+ CASE_RETURN_STRING(eWNI_PMC_SMPS_STATE_IND);
+#if defined WLAN_FEATURE_VOWIFI
+ CASE_RETURN_STRING(eWNI_SME_RRM_MSG_TYPE_BEGIN);
+ CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_REQ_IND);
+ CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND);
+ CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND);
+ CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND);
+#endif
+ CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_RSP);
+ CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_RSP);
+#if defined WLAN_FEATURE_VOWIFI_11R
+ CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_REQ);
+ CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_RSP);
+ CASE_RETURN_STRING(eWNI_SME_FT_UPDATE_KEY);
+ CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP);
+#endif
+#if defined FEATURE_WLAN_ESE
+ CASE_RETURN_STRING(eWNI_SME_ESE_ADJACENT_AP_REPORT);
+#endif
+ CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_REQ);
+#ifdef FEATURE_WLAN_SCAN_PNO
+ CASE_RETURN_STRING(eWNI_SME_PREF_NETWORK_FOUND_IND);
+#endif /* FEATURE_WLAN_SCAN_PNO */
+ CASE_RETURN_STRING(eWNI_SME_CHANGE_COUNTRY_CODE);
+ CASE_RETURN_STRING(eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE);
+ CASE_RETURN_STRING(eWNI_SME_MAX_ASSOC_EXCEEDED);
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+ CASE_RETURN_STRING(eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP);
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+ CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
+ CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_REQ);
+ CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_RSP);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ CASE_RETURN_STRING(eWNI_SME_ROAM_OFFLOAD_SYNCH_IND);
+#endif
+ CASE_RETURN_STRING(eWNI_SME_SET_HW_MODE_REQ);
+ CASE_RETURN_STRING(eWNI_SME_SET_HW_MODE_RESP);
+ CASE_RETURN_STRING(eWNI_SME_HW_MODE_TRANS_IND);
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_wma_msg_string() - Get the msg
+ * @wma_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
+{
+ switch (wma_msg) {
+ CASE_RETURN_STRING(WMA_ADD_STA_REQ);
+ CASE_RETURN_STRING(WMA_ADD_STA_RSP);
+ CASE_RETURN_STRING(WMA_ADD_STA_SELF_RSP);
+ CASE_RETURN_STRING(WMA_DELETE_STA_REQ);
+ CASE_RETURN_STRING(WMA_DELETE_STA_RSP);
+ CASE_RETURN_STRING(WMA_ADD_BSS_REQ);
+ CASE_RETURN_STRING(WMA_ADD_BSS_RSP);
+ CASE_RETURN_STRING(WMA_DELETE_BSS_REQ);
+ CASE_RETURN_STRING(WMA_DELETE_BSS_RSP);
+ CASE_RETURN_STRING(WMA_SEND_BEACON_REQ);
+ CASE_RETURN_STRING(WMA_SET_BSSKEY_REQ);
+ CASE_RETURN_STRING(WMA_SET_BSSKEY_RSP);
+ CASE_RETURN_STRING(WMA_SET_STAKEY_REQ);
+ CASE_RETURN_STRING(WMA_SET_STAKEY_RSP);
+ CASE_RETURN_STRING(WMA_UPDATE_EDCA_PROFILE_IND);
+
+ CASE_RETURN_STRING(WMA_UPDATE_BEACON_IND);
+ CASE_RETURN_STRING(WMA_UPDATE_CF_IND);
+ CASE_RETURN_STRING(WMA_CHNL_SWITCH_REQ);
+ CASE_RETURN_STRING(WMA_ADD_TS_REQ);
+ CASE_RETURN_STRING(WMA_DEL_TS_REQ);
+ CASE_RETURN_STRING(WMA_EXIT_PS_REQ);
+ CASE_RETURN_STRING(WMA_ENTER_PS_REQ);
+ CASE_RETURN_STRING(WMA_MISSED_BEACON_IND);
+
+ CASE_RETURN_STRING(WMA_CFG_RXP_FILTER_REQ);
+ CASE_RETURN_STRING(WMA_SWITCH_CHANNEL_RSP);
+ CASE_RETURN_STRING(WMA_P2P_NOA_ATTR_IND);
+ CASE_RETURN_STRING(WMA_P2P_NOA_START_IND);
+ CASE_RETURN_STRING(WMA_PWR_SAVE_CFG);
+ CASE_RETURN_STRING(WMA_REGISTER_PE_CALLBACK);
+
+ CASE_RETURN_STRING(WMA_IBSS_STA_ADD);
+ CASE_RETURN_STRING(WMA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND);
+ CASE_RETURN_STRING(WMA_SET_LINK_STATE);
+ CASE_RETURN_STRING(WMA_SET_LINK_STATE_RSP);
+ CASE_RETURN_STRING(WMA_SET_STA_BCASTKEY_REQ);
+ CASE_RETURN_STRING(WMA_SET_STA_BCASTKEY_RSP);
+ CASE_RETURN_STRING(WMA_ADD_TS_RSP);
+ CASE_RETURN_STRING(WMA_DPU_MIC_ERROR);
+
+ CASE_RETURN_STRING(WMA_TIMER_CHIP_MONITOR_TIMEOUT);
+ CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_ACTIVITY_REQ);
+ CASE_RETURN_STRING(WMA_TIMER_ADC_RSSI_STATS);
+#ifdef FEATURE_WLAN_ESE
+ CASE_RETURN_STRING(WMA_TSM_STATS_REQ);
+ CASE_RETURN_STRING(WMA_TSM_STATS_RSP);
+#endif
+ CASE_RETURN_STRING(WMA_SET_MIMOPS_REQ);
+ CASE_RETURN_STRING(WMA_SET_MIMOPS_RSP);
+ CASE_RETURN_STRING(WMA_SYS_READY_IND);
+ CASE_RETURN_STRING(WMA_SET_TX_POWER_REQ);
+ CASE_RETURN_STRING(WMA_SET_TX_POWER_RSP);
+ CASE_RETURN_STRING(WMA_GET_TX_POWER_REQ);
+
+ CASE_RETURN_STRING(WMA_TRANSMISSION_CONTROL_IND);
+ CASE_RETURN_STRING(WMA_ENABLE_UAPSD_REQ);
+ CASE_RETURN_STRING(WMA_DISABLE_UAPSD_REQ);
+ CASE_RETURN_STRING(WMA_BEACON_FILTER_IND);
+ CASE_RETURN_STRING(WMA_WOW_ADD_PTRN);
+ CASE_RETURN_STRING(WMA_WOW_DEL_PTRN);
+ CASE_RETURN_STRING(WMA_WOWL_ENTER_REQ);
+ CASE_RETURN_STRING(WMA_WOWL_EXIT_REQ);
+ CASE_RETURN_STRING(WMA_GET_STATISTICS_REQ);
+ CASE_RETURN_STRING(WMA_GET_STATISTICS_RSP);
+ CASE_RETURN_STRING(WMA_SET_KEY_DONE);
+
+ CASE_RETURN_STRING(WMA_BTC_SET_CFG);
+ CASE_RETURN_STRING(WMA_HANDLE_FW_MBOX_RSP);
+ CASE_RETURN_STRING(WMA_SEND_PROBE_RSP_TMPL);
+#ifdef FEATURE_OEM_DATA_SUPPORT
+ CASE_RETURN_STRING(WMA_START_OEM_DATA_REQ);
+ CASE_RETURN_STRING(WMA_START_OEM_DATA_RSP);
+#endif /* SUPPORT_BEACON_FILTER */
+ CASE_RETURN_STRING(WMA_SET_MAX_TX_POWER_REQ);
+ CASE_RETURN_STRING(WMA_SET_HOST_OFFLOAD);
+ CASE_RETURN_STRING(WMA_SET_KEEP_ALIVE);
+#ifdef WLAN_NS_OFFLOAD
+ CASE_RETURN_STRING(WMA_SET_NS_OFFLOAD);
+#endif /* WLAN_NS_OFFLOAD */
+ CASE_RETURN_STRING(WMA_ADD_STA_SELF_REQ);
+ CASE_RETURN_STRING(WMA_DEL_STA_SELF_REQ);
+ CASE_RETURN_STRING(WMA_SET_P2P_GO_NOA_REQ);
+ CASE_RETURN_STRING(WMA_WLAN_SUSPEND_IND);
+ CASE_RETURN_STRING(WMA_WLAN_RESUME_REQ);
+#ifdef WLAN_FEATURE_EXTWOW_SUPPORT
+ CASE_RETURN_STRING(WMA_WLAN_EXT_WOW);
+ CASE_RETURN_STRING(WMA_WLAN_SET_APP_TYPE1_PARAMS);
+ CASE_RETURN_STRING(WMA_WLAN_SET_APP_TYPE2_PARAMS);
+#endif
+ CASE_RETURN_STRING(WMA_MSG_TYPES_END);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ CASE_RETURN_STRING(WMA_AGGR_QOS_REQ);
+ CASE_RETURN_STRING(WMA_AGGR_QOS_RSP);
+#endif /* WLAN_FEATURE_VOWIFI_11R */
+ CASE_RETURN_STRING(WMA_FTM_CMD_REQ);
+ CASE_RETURN_STRING(WMA_FTM_CMD_RSP);
+#ifdef FEATURE_WLAN_SCAN_PNO
+ CASE_RETURN_STRING(WMA_SET_PNO_REQ);
+ CASE_RETURN_STRING(WMA_SME_SCAN_CACHE_UPDATED);
+#endif /* FEATURE_WLAN_SCAN_PNO */
+ CASE_RETURN_STRING(WMA_ROAM_SCAN_OFFLOAD_REQ);
+#ifdef WLAN_FEATURE_PACKET_FILTERING
+ CASE_RETURN_STRING(WMA_8023_MULTICAST_LIST_REQ);
+ CASE_RETURN_STRING(WMA_RECEIVE_FILTER_SET_FILTER_REQ);
+ CASE_RETURN_STRING
+ (WMA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ);
+ CASE_RETURN_STRING
+ (WMA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP);
+ CASE_RETURN_STRING(WMA_RECEIVE_FILTER_CLEAR_FILTER_REQ);
+#endif /* WLAN_FEATURE_PACKET_FILTERING */
+#ifdef WLAN_FEATURE_GTK_OFFLOAD
+ CASE_RETURN_STRING(WMA_GTK_OFFLOAD_REQ);
+ CASE_RETURN_STRING(WMA_GTK_OFFLOAD_GETINFO_REQ);
+ CASE_RETURN_STRING(WMA_GTK_OFFLOAD_GETINFO_RSP);
+#endif /* WLAN_FEATURE_GTK_OFFLOAD */
+ CASE_RETURN_STRING(WMA_SET_TM_LEVEL_REQ);
+#ifdef WLAN_FEATURE_11AC
+ CASE_RETURN_STRING(WMA_UPDATE_OP_MODE);
+ CASE_RETURN_STRING(WMA_UPDATE_MEMBERSHIP);
+ CASE_RETURN_STRING(WMA_UPDATE_USERPOS);
+#endif
+ CASE_RETURN_STRING(WMA_START_SCAN_OFFLOAD_REQ);
+ CASE_RETURN_STRING(WMA_STOP_SCAN_OFFLOAD_REQ);
+ CASE_RETURN_STRING(WMA_UPDATE_CHAN_LIST_REQ);
+ CASE_RETURN_STRING(WMA_CLI_SET_CMD);
+#ifndef REMOVE_PKT_LOG
+ CASE_RETURN_STRING(WMA_PKTLOG_ENABLE_REQ);
+#endif
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+ CASE_RETURN_STRING(WMA_SET_PLM_REQ);
+#endif
+ CASE_RETURN_STRING(WMA_CONFIG_PARAM_UPDATE_REQ);
+ CASE_RETURN_STRING(WMA_RATE_UPDATE_IND);
+#ifdef FEATURE_WLAN_TDLS
+ CASE_RETURN_STRING(WMA_UPDATE_FW_TDLS_STATE);
+ CASE_RETURN_STRING(WMA_UPDATE_TDLS_PEER_STATE);
+#endif
+ CASE_RETURN_STRING(WMA_ADD_PERIODIC_TX_PTRN_IND);
+ CASE_RETURN_STRING(WMA_TX_POWER_LIMIT);
+#ifdef FEATURE_WLAN_LPHB
+ CASE_RETURN_STRING(WMA_LPHB_CONF_REQ);
+#endif
+ CASE_RETURN_STRING(WMA_DHCP_START_IND);
+ CASE_RETURN_STRING(WMA_DHCP_STOP_IND);
+#ifdef FEATURE_WLAN_CH_AVOID
+ CASE_RETURN_STRING(WMA_CH_AVOID_UPDATE_REQ);
+#endif
+#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
+ CASE_RETURN_STRING(WMA_SET_AUTO_SHUTDOWN_TIMER_REQ);
+#endif
+ CASE_RETURN_STRING(WMA_INIT_THERMAL_INFO_CMD);
+ CASE_RETURN_STRING(WMA_SET_THERMAL_LEVEL);
+ CASE_RETURN_STRING(WMA_SET_SAP_INTRABSS_DIS);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_CNF);
+ CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_FAIL);
+#endif
+ CASE_RETURN_STRING(SIR_HAL_SET_BASE_MACADDR_IND);
+ CASE_RETURN_STRING(WMA_LINK_STATUS_GET_REQ);
+#ifdef DHCP_SERVER_OFFLOAD
+ CASE_RETURN_STRING(WMA_SET_DHCP_SERVER_OFFLOAD_CMD);
+#endif
+ CASE_RETURN_STRING(WMA_OCB_SET_CONFIG_CMD);
+ CASE_RETURN_STRING(WMA_OCB_SET_UTC_TIME_CMD);
+ CASE_RETURN_STRING(WMA_OCB_START_TIMING_ADVERT_CMD);
+ CASE_RETURN_STRING(WMA_OCB_STOP_TIMING_ADVERT_CMD);
+ CASE_RETURN_STRING(WMA_OCB_GET_TSF_TIMER_CMD);
+ CASE_RETURN_STRING(WMA_DCC_GET_STATS_CMD);
+ CASE_RETURN_STRING(WMA_DCC_CLEAR_STATS_CMD);
+ CASE_RETURN_STRING(WMA_DCC_UPDATE_NDL_CMD);
+ CASE_RETURN_STRING(WMA_SET_IE_INFO);
+ CASE_RETURN_STRING(WNI_CFG_DNLD_REQ);
+ CASE_RETURN_STRING(SIR_HAL_UNIT_TEST_CMD);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ CASE_RETURN_STRING(SIR_HAL_ROAM_INVOKE);
+#endif
+ CASE_RETURN_STRING(SIR_HAL_SET_MAS);
+ CASE_RETURN_STRING(SIR_HAL_SET_MIRACAST);
+ CASE_RETURN_STRING(SIR_HAL_CONFIG_STATS_FACTOR);
+ CASE_RETURN_STRING(SIR_HAL_CONFIG_GUARD_TIME);
+ CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING);
+ CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW);
+ CASE_RETURN_STRING(SIR_HAL_SOC_SET_PCL_TO_FW);
+ CASE_RETURN_STRING(SIR_HAL_SOC_SET_HW_MODE);
+ CASE_RETURN_STRING(SIR_HAL_SOC_DUAL_MAC_CFG_REQ);
+ CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND);
+ CASE_RETURN_STRING(WMA_TIMER_TRAFFIC_STATS_IND);
+#ifdef WLAN_FEATURE_11W
+ CASE_RETURN_STRING(WMA_EXCLUDE_UNENCRYPTED_IND);
+#endif
+ CASE_RETURN_STRING(WMA_WOWL_ENTER_RSP);
+ CASE_RETURN_STRING(WMA_WOWL_EXIT_RSP);
+ CASE_RETURN_STRING(WMA_SET_MAX_TX_POWER_RSP);
+ CASE_RETURN_STRING(WMA_SET_MAX_TX_POWER_PER_BAND_REQ);
+#ifdef FEATURE_WLAN_TDLS
+ CASE_RETURN_STRING(WMA_SET_TDLS_LINK_ESTABLISH_REQ);
+ CASE_RETURN_STRING(WMA_SET_TDLS_LINK_ESTABLISH_REQ_RSP);
+#endif
+ CASE_RETURN_STRING(WMA_CSA_OFFLOAD_EVENT);
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ CASE_RETURN_STRING(WMA_ROAM_OFFLOAD_SYNCH_IND);
+#endif
+ CASE_RETURN_STRING(WMA_HIDDEN_SSID_VDEV_RESTART);
+#ifdef WLAN_FEATURE_11AC
+ CASE_RETURN_STRING(WMA_UPDATE_RX_NSS);
+#endif
+#ifdef WLAN_FEATURE_NAN
+ CASE_RETURN_STRING(WMA_NAN_REQUEST);
+#endif
+ CASE_RETURN_STRING(WMA_RX_SCAN_EVENT);
+ CASE_RETURN_STRING(WMA_IBSS_PEER_INACTIVITY_IND);
+ CASE_RETURN_STRING(WMA_DEL_PERIODIC_TX_PTRN_IND);
+#ifdef FEATURE_WLAN_TDLS
+ CASE_RETURN_STRING(WMA_TDLS_SHOULD_DISCOVER_CMD);
+ CASE_RETURN_STRING(WMA_TDLS_SHOULD_TEARDOWN_CMD);
+ CASE_RETURN_STRING(WMA_TDLS_PEER_DISCONNECTED_CMD);
+ CASE_RETURN_STRING(WMA_TDLS_SET_OFFCHAN_MODE);
+#endif
+ CASE_RETURN_STRING(WMA_DFS_RADAR_IND);
+ CASE_RETURN_STRING(WMA_DFS_BEACON_TX_SUCCESS_IND);
+ CASE_RETURN_STRING(WMA_DISASSOC_TX_COMP);
+ CASE_RETURN_STRING(WMA_DEAUTH_TX_COMP);
+ CASE_RETURN_STRING(WMA_GET_LINK_SPEED);
+ CASE_RETURN_STRING(WMA_MODEM_POWER_STATE_IND);
+#ifdef WLAN_FEATURE_STATS_EXT
+ CASE_RETURN_STRING(WMA_STATS_EXT_REQUEST);
+#endif
+ CASE_RETURN_STRING(WMA_IPA_OFFLOAD_ENABLE_DISABLE);
+ CASE_RETURN_STRING(WMA_GET_TEMPERATURE_REQ);
+#ifdef FEATURE_WLAN_EXTSCAN
+ CASE_RETURN_STRING(WMA_EXTSCAN_GET_CAPABILITIES_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_START_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_STOP_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_GET_CACHED_RESULTS_REQ);
+ CASE_RETURN_STRING(WMA_SET_EPNO_LIST_REQ);
+ CASE_RETURN_STRING(WMA_SET_PASSPOINT_LIST_REQ);
+ CASE_RETURN_STRING(WMA_RESET_PASSPOINT_LIST_REQ);
+ CASE_RETURN_STRING(WMA_EXTSCAN_SET_SSID_HOTLIST_REQ);
+#endif /* FEATURE_WLAN_EXTSCAN */
+#ifdef WLAN_FEATURE_LINK_LAYER_STATS
+ CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_CLEAR_REQ);
+ CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_SET_REQ);
+ CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_GET_REQ);
+ CASE_RETURN_STRING(WMA_LINK_LAYER_STATS_RESULTS_RSP);
+#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+ CASE_RETURN_STRING(WMA_SET_SCAN_MAC_OUI_REQ);
+#ifdef WLAN_FEATURE_GPIO_LED_FLASHING
+ CASE_RETURN_STRING(WMA_LED_FLASHING_REQ);
+#endif
+ CASE_RETURN_STRING(WMA_PROCESS_FW_EVENT);
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ CASE_RETURN_STRING(WMA_UPDATE_Q2Q_IE_IND);
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+ CASE_RETURN_STRING(WMA_SET_RSSI_MONITOR_REQ);
+ CASE_RETURN_STRING(WMA_FW_MEM_DUMP_REQ);
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_lim_msg_string() - Get the msg
+ * @lim_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_lim_msg_string(uint16_t lim_msg)
+{
+ switch (lim_msg) {
+ CASE_RETURN_STRING(SIR_LIM_RETRY_INTERRUPT_MSG);
+ CASE_RETURN_STRING(SIR_BB_XPORT_MGMT_MSG);
+ CASE_RETURN_STRING(SIR_LIM_INV_KEY_INTERRUPT_MSG);
+ CASE_RETURN_STRING(SIR_LIM_KEY_ID_INTERRUPT_MSG);
+ CASE_RETURN_STRING(SIR_LIM_REPLAY_THRES_INTERRUPT_MSG);
+ CASE_RETURN_STRING(SIR_LIM_TD_DUMMY_CALLBACK_MSG);
+ CASE_RETURN_STRING(SIR_LIM_SCH_CLEAN_MSG);
+ CASE_RETURN_STRING(SIR_LIM_RADAR_DETECT_IND);
+ CASE_RETURN_STRING(SIR_LIM_DEL_TS_IND);
+ CASE_RETURN_STRING(SIR_LIM_DELETE_STA_CONTEXT_IND);
+ CASE_RETURN_STRING(SIR_LIM_UPDATE_BEACON);
+ CASE_RETURN_STRING(SIR_LIM_JOIN_FAIL_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_AUTH_FAIL_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_AUTH_RSP_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_ASSOC_FAIL_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_REASSOC_FAIL_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_HEART_BEAT_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_PROBE_HB_FAILURE_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_ADDTS_RSP_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_LINK_TEST_DURATION_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_HASH_MISS_THRES_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_CNF_WAIT_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_CHANNEL_SWITCH_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_QUIET_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_QUIET_BSS_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_WPS_OVERLAP_TIMEOUT);
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ CASE_RETURN_STRING(SIR_LIM_FT_PREAUTH_RSP_TIMEOUT);
+#endif
+ CASE_RETURN_STRING(SIR_LIM_REMAIN_CHN_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE);
+ CASE_RETURN_STRING(SIR_LIM_BEACON_GEN_IND);
+ CASE_RETURN_STRING(SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT);
+#ifdef FEATURE_WLAN_ESE
+ CASE_RETURN_STRING(SIR_LIM_ESE_TSM_TIMEOUT);
+#endif
+ CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT);
+ CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END);
+
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_cfg_msg_string() - Get the msg
+ * @cfg_msg: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_cfg_msg_string(uint16_t cfg_msg)
+{
+ switch (cfg_msg) {
+ CASE_RETURN_STRING(WNI_CFG_PARAM_UPDATE_IND);
+ CASE_RETURN_STRING(WNI_CFG_DNLD_REQ);
+ CASE_RETURN_STRING(WNI_CFG_DNLD_CNF);
+ CASE_RETURN_STRING(WNI_CFG_GET_RSP);
+ CASE_RETURN_STRING(WNI_CFG_SET_CNF);
+ CASE_RETURN_STRING(SIR_CFG_PARAM_UPDATE_IND);
+ CASE_RETURN_STRING(SIR_CFG_DOWNLOAD_COMPLETE_IND);
+
+ CASE_RETURN_STRING(WNI_CFG_SET_REQ_NO_RSP);
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace_get_info_log_string() - Get the log info
+ * @info_log: message type in numeric form
+ *
+ * This function will return a string equivalent of the message.
+ *
+ * Return: String equivalent of the message type.
+ **/
+uint8_t *mac_trace_get_info_log_string(uint16_t info_log)
+{
+ switch (info_log) {
+ CASE_RETURN_STRING(eLOG_NODROP_MISSED_BEACON_SCENARIO);
+ CASE_RETURN_STRING(eLOG_PROC_DEAUTH_FRAME_SCENARIO);
+ default:
+ return (uint8_t *) "UNKNOWN";
+ break;
+ }
+}
+
+/**
+ * mac_trace() - Main function used for MAC Trace
+ * @mac_ctx: Global MAC context
+ * @code: code
+ * @session: session id
+ * @data: data to be traced.
+ *
+ * Return: None
+ **/
+void mac_trace(tpAniSirGlobal mac_ctx, uint8_t code,
+ uint16_t session, uint32_t data)
+{
+ /*
+ * Today mac_trace is being invoked by PE only, need to remove this
+ * function once PE is migrated to using new trace API.
+ */
+ mac_trace_new(mac_ctx, CDF_MODULE_ID_PE, code, session, data);
+}
+
+/**
+ * mac_trace_new() - New function used for MAC Trace
+ * @mac_ctx: Global MAC context
+ * @code: code
+ * @session: session id
+ * @data: data to be traced.
+ *
+ * Return: None
+ **/
+void mac_trace_new(tpAniSirGlobal mac_ctx, uint8_t module, uint8_t code,
+ uint16_t session, uint32_t data)
+{
+ cdf_trace(module, code, session, data);
+}
+
+#endif
diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
new file mode 100644
index 0000000..7dea42c
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c
@@ -0,0 +1,5654 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file parser_api.cc contains the code for parsing
+ * 802.11 messages.
+ * Author: Pierre Vandwalle
+ * Date: 03/18/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "sir_api.h"
+#include "ani_global.h"
+#include "parser_api.h"
+#include "cfg_api.h"
+#include "lim_utils.h"
+#include "utils_parser.h"
+#include "lim_ser_des_utils.h"
+#include "sch_api.h"
+#include "wmm_apsd.h"
+#if defined WLAN_FEATURE_VOWIFI
+#include "rrm_api.h"
+#endif
+
+#include "cds_regdomain_common.h"
+
+/* ////////////////////////////////////////////////////////////////////// */
+void dot11f_log(tpAniSirGlobal pMac, int loglevel, const char *pString, ...)
+{
+#ifdef WLAN_DEBUG
+ if ((uint32_t) loglevel >
+ pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(SIR_DBG_MODULE_ID)]) {
+ return;
+ } else {
+ va_list marker;
+
+ va_start(marker, pString); /* Initialize variable arguments. */
+
+ log_debug(pMac, SIR_DBG_MODULE_ID, loglevel, pString, marker);
+
+ va_end(marker); /* Reset variable arguments. */
+ }
+#endif
+}
+
+void swap_bit_field16(uint16_t in, uint16_t *out)
+{
+#ifdef ANI_LITTLE_BIT_ENDIAN
+ *out = in;
+#else /* Big-Endian... */
+ *out = ((in & 0x8000) >> 15) |
+ ((in & 0x4000) >> 13) |
+ ((in & 0x2000) >> 11) |
+ ((in & 0x1000) >> 9) |
+ ((in & 0x0800) >> 7) |
+ ((in & 0x0400) >> 5) |
+ ((in & 0x0200) >> 3) |
+ ((in & 0x0100) >> 1) |
+ ((in & 0x0080) << 1) |
+ ((in & 0x0040) << 3) |
+ ((in & 0x0020) << 5) |
+ ((in & 0x0010) << 7) |
+ ((in & 0x0008) << 9) |
+ ((in & 0x0004) << 11) |
+ ((in & 0x0002) << 13) | ((in & 0x0001) << 15);
+#endif /* ANI_LITTLE_BIT_ENDIAN */
+}
+
+void swap_bit_field32(uint32_t in, uint32_t *out)
+{
+#ifdef ANI_LITTLE_BIT_ENDIAN
+ *out = in;
+#else /* Big-Endian... */
+ *out = ((in & 0x80000000) >> 31) |
+ ((in & 0x40000000) >> 29) |
+ ((in & 0x20000000) >> 27) |
+ ((in & 0x10000000) >> 25) |
+ ((in & 0x08000000) >> 23) |
+ ((in & 0x04000000) >> 21) |
+ ((in & 0x02000000) >> 19) |
+ ((in & 0x01000000) >> 17) |
+ ((in & 0x00800000) >> 15) |
+ ((in & 0x00400000) >> 13) |
+ ((in & 0x00200000) >> 11) |
+ ((in & 0x00100000) >> 9) |
+ ((in & 0x00080000) >> 7) |
+ ((in & 0x00040000) >> 5) |
+ ((in & 0x00020000) >> 3) |
+ ((in & 0x00010000) >> 1) |
+ ((in & 0x00008000) << 1) |
+ ((in & 0x00004000) << 3) |
+ ((in & 0x00002000) << 5) |
+ ((in & 0x00001000) << 7) |
+ ((in & 0x00000800) << 9) |
+ ((in & 0x00000400) << 11) |
+ ((in & 0x00000200) << 13) |
+ ((in & 0x00000100) << 15) |
+ ((in & 0x00000080) << 17) |
+ ((in & 0x00000040) << 19) |
+ ((in & 0x00000020) << 21) |
+ ((in & 0x00000010) << 23) |
+ ((in & 0x00000008) << 25) |
+ ((in & 0x00000004) << 27) |
+ ((in & 0x00000002) << 29) | ((in & 0x00000001) << 31);
+#endif /* ANI_LITTLE_BIT_ENDIAN */
+}
+
+inline static void __print_wmm_params(tpAniSirGlobal pMac,
+ tDot11fIEWMMParams *pWmm)
+{
+ lim_log(pMac, LOG1, FL("WMM Parameters Received: \n"));
+ lim_log(pMac, LOG1,
+ FL
+ ("BE: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"),
+ pWmm->acbe_aifsn, pWmm->acbe_acm, pWmm->acbe_aci,
+ pWmm->acbe_acwmin, pWmm->acbe_acwmax, pWmm->acbe_txoplimit);
+
+ lim_log(pMac, LOG1,
+ FL
+ ("BK: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"),
+ pWmm->acbk_aifsn, pWmm->acbk_acm, pWmm->acbk_aci,
+ pWmm->acbk_acwmin, pWmm->acbk_acwmax, pWmm->acbk_txoplimit);
+
+ lim_log(pMac, LOG1,
+ FL
+ ("VI: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"),
+ pWmm->acvi_aifsn, pWmm->acvi_acm, pWmm->acvi_aci,
+ pWmm->acvi_acwmin, pWmm->acvi_acwmax, pWmm->acvi_txoplimit);
+
+ lim_log(pMac, LOG1,
+ FL
+ ("VO: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d \n"),
+ pWmm->acvo_aifsn, pWmm->acvo_acm, pWmm->acvo_aci,
+ pWmm->acvo_acwmin, pWmm->acvo_acwmax, pWmm->acvo_txoplimit);
+
+ return;
+}
+
+/* ////////////////////////////////////////////////////////////////////// */
+/* Functions for populating "dot11f" style IEs */
+
+/* return: >= 0, the starting location of the IE in rsnIEdata inside tSirRSNie */
+/* < 0, cannot find */
+int find_ie_location(tpAniSirGlobal pMac, tpSirRSNie pRsnIe, uint8_t EID)
+{
+ int idx, ieLen, bytesLeft;
+ int ret_val = -1;
+
+ /* Here's what's going on: 'rsnIe' looks like this: */
+
+ /* typedef struct sSirRSNie */
+ /* { */
+ /* uint16_t length; */
+ /* uint8_t rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; */
+ /* } tSirRSNie, *tpSirRSNie; */
+
+ /* other code records both the WPA & RSN IEs (including their EIDs & */
+ /* lengths) into the array 'rsnIEdata'. We may have: */
+
+ /* With WAPI support, there may be 3 IEs here */
+ /* It can be only WPA IE, or only RSN IE or only WAPI IE */
+ /* Or two or all three of them with no particular ordering */
+
+ /* The if/then/else statements that follow are here to figure out */
+ /* whether we have the WPA IE, and where it is if we *do* have it. */
+
+ /* Save the first IE length */
+ ieLen = pRsnIe->rsnIEdata[1] + 2;
+ idx = 0;
+ bytesLeft = pRsnIe->length;
+
+ while (1) {
+ if (EID == pRsnIe->rsnIEdata[idx]) {
+ /* Found it */
+ return (idx);
+ } else if (EID != pRsnIe->rsnIEdata[idx] &&
+ /* & if no more IE, */
+ bytesLeft <= (uint16_t) (ieLen)) {
+ dot11f_log(pMac, LOG3,
+ FL("No IE (%d) in find_ie_location.\n"), EID);
+ return ret_val;
+ }
+ bytesLeft -= ieLen;
+ ieLen = pRsnIe->rsnIEdata[idx + 1] + 2;
+ idx += ieLen;
+ }
+
+ return ret_val;
+}
+
+tSirRetStatus
+populate_dot11f_capabilities(tpAniSirGlobal pMac,
+ tDot11fFfCapabilities *pDot11f,
+ tpPESession psessionEntry)
+{
+ uint16_t cfg;
+ tSirRetStatus nSirStatus;
+
+ nSirStatus = cfg_get_capability_info(pMac, &cfg, psessionEntry);
+ if (eSIR_SUCCESS != nSirStatus) {
+ dot11f_log(pMac, LOGP, FL("Failed to retrieve the Capabilities b"
+ "itfield from CFG (%d).\n"),
+ nSirStatus);
+ return nSirStatus;
+ }
+
+ swap_bit_field16(cfg, (uint16_t *) pDot11f);
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_capabilities. */
+
+/**
+ * populate_dot_11_f_ext_chann_switch_ann() - Function to populate ECS
+ * @mac_ptr: Pointer to PMAC structure
+ * @dot_11_ptr: ECS element
+ * @session_entry: PE session entry
+ *
+ * This function is used to populate the extended channel switch element
+ *
+ * Return: None
+ */
+void populate_dot_11_f_ext_chann_switch_ann(tpAniSirGlobal mac_ptr,
+ tDot11fIEext_chan_switch_ann *dot_11_ptr,
+ tpPESession session_entry)
+{
+ dot_11_ptr->switch_mode = session_entry->gLimChannelSwitch.switchMode;
+ dot_11_ptr->new_reg_class = cds_regdm_get_opclass_from_channel(
+ mac_ptr->scan.countryCodeCurrent,
+ session_entry->gLimChannelSwitch.primaryChannel,
+ session_entry->gLimChannelSwitch.ch_width);
+ dot_11_ptr->new_channel =
+ session_entry->gLimChannelSwitch.primaryChannel;
+ dot_11_ptr->switch_count =
+ session_entry->gLimChannelSwitch.switchCount;
+ dot_11_ptr->present = 1;
+}
+
+void
+populate_dot11f_chan_switch_ann(tpAniSirGlobal pMac,
+ tDot11fIEChanSwitchAnn *pDot11f,
+ tpPESession psessionEntry)
+{
+ pDot11f->switchMode = psessionEntry->gLimChannelSwitch.switchMode;
+ pDot11f->newChannel = psessionEntry->gLimChannelSwitch.primaryChannel;
+ pDot11f->switchCount =
+ (uint8_t) psessionEntry->gLimChannelSwitch.switchCount;
+
+ pDot11f->present = 1;
+}
+
+void
+populate_dot11f_chan_switch_wrapper(tpAniSirGlobal pMac,
+ tDot11fIEChannelSwitchWrapper *pDot11f,
+ tpPESession psessionEntry)
+{
+ /*
+ * The new country subelement is present only when
+ * 1. AP performs Extended Channel switching to new country.
+ * 2. New Operating Class table or a changed set of operating
+ * classes relative to the contents of the country element sent
+ * in the beacons.
+ *
+ * In the current scenario Channel Switch wrapper IE is included
+ * when we a radar is found and the AP does a channel change in
+ * the same regulatory domain(No country change or Operating class
+ * table). So, we do not need to include the New Country IE.
+ *
+ * Transmit Power Envlope Subelement is optional
+ * in Channel Switch Wrapper IE. So, not setting
+ * the TPE subelement. We include only WiderBWChanSwitchAnn.
+ */
+ pDot11f->present = 1;
+
+ /*
+ * Add the Wide Channel Bandwidth Sublement.
+ */
+ pDot11f->WiderBWChanSwitchAnn.newChanWidth =
+ psessionEntry->gLimWiderBWChannelSwitch.newChanWidth;
+ pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq0 =
+ psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0;
+ pDot11f->WiderBWChanSwitchAnn.newCenterChanFreq1 =
+ psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1;
+ pDot11f->WiderBWChanSwitchAnn.present = 1;
+
+}
+
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+void
+populate_dot11f_avoid_channel_ie(tpAniSirGlobal mac_ctx,
+ tDot11fIEQComVendorIE *dot11f,
+ tpPESession pe_session)
+{
+ if (!pe_session->sap_advertise_avoid_ch_ie)
+ return;
+
+ dot11f->present = true;
+ dot11f->type = QCOM_VENDOR_IE_MCC_AVOID_CH;
+ dot11f->channel = pe_session->currentOperChannel;
+}
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+#ifdef WLAN_FEATURE_11AC
+void
+populate_dot11f_wider_bw_chan_switch_ann(tpAniSirGlobal pMac,
+ tDot11fIEWiderBWChanSwitchAnn *pDot11f,
+ tpPESession psessionEntry)
+{
+ pDot11f->present = 1;
+ pDot11f->newChanWidth =
+ psessionEntry->gLimWiderBWChannelSwitch.newChanWidth;
+ pDot11f->newCenterChanFreq0 =
+ psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0;
+ pDot11f->newCenterChanFreq1 =
+ psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1;
+}
+#endif
+
+tSirRetStatus
+populate_dot11f_country(tpAniSirGlobal pMac,
+ tDot11fIECountry *pDot11f, tpPESession psessionEntry)
+{
+ uint32_t len, maxlen, codelen;
+ uint16_t item;
+ tSirRetStatus nSirStatus;
+ tSirRFBand rfBand;
+ uint8_t temp[CFG_MAX_STR_LEN], code[3];
+
+ if (psessionEntry->lim11dEnabled) {
+ lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+ if (rfBand == SIR_BAND_5_GHZ) {
+ item = WNI_CFG_MAX_TX_POWER_5;
+ maxlen = WNI_CFG_MAX_TX_POWER_5_LEN;
+ } else {
+ item = WNI_CFG_MAX_TX_POWER_2_4;
+ maxlen = WNI_CFG_MAX_TX_POWER_2_4_LEN;
+ }
+
+ CFG_GET_STR(nSirStatus, pMac, item, temp, len, maxlen);
+
+ if (3 > len) {
+ /* no limit on tx power, cannot include the IE because at least */
+ /* one (channel,num,tx power) must be present */
+ return eSIR_SUCCESS;
+ }
+
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_COUNTRY_CODE,
+ code, codelen, 3);
+
+ cdf_mem_copy(pDot11f->country, code, codelen);
+
+ if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) {
+ dot11f_log(pMac, LOGE,
+ FL("len:%d is out of bounds, resetting.\n"),
+ len);
+ len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE;
+ }
+
+ pDot11f->num_triplets = (uint8_t) (len / 3);
+ cdf_mem_copy((uint8_t *) pDot11f->triplets, temp, len);
+
+ pDot11f->present = 1;
+ }
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_country. */
+
+#ifdef QCA_WIFI_3_0_EMU
+/**
+ * populate_dot11f_ds_params() - To populate DS IE params
+ * mac_ctx: Pointer to global mac context
+ * dot11f_param: pointer to DS params IE
+ * channel: channel number
+ *
+ * This routine will populate DS param in management frame like
+ * beacon, probe response, and etc.
+ *
+ * Return: Overall sucess
+ */
+tSirRetStatus
+populate_dot11f_ds_params(tpAniSirGlobal mac_ctx,
+ tDot11fIEDSParams *dot11f_param, uint8_t channel)
+{
+ /* .11a/11b/g mode PHY => Include the DS Parameter Set IE: */
+ dot11f_param->curr_channel = channel;
+ dot11f_param->present = 1;
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_ds_params. */
+#else
+/**
+ * populate_dot11f_ds_params() - To populate DS IE params
+ * mac_ctx: Pointer to global mac context
+ * dot11f_param: pointer to DS params IE
+ * channel: channel number
+ *
+ * This routine will populate DS param in management frame like
+ * beacon, probe response, and etc.
+ *
+ * Return: Overall sucess
+ */
+tSirRetStatus
+populate_dot11f_ds_params(tpAniSirGlobal mac_ctx,
+ tDot11fIEDSParams *dot11f_param, uint8_t channel)
+{
+ if (IS_24G_CH(channel)) {
+ /* .11b/g mode PHY => Include the DS Parameter Set IE: */
+ dot11f_param->curr_channel = channel;
+ dot11f_param->present = 1;
+ }
+
+ return eSIR_SUCCESS;
+}
+#endif
+
+#define SET_AIFSN(aifsn) (((aifsn) < 2) ? 2 : (aifsn))
+
+void
+populate_dot11f_edca_param_set(tpAniSirGlobal pMac,
+ tDot11fIEEDCAParamSet *pDot11f,
+ tpPESession psessionEntry)
+{
+
+ if (psessionEntry->limQosEnabled) {
+ /* change to bitwise operation, after this is fixed in frames. */
+ pDot11f->qos =
+ (uint8_t) (0xf0 &
+ (psessionEntry->gLimEdcaParamSetCount << 4));
+
+ /* Fill each EDCA parameter set in order: be, bk, vi, vo */
+ pDot11f->acbe_aifsn =
+ (0xf &
+ SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn));
+ pDot11f->acbe_acm =
+ (0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm);
+ pDot11f->acbe_aci = (0x3 & SIR_MAC_EDCAACI_BESTEFFORT);
+ pDot11f->acbe_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min);
+ pDot11f->acbe_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max);
+ pDot11f->acbe_txoplimit =
+ psessionEntry->gLimEdcaParamsBC[0].txoplimit;
+
+ pDot11f->acbk_aifsn =
+ (0xf &
+ SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn));
+ pDot11f->acbk_acm =
+ (0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm);
+ pDot11f->acbk_aci = (0x3 & SIR_MAC_EDCAACI_BACKGROUND);
+ pDot11f->acbk_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min);
+ pDot11f->acbk_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max);
+ pDot11f->acbk_txoplimit =
+ psessionEntry->gLimEdcaParamsBC[1].txoplimit;
+
+ pDot11f->acvi_aifsn =
+ (0xf &
+ SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn));
+ pDot11f->acvi_acm =
+ (0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm);
+ pDot11f->acvi_aci = (0x3 & SIR_MAC_EDCAACI_VIDEO);
+ pDot11f->acvi_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min);
+ pDot11f->acvi_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max);
+ pDot11f->acvi_txoplimit =
+ psessionEntry->gLimEdcaParamsBC[2].txoplimit;
+
+ pDot11f->acvo_aifsn =
+ (0xf &
+ SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn));
+ pDot11f->acvo_acm =
+ (0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm);
+ pDot11f->acvo_aci = (0x3 & SIR_MAC_EDCAACI_VOICE);
+ pDot11f->acvo_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min);
+ pDot11f->acvo_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max);
+ pDot11f->acvo_txoplimit =
+ psessionEntry->gLimEdcaParamsBC[3].txoplimit;
+
+ pDot11f->present = 1;
+ }
+
+} /* End PopluateDot11fEDCAParamSet. */
+
+tSirRetStatus
+populate_dot11f_erp_info(tpAniSirGlobal pMac,
+ tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry)
+{
+ tSirRetStatus nSirStatus;
+ uint32_t val;
+ tSirRFBand rfBand = SIR_BAND_UNKNOWN;
+
+ lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
+ if (SIR_BAND_2_4_GHZ == rfBand) {
+ pDot11f->present = 1;
+
+ val = psessionEntry->cfgProtection.fromllb;
+ if (!val) {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("11B protection not enabled. Not populating ERP IE %d\n"),
+ val);
+ return eSIR_SUCCESS;
+ }
+
+ if (psessionEntry->gLim11bParams.protectionEnabled) {
+ pDot11f->non_erp_present = 1;
+ pDot11f->use_prot = 1;
+ }
+
+ if (psessionEntry->gLimOlbcParams.protectionEnabled) {
+ /* FIXME_PROTECTION: we should be setting non_erp present also. */
+ /* check the test plan first. */
+ pDot11f->use_prot = 1;
+ }
+
+ if ((psessionEntry->gLimNoShortParams.numNonShortPreambleSta)
+ || !psessionEntry->beaconParams.fShortPreamble) {
+ pDot11f->barker_preamble = 1;
+
+ }
+ /* if protection always flag is set, advertise protection enabled */
+ /* regardless of legacy stations presence */
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_11G_PROTECTION_ALWAYS,
+ val);
+
+ if (val) {
+ pDot11f->use_prot = 1;
+ }
+ }
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_erp_info. */
+
+tSirRetStatus
+populate_dot11f_ext_supp_rates(tpAniSirGlobal pMac, uint8_t nChannelNum,
+ tDot11fIEExtSuppRates *pDot11f,
+ tpPESession psessionEntry)
+{
+ tSirRetStatus nSirStatus;
+ uint32_t nRates = 0;
+ uint8_t rates[WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN];
+
+ /* Use the ext rates present in session entry whenever nChannelNum is set to OPERATIONAL
+ else use the ext supported rate set from CFG, which is fixed and does not change dynamically and is used for
+ sending mgmt frames (lile probe req) which need to go out before any session is present.
+ */
+ if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) {
+ if (psessionEntry != NULL) {
+ nRates = psessionEntry->extRateSet.numRates;
+ cdf_mem_copy(rates, psessionEntry->extRateSet.rate,
+ nRates);
+ } else {
+ dot11f_log(pMac, LOGE,
+ FL("no session context exists while"
+ " populating Operational Rate Set\n"));
+ }
+ } else if (HIGHEST_24GHZ_CHANNEL_NUM >= nChannelNum) {
+ CFG_GET_STR(nSirStatus, pMac,
+ WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, rates,
+ nRates, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN);
+ }
+
+ if (0 != nRates) {
+ pDot11f->num_rates = (uint8_t) nRates;
+ cdf_mem_copy(pDot11f->rates, rates, nRates);
+ pDot11f->present = 1;
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_ext_supp_rates. */
+
+tSirRetStatus
+populate_dot11f_ext_supp_rates1(tpAniSirGlobal pMac,
+ uint8_t nChannelNum,
+ tDot11fIEExtSuppRates *pDot11f)
+{
+ uint32_t nRates;
+ tSirRetStatus nSirStatus;
+ uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
+
+ if (14 < nChannelNum) {
+ pDot11f->present = 0;
+ return eSIR_SUCCESS;
+ }
+ /* N.B. I have *no* idea why we're calling 'wlan_cfg_get_str' with an argument */
+ /* of WNI_CFG_SUPPORTED_RATES_11A here, but that's what was done */
+ /* previously & I'm afraid to change it! */
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A,
+ rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES);
+
+ if (0 != nRates) {
+ pDot11f->num_rates = (uint8_t) nRates;
+ cdf_mem_copy(pDot11f->rates, rates, nRates);
+ pDot11f->present = 1;
+ }
+
+ return eSIR_SUCCESS;
+} /* populate_dot11f_ext_supp_rates1. */
+
+tSirRetStatus
+populate_dot11f_ht_caps(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, tDot11fIEHTCaps *pDot11f)
+{
+ uint32_t nCfgValue, nCfgLen;
+ uint8_t nCfgValue8;
+ tSirRetStatus nSirStatus;
+ tSirMacHTParametersInfo *pHTParametersInfo;
+ union {
+ uint16_t nCfgValue16;
+ tSirMacHTCapabilityInfo htCapInfo;
+ tSirMacExtendedHTCapabilityInfo extHtCapInfo;
+ } uHTCapabilityInfo;
+
+ tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo;
+ tSirMacASCapabilityInfo *pASCapabilityInfo;
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_CAP_INFO, nCfgValue);
+
+ uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
+
+ pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave;
+ pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField;
+ pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA;
+ pDot11f->maximalAMSDUsize =
+ uHTCapabilityInfo.htCapInfo.maximalAMSDUsize;
+ pDot11f->dsssCckMode40MHz =
+ uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz;
+ pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp;
+ pDot11f->stbcControlFrame =
+ uHTCapabilityInfo.htCapInfo.stbcControlFrame;
+ pDot11f->lsigTXOPProtection =
+ uHTCapabilityInfo.htCapInfo.lsigTXOPProtection;
+
+ /* All sessionized entries will need the check below */
+ if (psessionEntry == NULL) /* Only in case of NO session */
+ {
+ pDot11f->supportedChannelWidthSet =
+ uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet;
+ pDot11f->advCodingCap =
+ uHTCapabilityInfo.htCapInfo.advCodingCap;
+ pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC;
+ pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC;
+ pDot11f->shortGI20MHz =
+ uHTCapabilityInfo.htCapInfo.shortGI20MHz;
+ pDot11f->shortGI40MHz =
+ uHTCapabilityInfo.htCapInfo.shortGI40MHz;
+ } else {
+ pDot11f->advCodingCap = psessionEntry->htConfig.ht_rx_ldpc;
+ pDot11f->supportedChannelWidthSet =
+ psessionEntry->htSupportedChannelWidthSet;
+ pDot11f->txSTBC = psessionEntry->htConfig.ht_tx_stbc;
+ pDot11f->rxSTBC = psessionEntry->htConfig.ht_rx_stbc;
+ if (psessionEntry->htConfig.ht_sgi) {
+ pDot11f->shortGI20MHz =
+ uHTCapabilityInfo.htCapInfo.shortGI20MHz;
+ pDot11f->shortGI40MHz =
+ uHTCapabilityInfo.htCapInfo.shortGI40MHz;
+ }
+ }
+
+ /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is
+ eHT_CHANNEL_WIDTH_20MHZ */
+ if (pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) {
+ pDot11f->shortGI40MHz = 0;
+ }
+
+ dot11f_log(pMac, LOG2,
+ FL
+ ("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d\n"),
+ pDot11f->supportedChannelWidthSet, pDot11f->mimoPowerSave,
+ pDot11f->greenField, pDot11f->shortGI20MHz,
+ pDot11f->shortGI40MHz, pDot11f->dsssCckMode40MHz);
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_AMPDU_PARAMS, nCfgValue);
+
+ nCfgValue8 = (uint8_t) nCfgValue;
+ pHTParametersInfo = (tSirMacHTParametersInfo *) &nCfgValue8;
+
+ pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor;
+ pDot11f->mpduDensity = pHTParametersInfo->mpduDensity;
+ pDot11f->reserved1 = pHTParametersInfo->reserved;
+
+ dot11f_log(pMac, LOG2, FL("AMPDU Param: %x\n"), nCfgValue);
+
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_MCS_SET,
+ pDot11f->supportedMCSSet, nCfgLen,
+ SIZE_OF_SUPPORTED_MCS_SET);
+
+ if (psessionEntry) {
+ if (pMac->lteCoexAntShare
+ && (IS_24G_CH(psessionEntry->currentOperChannel))) {
+ if (!(IS_2X2_CHAIN(psessionEntry->chainMask))) {
+ pDot11f->supportedMCSSet[1] = 0;
+ if (LIM_IS_STA_ROLE(psessionEntry)) {
+ pDot11f->mimoPowerSave =
+ psessionEntry->smpsMode;
+ }
+ }
+ }
+ if (psessionEntry->nss == 1)
+ pDot11f->supportedMCSSet[1] = 0;
+ }
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_EXT_HT_CAP_INFO, nCfgValue);
+
+ uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF;
+
+ pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco;
+ pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime;
+ pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback;
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_TX_BF_CAP, nCfgValue);
+
+ pTxBFCapabilityInfo = (tSirMacTxBFCapabilityInfo *) &nCfgValue;
+ pDot11f->txBF = pTxBFCapabilityInfo->txBF;
+ pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding;
+ pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding;
+ pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF;
+ pDot11f->txZLF = pTxBFCapabilityInfo->txZLF;
+ pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF;
+ pDot11f->calibration = pTxBFCapabilityInfo->calibration;
+ pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF;
+ pDot11f->explicitUncompressedSteeringMatrix =
+ pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix;
+ pDot11f->explicitBFCSIFeedback =
+ pTxBFCapabilityInfo->explicitBFCSIFeedback;
+ pDot11f->explicitUncompressedSteeringMatrixFeedback =
+ pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback;
+ pDot11f->explicitCompressedSteeringMatrixFeedback =
+ pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback;
+ pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae;
+ pDot11f->uncompressedSteeringMatrixBFAntennae =
+ pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae;
+ pDot11f->compressedSteeringMatrixBFAntennae =
+ pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae;
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_AS_CAP, nCfgValue);
+
+ nCfgValue8 = (uint8_t) nCfgValue;
+
+ pASCapabilityInfo = (tSirMacASCapabilityInfo *) &nCfgValue8;
+ pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection;
+ pDot11f->explicitCSIFeedbackTx =
+ pASCapabilityInfo->explicitCSIFeedbackTx;
+ pDot11f->antennaIndicesFeedbackTx =
+ pASCapabilityInfo->antennaIndicesFeedbackTx;
+ pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback;
+ pDot11f->antennaIndicesFeedback =
+ pASCapabilityInfo->antennaIndicesFeedback;
+ pDot11f->rxAS = pASCapabilityInfo->rxAS;
+ pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs;
+
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_ht_caps. */
+
+#ifdef WLAN_FEATURE_11AC
+
+void lim_log_vht_cap(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+ lim_log(pMac, LOG1, FL("maxMPDULen (2): %d\n"), pDot11f->maxMPDULen);
+ lim_log(pMac, LOG1, FL("supportedChannelWidthSet (2): %d\n"),
+ pDot11f->supportedChannelWidthSet);
+ lim_log(pMac, LOG1, FL("ldpcCodingCap (1): %d\n"),
+ pDot11f->ldpcCodingCap);
+ lim_log(pMac, LOG1, FL("shortGI80MHz (1): %d\n"), pDot11f->shortGI80MHz);
+ lim_log(pMac, LOG1, FL("shortGI160and80plus80MHz (1): %d\n"),
+ pDot11f->shortGI160and80plus80MHz);
+ lim_log(pMac, LOG1, FL("txSTBC (1): %d\n"), pDot11f->txSTBC);
+ lim_log(pMac, LOG1, FL("rxSTBC (3): %d\n"), pDot11f->rxSTBC);
+ lim_log(pMac, LOG1, FL("suBeamFormerCap (1): %d\n"),
+ pDot11f->suBeamFormerCap);
+ lim_log(pMac, LOG1, FL("suBeamformeeCap (1): %d\n"),
+ pDot11f->suBeamformeeCap);
+ lim_log(pMac, LOG1, FL("csnofBeamformerAntSup (3): %d\n"),
+ pDot11f->csnofBeamformerAntSup);
+ lim_log(pMac, LOG1, FL("numSoundingDim (3): %d\n"),
+ pDot11f->numSoundingDim);
+ lim_log(pMac, LOG1, FL("muBeamformerCap (1): %d\n"),
+ pDot11f->muBeamformerCap);
+ lim_log(pMac, LOG1, FL("muBeamformeeCap (1): %d\n"),
+ pDot11f->muBeamformeeCap);
+ lim_log(pMac, LOG1, FL("vhtTXOPPS (1): %d\n"), pDot11f->vhtTXOPPS);
+ lim_log(pMac, LOG1, FL("htcVHTCap (1): %d\n"), pDot11f->htcVHTCap);
+ lim_log(pMac, LOG1, FL("maxAMPDULenExp (3): %d\n"),
+ pDot11f->maxAMPDULenExp);
+ lim_log(pMac, LOG1, FL("vhtLinkAdaptCap (2): %d\n"),
+ pDot11f->vhtLinkAdaptCap);
+ lim_log(pMac, LOG1, FL("rxAntPattern (1): %d\n"),
+ pDot11f->vhtLinkAdaptCap);
+ lim_log(pMac, LOG1, FL("txAntPattern (1): %d\n"),
+ pDot11f->vhtLinkAdaptCap);
+ lim_log(pMac, LOG1, FL("reserved1 (2): %d\n"), pDot11f->reserved1);
+ lim_log(pMac, LOG1, FL("rxMCSMap (16): %d\n"), pDot11f->rxMCSMap);
+ lim_log(pMac, LOG1, FL("rxHighSupDataRate (13): %d\n"),
+ pDot11f->rxHighSupDataRate);
+ lim_log(pMac, LOG1, FL("reserve (3): %d\n"), pDot11f->reserved2);
+ lim_log(pMac, LOG1, FL("txMCSMap (16): %d\n"), pDot11f->txMCSMap);
+ lim_log(pMac, LOG1, FL("txSupDataRate (13): %d\n"),
+ pDot11f->txSupDataRate);
+ lim_log(pMac, LOG1, FL("reserv (3): %d\n"), pDot11f->reserved3);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+void lim_log_vht_operation(tpAniSirGlobal pMac, tDot11fIEVHTOperation *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+ lim_log(pMac, LOG1, FL("chanWidth : %d\n"), pDot11f->chanWidth);
+ lim_log(pMac, LOG1, FL("chanCenterFreqSeg1: %d\n"),
+ pDot11f->chanCenterFreqSeg1);
+ lim_log(pMac, LOG1, FL("chanCenterFreqSeg2: %d\n"),
+ pDot11f->chanCenterFreqSeg2);
+ lim_log(pMac, LOG1, FL("basicMCSSet: %d\n"), pDot11f->basicMCSSet);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+void lim_log_vht_ext_bss_load(tpAniSirGlobal pMac, tDot11fIEVHTExtBssLoad *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+ lim_log(pMac, LOG1, FL("muMIMOCapStaCount : %d\n"),
+ pDot11f->muMIMOCapStaCount);
+ lim_log(pMac, LOG1, FL("ssUnderUtil: %d\n"), pDot11f->ssUnderUtil);
+ lim_log(pMac, LOG1, FL("FortyMHzUtil: %d\n"), pDot11f->FortyMHzUtil);
+ lim_log(pMac, LOG1, FL("EightyMHzUtil: %d\n"), pDot11f->EightyMHzUtil);
+ lim_log(pMac, LOG1, FL("OneSixtyMHzUtil: %d\n"),
+ pDot11f->OneSixtyMHzUtil);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+void lim_log_operating_mode(tpAniSirGlobal pMac, tDot11fIEOperatingMode *pDot11f)
+{
+#ifdef DUMP_MGMT_CNTNTS
+ lim_log(pMac, LOG1, FL("ChanWidth : %d\n"), pDot11f->chanWidth);
+ lim_log(pMac, LOG1, FL("reserved: %d\n"), pDot11f->reserved);
+ lim_log(pMac, LOG1, FL("rxNSS: %d\n"), pDot11f->rxNSS);
+ lim_log(pMac, LOG1, FL("rxNSS Type: %d\n"), pDot11f->rxNSSType);
+#endif /* DUMP_MGMT_CNTNTS */
+}
+
+void lim_log_qos_map_set(tpAniSirGlobal pMac, tSirQosMapSet *pQosMapSet)
+{
+ uint8_t i;
+ lim_log(pMac, LOG1, FL("num of dscp exceptions : %d"),
+ pQosMapSet->num_dscp_exceptions);
+ for (i = 0; i < pQosMapSet->num_dscp_exceptions; i++) {
+ lim_log(pMac, LOG1, FL("dscp value: %d"),
+ pQosMapSet->dscp_exceptions[i][0]);
+ lim_log(pMac, LOG1, FL("User priority value: %d"),
+ pQosMapSet->dscp_exceptions[i][1]);
+ }
+ for (i = 0; i < 8; i++) {
+ lim_log(pMac, LOG1, FL("dscp low for up %d: %d"), i,
+ pQosMapSet->dscp_range[i][0]);
+ lim_log(pMac, LOG1, FL("dscp high for up %d: %d"), i,
+ pQosMapSet->dscp_range[i][1]);
+ }
+}
+
+tSirRetStatus
+populate_dot11f_vht_caps(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, tDot11fIEVHTCaps *pDot11f)
+{
+ tSirRetStatus nStatus;
+ uint32_t nCfgValue = 0;
+
+ pDot11f->present = 1;
+
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_MAX_MPDU_LENGTH, nCfgValue);
+ pDot11f->maxMPDULen = (nCfgValue & 0x0003);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET,
+ nCfgValue);
+ pDot11f->supportedChannelWidthSet = (nCfgValue & 0x0003);
+
+ nCfgValue = 0;
+ /* With VHT it suffices if we just examine HT */
+ if (psessionEntry) {
+ if (psessionEntry->htConfig.ht_rx_ldpc)
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_LDPC_CODING_CAP,
+ nCfgValue);
+
+ pDot11f->ldpcCodingCap = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ if (psessionEntry->htConfig.ht_sgi)
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SHORT_GI_80MHZ,
+ nCfgValue);
+
+ pDot11f->shortGI80MHz = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ if (psessionEntry->htConfig.ht_sgi)
+ CFG_GET_INT(nStatus, pMac,
+ WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
+ nCfgValue);
+
+ pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ if (psessionEntry->htConfig.ht_tx_stbc)
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TXSTBC,
+ nCfgValue);
+
+ pDot11f->txSTBC = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ if (psessionEntry->htConfig.ht_rx_stbc)
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RXSTBC,
+ nCfgValue);
+
+ pDot11f->rxSTBC = (nCfgValue & 0x0007);
+
+ pDot11f->suBeamformeeCap = psessionEntry->txBFIniFeatureEnabled;
+ if (psessionEntry->txBFIniFeatureEnabled) {
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac,
+ WNI_CFG_VHT_MU_BEAMFORMEE_CAP, nCfgValue);
+ pDot11f->muBeamformeeCap = (nCfgValue & 0x0001);
+ } else {
+ pDot11f->muBeamformeeCap = 0;
+ }
+ pDot11f->suBeamFormerCap = psessionEntry->enable_su_tx_bformer;
+ } else {
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_LDPC_CODING_CAP,
+ nCfgValue);
+ pDot11f->ldpcCodingCap = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SHORT_GI_80MHZ,
+ nCfgValue);
+ pDot11f->shortGI80MHz = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac,
+ WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ,
+ nCfgValue);
+ pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TXSTBC, nCfgValue);
+ pDot11f->txSTBC = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RXSTBC, nCfgValue);
+ pDot11f->rxSTBC = (nCfgValue & 0x0007);
+
+ pDot11f->suBeamformeeCap = 0;
+ pDot11f->muBeamformeeCap = 0;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SU_BEAMFORMER_CAP,
+ nCfgValue);
+ pDot11f->suBeamFormerCap = (nCfgValue & 0x0001);
+ }
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED,
+ nCfgValue);
+ pDot11f->csnofBeamformerAntSup = (nCfgValue & 0x0007);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS,
+ nCfgValue);
+ pDot11f->numSoundingDim = (nCfgValue & 0x0007);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_MU_BEAMFORMER_CAP, nCfgValue);
+ pDot11f->muBeamformerCap = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TXOP_PS, nCfgValue);
+ pDot11f->vhtTXOPPS = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_HTC_VHTC_CAP, nCfgValue);
+ pDot11f->htcVHTCap = (nCfgValue & 0x0001);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, nCfgValue);
+ pDot11f->maxAMPDULenExp = (nCfgValue & 0x0007);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_LINK_ADAPTATION_CAP, nCfgValue);
+ pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RX_ANT_PATTERN, nCfgValue);
+ pDot11f->rxAntPattern = nCfgValue;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TX_ANT_PATTERN, nCfgValue);
+ pDot11f->txAntPattern = nCfgValue;
+
+ pDot11f->reserved1 = 0;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RX_MCS_MAP, nCfgValue);
+ pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF);
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
+ nCfgValue);
+ pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF);
+
+ pDot11f->reserved2 = 0;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TX_MCS_MAP, nCfgValue);
+ pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF);
+ if (psessionEntry) {
+ if (pMac->lteCoexAntShare
+ && (IS_24G_CH(psessionEntry->currentOperChannel))) {
+ if (!(IS_2X2_CHAIN(psessionEntry->chainMask))) {
+ pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
+ pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
+ }
+ }
+ if (psessionEntry->nss == 1) {
+ pDot11f->txMCSMap |= DISABLE_NSS2_MCS;
+ pDot11f->rxMCSMap |= DISABLE_NSS2_MCS;
+ }
+ }
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
+ nCfgValue);
+ pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF);
+
+ pDot11f->reserved3 = 0;
+
+ lim_log_vht_cap(pMac, pDot11f);
+
+ return eSIR_SUCCESS;
+
+}
+
+tSirRetStatus
+populate_dot11f_vht_operation(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIEVHTOperation *pDot11f)
+{
+ tSirRetStatus nStatus;
+ uint32_t nCfgValue = 0;
+
+ pDot11f->present = 1;
+
+ if (psessionEntry->ch_width > CH_WIDTH_40MHZ) {
+ pDot11f->chanWidth = psessionEntry->ch_width - 1;
+ pDot11f->chanCenterFreqSeg1 =
+ psessionEntry->ch_center_freq_seg0;
+ if (psessionEntry->ch_width == CH_WIDTH_80P80MHZ)
+ pDot11f->chanCenterFreqSeg2 =
+ psessionEntry->ch_center_freq_seg1;
+ else
+ pDot11f->chanCenterFreqSeg2 = 0;
+ } else {
+ pDot11f->chanWidth = 0;
+ pDot11f->chanCenterFreqSeg1 = 0;
+ pDot11f->chanCenterFreqSeg2 = 0;
+ }
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_BASIC_MCS_SET, nCfgValue);
+ pDot11f->basicMCSSet = (uint16_t) nCfgValue;
+
+ lim_log_vht_operation(pMac, pDot11f);
+
+ return eSIR_SUCCESS;
+
+}
+
+tSirRetStatus
+populate_dot11f_vht_ext_bss_load(tpAniSirGlobal pMac,
+ tDot11fIEVHTExtBssLoad *pDot11f)
+{
+ tSirRetStatus nStatus;
+ uint32_t nCfgValue = 0;
+
+ pDot11f->present = 1;
+
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT,
+ nCfgValue);
+ pDot11f->muMIMOCapStaCount = (uint8_t) nCfgValue;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_SS_UNDER_UTIL, nCfgValue);
+ pDot11f->ssUnderUtil = (uint8_t) nCfgValue;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_40MHZ_UTILIZATION, nCfgValue);
+ pDot11f->FortyMHzUtil = (uint8_t) nCfgValue;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_80MHZ_UTILIZATION, nCfgValue);
+ pDot11f->EightyMHzUtil = (uint8_t) nCfgValue;
+
+ nCfgValue = 0;
+ CFG_GET_INT(nStatus, pMac, WNI_CFG_VHT_160MHZ_UTILIZATION, nCfgValue);
+ pDot11f->EightyMHzUtil = (uint8_t) nCfgValue;
+
+ lim_log_vht_ext_bss_load(pMac, pDot11f);
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus
+populate_dot11f_ext_cap(tpAniSirGlobal pMac,
+ bool isVHTEnabled, tDot11fIEExtCap *pDot11f,
+ tpPESession psessionEntry)
+{
+ uint32_t val = 0;
+ struct s_ext_cap *p_ext_cap;
+
+ pDot11f->present = 1;
+
+ if (!psessionEntry) {
+ lim_log(pMac, LOG1, FL("11MC - enabled for non-SAP cases"));
+ pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+ } else if (psessionEntry->sap_dot11mc) {
+ lim_log(pMac, LOG1, FL("11MC support enabled"));
+ pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+ } else {
+ if (eLIM_AP_ROLE != psessionEntry->limSystemRole) {
+ lim_log(pMac, LOG1, FL("11MC support enabled"));
+ pDot11f->num_bytes = DOT11F_IE_EXTCAP_MAX_LEN;
+ } else {
+ lim_log(pMac, LOG1, FL("11MC support disabled"));
+ pDot11f->num_bytes = DOT11F_IE_EXTCAP_MIN_LEN;
+ }
+ }
+
+ p_ext_cap = (struct s_ext_cap *)pDot11f->bytes;
+#ifdef WLAN_FEATURE_11AC
+ if (isVHTEnabled == true)
+ p_ext_cap->oper_mode_notification = 1;
+#endif
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_RTT3_ENABLE, &val) != eSIR_SUCCESS) {
+ lim_log(pMac, LOGE,
+ FL("could not retrieve RTT3 Variable from DAT File \n"));
+ return eSIR_FAILURE;
+ }
+
+ if (val) { /* If set to true then set RTTv3 */
+ if (!psessionEntry || LIM_IS_STA_ROLE(psessionEntry)) {
+ p_ext_cap->fine_time_meas_initiator =
+ (pMac->fine_time_meas_cap &
+ FINE_TIME_MEAS_STA_INITIATOR) ? 1 : 0;
+ p_ext_cap->fine_time_meas_responder =
+ (pMac->fine_time_meas_cap &
+ FINE_TIME_MEAS_STA_RESPONDER) ? 1 : 0;
+ } else if (LIM_IS_AP_ROLE(psessionEntry)) {
+ p_ext_cap->fine_time_meas_initiator =
+ (pMac->fine_time_meas_cap &
+ FINE_TIME_MEAS_SAP_INITIATOR) ? 1 : 0;
+ p_ext_cap->fine_time_meas_responder =
+ (pMac->fine_time_meas_cap &
+ FINE_TIME_MEAS_SAP_RESPONDER) ? 1 : 0;
+ }
+ }
+#ifdef QCA_HT_2040_COEX
+ if (pMac->roam.configParam.obssEnabled)
+ p_ext_cap->bss_coexist_mgmt_support = 1;
+#endif
+ p_ext_cap->ext_chan_switch = 1;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus
+populate_dot11f_operating_mode(tpAniSirGlobal pMac,
+ tDot11fIEOperatingMode *pDot11f,
+ tpPESession psessionEntry)
+{
+ pDot11f->present = 1;
+
+ pDot11f->chanWidth = psessionEntry->gLimOperatingMode.chanWidth;
+ pDot11f->rxNSS = psessionEntry->gLimOperatingMode.rxNSS;
+ pDot11f->rxNSSType = psessionEntry->gLimOperatingMode.rxNSSType;
+
+ return eSIR_SUCCESS;
+}
+
+#endif
+tSirRetStatus
+populate_dot11f_ht_info(tpAniSirGlobal pMac,
+ tDot11fIEHTInfo *pDot11f, tpPESession psessionEntry)
+{
+ uint32_t nCfgValue, nCfgLen;
+ uint8_t htInfoField1;
+ uint16_t htInfoField2;
+ tSirRetStatus nSirStatus;
+ tSirMacHTInfoField1 *pHTInfoField1;
+ tSirMacHTInfoField2 *pHTInfoField2;
+ union {
+ uint16_t nCfgValue16;
+ tSirMacHTInfoField3 infoField3;
+ } uHTInfoField;
+ union {
+ uint16_t nCfgValue16;
+ tSirMacHTInfoField2 infoField2;
+ } uHTInfoField2 = {
+ 0
+ };
+
+#if 0
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_CURRENT_CHANNEL, nCfgValue);
+#endif /* TO SUPPORT BT-AMP */
+
+ if (NULL == psessionEntry) {
+ PELOGE(lim_log(pMac, LOG1,
+ FL
+ ("Invalid session entry in populate_dot11f_ht_info()\n"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ pDot11f->primaryChannel = psessionEntry->currentOperChannel;
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD1, nCfgValue);
+
+ htInfoField1 = (uint8_t) nCfgValue;
+
+ pHTInfoField1 = (tSirMacHTInfoField1 *) &htInfoField1;
+ pHTInfoField1->rifsMode = psessionEntry->beaconParams.fRIFSMode;
+ pHTInfoField1->serviceIntervalGranularity =
+ pMac->lim.gHTServiceIntervalGranularity;
+
+ if (psessionEntry == NULL) {
+ PELOGE(lim_log(pMac, LOG1,
+ FL
+ ("Keep the value retrieved from cfg for secondary channel offset and recommended Tx Width set\n"));
+ )
+ } else {
+ pHTInfoField1->secondaryChannelOffset =
+ psessionEntry->htSecondaryChannelOffset;
+ pHTInfoField1->recommendedTxWidthSet =
+ psessionEntry->htRecommendedTxWidthSet;
+ }
+
+ if ((psessionEntry) && LIM_IS_AP_ROLE(psessionEntry)) {
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2,
+ nCfgValue);
+
+ uHTInfoField2.nCfgValue16 = nCfgValue & 0xFFFF; /* this is added for fixing CRs on MDM9K platform - 257951, 259577 */
+
+ uHTInfoField2.infoField2.opMode = psessionEntry->htOperMode;
+ uHTInfoField2.infoField2.nonGFDevicesPresent =
+ psessionEntry->beaconParams.llnNonGFCoexist;
+ uHTInfoField2.infoField2.obssNonHTStaPresent = psessionEntry->beaconParams.gHTObssMode; /*added for Obss */
+
+ uHTInfoField2.infoField2.reserved = 0;
+
+ } else {
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2,
+ nCfgValue);
+
+ htInfoField2 = (uint16_t) nCfgValue;
+
+ pHTInfoField2 = (tSirMacHTInfoField2 *) &htInfoField2;
+ pHTInfoField2->opMode = pMac->lim.gHTOperMode;
+ pHTInfoField2->nonGFDevicesPresent =
+ pMac->lim.gHTNonGFDevicesPresent;
+ pHTInfoField2->obssNonHTStaPresent = pMac->lim.gHTObssMode; /*added for Obss */
+
+ pHTInfoField2->reserved = 0;
+ }
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD3, nCfgValue);
+
+ uHTInfoField.nCfgValue16 = nCfgValue & 0xFFFF;
+
+ uHTInfoField.infoField3.basicSTBCMCS = pMac->lim.gHTSTBCBasicMCS;
+ uHTInfoField.infoField3.dualCTSProtection =
+ pMac->lim.gHTDualCTSProtection;
+ uHTInfoField.infoField3.secondaryBeacon = pMac->lim.gHTSecondaryBeacon;
+ uHTInfoField.infoField3.lsigTXOPProtectionFullSupport =
+ psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport;
+ uHTInfoField.infoField3.pcoActive = pMac->lim.gHTPCOActive;
+ uHTInfoField.infoField3.pcoPhase = pMac->lim.gHTPCOPhase;
+ uHTInfoField.infoField3.reserved = 0;
+
+ pDot11f->secondaryChannelOffset = pHTInfoField1->secondaryChannelOffset;
+ pDot11f->recommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet;
+ pDot11f->rifsMode = pHTInfoField1->rifsMode;
+ pDot11f->controlledAccessOnly = pHTInfoField1->controlledAccessOnly;
+ pDot11f->serviceIntervalGranularity =
+ pHTInfoField1->serviceIntervalGranularity;
+
+ pDot11f->opMode = uHTInfoField2.infoField2.opMode;
+ pDot11f->nonGFDevicesPresent =
+ uHTInfoField2.infoField2.nonGFDevicesPresent;
+ pDot11f->obssNonHTStaPresent =
+ uHTInfoField2.infoField2.obssNonHTStaPresent;
+ pDot11f->reserved = uHTInfoField2.infoField2.reserved;
+
+ pDot11f->basicSTBCMCS = uHTInfoField.infoField3.basicSTBCMCS;
+ pDot11f->dualCTSProtection = uHTInfoField.infoField3.dualCTSProtection;
+ pDot11f->secondaryBeacon = uHTInfoField.infoField3.secondaryBeacon;
+ pDot11f->lsigTXOPProtectionFullSupport =
+ uHTInfoField.infoField3.lsigTXOPProtectionFullSupport;
+ pDot11f->pcoActive = uHTInfoField.infoField3.pcoActive;
+ pDot11f->pcoPhase = uHTInfoField.infoField3.pcoPhase;
+ pDot11f->reserved2 = uHTInfoField.infoField3.reserved;
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_BASIC_MCS_SET,
+ pDot11f->basicMCSSet, nCfgLen, SIZE_OF_BASIC_MCS_SET);
+
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_ht_info. */
+
+void
+populate_dot11f_ibss_params(tpAniSirGlobal pMac,
+ tDot11fIEIBSSParams *pDot11f,
+ tpPESession psessionEntry)
+{
+ uint32_t val = 0;
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ if (wlan_cfg_get_int(pMac,
+ WNI_CFG_IBSS_ATIM_WIN_SIZE,
+ &val) != eSIR_SUCCESS) {
+ PELOGE(lim_log
+ (pMac, LOGE,
+ FL("could not retrieve IBSS ATIM WIN size"));
+ )
+ }
+ pDot11f->present = 1;
+ /* ATIM duration is always set to 0 */
+ pDot11f->atim = val;
+ }
+
+} /* End populate_dot11f_ibss_params. */
+
+#ifdef ANI_SUPPORT_11H
+tSirRetStatus
+populate_dot11f_measurement_report0(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pReq,
+ tDot11fIEMeasurementReport *pDot11f)
+{
+ pDot11f->token = pReq->measReqIE.measToken;
+ pDot11f->late = 0;
+ pDot11f->incapable = 0;
+ pDot11f->refused = 1;
+ pDot11f->type = SIR_MAC_BASIC_MEASUREMENT_TYPE;
+
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+
+} /* End PopulatedDot11fMeasurementReport0. */
+tSirRetStatus
+populate_dot11f_measurement_report1(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pReq,
+ tDot11fIEMeasurementReport *pDot11f)
+{
+ pDot11f->token = pReq->measReqIE.measToken;
+ pDot11f->late = 0;
+ pDot11f->incapable = 0;
+ pDot11f->refused = 1;
+ pDot11f->type = SIR_MAC_CCA_MEASUREMENT_TYPE;
+ pDot11f->present = 1;
+ return eSIR_SUCCESS;
+} /* End PopulatedDot11fMeasurementReport1. */
+tSirRetStatus
+populate_dot11f_measurement_report2(tpAniSirGlobal pMac,
+ tpSirMacMeasReqActionFrame pReq,
+ tDot11fIEMeasurementReport *pDot11f)
+{
+ pDot11f->token = pReq->measReqIE.measToken;
+ pDot11f->late = 0;
+ pDot11f->incapable = 0;
+ pDot11f->refused = 1;
+ pDot11f->type = SIR_MAC_RPI_MEASUREMENT_TYPE;
+ pDot11f->present = 1;
+ return eSIR_SUCCESS;
+} /* End PopulatedDot11fMeasurementReport2. */
+#endif
+
+void
+populate_dot11f_power_caps(tpAniSirGlobal pMac,
+ tDot11fIEPowerCaps *pCaps,
+ uint8_t nAssocType, tpPESession psessionEntry)
+{
+ if (nAssocType == LIM_REASSOC) {
+ pCaps->minTxPower =
+ psessionEntry->pLimReAssocReq->powerCap.minTxPower;
+ pCaps->maxTxPower =
+ psessionEntry->pLimReAssocReq->powerCap.maxTxPower;
+ } else {
+ pCaps->minTxPower =
+ psessionEntry->pLimJoinReq->powerCap.minTxPower;
+ pCaps->maxTxPower =
+ psessionEntry->pLimJoinReq->powerCap.maxTxPower;
+
+ }
+
+ pCaps->present = 1;
+} /* End populate_dot11f_power_caps. */
+
+tSirRetStatus
+populate_dot11f_power_constraints(tpAniSirGlobal pMac,
+ tDot11fIEPowerConstraints *pDot11f)
+{
+ uint32_t cfg;
+ tSirRetStatus nSirStatus;
+
+ CFG_GET_INT(nSirStatus, pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, cfg);
+
+ pDot11f->localPowerConstraints = (uint8_t) cfg;
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_power_constraints. */
+
+void
+populate_dot11f_qos_caps_ap(tpAniSirGlobal pMac,
+ tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry)
+{
+ pDot11f->count = psessionEntry->gLimEdcaParamSetCount;
+ pDot11f->reserved = 0;
+ pDot11f->txopreq = 0;
+ pDot11f->qreq = 0;
+ pDot11f->qack = 0;
+ pDot11f->present = 1;
+} /* End PopulatedDot11fQOSCaps. */
+
+void
+populate_dot11f_qos_caps_station(tpAniSirGlobal pMac,
+ tDot11fIEQOSCapsStation *pDot11f)
+{
+ uint32_t val = 0;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not retrieve Max SP Length \n"));
+ )
+
+ pDot11f->more_data_ack = 0;
+ pDot11f->max_sp_length = (uint8_t) val;
+ pDot11f->qack = 0;
+
+ if (pMac->lim.gUapsdEnable) {
+ pDot11f->acbe_uapsd =
+ LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask);
+ pDot11f->acbk_uapsd =
+ LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask);
+ pDot11f->acvi_uapsd =
+ LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask);
+ pDot11f->acvo_uapsd =
+ LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask);
+ }
+ pDot11f->present = 1;
+} /* End PopulatedDot11fQOSCaps. */
+
+tSirRetStatus
+populate_dot11f_rsn(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIERSN *pDot11f)
+{
+ uint32_t status;
+ int idx;
+
+ if (pRsnIe->length) {
+ if (0 <= (idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_RSN))) {
+ status = dot11f_unpack_ie_rsn(pMac, pRsnIe->rsnIEdata + idx + 2, /* EID, length */
+ pRsnIe->rsnIEdata[idx + 1],
+ pDot11f);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOGE,
+ FL("Parse failure in PopulateDot11fRS"
+ "N (0x%08x).\n"), status);
+ return eSIR_FAILURE;
+ }
+ dot11f_log(pMac, LOG2,
+ FL("dot11f_unpack_ie_rsn returned 0x%08x in "
+ "populate_dot11f_rsn.\n"), status);
+ }
+
+ }
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_rsn. */
+
+tSirRetStatus populate_dot11f_rsn_opaque(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe,
+ tDot11fIERSNOpaque *pDot11f)
+{
+ int idx;
+
+ if (pRsnIe->length) {
+ if (0 <= (idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_RSN))) {
+ pDot11f->present = 1;
+ pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1];
+ cdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2, /* EID, len */
+ pRsnIe->rsnIEdata[idx + 1]);
+ }
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_rsn_opaque. */
+
+#if defined(FEATURE_WLAN_WAPI)
+
+tSirRetStatus
+populate_dot11f_wapi(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f)
+{
+ uint32_t status;
+ int idx;
+
+ if (pRsnIe->length) {
+ if (0 <= (idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WAPI))) {
+ status = dot11f_unpack_ie_wapi(pMac, pRsnIe->rsnIEdata + idx + 2, /* EID, length */
+ pRsnIe->rsnIEdata[idx + 1],
+ pDot11f);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("Parse failure in populate_dot11f_wapi (0x%08x).\n"),
+ status);
+ return eSIR_FAILURE;
+ }
+ dot11f_log(pMac, LOG2,
+ FL("dot11f_unpack_ie_rsn returned 0x%08x in "
+ "populate_dot11f_wapi.\n"), status);
+ }
+ }
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_wapi. */
+
+tSirRetStatus populate_dot11f_wapi_opaque(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe,
+ tDot11fIEWAPIOpaque *pDot11f)
+{
+ int idx;
+
+ if (pRsnIe->length) {
+ if (0 <= (idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WAPI))) {
+ pDot11f->present = 1;
+ pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1];
+ cdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2, /* EID, len */
+ pRsnIe->rsnIEdata[idx + 1]);
+ }
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_wapi_opaque. */
+
+#endif /* defined(FEATURE_WLAN_WAPI) */
+
+void
+populate_dot11f_ssid(tpAniSirGlobal pMac,
+ tSirMacSSid *pInternal, tDot11fIESSID *pDot11f)
+{
+ pDot11f->present = 1;
+ pDot11f->num_ssid = pInternal->length;
+ if (pInternal->length) {
+ cdf_mem_copy((uint8_t *) pDot11f->ssid,
+ (uint8_t *) &pInternal->ssId, pInternal->length);
+ }
+} /* End populate_dot11f_ssid. */
+
+tSirRetStatus populate_dot11f_ssid2(tpAniSirGlobal pMac, tDot11fIESSID *pDot11f)
+{
+ uint32_t nCfg;
+ tSirRetStatus nSirStatus;
+
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SSID, pDot11f->ssid, nCfg, 32);
+ pDot11f->num_ssid = (uint8_t) nCfg;
+ pDot11f->present = 1;
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_ssid2. */
+
+void
+populate_dot11f_schedule(tSirMacScheduleIE *pSchedule,
+ tDot11fIESchedule *pDot11f)
+{
+ pDot11f->aggregation = pSchedule->info.aggregation;
+ pDot11f->tsid = pSchedule->info.tsid;
+ pDot11f->direction = pSchedule->info.direction;
+ pDot11f->reserved = pSchedule->info.rsvd;
+ pDot11f->service_start_time = pSchedule->svcStartTime;
+ pDot11f->service_interval = pSchedule->svcInterval;
+ pDot11f->max_service_dur = pSchedule->maxSvcDuration;
+ pDot11f->spec_interval = pSchedule->specInterval;
+
+ pDot11f->present = 1;
+} /* End populate_dot11f_schedule. */
+
+void
+populate_dot11f_supp_channels(tpAniSirGlobal pMac,
+ tDot11fIESuppChannels *pDot11f,
+ uint8_t nAssocType, tpPESession psessionEntry)
+{
+ uint8_t i;
+ uint8_t *p;
+
+ if (nAssocType == LIM_REASSOC) {
+ p = (uint8_t *) psessionEntry->pLimReAssocReq->
+ supportedChannels.channelList;
+ pDot11f->num_bands =
+ psessionEntry->pLimReAssocReq->supportedChannels.numChnl;
+ } else {
+ p = (uint8_t *) psessionEntry->pLimJoinReq->supportedChannels.
+ channelList;
+ pDot11f->num_bands =
+ psessionEntry->pLimJoinReq->supportedChannels.numChnl;
+ }
+ for (i = 0U; i < pDot11f->num_bands; ++i, ++p) {
+ pDot11f->bands[i][0] = *p;
+ pDot11f->bands[i][1] = 1;
+ }
+
+ pDot11f->present = 1;
+
+} /* End populate_dot11f_supp_channels. */
+
+tSirRetStatus
+populate_dot11f_supp_rates(tpAniSirGlobal pMac,
+ uint8_t nChannelNum,
+ tDot11fIESuppRates *pDot11f, tpPESession psessionEntry)
+{
+ tSirRetStatus nSirStatus;
+ uint32_t nRates;
+ uint8_t rates[SIR_MAC_MAX_NUMBER_OF_RATES];
+
+ /* Use the operational rates present in session entry whenever nChannelNum is set to OPERATIONAL
+ else use the supported rate set from CFG, which is fixed and does not change dynamically and is used for
+ sending mgmt frames (lile probe req) which need to go out before any session is present.
+ */
+ if (POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum) {
+#if 0
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_OPERATIONAL_RATE_SET,
+ rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES);
+#endif /* TO SUPPORT BT-AMP */
+ if (psessionEntry != NULL) {
+ nRates = psessionEntry->rateSet.numRates;
+ cdf_mem_copy(rates, psessionEntry->rateSet.rate,
+ nRates);
+ } else {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("no session context exists while populating Operational Rate Set\n"));
+ nRates = 0;
+ }
+ } else if (14 >= nChannelNum) {
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11B,
+ rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES);
+ } else {
+ CFG_GET_STR(nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A,
+ rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES);
+ }
+
+ if (0 != nRates) {
+ pDot11f->num_rates = (uint8_t) nRates;
+ cdf_mem_copy(pDot11f->rates, rates, nRates);
+ pDot11f->present = 1;
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_supp_rates. */
+
+/**
+ * populate_dot11f_rates_tdls() - populate supported rates and
+ * extended supported rates IE.
+ * @p_mac gloabl - header.
+ * @p_supp_rates - pointer to supported rates IE
+ * @p_ext_supp_rates - pointer to extended supported rates IE
+ *
+ * This function populates the supported rates and extended supported
+ * rates IE based in the STA capability. If the number of rates
+ * supported is less than MAX_NUM_SUPPORTED_RATES, only supported rates
+ * IE is populated.
+ *
+ * Return: tSirRetStatus eSIR_SUCCESS on Success and eSIR_FAILURE
+ * on failure.
+ */
+
+tSirRetStatus
+populate_dot11f_rates_tdls(tpAniSirGlobal p_mac,
+ tDot11fIESuppRates *p_supp_rates,
+ tDot11fIEExtSuppRates *p_ext_supp_rates)
+{
+ tSirMacRateSet temp_rateset;
+ tSirMacRateSet temp_rateset2;
+ uint32_t val, i;
+ uint32_t self_dot11mode = 0;
+
+ wlan_cfg_get_int(p_mac, WNI_CFG_DOT11_MODE, &self_dot11mode);
+
+ /**
+ * Include 11b rates only when the device configured in
+ * auto, 11a/b/g or 11b_only
+ */
+ if ((self_dot11mode == WNI_CFG_DOT11_MODE_ALL) ||
+ (self_dot11mode == WNI_CFG_DOT11_MODE_11A) ||
+ (self_dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
+ (self_dot11mode == WNI_CFG_DOT11_MODE_11N) ||
+ (self_dot11mode == WNI_CFG_DOT11_MODE_11G) ||
+ (self_dot11mode == WNI_CFG_DOT11_MODE_11B) ) {
+ val = WNI_CFG_SUPPORTED_RATES_11B_LEN;
+ wlan_cfg_get_str(p_mac, WNI_CFG_SUPPORTED_RATES_11B,
+ (uint8_t *)&temp_rateset.rate, &val);
+ temp_rateset.numRates = (uint8_t) val;
+ }
+ else {
+ temp_rateset.numRates = 0;
+ }
+
+ /* Include 11a rates when the device configured in non-11b mode */
+ if (!IS_DOT11_MODE_11B(self_dot11mode)) {
+ val = WNI_CFG_SUPPORTED_RATES_11A_LEN;
+ wlan_cfg_get_str(p_mac, WNI_CFG_SUPPORTED_RATES_11A,
+ (uint8_t *)&temp_rateset2.rate, &val);
+ temp_rateset2.numRates = (uint8_t) val;
+ } else {
+ temp_rateset2.numRates = 0;
+ }
+
+ if ((temp_rateset.numRates + temp_rateset2.numRates) >
+ SIR_MAC_MAX_NUMBER_OF_RATES) {
+ lim_log(p_mac, LOGP, FL("more than %d rates in CFG"),
+ SIR_MAC_MAX_NUMBER_OF_RATES);
+ return eSIR_FAILURE;
+ }
+
+ /**
+ * copy all rates in temp_rateset,
+ * there are SIR_MAC_MAX_NUMBER_OF_RATES rates max
+ */
+ for (i = 0; i < temp_rateset2.numRates; i++)
+ temp_rateset.rate[i + temp_rateset.numRates] =
+ temp_rateset2.rate[i];
+
+ temp_rateset.numRates += temp_rateset2.numRates;
+
+ if (temp_rateset.numRates <= MAX_NUM_SUPPORTED_RATES) {
+ p_supp_rates->num_rates = temp_rateset.numRates;
+ cdf_mem_copy(p_supp_rates->rates, temp_rateset.rate,
+ p_supp_rates->num_rates);
+ p_supp_rates->present = 1;
+ } else { /* Populate extended capability as well */
+ p_supp_rates->num_rates = MAX_NUM_SUPPORTED_RATES;
+ cdf_mem_copy(p_supp_rates->rates, temp_rateset.rate,
+ p_supp_rates->num_rates);
+ p_supp_rates->present = 1;
+
+ p_ext_supp_rates->num_rates = temp_rateset.numRates -
+ MAX_NUM_SUPPORTED_RATES;
+ cdf_mem_copy(p_ext_supp_rates->rates,
+ (uint8_t *)temp_rateset.rate +
+ MAX_NUM_SUPPORTED_RATES,
+ p_ext_supp_rates->num_rates);
+ p_ext_supp_rates->present = 1;
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_rates_tdls */
+
+
+tSirRetStatus
+populate_dot11f_tpc_report(tpAniSirGlobal pMac,
+ tDot11fIETPCReport *pDot11f, tpPESession psessionEntry)
+{
+ uint16_t staid, txPower;
+ tSirRetStatus nSirStatus;
+
+ nSirStatus = lim_get_mgmt_staid(pMac, &staid, psessionEntry);
+ if (eSIR_SUCCESS != nSirStatus) {
+ dot11f_log(pMac, LOG1, FL("Failed to get the STAID in Populat"
+ "eDot11fTPCReport; lim_get_mgmt_staid "
+ "returned status %d.\n"), nSirStatus);
+ return eSIR_FAILURE;
+ }
+ /* FramesToDo: This function was "misplaced" in the move to Gen4_TVM... */
+ /* txPower = halGetRateToPwrValue( pMac, staid, pMac->lim.gLimCurrentChannelId, isBeacon ); */
+ txPower = 0;
+ pDot11f->tx_power = (uint8_t) txPower;
+ pDot11f->link_margin = 0;
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_tpc_report. */
+
+void populate_dot11f_ts_info(tSirMacTSInfo *pInfo, tDot11fFfTSInfo *pDot11f)
+{
+ pDot11f->traffic_type = pInfo->traffic.trafficType;
+ pDot11f->tsid = pInfo->traffic.tsid;
+ pDot11f->direction = pInfo->traffic.direction;
+ pDot11f->access_policy = pInfo->traffic.accessPolicy;
+ pDot11f->aggregation = pInfo->traffic.aggregation;
+ pDot11f->psb = pInfo->traffic.psb;
+ pDot11f->user_priority = pInfo->traffic.userPrio;
+ pDot11f->tsinfo_ack_pol = pInfo->traffic.ackPolicy;
+ pDot11f->schedule = pInfo->schedule.schedule;
+} /* End PopulatedDot11fTSInfo. */
+
+void populate_dot11f_wmm(tpAniSirGlobal pMac,
+ tDot11fIEWMMInfoAp *pInfo,
+ tDot11fIEWMMParams *pParams,
+ tDot11fIEWMMCaps *pCaps, tpPESession psessionEntry)
+{
+ if (psessionEntry->limWmeEnabled) {
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ /* if ( ! sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_WME ) ) */
+ {
+ populate_dot11f_wmm_info_ap(pMac, pInfo,
+ psessionEntry);
+ }
+ } else {
+ {
+ populate_dot11f_wmm_params(pMac, pParams,
+ psessionEntry);
+ }
+
+ if (psessionEntry->limWsmEnabled) {
+ populate_dot11f_wmm_caps(pCaps);
+ }
+ }
+ }
+} /* End populate_dot11f_wmm. */
+
+void populate_dot11f_wmm_caps(tDot11fIEWMMCaps *pCaps)
+{
+ pCaps->version = SIR_MAC_OUI_VERSION_1;
+ pCaps->qack = 0;
+ pCaps->queue_request = 1;
+ pCaps->txop_request = 0;
+ pCaps->more_ack = 0;
+ pCaps->present = 1;
+} /* End PopulateDot11fWmmCaps. */
+
+#ifdef FEATURE_WLAN_ESE
+void populate_dot11f_re_assoc_tspec(tpAniSirGlobal pMac,
+ tDot11fReAssocRequest *pReassoc,
+ tpPESession psessionEntry)
+{
+ uint8_t numTspecs = 0, idx;
+ tTspecInfo *pTspec = NULL;
+
+ numTspecs = psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs;
+ pTspec = &psessionEntry->pLimReAssocReq->eseTspecInfo.tspec[0];
+ pReassoc->num_WMMTSPEC = numTspecs;
+ if (numTspecs) {
+ for (idx = 0; idx < numTspecs; idx++) {
+ populate_dot11f_wmmtspec(&pTspec->tspec,
+ &pReassoc->WMMTSPEC[idx]);
+ pTspec->tspec.mediumTime = 0;
+ pTspec++;
+ }
+ }
+}
+#endif
+
+void populate_dot11f_wmm_info_ap(tpAniSirGlobal pMac, tDot11fIEWMMInfoAp *pInfo,
+ tpPESession psessionEntry)
+{
+ pInfo->version = SIR_MAC_OUI_VERSION_1;
+
+ /* WMM Specification 3.1.3, 3.2.3
+ * An IBSS staion shall always use its default WMM parameters.
+ */
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ pInfo->param_set_count = 0;
+ pInfo->uapsd = 0;
+ } else {
+ pInfo->param_set_count =
+ (0xf & psessionEntry->gLimEdcaParamSetCount);
+ if (LIM_IS_AP_ROLE(psessionEntry)) {
+ pInfo->uapsd = (0x1 & psessionEntry->apUapsdEnable);
+ } else
+ pInfo->uapsd = (0x1 & pMac->lim.gUapsdEnable);
+ }
+ pInfo->present = 1;
+}
+
+void populate_dot11f_wmm_info_station_per_session(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tDot11fIEWMMInfoStation *pInfo)
+{
+ uint32_t val = 0;
+
+ pInfo->version = SIR_MAC_OUI_VERSION_1;
+ pInfo->acvo_uapsd =
+ LIM_UAPSD_GET(ACVO, psessionEntry->gUapsdPerAcBitmask);
+ pInfo->acvi_uapsd =
+ LIM_UAPSD_GET(ACVI, psessionEntry->gUapsdPerAcBitmask);
+ pInfo->acbk_uapsd =
+ LIM_UAPSD_GET(ACBK, psessionEntry->gUapsdPerAcBitmask);
+ pInfo->acbe_uapsd =
+ LIM_UAPSD_GET(ACBE, psessionEntry->gUapsdPerAcBitmask);
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS)
+ PELOGE(lim_log
+ (pMac, LOGE, FL("could not retrieve Max SP Length \n"));
+ )
+
+ pInfo->max_sp_length = (uint8_t) val;
+ pInfo->present = 1;
+}
+
+void populate_dot11f_wmm_params(tpAniSirGlobal pMac,
+ tDot11fIEWMMParams *pParams,
+ tpPESession psessionEntry)
+{
+ pParams->version = SIR_MAC_OUI_VERSION_1;
+
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ pParams->qosInfo =
+ (psessionEntry->
+ apUapsdEnable << 7) | ((uint8_t) (0x0f & psessionEntry->
+ gLimEdcaParamSetCount));
+ else
+ pParams->qosInfo =
+ (pMac->lim.
+ gUapsdEnable << 7) | ((uint8_t) (0x0f & psessionEntry->
+ gLimEdcaParamSetCount));
+
+ /* Fill each EDCA parameter set in order: be, bk, vi, vo */
+ pParams->acbe_aifsn =
+ (0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn));
+ pParams->acbe_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm);
+ pParams->acbe_aci = (0x3 & SIR_MAC_EDCAACI_BESTEFFORT);
+ pParams->acbe_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min);
+ pParams->acbe_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max);
+ pParams->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit;
+
+ pParams->acbk_aifsn =
+ (0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn));
+ pParams->acbk_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm);
+ pParams->acbk_aci = (0x3 & SIR_MAC_EDCAACI_BACKGROUND);
+ pParams->acbk_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min);
+ pParams->acbk_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max);
+ pParams->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit;
+
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ pParams->acvi_aifsn =
+ (0xf & psessionEntry->gLimEdcaParamsBC[2].aci.aifsn);
+ else
+ pParams->acvi_aifsn =
+ (0xf &
+ SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn));
+
+ pParams->acvi_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm);
+ pParams->acvi_aci = (0x3 & SIR_MAC_EDCAACI_VIDEO);
+ pParams->acvi_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min);
+ pParams->acvi_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max);
+ pParams->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit;
+
+ if (LIM_IS_AP_ROLE(psessionEntry))
+ pParams->acvo_aifsn =
+ (0xf & psessionEntry->gLimEdcaParamsBC[3].aci.aifsn);
+ else
+ pParams->acvo_aifsn =
+ (0xf &
+ SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn));
+
+ pParams->acvo_acm = (0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm);
+ pParams->acvo_aci = (0x3 & SIR_MAC_EDCAACI_VOICE);
+ pParams->acvo_acwmin =
+ (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min);
+ pParams->acvo_acwmax =
+ (0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max);
+ pParams->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit;
+
+ pParams->present = 1;
+
+} /* End populate_dot11f_wmm_params. */
+
+void populate_dot11f_wmm_schedule(tSirMacScheduleIE *pSchedule,
+ tDot11fIEWMMSchedule *pDot11f)
+{
+ pDot11f->version = 1;
+ pDot11f->aggregation = pSchedule->info.aggregation;
+ pDot11f->tsid = pSchedule->info.tsid;
+ pDot11f->direction = pSchedule->info.direction;
+ pDot11f->reserved = pSchedule->info.rsvd;
+ pDot11f->service_start_time = pSchedule->svcStartTime;
+ pDot11f->service_interval = pSchedule->svcInterval;
+ pDot11f->max_service_dur = pSchedule->maxSvcDuration;
+ pDot11f->spec_interval = pSchedule->specInterval;
+
+ pDot11f->present = 1;
+} /* End populate_dot11f_wmm_schedule. */
+
+tSirRetStatus
+populate_dot11f_wpa(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe, tDot11fIEWPA *pDot11f)
+{
+ uint32_t status;
+ int idx;
+
+ if (pRsnIe->length) {
+ if (0 <= (idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WPA))) {
+ status = dot11f_unpack_ie_wpa(pMac, pRsnIe->rsnIEdata + idx + 2 + 4, /* EID, length, OUI */
+ pRsnIe->rsnIEdata[idx + 1] - 4, /* OUI */
+ pDot11f);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOGE,
+ FL("Parse failure in PopulateDot11fWP"
+ "A (0x%08x).\n"), status);
+ return eSIR_FAILURE;
+ }
+ }
+ }
+
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_wpa. */
+
+tSirRetStatus populate_dot11f_wpa_opaque(tpAniSirGlobal pMac,
+ tpSirRSNie pRsnIe,
+ tDot11fIEWPAOpaque *pDot11f)
+{
+ int idx;
+
+ if (pRsnIe->length) {
+ if (0 <= (idx = find_ie_location(pMac, pRsnIe, DOT11F_EID_WPA))) {
+ pDot11f->present = 1;
+ pDot11f->num_data = pRsnIe->rsnIEdata[idx + 1] - 4;
+ cdf_mem_copy(pDot11f->data, pRsnIe->rsnIEdata + idx + 2 + 4, /* EID, len, OUI */
+ pRsnIe->rsnIEdata[idx + 1] - 4); /* OUI */
+ }
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_wpa_opaque. */
+
+/* ////////////////////////////////////////////////////////////////////// */
+
+tSirRetStatus
+sir_convert_probe_req_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tpSirProbeReq pProbeReq)
+{
+ uint32_t status;
+ tDot11fProbeRequest pr;
+
+ /* Ok, zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pProbeReq, sizeof(tSirProbeReq), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_probe_request(pMac, pFrame, nFrame, &pr);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to parse a Probe Request (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Probe Request (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fProbeRequestto' a 'tSirProbeReq'... */
+ if (!pr.SSID.present) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Mandatory IE SSID not present!\n"));
+ )
+ } else {
+ pProbeReq->ssidPresent = 1;
+ convert_ssid(pMac, &pProbeReq->ssId, &pr.SSID);
+ }
+
+ if (!pr.SuppRates.present) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Mandatory IE Supported Rates not present!\n"));
+ )
+ return eSIR_FAILURE;
+ } else {
+ pProbeReq->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pProbeReq->supportedRates,
+ &pr.SuppRates);
+ }
+
+ if (pr.ExtSuppRates.present) {
+ pProbeReq->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pProbeReq->extendedRates,
+ &pr.ExtSuppRates);
+ }
+
+ if (pr.HTCaps.present) {
+ cdf_mem_copy(&pProbeReq->HTCaps, &pr.HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (pr.WscProbeReq.present) {
+ pProbeReq->wscIePresent = 1;
+ memcpy(&pProbeReq->probeReqWscIeInfo, &pr.WscProbeReq,
+ sizeof(tDot11fIEWscProbeReq));
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pr.VHTCaps.present) {
+ cdf_mem_copy(&pProbeReq->VHTCaps, &pr.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+#endif
+
+ if (pr.P2PProbeReq.present) {
+ pProbeReq->p2pIePresent = 1;
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_probe_req_frame2_struct. */
+
+tSirRetStatus sir_convert_probe_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame,
+ tpSirProbeRespBeacon pProbeResp)
+{
+ uint32_t status;
+ tDot11fProbeResponse *pr;
+
+ /* Ok, zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pProbeResp, sizeof(tSirProbeRespBeacon), 0);
+
+ pr = cdf_mem_malloc(sizeof(tDot11fProbeResponse));
+ if (NULL == pr) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory\n"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set((uint8_t *) pr, sizeof(tDot11fProbeResponse), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_probe_response(pMac, pFrame, nFrame, pr);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to parse a Probe Response (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ cdf_mem_free(pr);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Probe Response (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fProbeResponse' to a 'tSirProbeRespBeacon'... */
+
+ /* Timestamp */
+ cdf_mem_copy((uint8_t *) pProbeResp->timeStamp,
+ (uint8_t *) &pr->TimeStamp, sizeof(tSirMacTimeStamp));
+
+ /* Beacon Interval */
+ pProbeResp->beaconInterval = pr->BeaconInterval.interval;
+
+ /* Capabilities */
+ pProbeResp->capabilityInfo.ess = pr->Capabilities.ess;
+ pProbeResp->capabilityInfo.ibss = pr->Capabilities.ibss;
+ pProbeResp->capabilityInfo.cfPollable = pr->Capabilities.cfPollable;
+ pProbeResp->capabilityInfo.cfPollReq = pr->Capabilities.cfPollReq;
+ pProbeResp->capabilityInfo.privacy = pr->Capabilities.privacy;
+ pProbeResp->capabilityInfo.shortPreamble =
+ pr->Capabilities.shortPreamble;
+ pProbeResp->capabilityInfo.pbcc = pr->Capabilities.pbcc;
+ pProbeResp->capabilityInfo.channelAgility =
+ pr->Capabilities.channelAgility;
+ pProbeResp->capabilityInfo.spectrumMgt = pr->Capabilities.spectrumMgt;
+ pProbeResp->capabilityInfo.qos = pr->Capabilities.qos;
+ pProbeResp->capabilityInfo.shortSlotTime =
+ pr->Capabilities.shortSlotTime;
+ pProbeResp->capabilityInfo.apsd = pr->Capabilities.apsd;
+ pProbeResp->capabilityInfo.rrm = pr->Capabilities.rrm;
+ pProbeResp->capabilityInfo.dsssOfdm = pr->Capabilities.dsssOfdm;
+ pProbeResp->capabilityInfo.delayedBA = pr->Capabilities.delayedBA;
+ pProbeResp->capabilityInfo.immediateBA = pr->Capabilities.immediateBA;
+
+ if (!pr->SSID.present) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Mandatory IE SSID not present!\n"));
+ )
+ } else {
+ pProbeResp->ssidPresent = 1;
+ convert_ssid(pMac, &pProbeResp->ssId, &pr->SSID);
+ }
+
+ if (!pr->SuppRates.present) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Mandatory IE Supported Rates not present!\n"));
+ )
+ } else {
+ pProbeResp->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pProbeResp->supportedRates,
+ &pr->SuppRates);
+ }
+
+ if (pr->ExtSuppRates.present) {
+ pProbeResp->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pProbeResp->extendedRates,
+ &pr->ExtSuppRates);
+ }
+
+ if (pr->CFParams.present) {
+ pProbeResp->cfPresent = 1;
+ convert_cf_params(pMac, &pProbeResp->cfParamSet, &pr->CFParams);
+ }
+
+ if (pr->Country.present) {
+ pProbeResp->countryInfoPresent = 1;
+ convert_country(pMac, &pProbeResp->countryInfoParam,
+ &pr->Country);
+ }
+
+ if (pr->EDCAParamSet.present) {
+ pProbeResp->edcaPresent = 1;
+ convert_edca_param(pMac, &pProbeResp->edcaParams,
+ &pr->EDCAParamSet);
+ }
+
+ if (pr->ChanSwitchAnn.present) {
+ pProbeResp->channelSwitchPresent = 1;
+ cdf_mem_copy(&pProbeResp->channelSwitchIE, &pr->ChanSwitchAnn,
+ sizeof(pProbeResp->channelSwitchIE));
+ }
+
+ if (pr->ext_chan_switch_ann.present) {
+ pProbeResp->ext_chan_switch_present = 1;
+ cdf_mem_copy(&pProbeResp->ext_chan_switch,
+ &pr->ext_chan_switch_ann,
+ sizeof(tDot11fIEext_chan_switch_ann));
+ }
+
+ if (pr->sec_chan_offset_ele.present) {
+ pProbeResp->sec_chan_offset_present = 1;
+ cdf_mem_copy(&pProbeResp->sec_chan_offset,
+ &pr->sec_chan_offset_ele,
+ sizeof(pProbeResp->sec_chan_offset));
+ }
+
+ if (pr->TPCReport.present) {
+ pProbeResp->tpcReportPresent = 1;
+ cdf_mem_copy(&pProbeResp->tpcReport, &pr->TPCReport,
+ sizeof(tDot11fIETPCReport));
+ }
+
+ if (pr->PowerConstraints.present) {
+ pProbeResp->powerConstraintPresent = 1;
+ cdf_mem_copy(&pProbeResp->localPowerConstraint,
+ &pr->PowerConstraints,
+ sizeof(tDot11fIEPowerConstraints));
+ }
+
+ if (pr->Quiet.present) {
+ pProbeResp->quietIEPresent = 1;
+ cdf_mem_copy(&pProbeResp->quietIE, &pr->Quiet,
+ sizeof(tDot11fIEQuiet));
+ }
+
+ if (pr->HTCaps.present) {
+ cdf_mem_copy(&pProbeResp->HTCaps, &pr->HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (pr->HTInfo.present) {
+ cdf_mem_copy(&pProbeResp->HTInfo, &pr->HTInfo,
+ sizeof(tDot11fIEHTInfo));
+ }
+
+ if (pr->DSParams.present) {
+ pProbeResp->dsParamsPresent = 1;
+ pProbeResp->channelNumber = pr->DSParams.curr_channel;
+ } else if (pr->HTInfo.present) {
+ pProbeResp->channelNumber = pr->HTInfo.primaryChannel;
+ }
+
+ if (pr->RSNOpaque.present) {
+ pProbeResp->rsnPresent = 1;
+ convert_rsn_opaque(pMac, &pProbeResp->rsn, &pr->RSNOpaque);
+ }
+
+ if (pr->WPA.present) {
+ pProbeResp->wpaPresent = 1;
+ convert_wpa(pMac, &pProbeResp->wpa, &pr->WPA);
+ }
+
+ if (pr->WMMParams.present) {
+ pProbeResp->wmeEdcaPresent = 1;
+ convert_wmm_params(pMac, &pProbeResp->edcaParams, &pr->WMMParams);
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("WMM Parameter present in Probe Response Frame!\n"));
+ __print_wmm_params(pMac, &pr->WMMParams);
+ )
+ }
+
+ if (pr->WMMInfoAp.present) {
+ pProbeResp->wmeInfoPresent = 1;
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL
+ ("WMM Information Element present in Probe Response Frame!\n"));
+ )
+ }
+
+ if (pr->WMMCaps.present) {
+ pProbeResp->wsmCapablePresent = 1;
+ }
+
+ if (pr->ERPInfo.present) {
+ pProbeResp->erpPresent = 1;
+ convert_erp_info(pMac, &pProbeResp->erpIEInfo, &pr->ERPInfo);
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (pr->MobilityDomain.present) {
+ /* MobilityDomain */
+ pProbeResp->mdiePresent = 1;
+ cdf_mem_copy((uint8_t *) &(pProbeResp->mdie[0]),
+ (uint8_t *) &(pr->MobilityDomain.MDID),
+ sizeof(uint16_t));
+ pProbeResp->mdie[2] =
+ ((pr->MobilityDomain.overDSCap << 0) | (pr->MobilityDomain.
+ resourceReqCap <<
+ 1));
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG2, FL("mdie=%02x%02x%02x\n"),
+ (unsigned int)pProbeResp->mdie[0],
+ (unsigned int)pProbeResp->mdie[1],
+ (unsigned int)pProbeResp->mdie[2]);
+#endif
+ }
+#endif
+
+#if defined FEATURE_WLAN_ESE
+ if (pr->ESEVersion.present)
+ pProbeResp->is_ese_ver_ie_present = 1;
+ if (pr->QBSSLoad.present) {
+ cdf_mem_copy(&pProbeResp->QBSSLoad, &pr->QBSSLoad,
+ sizeof(tDot11fIEQBSSLoad));
+ }
+#endif
+ if (pr->P2PProbeRes.present) {
+ cdf_mem_copy(&pProbeResp->P2PProbeRes, &pr->P2PProbeRes,
+ sizeof(tDot11fIEP2PProbeRes));
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pr->VHTCaps.present) {
+ cdf_mem_copy(&pProbeResp->VHTCaps, &pr->VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (pr->VHTOperation.present) {
+ cdf_mem_copy(&pProbeResp->VHTOperation, &pr->VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ }
+ if (pr->VHTExtBssLoad.present) {
+ cdf_mem_copy(&pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad,
+ sizeof(tDot11fIEVHTExtBssLoad));
+ }
+#endif
+ pProbeResp->Vendor1IEPresent = pr->Vendor1IE.present;
+ pProbeResp->Vendor3IEPresent = pr->Vendor3IE.present;
+
+ pProbeResp->vendor2_ie.present = pr->vendor2_ie.present;
+ if (pr->vendor2_ie.present) {
+ pProbeResp->vendor2_ie.type = pr->vendor2_ie.type;
+ pProbeResp->vendor2_ie.sub_type = pr->vendor2_ie.sub_type;
+ }
+ if (pr->vendor2_ie.VHTCaps.present) {
+ cdf_mem_copy(&pProbeResp->vendor2_ie.VHTCaps,
+ &pr->vendor2_ie.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (pr->vendor2_ie.VHTOperation.present) {
+ cdf_mem_copy(&pProbeResp->vendor2_ie.VHTOperation,
+ &pr->vendor2_ie.VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ }
+ cdf_mem_free(pr);
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_probe_frame2_struct. */
+
+tSirRetStatus
+sir_convert_assoc_req_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tpSirAssocReq pAssocReq)
+{
+ tDot11fAssocRequest *ar;
+ uint32_t status;
+
+ ar = cdf_mem_malloc(sizeof(tDot11fAssocRequest));
+ if (NULL == ar) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory\n"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pAssocReq, sizeof(tSirAssocReq), 0);
+ cdf_mem_set((uint8_t *) ar, sizeof(tDot11fAssocRequest), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_assoc_request(pMac, pFrame, nFrame, ar);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to parse an Association Request (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ cdf_mem_free(ar);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking an Assoication Request (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fAssocRequest' to a 'tSirAssocReq'... */
+
+ /* make sure this is seen as an assoc request */
+ pAssocReq->reassocRequest = 0;
+
+ /* Capabilities */
+ pAssocReq->capabilityInfo.ess = ar->Capabilities.ess;
+ pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss;
+ pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable;
+ pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq;
+ pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy;
+ pAssocReq->capabilityInfo.shortPreamble =
+ ar->Capabilities.shortPreamble;
+ pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc;
+ pAssocReq->capabilityInfo.channelAgility =
+ ar->Capabilities.channelAgility;
+ pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt;
+ pAssocReq->capabilityInfo.qos = ar->Capabilities.qos;
+ pAssocReq->capabilityInfo.shortSlotTime =
+ ar->Capabilities.shortSlotTime;
+ pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd;
+ pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm;
+ pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm;
+ pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA;
+ pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA;
+
+ /* Listen Interval */
+ pAssocReq->listenInterval = ar->ListenInterval.interval;
+
+ /* SSID */
+ if (ar->SSID.present) {
+ pAssocReq->ssidPresent = 1;
+ convert_ssid(pMac, &pAssocReq->ssId, &ar->SSID);
+ }
+ /* Supported Rates */
+ if (ar->SuppRates.present) {
+ pAssocReq->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pAssocReq->supportedRates,
+ &ar->SuppRates);
+ }
+ /* Extended Supported Rates */
+ if (ar->ExtSuppRates.present) {
+ pAssocReq->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pAssocReq->extendedRates,
+ &ar->ExtSuppRates);
+ }
+ /* QOS Capabilities: */
+ if (ar->QOSCapsStation.present) {
+ pAssocReq->qosCapabilityPresent = 1;
+ convert_qos_caps_station(pMac, &pAssocReq->qosCapability,
+ &ar->QOSCapsStation);
+ }
+ /* WPA */
+ if (ar->WPAOpaque.present) {
+ pAssocReq->wpaPresent = 1;
+ convert_wpa_opaque(pMac, &pAssocReq->wpa, &ar->WPAOpaque);
+ }
+#ifdef FEATURE_WLAN_WAPI
+ if (ar->WAPIOpaque.present) {
+ pAssocReq->wapiPresent = 1;
+ convert_wapi_opaque(pMac, &pAssocReq->wapi, &ar->WAPIOpaque);
+ }
+#endif
+ /* RSN */
+ if (ar->RSNOpaque.present) {
+ pAssocReq->rsnPresent = 1;
+ convert_rsn_opaque(pMac, &pAssocReq->rsn, &ar->RSNOpaque);
+ }
+ /* WSC IE */
+ if (ar->WscIEOpaque.present) {
+ pAssocReq->addIEPresent = 1;
+ convert_wsc_opaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque);
+ }
+
+ if (ar->P2PIEOpaque.present) {
+ pAssocReq->addIEPresent = 1;
+ convert_p2p_opaque(pMac, &pAssocReq->addIE, &ar->P2PIEOpaque);
+ }
+#ifdef WLAN_FEATURE_WFD
+ if (ar->WFDIEOpaque.present) {
+ pAssocReq->addIEPresent = 1;
+ convert_wfd_opaque(pMac, &pAssocReq->addIE, &ar->WFDIEOpaque);
+ }
+#endif
+
+ /* Power Capabilities */
+ if (ar->PowerCaps.present) {
+ pAssocReq->powerCapabilityPresent = 1;
+ convert_power_caps(pMac, &pAssocReq->powerCapability,
+ &ar->PowerCaps);
+ }
+ /* Supported Channels */
+ if (ar->SuppChannels.present) {
+ pAssocReq->supportedChannelsPresent = 1;
+ convert_supp_channels(pMac, &pAssocReq->supportedChannels,
+ &ar->SuppChannels);
+ }
+
+ if (ar->HTCaps.present) {
+ cdf_mem_copy(&pAssocReq->HTCaps, &ar->HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (ar->WMMInfoStation.present) {
+ pAssocReq->wmeInfoPresent = 1;
+ cdf_mem_copy(&pAssocReq->WMMInfoStation, &ar->WMMInfoStation,
+ sizeof(tDot11fIEWMMInfoStation));
+
+ }
+
+ if (ar->WMMCaps.present)
+ pAssocReq->wsmCapablePresent = 1;
+
+ if (!pAssocReq->ssidPresent) {
+ PELOG2(lim_log
+ (pMac, LOG2, FL("Received Assoc without SSID IE.\n"));
+ )
+ cdf_mem_free(ar);
+ return eSIR_FAILURE;
+ }
+
+ if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) {
+ PELOG2(lim_log
+ (pMac, LOG2,
+ FL("Received Assoc without supp rate IE.\n"));
+ )
+ cdf_mem_free(ar);
+ return eSIR_FAILURE;
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (ar->VHTCaps.present) {
+ cdf_mem_copy(&pAssocReq->VHTCaps, &ar->VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ lim_log(pMac, LOGW, FL("Received Assoc Req with VHT Cap\n"));
+ lim_log_vht_cap(pMac, &pAssocReq->VHTCaps);
+ }
+ if (ar->OperatingMode.present) {
+ cdf_mem_copy(&pAssocReq->operMode, &ar->OperatingMode,
+ sizeof(tDot11fIEOperatingMode));
+ lim_log(pMac, LOGW,
+ FL("Received Assoc Req with Operating Mode IE\n"));
+ lim_log_operating_mode(pMac, &pAssocReq->operMode);
+ }
+#endif
+ if (ar->ExtCap.present) {
+ struct s_ext_cap *ext_cap;
+ cdf_mem_copy(&pAssocReq->ExtCap.bytes, &ar->ExtCap.bytes,
+ ar->ExtCap.num_bytes);
+
+ ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes;
+ lim_log(pMac, LOG1,
+ FL("timingMeas: %d, finetimingMeas Init: %d, Resp: %d"),
+ ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+ ext_cap->fine_time_meas_responder);
+ }
+ cdf_mem_free(ar);
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_assoc_req_frame2_struct. */
+
+tSirRetStatus
+sir_convert_assoc_resp_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tpSirAssocRsp pAssocRsp)
+{
+ static tDot11fAssocResponse ar;
+ uint32_t status;
+ uint8_t cnt = 0;
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pAssocRsp, sizeof(tSirAssocRsp), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_assoc_response(pMac, pFrame, nFrame, &ar);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to parse an Association Response (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking an Association Response (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fAssocResponse' a 'tSirAssocRsp'... */
+
+ /* Capabilities */
+ pAssocRsp->capabilityInfo.ess = ar.Capabilities.ess;
+ pAssocRsp->capabilityInfo.ibss = ar.Capabilities.ibss;
+ pAssocRsp->capabilityInfo.cfPollable = ar.Capabilities.cfPollable;
+ pAssocRsp->capabilityInfo.cfPollReq = ar.Capabilities.cfPollReq;
+ pAssocRsp->capabilityInfo.privacy = ar.Capabilities.privacy;
+ pAssocRsp->capabilityInfo.shortPreamble = ar.Capabilities.shortPreamble;
+ pAssocRsp->capabilityInfo.pbcc = ar.Capabilities.pbcc;
+ pAssocRsp->capabilityInfo.channelAgility =
+ ar.Capabilities.channelAgility;
+ pAssocRsp->capabilityInfo.spectrumMgt = ar.Capabilities.spectrumMgt;
+ pAssocRsp->capabilityInfo.qos = ar.Capabilities.qos;
+ pAssocRsp->capabilityInfo.shortSlotTime = ar.Capabilities.shortSlotTime;
+ pAssocRsp->capabilityInfo.apsd = ar.Capabilities.apsd;
+ pAssocRsp->capabilityInfo.rrm = ar.Capabilities.rrm;
+ pAssocRsp->capabilityInfo.dsssOfdm = ar.Capabilities.dsssOfdm;
+ pAssocRsp->capabilityInfo.delayedBA = ar.Capabilities.delayedBA;
+ pAssocRsp->capabilityInfo.immediateBA = ar.Capabilities.immediateBA;
+
+ pAssocRsp->statusCode = ar.Status.status;
+ pAssocRsp->aid = ar.AID.associd;
+#ifdef WLAN_FEATURE_11W
+ if (ar.TimeoutInterval.present) {
+ pAssocRsp->TimeoutInterval.present = 1;
+ pAssocRsp->TimeoutInterval.timeoutType =
+ ar.TimeoutInterval.timeoutType;
+ pAssocRsp->TimeoutInterval.timeoutValue =
+ ar.TimeoutInterval.timeoutValue;
+ }
+#endif
+
+ if (!ar.SuppRates.present) {
+ pAssocRsp->suppRatesPresent = 0;
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Mandatory IE Supported Rates not present!\n"));
+ )
+ } else {
+ pAssocRsp->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pAssocRsp->supportedRates,
+ &ar.SuppRates);
+ }
+
+ if (ar.ExtSuppRates.present) {
+ pAssocRsp->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pAssocRsp->extendedRates,
+ &ar.ExtSuppRates);
+ }
+
+ if (ar.EDCAParamSet.present) {
+ pAssocRsp->edcaPresent = 1;
+ convert_edca_param(pMac, &pAssocRsp->edca, &ar.EDCAParamSet);
+ }
+
+ if (ar.WMMParams.present) {
+ pAssocRsp->wmeEdcaPresent = 1;
+ convert_wmm_params(pMac, &pAssocRsp->edca, &ar.WMMParams);
+ lim_log(pMac, LOG1, FL("Received Assoc Resp with WMM Param"));
+ __print_wmm_params(pMac, &ar.WMMParams);
+ }
+
+ if (ar.HTCaps.present) {
+ lim_log(pMac, LOG1, FL("Received Assoc Resp with HT Cap"));
+ cdf_mem_copy(&pAssocRsp->HTCaps, &ar.HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (ar.HTInfo.present) {
+ lim_log(pMac, LOG1, FL("Received Assoc Resp with HT Info"));
+ cdf_mem_copy(&pAssocRsp->HTInfo, &ar.HTInfo,
+ sizeof(tDot11fIEHTInfo));
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (ar.MobilityDomain.present) {
+ /* MobilityDomain */
+ pAssocRsp->mdiePresent = 1;
+ cdf_mem_copy((uint8_t *) &(pAssocRsp->mdie[0]),
+ (uint8_t *) &(ar.MobilityDomain.MDID),
+ sizeof(uint16_t));
+ pAssocRsp->mdie[2] =
+ ((ar.MobilityDomain.overDSCap << 0) | (ar.MobilityDomain.
+ resourceReqCap <<
+ 1));
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1, FL("new mdie=%02x%02x%02x"),
+ (unsigned int)pAssocRsp->mdie[0],
+ (unsigned int)pAssocRsp->mdie[1],
+ (unsigned int)pAssocRsp->mdie[2]);
+#endif
+ }
+
+ if (ar.FTInfo.present) {
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(pMac, LOG1, FL("FT Info present %d %d %d"),
+ ar.FTInfo.R0KH_ID.num_PMK_R0_ID,
+ ar.FTInfo.R0KH_ID.present, ar.FTInfo.R1KH_ID.present);
+#endif
+ pAssocRsp->ftinfoPresent = 1;
+ cdf_mem_copy(&pAssocRsp->FTInfo, &ar.FTInfo,
+ sizeof(tDot11fIEFTInfo));
+ }
+#endif
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (ar.num_RICDataDesc) {
+ for (cnt = 0; cnt < ar.num_RICDataDesc; cnt++) {
+ if (ar.RICDataDesc[cnt].present) {
+ cdf_mem_copy(&pAssocRsp->RICData[cnt],
+ &ar.RICDataDesc[cnt],
+ sizeof(tDot11fIERICDataDesc));
+ }
+ }
+ pAssocRsp->num_RICData = ar.num_RICDataDesc;
+ pAssocRsp->ricPresent = true;
+ }
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ if (ar.num_WMMTSPEC) {
+ pAssocRsp->num_tspecs = ar.num_WMMTSPEC;
+ for (cnt = 0; cnt < ar.num_WMMTSPEC; cnt++) {
+ cdf_mem_copy(&pAssocRsp->TSPECInfo[cnt],
+ &ar.WMMTSPEC[cnt],
+ (sizeof(tDot11fIEWMMTSPEC) *
+ ar.num_WMMTSPEC));
+ }
+ pAssocRsp->tspecPresent = true;
+ }
+
+ if (ar.ESETrafStrmMet.present) {
+ pAssocRsp->tsmPresent = 1;
+ cdf_mem_copy(&pAssocRsp->tsmIE.tsid,
+ &ar.ESETrafStrmMet.tsid, sizeof(tSirMacESETSMIE));
+ }
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+ if (ar.VHTCaps.present) {
+ cdf_mem_copy(&pAssocRsp->VHTCaps, &ar.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ lim_log(pMac, LOG1, FL("Received Assoc Response with VHT Cap"));
+ lim_log_vht_cap(pMac, &pAssocRsp->VHTCaps);
+ }
+ if (ar.VHTOperation.present) {
+ cdf_mem_copy(&pAssocRsp->VHTOperation, &ar.VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ lim_log(pMac, LOG1,
+ FL("Received Assoc Response with VHT Operation"));
+ lim_log_vht_operation(pMac, &pAssocRsp->VHTOperation);
+ }
+#endif
+
+ if (ar.ExtCap.present) {
+ struct s_ext_cap *ext_cap;
+ cdf_mem_copy(&pAssocRsp->ExtCap.bytes, &ar.ExtCap.bytes,
+ ar.ExtCap.num_bytes);
+
+ ext_cap = (struct s_ext_cap *)&pAssocRsp->ExtCap.bytes;
+ lim_log(pMac, LOG1,
+ FL("timingMeas: %d, finetimingMeas Init: %d, Resp: %d"),
+ ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+ ext_cap->fine_time_meas_responder);
+ }
+
+ if (ar.QosMapSet.present) {
+ pAssocRsp->QosMapSet.present = 1;
+ convert_qos_mapset_frame(pMac, &pAssocRsp->QosMapSet,
+ &ar.QosMapSet);
+ lim_log(pMac, LOG1,
+ FL("Received Assoc Response with Qos Map Set"));
+ lim_log_qos_map_set(pMac, &pAssocRsp->QosMapSet);
+ }
+
+ pAssocRsp->vendor2_ie.present = ar.vendor2_ie.present;
+ if (ar.vendor2_ie.present) {
+ pAssocRsp->vendor2_ie.type = ar.vendor2_ie.type;
+ pAssocRsp->vendor2_ie.sub_type = ar.vendor2_ie.sub_type;
+ }
+
+ if (ar.vendor2_ie.VHTCaps.present) {
+ cdf_mem_copy(&pAssocRsp->vendor2_ie.VHTCaps,
+ &ar.vendor2_ie.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ lim_log(pMac, LOG1,
+ FL("Received Assoc Response with Vendor specific VHT Cap"));
+ lim_log_vht_cap(pMac, &pAssocRsp->VHTCaps);
+ }
+ if (ar.vendor2_ie.VHTOperation.present) {
+ cdf_mem_copy(&pAssocRsp->vendor2_ie.VHTOperation,
+ &ar.vendor2_ie.VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ lim_log(pMac, LOG1,
+ FL("Received Assoc Response with Vendor specific VHT Oper"));
+ lim_log_vht_operation(pMac, &pAssocRsp->VHTOperation);
+ }
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_assoc_resp_frame2_struct. */
+
+tSirRetStatus
+sir_convert_reassoc_req_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tpSirAssocReq pAssocReq)
+{
+ static tDot11fReAssocRequest ar;
+ uint32_t status;
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pAssocReq, sizeof(tSirAssocReq), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_re_assoc_request(pMac, pFrame, nFrame, &ar);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to parse a Re-association Request (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fReAssocRequest' to a 'tSirAssocReq'... */
+
+ /* make sure this is seen as a re-assoc request */
+ pAssocReq->reassocRequest = 1;
+
+ /* Capabilities */
+ pAssocReq->capabilityInfo.ess = ar.Capabilities.ess;
+ pAssocReq->capabilityInfo.ibss = ar.Capabilities.ibss;
+ pAssocReq->capabilityInfo.cfPollable = ar.Capabilities.cfPollable;
+ pAssocReq->capabilityInfo.cfPollReq = ar.Capabilities.cfPollReq;
+ pAssocReq->capabilityInfo.privacy = ar.Capabilities.privacy;
+ pAssocReq->capabilityInfo.shortPreamble = ar.Capabilities.shortPreamble;
+ pAssocReq->capabilityInfo.pbcc = ar.Capabilities.pbcc;
+ pAssocReq->capabilityInfo.channelAgility =
+ ar.Capabilities.channelAgility;
+ pAssocReq->capabilityInfo.spectrumMgt = ar.Capabilities.spectrumMgt;
+ pAssocReq->capabilityInfo.qos = ar.Capabilities.qos;
+ pAssocReq->capabilityInfo.shortSlotTime = ar.Capabilities.shortSlotTime;
+ pAssocReq->capabilityInfo.apsd = ar.Capabilities.apsd;
+ pAssocReq->capabilityInfo.rrm = ar.Capabilities.rrm;
+ pAssocReq->capabilityInfo.dsssOfdm = ar.Capabilities.dsssOfdm;
+ pAssocReq->capabilityInfo.delayedBA = ar.Capabilities.delayedBA;
+ pAssocReq->capabilityInfo.immediateBA = ar.Capabilities.immediateBA;
+
+ /* Listen Interval */
+ pAssocReq->listenInterval = ar.ListenInterval.interval;
+
+ /* SSID */
+ if (ar.SSID.present) {
+ pAssocReq->ssidPresent = 1;
+ convert_ssid(pMac, &pAssocReq->ssId, &ar.SSID);
+ }
+ /* Supported Rates */
+ if (ar.SuppRates.present) {
+ pAssocReq->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pAssocReq->supportedRates,
+ &ar.SuppRates);
+ }
+ /* Extended Supported Rates */
+ if (ar.ExtSuppRates.present) {
+ pAssocReq->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pAssocReq->extendedRates,
+ &ar.ExtSuppRates);
+ }
+ /* QOS Capabilities: */
+ if (ar.QOSCapsStation.present) {
+ pAssocReq->qosCapabilityPresent = 1;
+ convert_qos_caps_station(pMac, &pAssocReq->qosCapability,
+ &ar.QOSCapsStation);
+ }
+ /* WPA */
+ if (ar.WPAOpaque.present) {
+ pAssocReq->wpaPresent = 1;
+ convert_wpa_opaque(pMac, &pAssocReq->wpa, &ar.WPAOpaque);
+ }
+ /* RSN */
+ if (ar.RSNOpaque.present) {
+ pAssocReq->rsnPresent = 1;
+ convert_rsn_opaque(pMac, &pAssocReq->rsn, &ar.RSNOpaque);
+ }
+
+ /* Power Capabilities */
+ if (ar.PowerCaps.present) {
+ pAssocReq->powerCapabilityPresent = 1;
+ convert_power_caps(pMac, &pAssocReq->powerCapability,
+ &ar.PowerCaps);
+ }
+ /* Supported Channels */
+ if (ar.SuppChannels.present) {
+ pAssocReq->supportedChannelsPresent = 1;
+ convert_supp_channels(pMac, &pAssocReq->supportedChannels,
+ &ar.SuppChannels);
+ }
+
+ if (ar.HTCaps.present) {
+ cdf_mem_copy(&pAssocReq->HTCaps, &ar.HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (ar.WMMInfoStation.present) {
+ pAssocReq->wmeInfoPresent = 1;
+ cdf_mem_copy(&pAssocReq->WMMInfoStation, &ar.WMMInfoStation,
+ sizeof(tDot11fIEWMMInfoStation));
+
+ }
+
+ if (ar.WMMCaps.present)
+ pAssocReq->wsmCapablePresent = 1;
+
+ if (!pAssocReq->ssidPresent) {
+ PELOG2(lim_log
+ (pMac, LOG2, FL("Received Assoc without SSID IE.\n"));
+ )
+ return eSIR_FAILURE;
+ }
+
+ if (!pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent) {
+ PELOG2(lim_log
+ (pMac, LOG2,
+ FL("Received Assoc without supp rate IE.\n"));
+ )
+ return eSIR_FAILURE;
+ }
+ /* Why no call to 'updateAssocReqFromPropCapability' here, like */
+ /* there is in 'sir_convert_assoc_req_frame2_struct'? */
+
+ /* WSC IE */
+ if (ar.WscIEOpaque.present) {
+ pAssocReq->addIEPresent = 1;
+ convert_wsc_opaque(pMac, &pAssocReq->addIE, &ar.WscIEOpaque);
+ }
+
+ if (ar.P2PIEOpaque.present) {
+ pAssocReq->addIEPresent = 1;
+ convert_p2p_opaque(pMac, &pAssocReq->addIE, &ar.P2PIEOpaque);
+ }
+#ifdef WLAN_FEATURE_WFD
+ if (ar.WFDIEOpaque.present) {
+ pAssocReq->addIEPresent = 1;
+ convert_wfd_opaque(pMac, &pAssocReq->addIE, &ar.WFDIEOpaque);
+ }
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+ if (ar.VHTCaps.present) {
+ cdf_mem_copy(&pAssocReq->VHTCaps, &ar.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (ar.OperatingMode.present) {
+ cdf_mem_copy(&pAssocReq->operMode, &ar.OperatingMode,
+ sizeof(tDot11fIEOperatingMode));
+ lim_log(pMac, LOGW,
+ FL("Received Assoc Req with Operating Mode IE\n"));
+ lim_log_operating_mode(pMac, &pAssocReq->operMode);
+ }
+#endif
+
+ if (ar.ExtCap.present) {
+ struct s_ext_cap *ext_cap;
+ cdf_mem_copy(&pAssocReq->ExtCap.bytes, &ar.ExtCap.bytes,
+ ar.ExtCap.num_bytes);
+
+ ext_cap = (struct s_ext_cap *)&pAssocReq->ExtCap.bytes;
+ lim_log(pMac, LOG1,
+ FL("timingMeas: %d, finetimingMeas Init: %d, Resp: %d"),
+ ext_cap->timing_meas, ext_cap->fine_time_meas_initiator,
+ ext_cap->fine_time_meas_responder);
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_reassoc_req_frame2_struct. */
+
+#if defined(FEATURE_WLAN_ESE_UPLOAD)
+tSirRetStatus
+sir_beacon_ie_ese_bcn_report(tpAniSirGlobal pMac,
+ uint8_t *pPayload, const uint32_t nPayload,
+ uint8_t **outIeBuf, uint32_t *pOutIeLen)
+{
+ tDot11fBeaconIEs *pBies = NULL;
+ uint32_t status = CDF_STATUS_SUCCESS;
+ tSirRetStatus retStatus = eSIR_SUCCESS;
+ tSirEseBcnReportMandatoryIe eseBcnReportMandatoryIe;
+
+ /* To store how many bytes are required to be allocated
+ for Bcn report mandatory Ies */
+ uint16_t numBytes = 0, freeBytes = 0;
+ uint8_t *pos = NULL;
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) &eseBcnReportMandatoryIe,
+ sizeof(eseBcnReportMandatoryIe), 0);
+ pBies = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+ if (NULL == pBies) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory\n"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_beacon_i_es(pMac, pPayload, nPayload, pBies);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to parse Beacon IEs (0x%08x, %d bytes):\n"),
+ status, nPayload);
+ cdf_mem_free(pBies);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):\n"),
+ status, nPayload);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fBeaconIEs' to a 'eseBcnReportMandatoryIe'... */
+ if (!pBies->SSID.present) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Mandatory IE SSID not present!\n"));
+ )
+ } else {
+ eseBcnReportMandatoryIe.ssidPresent = 1;
+ convert_ssid(pMac, &eseBcnReportMandatoryIe.ssId, &pBies->SSID);
+ /* 1 for EID, 1 for length and length bytes */
+ numBytes += 1 + 1 + eseBcnReportMandatoryIe.ssId.length;
+ }
+
+ if (!pBies->SuppRates.present) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Mandatory IE Supported Rates not present!\n"));
+ )
+ } else {
+ eseBcnReportMandatoryIe.suppRatesPresent = 1;
+ convert_supp_rates(pMac, &eseBcnReportMandatoryIe.supportedRates,
+ &pBies->SuppRates);
+ numBytes +=
+ 1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates;
+ }
+
+ if (pBies->FHParamSet.present) {
+ eseBcnReportMandatoryIe.fhParamPresent = 1;
+ convert_fh_params(pMac, &eseBcnReportMandatoryIe.fhParamSet,
+ &pBies->FHParamSet);
+ numBytes += 1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX;
+ }
+
+ if (pBies->DSParams.present) {
+ eseBcnReportMandatoryIe.dsParamsPresent = 1;
+ eseBcnReportMandatoryIe.dsParamSet.channelNumber =
+ pBies->DSParams.curr_channel;
+ numBytes += 1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX;
+ }
+
+ if (pBies->CFParams.present) {
+ eseBcnReportMandatoryIe.cfPresent = 1;
+ convert_cf_params(pMac, &eseBcnReportMandatoryIe.cfParamSet,
+ &pBies->CFParams);
+ numBytes += 1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX;
+ }
+
+ if (pBies->IBSSParams.present) {
+ eseBcnReportMandatoryIe.ibssParamPresent = 1;
+ eseBcnReportMandatoryIe.ibssParamSet.atim =
+ pBies->IBSSParams.atim;
+ numBytes += 1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX;
+ }
+
+ if (pBies->TIM.present) {
+ eseBcnReportMandatoryIe.timPresent = 1;
+ eseBcnReportMandatoryIe.tim.dtimCount = pBies->TIM.dtim_count;
+ eseBcnReportMandatoryIe.tim.dtimPeriod = pBies->TIM.dtim_period;
+ eseBcnReportMandatoryIe.tim.bitmapControl = pBies->TIM.bmpctl;
+ /* As per the ESE spec, May truncate and report first 4 octets only */
+ numBytes += 1 + 1 + SIR_MAC_TIM_EID_MIN;
+ }
+
+ if (pBies->RRMEnabledCap.present) {
+ eseBcnReportMandatoryIe.rrmPresent = 1;
+ cdf_mem_copy(&eseBcnReportMandatoryIe.rmEnabledCapabilities,
+ &pBies->RRMEnabledCap,
+ sizeof(tDot11fIERRMEnabledCap));
+ numBytes += 1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX;
+ }
+
+ *outIeBuf = cdf_mem_malloc(numBytes);
+ if (NULL == *outIeBuf) {
+ lim_log(pMac, LOGP, FL("Memory Allocation failure"));
+ cdf_mem_free(pBies);
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ pos = *outIeBuf;
+ *pOutIeLen = numBytes;
+ freeBytes = numBytes;
+
+ /* Start filling the output Ie with Mandatory IE information */
+ /* Fill SSID IE */
+ if (eseBcnReportMandatoryIe.ssidPresent) {
+ if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.ssId.length)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy SSID"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_SSID_EID;
+ pos++;
+ *pos = eseBcnReportMandatoryIe.ssId.length;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) eseBcnReportMandatoryIe.ssId.ssId,
+ eseBcnReportMandatoryIe.ssId.length);
+ pos += eseBcnReportMandatoryIe.ssId.length;
+ freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.ssId.length);
+ }
+
+ /* Fill Supported Rates IE */
+ if (eseBcnReportMandatoryIe.suppRatesPresent) {
+ if (freeBytes <
+ (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy Rates IE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_RATESET_EID;
+ pos++;
+ *pos = eseBcnReportMandatoryIe.supportedRates.numRates;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) eseBcnReportMandatoryIe.supportedRates.
+ rate,
+ eseBcnReportMandatoryIe.supportedRates.numRates);
+ pos += eseBcnReportMandatoryIe.supportedRates.numRates;
+ freeBytes -=
+ (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates);
+ }
+
+ /* Fill FH Parameter set IE */
+ if (eseBcnReportMandatoryIe.fhParamPresent) {
+ if (freeBytes < (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy FHIE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_FH_PARAM_SET_EID;
+ pos++;
+ *pos = SIR_MAC_FH_PARAM_SET_EID_MAX;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) &eseBcnReportMandatoryIe.fhParamSet,
+ SIR_MAC_FH_PARAM_SET_EID_MAX);
+ pos += SIR_MAC_FH_PARAM_SET_EID_MAX;
+ freeBytes -= (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX);
+ }
+
+ /* Fill DS Parameter set IE */
+ if (eseBcnReportMandatoryIe.dsParamsPresent) {
+ if (freeBytes < (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy DS IE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_DS_PARAM_SET_EID;
+ pos++;
+ *pos = SIR_MAC_DS_PARAM_SET_EID_MAX;
+ pos++;
+ *pos = eseBcnReportMandatoryIe.dsParamSet.channelNumber;
+ pos += SIR_MAC_DS_PARAM_SET_EID_MAX;
+ freeBytes -= (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX);
+ }
+
+ /* Fill CF Parameter set */
+ if (eseBcnReportMandatoryIe.cfPresent) {
+ if (freeBytes < (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy CF IE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_CF_PARAM_SET_EID;
+ pos++;
+ *pos = SIR_MAC_CF_PARAM_SET_EID_MAX;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) &eseBcnReportMandatoryIe.cfParamSet,
+ SIR_MAC_CF_PARAM_SET_EID_MAX);
+ pos += SIR_MAC_CF_PARAM_SET_EID_MAX;
+ freeBytes -= (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX);
+ }
+
+ /* Fill IBSS Parameter set IE */
+ if (eseBcnReportMandatoryIe.ibssParamPresent) {
+ if (freeBytes < (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy IBSS IE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_IBSS_PARAM_SET_EID;
+ pos++;
+ *pos = SIR_MAC_IBSS_PARAM_SET_EID_MAX;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) &eseBcnReportMandatoryIe.ibssParamSet.
+ atim, SIR_MAC_IBSS_PARAM_SET_EID_MAX);
+ pos += SIR_MAC_IBSS_PARAM_SET_EID_MAX;
+ freeBytes -= (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX);
+ }
+
+ /* Fill TIM IE */
+ if (eseBcnReportMandatoryIe.timPresent) {
+ if (freeBytes < (1 + 1 + SIR_MAC_TIM_EID_MIN)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy TIM IE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_TIM_EID;
+ pos++;
+ *pos = SIR_MAC_TIM_EID_MIN;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) &eseBcnReportMandatoryIe.tim,
+ SIR_MAC_TIM_EID_MIN);
+ pos += SIR_MAC_TIM_EID_MIN;
+ freeBytes -= (1 + 1 + SIR_MAC_TIM_EID_MIN);
+ }
+
+ /* Fill RM Capability IE */
+ if (eseBcnReportMandatoryIe.rrmPresent) {
+ if (freeBytes < (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX)) {
+ lim_log(pMac, LOGP,
+ FL("Insufficient memory to copy RRM IE"));
+ retStatus = eSIR_FAILURE;
+ goto err_bcnrep;
+ }
+ *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID;
+ pos++;
+ *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX;
+ pos++;
+ cdf_mem_copy(pos,
+ (uint8_t *) &eseBcnReportMandatoryIe.
+ rmEnabledCapabilities,
+ SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX);
+ freeBytes -= (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX);
+ }
+
+ if (freeBytes != 0) {
+ lim_log(pMac, LOGP,
+ FL
+ ("Mismatch in allocation and copying of IE in Bcn Rep"));
+ retStatus = eSIR_FAILURE;
+ }
+
+err_bcnrep:
+ /* The message counter would not be incremented in case of
+ * returning failure and hence next time, this function gets
+ * called, it would be using the same msg ctr for a different
+ * BSS.So, it is good to clear the memory allocated for a BSS
+ * that is returning failure.On success, the caller would take
+ * care of freeing up the memory*/
+ if (retStatus == eSIR_FAILURE) {
+ cdf_mem_free(*outIeBuf);
+ *outIeBuf = NULL;
+ }
+
+ cdf_mem_free(pBies);
+ return retStatus;
+}
+
+#endif /* FEATURE_WLAN_ESE_UPLOAD */
+
+tSirRetStatus
+sir_parse_beacon_ie(tpAniSirGlobal pMac,
+ tpSirProbeRespBeacon pBeaconStruct,
+ uint8_t *pPayload, uint32_t nPayload)
+{
+ tDot11fBeaconIEs *pBies;
+ uint32_t status;
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0);
+
+ pBies = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
+ if (NULL == pBies) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory\n"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_beacon_i_es(pMac, pPayload, nPayload, pBies);
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to parse Beacon IEs (0x%08x, %d bytes):\n"),
+ status, nPayload);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);
+ )
+ cdf_mem_free(pBies);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):\n"),
+ status, nPayload);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fBeaconIEs' to a 'tSirProbeRespBeacon'... */
+ if (!pBies->SSID.present) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Mandatory IE SSID not present!\n"));
+ )
+ } else {
+ pBeaconStruct->ssidPresent = 1;
+ convert_ssid(pMac, &pBeaconStruct->ssId, &pBies->SSID);
+ }
+
+ if (!pBies->SuppRates.present) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Mandatory IE Supported Rates not present!\n"));
+ )
+ } else {
+ pBeaconStruct->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pBeaconStruct->supportedRates,
+ &pBies->SuppRates);
+ }
+
+ if (pBies->ExtSuppRates.present) {
+ pBeaconStruct->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pBeaconStruct->extendedRates,
+ &pBies->ExtSuppRates);
+ }
+
+ if (pBies->CFParams.present) {
+ pBeaconStruct->cfPresent = 1;
+ convert_cf_params(pMac, &pBeaconStruct->cfParamSet,
+ &pBies->CFParams);
+ }
+
+ if (pBies->TIM.present) {
+ pBeaconStruct->timPresent = 1;
+ convert_tim(pMac, &pBeaconStruct->tim, &pBies->TIM);
+ }
+
+ if (pBies->Country.present) {
+ pBeaconStruct->countryInfoPresent = 1;
+ convert_country(pMac, &pBeaconStruct->countryInfoParam,
+ &pBies->Country);
+ }
+ /* 11h IEs */
+ if (pBies->TPCReport.present) {
+ pBeaconStruct->tpcReportPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->tpcReport,
+ &pBies->TPCReport, sizeof(tDot11fIETPCReport));
+ }
+
+ if (pBies->PowerConstraints.present) {
+ pBeaconStruct->powerConstraintPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->localPowerConstraint,
+ &pBies->PowerConstraints,
+ sizeof(tDot11fIEPowerConstraints));
+ }
+#ifdef FEATURE_WLAN_ESE
+ if (pBies->ESEVersion.present)
+ pBeaconStruct->is_ese_ver_ie_present = 1;
+ if (pBies->ESETxmitPower.present) {
+ pBeaconStruct->eseTxPwr.present = 1;
+ pBeaconStruct->eseTxPwr.power_limit =
+ pBies->ESETxmitPower.power_limit;
+ }
+ if (pBies->QBSSLoad.present) {
+ cdf_mem_copy(&pBeaconStruct->QBSSLoad, &pBies->QBSSLoad,
+ sizeof(tDot11fIEQBSSLoad));
+ }
+#endif
+
+ if (pBies->EDCAParamSet.present) {
+ pBeaconStruct->edcaPresent = 1;
+ convert_edca_param(pMac, &pBeaconStruct->edcaParams,
+ &pBies->EDCAParamSet);
+ }
+ /* QOS Capabilities: */
+ if (pBies->QOSCapsAp.present) {
+ pBeaconStruct->qosCapabilityPresent = 1;
+ convert_qos_caps(pMac, &pBeaconStruct->qosCapability,
+ &pBies->QOSCapsAp);
+ }
+
+ if (pBies->ChanSwitchAnn.present) {
+ pBeaconStruct->channelSwitchPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->channelSwitchIE,
+ &pBies->ChanSwitchAnn,
+ sizeof(pBeaconStruct->channelSwitchIE));
+ }
+
+ if (pBies->ext_chan_switch_ann.present) {
+ pBeaconStruct->ext_chan_switch_present = 1;
+ cdf_mem_copy(&pBeaconStruct->ext_chan_switch,
+ &pBies->ext_chan_switch_ann,
+ sizeof(tDot11fIEext_chan_switch_ann));
+ }
+
+ if (pBies->sec_chan_offset_ele.present) {
+ pBeaconStruct->sec_chan_offset_present = 1;
+ cdf_mem_copy(&pBeaconStruct->sec_chan_offset,
+ &pBies->sec_chan_offset_ele,
+ sizeof(pBeaconStruct->sec_chan_offset));
+ }
+
+ if (pBies->Quiet.present) {
+ pBeaconStruct->quietIEPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->quietIE, &pBies->Quiet,
+ sizeof(tDot11fIEQuiet));
+ }
+
+ if (pBies->HTCaps.present) {
+ cdf_mem_copy(&pBeaconStruct->HTCaps, &pBies->HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (pBies->HTInfo.present) {
+ cdf_mem_copy(&pBeaconStruct->HTInfo, &pBies->HTInfo,
+ sizeof(tDot11fIEHTInfo));
+ }
+
+ if (pBies->DSParams.present) {
+ pBeaconStruct->dsParamsPresent = 1;
+ pBeaconStruct->channelNumber = pBies->DSParams.curr_channel;
+ } else if (pBies->HTInfo.present) {
+ pBeaconStruct->channelNumber = pBies->HTInfo.primaryChannel;
+ }
+
+ if (pBies->RSN.present) {
+ pBeaconStruct->rsnPresent = 1;
+ convert_rsn(pMac, &pBeaconStruct->rsn, &pBies->RSN);
+ }
+
+ if (pBies->WPA.present) {
+ pBeaconStruct->wpaPresent = 1;
+ convert_wpa(pMac, &pBeaconStruct->wpa, &pBies->WPA);
+ }
+
+ if (pBies->WMMParams.present) {
+ pBeaconStruct->wmeEdcaPresent = 1;
+ convert_wmm_params(pMac, &pBeaconStruct->edcaParams,
+ &pBies->WMMParams);
+ }
+
+ if (pBies->WMMInfoAp.present) {
+ pBeaconStruct->wmeInfoPresent = 1;
+ }
+
+ if (pBies->WMMCaps.present) {
+ pBeaconStruct->wsmCapablePresent = 1;
+ }
+
+ if (pBies->ERPInfo.present) {
+ pBeaconStruct->erpPresent = 1;
+ convert_erp_info(pMac, &pBeaconStruct->erpIEInfo,
+ &pBies->ERPInfo);
+ }
+#ifdef WLAN_FEATURE_11AC
+ if (pBies->VHTCaps.present) {
+ pBeaconStruct->VHTCaps.present = 1;
+ cdf_mem_copy(&pBeaconStruct->VHTCaps, &pBies->VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (pBies->VHTOperation.present) {
+ pBeaconStruct->VHTOperation.present = 1;
+ cdf_mem_copy(&pBeaconStruct->VHTOperation, &pBies->VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ }
+ if (pBies->VHTExtBssLoad.present) {
+ pBeaconStruct->VHTExtBssLoad.present = 1;
+ cdf_mem_copy(&pBeaconStruct->VHTExtBssLoad,
+ &pBies->VHTExtBssLoad,
+ sizeof(tDot11fIEVHTExtBssLoad));
+ }
+ if (pBies->OperatingMode.present) {
+ pBeaconStruct->OperatingMode.present = 1;
+ cdf_mem_copy(&pBeaconStruct->OperatingMode,
+ &pBies->OperatingMode,
+ sizeof(tDot11fIEOperatingMode));
+ }
+#endif
+
+ if (pBies->MobilityDomain.present) {
+ pBeaconStruct->mdiePresent = 1;
+ cdf_mem_copy(pBeaconStruct->mdie, &pBies->MobilityDomain.MDID,
+ SIR_MDIE_SIZE);
+ }
+
+ pBeaconStruct->Vendor1IEPresent = pBies->Vendor1IE.present;
+ pBeaconStruct->Vendor3IEPresent = pBies->Vendor3IE.present;
+ pBeaconStruct->vendor2_ie.present = pBies->vendor2_ie.present;
+ if (pBies->vendor2_ie.present) {
+ pBeaconStruct->vendor2_ie.type = pBies->vendor2_ie.type;
+ pBeaconStruct->vendor2_ie.sub_type = pBies->vendor2_ie.sub_type;
+ }
+
+ if (pBies->vendor2_ie.VHTCaps.present) {
+ pBeaconStruct->vendor2_ie.VHTCaps.present = 1;
+ cdf_mem_copy(&pBeaconStruct->vendor2_ie.VHTCaps,
+ &pBies->vendor2_ie.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (pBies->vendor2_ie.VHTOperation.present) {
+ pBeaconStruct->vendor2_ie.VHTOperation.present = 1;
+ cdf_mem_copy(&pBeaconStruct->vendor2_ie.VHTOperation,
+ &pBies->vendor2_ie.VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ }
+ cdf_mem_free(pBies);
+ return eSIR_SUCCESS;
+} /* End sir_parse_beacon_ie. */
+
+tSirRetStatus
+sir_convert_beacon_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ tpSirProbeRespBeacon pBeaconStruct)
+{
+ tDot11fBeacon *pBeacon;
+ uint32_t status, nPayload;
+ uint8_t *pPayload;
+ tpSirMacMgmtHdr pHdr;
+ uint8_t mappedRXCh;
+ uint8_t rfBand;
+
+ pPayload = WMA_GET_RX_MPDU_DATA(pFrame);
+ nPayload = WMA_GET_RX_PAYLOAD_LEN(pFrame);
+ pHdr = WMA_GET_RX_MAC_HEADER(pFrame);
+ mappedRXCh = WMA_GET_RX_CH(pFrame);
+ rfBand = WMA_GET_RX_RFBAND(pFrame);
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0);
+
+ pBeacon = cdf_mem_malloc(sizeof(tDot11fBeacon));
+ if (NULL == pBeacon) {
+ lim_log(pMac, LOGE, FL("Failed to allocate memory\n"));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ cdf_mem_set((uint8_t *) pBeacon, sizeof(tDot11fBeacon), 0);
+
+ /* get the MAC address out of the BD, */
+ cdf_mem_copy(pBeaconStruct->bssid, pHdr->sa, 6);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_beacon(pMac, pPayload, nPayload, pBeacon);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL("Failed to parse Beacon IEs (0x%08x, %d bytes):\n"),
+ status, nPayload);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);
+ )
+ cdf_mem_free(pBeacon);
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes):\n"),
+ status, nPayload);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fBeacon' to a 'tSirProbeRespBeacon'... */
+ /* Timestamp */
+ cdf_mem_copy((uint8_t *) pBeaconStruct->timeStamp,
+ (uint8_t *) &pBeacon->TimeStamp,
+ sizeof(tSirMacTimeStamp));
+
+ /* Beacon Interval */
+ pBeaconStruct->beaconInterval = pBeacon->BeaconInterval.interval;
+
+ /* Capabilities */
+ pBeaconStruct->capabilityInfo.ess = pBeacon->Capabilities.ess;
+ pBeaconStruct->capabilityInfo.ibss = pBeacon->Capabilities.ibss;
+ pBeaconStruct->capabilityInfo.cfPollable =
+ pBeacon->Capabilities.cfPollable;
+ pBeaconStruct->capabilityInfo.cfPollReq =
+ pBeacon->Capabilities.cfPollReq;
+ pBeaconStruct->capabilityInfo.privacy = pBeacon->Capabilities.privacy;
+ pBeaconStruct->capabilityInfo.shortPreamble =
+ pBeacon->Capabilities.shortPreamble;
+ pBeaconStruct->capabilityInfo.pbcc = pBeacon->Capabilities.pbcc;
+ pBeaconStruct->capabilityInfo.channelAgility =
+ pBeacon->Capabilities.channelAgility;
+ pBeaconStruct->capabilityInfo.spectrumMgt =
+ pBeacon->Capabilities.spectrumMgt;
+ pBeaconStruct->capabilityInfo.qos = pBeacon->Capabilities.qos;
+ pBeaconStruct->capabilityInfo.shortSlotTime =
+ pBeacon->Capabilities.shortSlotTime;
+ pBeaconStruct->capabilityInfo.apsd = pBeacon->Capabilities.apsd;
+ pBeaconStruct->capabilityInfo.rrm = pBeacon->Capabilities.rrm;
+ pBeaconStruct->capabilityInfo.dsssOfdm = pBeacon->Capabilities.dsssOfdm;
+ pBeaconStruct->capabilityInfo.delayedBA =
+ pBeacon->Capabilities.delayedBA;
+ pBeaconStruct->capabilityInfo.immediateBA =
+ pBeacon->Capabilities.immediateBA;
+
+ if (!pBeacon->SSID.present) {
+ PELOGW(lim_log
+ (pMac, LOGW, FL("Mandatory IE SSID not present!\n"));
+ )
+ } else {
+ pBeaconStruct->ssidPresent = 1;
+ convert_ssid(pMac, &pBeaconStruct->ssId, &pBeacon->SSID);
+ }
+
+ if (!pBeacon->SuppRates.present) {
+ PELOGW(lim_log
+ (pMac, LOGW,
+ FL("Mandatory IE Supported Rates not present!\n"));
+ )
+ } else {
+ pBeaconStruct->suppRatesPresent = 1;
+ convert_supp_rates(pMac, &pBeaconStruct->supportedRates,
+ &pBeacon->SuppRates);
+ }
+
+ if (pBeacon->ExtSuppRates.present) {
+ pBeaconStruct->extendedRatesPresent = 1;
+ convert_ext_supp_rates(pMac, &pBeaconStruct->extendedRates,
+ &pBeacon->ExtSuppRates);
+ }
+
+ if (pBeacon->CFParams.present) {
+ pBeaconStruct->cfPresent = 1;
+ convert_cf_params(pMac, &pBeaconStruct->cfParamSet,
+ &pBeacon->CFParams);
+ }
+
+ if (pBeacon->TIM.present) {
+ pBeaconStruct->timPresent = 1;
+ convert_tim(pMac, &pBeaconStruct->tim, &pBeacon->TIM);
+ }
+
+ if (pBeacon->Country.present) {
+ pBeaconStruct->countryInfoPresent = 1;
+ convert_country(pMac, &pBeaconStruct->countryInfoParam,
+ &pBeacon->Country);
+ }
+ /* QOS Capabilities: */
+ if (pBeacon->QOSCapsAp.present) {
+ pBeaconStruct->qosCapabilityPresent = 1;
+ convert_qos_caps(pMac, &pBeaconStruct->qosCapability,
+ &pBeacon->QOSCapsAp);
+ }
+
+ if (pBeacon->EDCAParamSet.present) {
+ pBeaconStruct->edcaPresent = 1;
+ convert_edca_param(pMac, &pBeaconStruct->edcaParams,
+ &pBeacon->EDCAParamSet);
+ }
+
+ if (pBeacon->ChanSwitchAnn.present) {
+ pBeaconStruct->channelSwitchPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->channelSwitchIE,
+ &pBeacon->ChanSwitchAnn,
+ sizeof(pBeaconStruct->channelSwitchIE));
+ }
+
+ if (pBeacon->ext_chan_switch_ann.present) {
+ pBeaconStruct->ext_chan_switch_present = 1;
+ cdf_mem_copy(&pBeaconStruct->ext_chan_switch,
+ &pBeacon->ext_chan_switch_ann,
+ sizeof(tDot11fIEext_chan_switch_ann));
+ }
+
+ if (pBeacon->sec_chan_offset_ele.present) {
+ pBeaconStruct->sec_chan_offset_present = 1;
+ cdf_mem_copy(&pBeaconStruct->sec_chan_offset,
+ &pBeacon->sec_chan_offset_ele,
+ sizeof(pBeaconStruct->sec_chan_offset));
+ }
+
+ if (pBeacon->TPCReport.present) {
+ pBeaconStruct->tpcReportPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->tpcReport, &pBeacon->TPCReport,
+ sizeof(tDot11fIETPCReport));
+ }
+
+ if (pBeacon->PowerConstraints.present) {
+ pBeaconStruct->powerConstraintPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->localPowerConstraint,
+ &pBeacon->PowerConstraints,
+ sizeof(tDot11fIEPowerConstraints));
+ }
+
+ if (pBeacon->Quiet.present) {
+ pBeaconStruct->quietIEPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->quietIE, &pBeacon->Quiet,
+ sizeof(tDot11fIEQuiet));
+ }
+
+ if (pBeacon->HTCaps.present) {
+ cdf_mem_copy(&pBeaconStruct->HTCaps, &pBeacon->HTCaps,
+ sizeof(tDot11fIEHTCaps));
+ }
+
+ if (pBeacon->HTInfo.present) {
+ cdf_mem_copy(&pBeaconStruct->HTInfo, &pBeacon->HTInfo,
+ sizeof(tDot11fIEHTInfo));
+
+ }
+
+ if (pBeacon->DSParams.present) {
+ pBeaconStruct->dsParamsPresent = 1;
+ pBeaconStruct->channelNumber = pBeacon->DSParams.curr_channel;
+ } else if (pBeacon->HTInfo.present) {
+ pBeaconStruct->channelNumber = pBeacon->HTInfo.primaryChannel;
+ } else {
+ pBeaconStruct->channelNumber = mappedRXCh;
+ lim_log(pMac, LOG1,
+ FL("Channel info is not present in Beacon"));
+ }
+
+ if (pBeacon->RSN.present) {
+ pBeaconStruct->rsnPresent = 1;
+ convert_rsn(pMac, &pBeaconStruct->rsn, &pBeacon->RSN);
+ }
+
+ if (pBeacon->WPA.present) {
+ pBeaconStruct->wpaPresent = 1;
+ convert_wpa(pMac, &pBeaconStruct->wpa, &pBeacon->WPA);
+ }
+
+ if (pBeacon->WMMParams.present) {
+ pBeaconStruct->wmeEdcaPresent = 1;
+ convert_wmm_params(pMac, &pBeaconStruct->edcaParams,
+ &pBeacon->WMMParams);
+ PELOG1(lim_log
+ (pMac, LOG1,
+ FL("WMM Parameter present in Beacon Frame!\n"));
+ __print_wmm_params(pMac, &pBeacon->WMMParams);
+ )
+ }
+
+ if (pBeacon->WMMInfoAp.present) {
+ pBeaconStruct->wmeInfoPresent = 1;
+ PELOG1(lim_log
+ (pMac, LOG1, FL("WMM Info present in Beacon Frame!\n"));
+ )
+ }
+
+ if (pBeacon->WMMCaps.present) {
+ pBeaconStruct->wsmCapablePresent = 1;
+ }
+
+ if (pBeacon->ERPInfo.present) {
+ pBeaconStruct->erpPresent = 1;
+ convert_erp_info(pMac, &pBeaconStruct->erpIEInfo,
+ &pBeacon->ERPInfo);
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (pBeacon->MobilityDomain.present) {
+ /* MobilityDomain */
+ pBeaconStruct->mdiePresent = 1;
+ cdf_mem_copy((uint8_t *) &(pBeaconStruct->mdie[0]),
+ (uint8_t *) &(pBeacon->MobilityDomain.MDID),
+ sizeof(uint16_t));
+ pBeaconStruct->mdie[2] =
+ ((pBeacon->MobilityDomain.overDSCap << 0) | (pBeacon->
+ MobilityDomain.
+ resourceReqCap
+ << 1));
+
+ }
+#endif
+
+#ifdef FEATURE_WLAN_ESE
+ if (pBeacon->ESEVersion.present)
+ pBeaconStruct->is_ese_ver_ie_present = 1;
+ if (pBeacon->ESETxmitPower.present) {
+ /* copy ESE TPC info element */
+ pBeaconStruct->eseTxPwr.present = 1;
+ cdf_mem_copy(&pBeaconStruct->eseTxPwr,
+ &pBeacon->ESETxmitPower,
+ sizeof(tDot11fIEESETxmitPower));
+ }
+ if (pBeacon->QBSSLoad.present) {
+ cdf_mem_copy(&pBeaconStruct->QBSSLoad,
+ &pBeacon->QBSSLoad, sizeof(tDot11fIEQBSSLoad));
+ }
+#endif
+
+#ifdef WLAN_FEATURE_11AC
+ if (pBeacon->VHTCaps.present) {
+ cdf_mem_copy(&pBeaconStruct->VHTCaps, &pBeacon->VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (pBeacon->VHTOperation.present) {
+ cdf_mem_copy(&pBeaconStruct->VHTOperation,
+ &pBeacon->VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ }
+ if (pBeacon->VHTExtBssLoad.present) {
+ cdf_mem_copy(&pBeaconStruct->VHTExtBssLoad,
+ &pBeacon->VHTExtBssLoad,
+ sizeof(tDot11fIEVHTExtBssLoad));
+ }
+ if (pBeacon->OperatingMode.present) {
+ cdf_mem_copy(&pBeaconStruct->OperatingMode,
+ &pBeacon->OperatingMode,
+ sizeof(tDot11fIEOperatingMode));
+ }
+ if (pBeacon->WiderBWChanSwitchAnn.present) {
+ pBeaconStruct->WiderBWChanSwitchAnnPresent = 1;
+ cdf_mem_copy(&pBeaconStruct->WiderBWChanSwitchAnn,
+ &pBeacon->WiderBWChanSwitchAnn,
+ sizeof(tDot11fIEWiderBWChanSwitchAnn));
+ }
+#endif
+
+ /* IBSS Peer Params */
+ if (pBeacon->IBSSParams.present) {
+ pBeaconStruct->IBSSParams.present = 1;
+ cdf_mem_copy(&pBeaconStruct->IBSSParams, &pBeacon->IBSSParams,
+ sizeof(tDot11fIEIBSSParams));
+ }
+
+ pBeaconStruct->Vendor1IEPresent = pBeacon->Vendor1IE.present;
+ pBeaconStruct->Vendor3IEPresent = pBeacon->Vendor3IE.present;
+
+ pBeaconStruct->vendor2_ie.present = pBeacon->vendor2_ie.present;
+ if (pBeacon->vendor2_ie.present) {
+ pBeaconStruct->vendor2_ie.type = pBeacon->vendor2_ie.type;
+ pBeaconStruct->vendor2_ie.sub_type =
+ pBeacon->vendor2_ie.sub_type;
+ }
+ if (pBeacon->vendor2_ie.present) {
+ PELOG1(lim_log(pMac, LOG1,
+ FL("Vendor Specific VHT caps present in Beacon Frame!"));
+ )
+ }
+ if (pBeacon->vendor2_ie.VHTCaps.present) {
+ cdf_mem_copy(&pBeaconStruct->vendor2_ie.VHTCaps,
+ &pBeacon->vendor2_ie.VHTCaps,
+ sizeof(tDot11fIEVHTCaps));
+ }
+ if (pBeacon->vendor2_ie.VHTOperation.present) {
+ cdf_mem_copy(&pBeaconStruct->vendor2_ie.VHTOperation,
+ &pBeacon->VHTOperation,
+ sizeof(tDot11fIEVHTOperation));
+ }
+#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
+ if (pBeacon->QComVendorIE.present) {
+ pBeaconStruct->AvoidChannelIE.present =
+ pBeacon->QComVendorIE.present;
+ pBeaconStruct->AvoidChannelIE.type =
+ pBeacon->QComVendorIE.type;
+ pBeaconStruct->AvoidChannelIE.channel =
+ pBeacon->QComVendorIE.channel;
+ }
+#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+
+
+ cdf_mem_free(pBeacon);
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_beacon_frame2_struct. */
+
+tSirRetStatus
+sir_convert_auth_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tpSirMacAuthFrameBody pAuth)
+{
+ static tDot11fAuthentication auth;
+ uint32_t status;
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pAuth, sizeof(tSirMacAuthFrameBody), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_authentication(pMac, pFrame, nFrame, &auth);
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to parse an Authentication frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking an Authentication frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fAuthentication' to a 'tSirMacAuthFrameBody'... */
+ pAuth->authAlgoNumber = auth.AuthAlgo.algo;
+ pAuth->authTransactionSeqNumber = auth.AuthSeqNo.no;
+ pAuth->authStatusCode = auth.Status.status;
+
+ if (auth.ChallengeText.present) {
+ pAuth->type = SIR_MAC_CHALLENGE_TEXT_EID;
+ pAuth->length = auth.ChallengeText.num_text;
+ cdf_mem_copy(pAuth->challengeText, auth.ChallengeText.text,
+ auth.ChallengeText.num_text);
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_auth_frame2_struct. */
+
+tSirRetStatus
+sir_convert_addts_req2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tSirAddtsReqInfo *pAddTs)
+{
+ tDot11fAddTSRequest addts = { {0}};
+ tDot11fWMMAddTSRequest wmmaddts = { {0}};
+ uint8_t j;
+ uint16_t i;
+ uint32_t status;
+
+ if (SIR_MAC_QOS_ADD_TS_REQ != *(pFrame + 1)) {
+ lim_log(pMac, LOGE, FL("sir_convert_addts_req2_struct invoked "
+ "with an Action of %d; this is not "
+ "supported & is probably an error."),
+ *(pFrame + 1));
+ return eSIR_FAILURE;
+ }
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pAddTs, sizeof(tSirAddtsReqInfo), 0);
+
+ /* delegate to the framesc-generated code, */
+ switch (*pFrame) {
+ case SIR_MAC_ACTION_QOS_MGMT:
+ status = dot11f_unpack_add_ts_request(pMac, pFrame, nFrame, &addts);
+ break;
+ case SIR_MAC_ACTION_WME:
+ status =
+ dot11f_unpack_wmm_add_ts_request(pMac, pFrame, nFrame,
+ &wmmaddts);
+ break;
+ default:
+ lim_log(pMac, LOGE, FL("sir_convert_addts_req2_struct invoked "
+ "with a Category of %d; this is not"
+ " supported & is probably an error."),
+ *pFrame);
+ return eSIR_FAILURE;
+ }
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE, FL("Failed to parse an Add TS Request f"
+ "rame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW, FL("There were warnings while unpackin"
+ "g an Add TS Request frame (0x%08x,"
+ "%d bytes):\n"), status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fAddTSRequest' or a */
+ /* 'tDot11WMMAddTSRequest' to a 'tSirMacAddtsReqInfo'... */
+ if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) {
+ pAddTs->dialogToken = addts.DialogToken.token;
+
+ if (addts.TSPEC.present) {
+ convert_tspec(pMac, &pAddTs->tspec, &addts.TSPEC);
+ } else {
+ lim_log(pMac, LOGE,
+ FL
+ ("Mandatory TSPEC element missing in Add TS Request.\n"));
+ return eSIR_FAILURE;
+ }
+
+ if (addts.num_TCLAS) {
+ pAddTs->numTclas = (uint8_t) addts.num_TCLAS;
+
+ for (i = 0U; i < addts.num_TCLAS; ++i) {
+ if (eSIR_SUCCESS !=
+ convert_tclas(pMac, &(pAddTs->tclasInfo[i]),
+ &(addts.TCLAS[i]))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to convert a TCLAS IE.\n"));
+ return eSIR_FAILURE;
+ }
+ }
+ }
+
+ if (addts.TCLASSPROC.present) {
+ pAddTs->tclasProcPresent = 1;
+ pAddTs->tclasProc = addts.TCLASSPROC.processing;
+ }
+
+ if (addts.WMMTSPEC.present) {
+ pAddTs->wsmTspecPresent = 1;
+ convert_wmmtspec(pMac, &pAddTs->tspec, &addts.WMMTSPEC);
+ }
+
+ if (addts.num_WMMTCLAS) {
+ j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
+ if (SIR_MAC_TCLASIE_MAXNUM > j)
+ j = SIR_MAC_TCLASIE_MAXNUM;
+
+ for (i = pAddTs->numTclas; i < j; ++i) {
+ if (eSIR_SUCCESS !=
+ convert_wmmtclas(pMac,
+ &(pAddTs->tclasInfo[i]),
+ &(addts.WMMTCLAS[i]))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to convert a TCLAS IE.\n"));
+ return eSIR_FAILURE;
+ }
+ }
+ }
+
+ if (addts.WMMTCLASPROC.present) {
+ pAddTs->tclasProcPresent = 1;
+ pAddTs->tclasProc = addts.WMMTCLASPROC.processing;
+ }
+
+ if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) {
+ lim_log(pMac, LOGE,
+ FL("%d TCLAS IE but not TCLASPROC IE.\n"),
+ pAddTs->numTclas);
+ return eSIR_FAILURE;
+ }
+ } else {
+ pAddTs->dialogToken = wmmaddts.DialogToken.token;
+
+ if (wmmaddts.WMMTSPEC.present) {
+ pAddTs->wmeTspecPresent = 1;
+ convert_wmmtspec(pMac, &pAddTs->tspec,
+ &wmmaddts.WMMTSPEC);
+ } else {
+ lim_log(pMac, LOGE,
+ FL("Mandatory WME TSPEC element missing!\n"));
+ return eSIR_FAILURE;
+ }
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_addts_req2_struct. */
+
+tSirRetStatus
+sir_convert_addts_rsp2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tSirAddtsRspInfo *pAddTs)
+{
+ tDot11fAddTSResponse addts = { {0}};
+ tDot11fWMMAddTSResponse wmmaddts = { {0}};
+ uint8_t j;
+ uint16_t i;
+ uint32_t status;
+
+ if (SIR_MAC_QOS_ADD_TS_RSP != *(pFrame + 1)) {
+ lim_log(pMac, LOGE, FL("sir_convert_addts_rsp2_struct invoked "
+ "with an Action of %d; this is not "
+ "supported & is probably an error."),
+ *(pFrame + 1));
+ return eSIR_FAILURE;
+ }
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pAddTs, sizeof(tSirAddtsRspInfo), 0);
+ cdf_mem_set((uint8_t *) &addts, sizeof(tDot11fAddTSResponse), 0);
+ cdf_mem_set((uint8_t *) &wmmaddts, sizeof(tDot11fWMMAddTSResponse), 0);
+
+ /* delegate to the framesc-generated code, */
+ switch (*pFrame) {
+ case SIR_MAC_ACTION_QOS_MGMT:
+ status =
+ dot11f_unpack_add_ts_response(pMac, pFrame, nFrame, &addts);
+ break;
+ case SIR_MAC_ACTION_WME:
+ status =
+ dot11f_unpack_wmm_add_ts_response(pMac, pFrame, nFrame,
+ &wmmaddts);
+ break;
+ default:
+ lim_log(pMac, LOGE, FL("sir_convert_addts_rsp2_struct invoked "
+ "with a Category of %d; this is not"
+ " supported & is probably an error."),
+ *pFrame);
+ return eSIR_FAILURE;
+ }
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE, FL("Failed to parse an Add TS Response f"
+ "rame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ lim_log(pMac, LOGW, FL("There were warnings while unpackin"
+ "g an Add TS Response frame (0x%08x,"
+ "%d bytes):\n"), status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fAddTSResponse' or a */
+ /* 'tDot11WMMAddTSResponse' to a 'tSirMacAddtsRspInfo'... */
+ if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) {
+ pAddTs->dialogToken = addts.DialogToken.token;
+ pAddTs->status = (tSirMacStatusCodes) addts.Status.status;
+
+ if (addts.TSDelay.present) {
+ convert_ts_delay(pMac, &pAddTs->delay, &addts.TSDelay);
+ }
+ /* TS Delay is present iff status indicates its presence */
+ if (eSIR_MAC_TS_NOT_CREATED_STATUS == pAddTs->status
+ && !addts.TSDelay.present) {
+ lim_log(pMac, LOGW, FL("Missing TSDelay IE.\n"));
+ }
+
+ if (addts.TSPEC.present) {
+ convert_tspec(pMac, &pAddTs->tspec, &addts.TSPEC);
+ } else {
+ lim_log(pMac, LOGE,
+ FL
+ ("Mandatory TSPEC element missing in Add TS Response.\n"));
+ return eSIR_FAILURE;
+ }
+
+ if (addts.num_TCLAS) {
+ pAddTs->numTclas = (uint8_t) addts.num_TCLAS;
+
+ for (i = 0U; i < addts.num_TCLAS; ++i) {
+ if (eSIR_SUCCESS !=
+ convert_tclas(pMac, &(pAddTs->tclasInfo[i]),
+ &(addts.TCLAS[i]))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to convert a TCLAS IE.\n"));
+ return eSIR_FAILURE;
+ }
+ }
+ }
+
+ if (addts.TCLASSPROC.present) {
+ pAddTs->tclasProcPresent = 1;
+ pAddTs->tclasProc = addts.TCLASSPROC.processing;
+ }
+#ifdef FEATURE_WLAN_ESE
+ if (addts.ESETrafStrmMet.present) {
+ pAddTs->tsmPresent = 1;
+ cdf_mem_copy(&pAddTs->tsmIE.tsid,
+ &addts.ESETrafStrmMet.tsid,
+ sizeof(tSirMacESETSMIE));
+ }
+#endif
+ if (addts.Schedule.present) {
+ pAddTs->schedulePresent = 1;
+ convert_schedule(pMac, &pAddTs->schedule,
+ &addts.Schedule);
+ }
+
+ if (addts.WMMSchedule.present) {
+ pAddTs->schedulePresent = 1;
+ convert_wmm_schedule(pMac, &pAddTs->schedule,
+ &addts.WMMSchedule);
+ }
+
+ if (addts.WMMTSPEC.present) {
+ pAddTs->wsmTspecPresent = 1;
+ convert_wmmtspec(pMac, &pAddTs->tspec, &addts.WMMTSPEC);
+ }
+
+ if (addts.num_WMMTCLAS) {
+ j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS);
+ if (SIR_MAC_TCLASIE_MAXNUM > j)
+ j = SIR_MAC_TCLASIE_MAXNUM;
+
+ for (i = pAddTs->numTclas; i < j; ++i) {
+ if (eSIR_SUCCESS !=
+ convert_wmmtclas(pMac,
+ &(pAddTs->tclasInfo[i]),
+ &(addts.WMMTCLAS[i]))) {
+ lim_log(pMac, LOGE,
+ FL
+ ("Failed to convert a TCLAS IE.\n"));
+ return eSIR_FAILURE;
+ }
+ }
+ }
+
+ if (addts.WMMTCLASPROC.present) {
+ pAddTs->tclasProcPresent = 1;
+ pAddTs->tclasProc = addts.WMMTCLASPROC.processing;
+ }
+
+ if (1 < pAddTs->numTclas && (!pAddTs->tclasProcPresent)) {
+ lim_log(pMac, LOGE,
+ FL("%d TCLAS IE but not TCLASPROC IE.\n"),
+ pAddTs->numTclas);
+ return eSIR_FAILURE;
+ }
+ } else {
+ pAddTs->dialogToken = wmmaddts.DialogToken.token;
+ pAddTs->status =
+ (tSirMacStatusCodes) wmmaddts.StatusCode.statusCode;
+
+ if (wmmaddts.WMMTSPEC.present) {
+ pAddTs->wmeTspecPresent = 1;
+ convert_wmmtspec(pMac, &pAddTs->tspec,
+ &wmmaddts.WMMTSPEC);
+ } else {
+ lim_log(pMac, LOGE,
+ FL("Mandatory WME TSPEC element missing!\n"));
+ return eSIR_FAILURE;
+ }
+
+#ifdef FEATURE_WLAN_ESE
+ if (wmmaddts.ESETrafStrmMet.present) {
+ pAddTs->tsmPresent = 1;
+ cdf_mem_copy(&pAddTs->tsmIE.tsid,
+ &wmmaddts.ESETrafStrmMet.tsid,
+ sizeof(tSirMacESETSMIE));
+ }
+#endif
+
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_addts_rsp2_struct. */
+
+tSirRetStatus
+sir_convert_delts_req2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame, tSirDeltsReqInfo *pDelTs)
+{
+ tDot11fDelTS delts = { {0}};
+ tDot11fWMMDelTS wmmdelts = { {0}};
+ uint32_t status;
+
+ if (SIR_MAC_QOS_DEL_TS_REQ != *(pFrame + 1)) {
+ lim_log(pMac, LOGE, FL("sirConvertDeltsRsp2Struct invoked "
+ "with an Action of %d; this is not "
+ "supported & is probably an error."),
+ *(pFrame + 1));
+ return eSIR_FAILURE;
+ }
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pDelTs, sizeof(tSirDeltsReqInfo), 0);
+
+ /* delegate to the framesc-generated code, */
+ switch (*pFrame) {
+ case SIR_MAC_ACTION_QOS_MGMT:
+ status = dot11f_unpack_del_ts(pMac, pFrame, nFrame, &delts);
+ break;
+ case SIR_MAC_ACTION_WME:
+ status = dot11f_unpack_wmm_del_ts(pMac, pFrame, nFrame, &wmmdelts);
+ break;
+ default:
+ lim_log(pMac, LOGE, FL("sirConvertDeltsRsp2Struct invoked "
+ "with a Category of %d; this is not"
+ " supported & is probably an error."),
+ *pFrame);
+ return eSIR_FAILURE;
+ }
+
+ if (DOT11F_FAILED(status)) {
+ lim_log(pMac, LOGE, FL("Failed to parse an Del TS Request f"
+ "rame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ dot11f_log(pMac, LOGW, FL("There were warnings while unpackin"
+ "g an Del TS Request frame (0x%08x,"
+ "%d bytes):\n"), status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fDelTSResponse' or a */
+ /* 'tDot11WMMDelTSResponse' to a 'tSirMacDeltsReqInfo'... */
+ if (SIR_MAC_ACTION_QOS_MGMT == *pFrame) {
+ pDelTs->tsinfo.traffic.trafficType =
+ (uint16_t) delts.TSInfo.traffic_type;
+ pDelTs->tsinfo.traffic.tsid = (uint16_t) delts.TSInfo.tsid;
+ pDelTs->tsinfo.traffic.direction =
+ (uint16_t) delts.TSInfo.direction;
+ pDelTs->tsinfo.traffic.accessPolicy =
+ (uint16_t) delts.TSInfo.access_policy;
+ pDelTs->tsinfo.traffic.aggregation =
+ (uint16_t) delts.TSInfo.aggregation;
+ pDelTs->tsinfo.traffic.psb = (uint16_t) delts.TSInfo.psb;
+ pDelTs->tsinfo.traffic.userPrio =
+ (uint16_t) delts.TSInfo.user_priority;
+ pDelTs->tsinfo.traffic.ackPolicy =
+ (uint16_t) delts.TSInfo.tsinfo_ack_pol;
+
+ pDelTs->tsinfo.schedule.schedule =
+ (uint8_t) delts.TSInfo.schedule;
+ } else {
+ if (wmmdelts.WMMTSPEC.present) {
+ pDelTs->wmeTspecPresent = 1;
+ convert_wmmtspec(pMac, &pDelTs->tspec,
+ &wmmdelts.WMMTSPEC);
+ } else {
+ dot11f_log(pMac, LOGE,
+ FL("Mandatory WME TSPEC element missing!\n"));
+ return eSIR_FAILURE;
+ }
+ }
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_delts_req2_struct. */
+
+tSirRetStatus
+sir_convert_qos_map_configure_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ uint32_t nFrame,
+ tSirQosMapSet *pQosMapSet)
+{
+ tDot11fQosMapConfigure mapConfigure;
+ uint32_t status;
+ status =
+ dot11f_unpack_qos_map_configure(pMac, pFrame, nFrame, &mapConfigure);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("Failed to parse Qos Map Configure frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ dot11f_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking Qos Map Configure frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ pQosMapSet->present = mapConfigure.QosMapSet.present;
+ convert_qos_mapset_frame(pMac->hHdd, pQosMapSet, &mapConfigure.QosMapSet);
+ lim_log_qos_map_set(pMac, pQosMapSet);
+ return eSIR_SUCCESS;
+}
+
+#ifdef ANI_SUPPORT_11H
+tSirRetStatus
+sir_convert_tpc_req_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ tpSirMacTpcReqActionFrame pTpcReqFrame,
+ uint32_t nFrame)
+{
+ tDot11fTPCRequest req;
+ uint32_t status;
+ cdf_mem_set((uint8_t *) pTpcReqFrame, sizeof(tSirMacTpcReqActionFrame),
+ 0);
+ status = dot11f_unpack_tpc_request(pMac, pFrame, nFrame, &req);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("Failed to parse a TPC Request frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ dot11f_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a TPC Request frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fTPCRequest' to a */
+ /* 'tSirMacTpcReqActionFrame'... */
+ pTpcReqFrame->actionHeader.category = req.Category.category;
+ pTpcReqFrame->actionHeader.actionID = req.Action.action;
+ pTpcReqFrame->actionHeader.dialogToken = req.DialogToken.token;
+ if (req.TPCRequest.present) {
+ pTpcReqFrame->type = DOT11F_EID_TPCREQUEST;
+ pTpcReqFrame->length = 0;
+ } else {
+ dot11f_log(pMac, LOGW, FL("!!!Rcv TPC Req of inalid type!\n"));
+ return eSIR_FAILURE;
+ }
+ return eSIR_SUCCESS;
+} /* End sir_convert_tpc_req_frame2_struct. */
+tSirRetStatus
+sir_convert_meas_req_frame2_struct(tpAniSirGlobal pMac,
+ uint8_t *pFrame,
+ tpSirMacMeasReqActionFrame pMeasReqFrame,
+ uint32_t nFrame)
+{
+ tDot11fMeasurementRequest mr;
+ uint32_t status;
+
+ /* Zero-init our [out] parameter, */
+ cdf_mem_set((uint8_t *) pMeasReqFrame,
+ sizeof(tpSirMacMeasReqActionFrame), 0);
+
+ /* delegate to the framesc-generated code, */
+ status = dot11f_unpack_measurement_request(pMac, pFrame, nFrame, &mr);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("Failed to parse a Measurement Request frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ return eSIR_FAILURE;
+ } else if (DOT11F_WARNED(status)) {
+ dot11f_log(pMac, LOGW,
+ FL
+ ("There were warnings while unpacking a Measurement Request frame (0x%08x, %d bytes):\n"),
+ status, nFrame);
+ PELOG2(sir_dump_buf
+ (pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);
+ )
+ }
+ /* & "transliterate" from a 'tDot11fMeasurementRequest' to a */
+ /* 'tpSirMacMeasReqActionFrame'... */
+ pMeasReqFrame->actionHeader.category = mr.Category.category;
+ pMeasReqFrame->actionHeader.actionID = mr.Action.action;
+ pMeasReqFrame->actionHeader.dialogToken = mr.DialogToken.token;
+
+ if (0 == mr.num_MeasurementRequest) {
+ dot11f_log(pMac, LOGE,
+ FL
+ ("Missing mandatory IE in Measurement Request Frame.\n"));
+ return eSIR_FAILURE;
+ } else if (1 < mr.num_MeasurementRequest) {
+ lim_log(pMac, LOGW,
+ FL("Warning: dropping extra Measurement Request IEs!"));
+ }
+
+ pMeasReqFrame->measReqIE.type = DOT11F_EID_MEASUREMENTREQUEST;
+ pMeasReqFrame->measReqIE.length = DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN;
+ pMeasReqFrame->measReqIE.measToken =
+ mr.MeasurementRequest[0].measurement_token;
+ pMeasReqFrame->measReqIE.measReqMode =
+ (mr.MeasurementRequest[0].reserved << 3) | (mr.
+ MeasurementRequest[0].
+ enable << 2) | (mr.
+ MeasurementRequest
+ [0].
+ request
+ << 1) |
+ (mr.MeasurementRequest[0].report /*<< 0 */ );
+ pMeasReqFrame->measReqIE.measType =
+ mr.MeasurementRequest[0].measurement_type;
+
+ pMeasReqFrame->measReqIE.measReqField.channelNumber =
+ mr.MeasurementRequest[0].channel_no;
+
+ cdf_mem_copy(pMeasReqFrame->measReqIE.measReqField.measStartTime,
+ mr.MeasurementRequest[0].meas_start_time, 8);
+
+ pMeasReqFrame->measReqIE.measReqField.measDuration =
+ mr.MeasurementRequest[0].meas_duration;
+
+ return eSIR_SUCCESS;
+
+} /* End sir_convert_meas_req_frame2_struct. */
+#endif
+
+void populate_dot11f_tspec(tSirMacTspecIE *pOld, tDot11fIETSPEC *pDot11f)
+{
+ pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType;
+ pDot11f->tsid = pOld->tsinfo.traffic.tsid;
+ pDot11f->direction = pOld->tsinfo.traffic.direction;
+ pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy;
+ pDot11f->aggregation = pOld->tsinfo.traffic.aggregation;
+ pDot11f->psb = pOld->tsinfo.traffic.psb;
+ pDot11f->user_priority = pOld->tsinfo.traffic.userPrio;
+ pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy;
+ pDot11f->schedule = pOld->tsinfo.schedule.schedule;
+ /* As defined in IEEE 802.11-2007, section 7.3.2.30
+ * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
+ */
+ pDot11f->size = (pOld->nomMsduSz & 0x7fff);
+ pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0;
+ pDot11f->max_msdu_size = pOld->maxMsduSz;
+ pDot11f->min_service_int = pOld->minSvcInterval;
+ pDot11f->max_service_int = pOld->maxSvcInterval;
+ pDot11f->inactivity_int = pOld->inactInterval;
+ pDot11f->suspension_int = pOld->suspendInterval;
+ pDot11f->service_start_time = pOld->svcStartTime;
+ pDot11f->min_data_rate = pOld->minDataRate;
+ pDot11f->mean_data_rate = pOld->meanDataRate;
+ pDot11f->peak_data_rate = pOld->peakDataRate;
+ pDot11f->burst_size = pOld->maxBurstSz;
+ pDot11f->delay_bound = pOld->delayBound;
+ pDot11f->min_phy_rate = pOld->minPhyRate;
+ pDot11f->surplus_bw_allowance = pOld->surplusBw;
+ pDot11f->medium_time = pOld->mediumTime;
+
+ pDot11f->present = 1;
+
+} /* End populate_dot11f_tspec. */
+
+void populate_dot11f_wmmtspec(tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pDot11f)
+{
+ pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType;
+ pDot11f->tsid = pOld->tsinfo.traffic.tsid;
+ pDot11f->direction = pOld->tsinfo.traffic.direction;
+ pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy;
+ pDot11f->aggregation = pOld->tsinfo.traffic.aggregation;
+ pDot11f->psb = pOld->tsinfo.traffic.psb;
+ pDot11f->user_priority = pOld->tsinfo.traffic.userPrio;
+ pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy;
+ pDot11f->burst_size_defn = pOld->tsinfo.traffic.burstSizeDefn;
+ /* As defined in IEEE 802.11-2007, section 7.3.2.30
+ * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed
+ */
+ pDot11f->size = (pOld->nomMsduSz & 0x7fff);
+ pDot11f->fixed = (pOld->nomMsduSz & 0x8000) ? 1 : 0;
+ pDot11f->max_msdu_size = pOld->maxMsduSz;
+ pDot11f->min_service_int = pOld->minSvcInterval;
+ pDot11f->max_service_int = pOld->maxSvcInterval;
+ pDot11f->inactivity_int = pOld->inactInterval;
+ pDot11f->suspension_int = pOld->suspendInterval;
+ pDot11f->service_start_time = pOld->svcStartTime;
+ pDot11f->min_data_rate = pOld->minDataRate;
+ pDot11f->mean_data_rate = pOld->meanDataRate;
+ pDot11f->peak_data_rate = pOld->peakDataRate;
+ pDot11f->burst_size = pOld->maxBurstSz;
+ pDot11f->delay_bound = pOld->delayBound;
+ pDot11f->min_phy_rate = pOld->minPhyRate;
+ pDot11f->surplus_bw_allowance = pOld->surplusBw;
+ pDot11f->medium_time = pOld->mediumTime;
+
+ pDot11f->version = 1;
+ pDot11f->present = 1;
+
+} /* End populate_dot11f_wmmtspec. */
+
+#if defined(FEATURE_WLAN_ESE)
+/* Fill the ESE version currently supported */
+void populate_dot11f_ese_version(tDot11fIEESEVersion *pESEVersion)
+{
+ pESEVersion->present = 1;
+ pESEVersion->version = ESE_VERSION_SUPPORTED;
+}
+
+/* Fill the ESE ie for the station. */
+/* The State is Normal (1) */
+/* The MBSSID for station is set to 0. */
+void populate_dot11f_ese_rad_mgmt_cap(tDot11fIEESERadMgmtCap *pESERadMgmtCap)
+{
+ pESERadMgmtCap->present = 1;
+ pESERadMgmtCap->mgmt_state = RM_STATE_NORMAL;
+ pESERadMgmtCap->mbssid_mask = 0;
+ pESERadMgmtCap->reserved = 0;
+}
+
+tSirRetStatus populate_dot11f_ese_cckm_opaque(tpAniSirGlobal pMac,
+ tpSirCCKMie pCCKMie,
+ tDot11fIEESECckmOpaque *pDot11f)
+{
+ int idx;
+ if (pCCKMie->length) {
+ if (0 <= (idx = find_ie_location(pMac, (tpSirRSNie) pCCKMie,
+ DOT11F_EID_ESECCKMOPAQUE))) {
+ pDot11f->present = 1;
+ /* Dont include OUI */
+ pDot11f->num_data = pCCKMie->cckmIEdata[idx + 1] - 4;
+ cdf_mem_copy(pDot11f->data, pCCKMie->cckmIEdata + idx + 2 + 4, /* EID,len,OUI */
+ pCCKMie->cckmIEdata[idx + 1] - 4); /* Skip OUI */
+ }
+ }
+ return eSIR_SUCCESS;
+} /* End populate_dot11f_ese_cckm_opaque. */
+
+void populate_dot11_tsrsie(tpAniSirGlobal pMac,
+ tSirMacESETSRSIE *pOld,
+ tDot11fIEESETrafStrmRateSet *pDot11f,
+ uint8_t rate_length)
+{
+ pDot11f->tsid = pOld->tsid;
+ cdf_mem_copy(pDot11f->tsrates, pOld->rates, rate_length);
+ pDot11f->num_tsrates = rate_length;
+ pDot11f->present = 1;
+}
+#endif
+
+tSirRetStatus
+populate_dot11f_tclas(tpAniSirGlobal pMac,
+ tSirTclasInfo *pOld, tDot11fIETCLAS *pDot11f)
+{
+ pDot11f->user_priority = pOld->tclas.userPrio;
+ pDot11f->classifier_type = pOld->tclas.classifierType;
+ pDot11f->classifier_mask = pOld->tclas.classifierMask;
+
+ switch (pDot11f->classifier_type) {
+ case SIR_MAC_TCLASTYPE_ETHERNET:
+ cdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source,
+ (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6);
+ cdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest,
+ (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6);
+ pDot11f->info.EthParams.type = pOld->tclasParams.eth.type;
+ break;
+ case SIR_MAC_TCLASTYPE_TCPUDPIP:
+ pDot11f->info.IpParams.version = pOld->version;
+ if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) {
+ cdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params.
+ source, pOld->tclasParams.ipv4.srcIpAddr,
+ 4);
+ cdf_mem_copy(pDot11f->info.IpParams.params.IpV4Params.
+ dest, pOld->tclasParams.ipv4.dstIpAddr, 4);
+ pDot11f->info.IpParams.params.IpV4Params.src_port =
+ pOld->tclasParams.ipv4.srcPort;
+ pDot11f->info.IpParams.params.IpV4Params.dest_port =
+ pOld->tclasParams.ipv4.dstPort;
+ pDot11f->info.IpParams.params.IpV4Params.DSCP =
+ pOld->tclasParams.ipv4.dscp;
+ pDot11f->info.IpParams.params.IpV4Params.proto =
+ pOld->tclasParams.ipv4.protocol;
+ pDot11f->info.IpParams.params.IpV4Params.reserved =
+ pOld->tclasParams.ipv4.rsvd;
+ } else {
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV6Params.source,
+ (uint8_t *) pOld->tclasParams.ipv6.
+ srcIpAddr, 16);
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV6Params.dest,
+ (uint8_t *) pOld->tclasParams.ipv6.
+ dstIpAddr, 16);
+ pDot11f->info.IpParams.params.IpV6Params.src_port =
+ pOld->tclasParams.ipv6.srcPort;
+ pDot11f->info.IpParams.params.IpV6Params.dest_port =
+ pOld->tclasParams.ipv6.dstPort;
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV6Params.flow_label,
+ (uint8_t *) pOld->tclasParams.ipv6.
+ flowLabel, 3);
+ }
+ break;
+ case SIR_MAC_TCLASTYPE_8021DQ:
+ pDot11f->info.Params8021dq.tag_type =
+ pOld->tclasParams.t8021dq.tag;
+ break;
+ default:
+ lim_log(pMac, LOGE,
+ FL("Bad TCLAS type %d in populate_dot11f_tclas.\n"),
+ pDot11f->classifier_type);
+ return eSIR_FAILURE;
+ }
+
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_tclas. */
+
+tSirRetStatus
+populate_dot11f_wmmtclas(tpAniSirGlobal pMac,
+ tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pDot11f)
+{
+ pDot11f->version = 1;
+ pDot11f->user_priority = pOld->tclas.userPrio;
+ pDot11f->classifier_type = pOld->tclas.classifierType;
+ pDot11f->classifier_mask = pOld->tclas.classifierMask;
+
+ switch (pDot11f->classifier_type) {
+ case SIR_MAC_TCLASTYPE_ETHERNET:
+ cdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.source,
+ (uint8_t *) &pOld->tclasParams.eth.srcAddr, 6);
+ cdf_mem_copy((uint8_t *) &pDot11f->info.EthParams.dest,
+ (uint8_t *) &pOld->tclasParams.eth.dstAddr, 6);
+ pDot11f->info.EthParams.type = pOld->tclasParams.eth.type;
+ break;
+ case SIR_MAC_TCLASTYPE_TCPUDPIP:
+ pDot11f->info.IpParams.version = pOld->version;
+ if (SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version) {
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV4Params.source,
+ (uint8_t *) pOld->tclasParams.ipv4.
+ srcIpAddr, 4);
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV4Params.dest,
+ (uint8_t *) pOld->tclasParams.ipv4.
+ dstIpAddr, 4);
+ pDot11f->info.IpParams.params.IpV4Params.src_port =
+ pOld->tclasParams.ipv4.srcPort;
+ pDot11f->info.IpParams.params.IpV4Params.dest_port =
+ pOld->tclasParams.ipv4.dstPort;
+ pDot11f->info.IpParams.params.IpV4Params.DSCP =
+ pOld->tclasParams.ipv4.dscp;
+ pDot11f->info.IpParams.params.IpV4Params.proto =
+ pOld->tclasParams.ipv4.protocol;
+ pDot11f->info.IpParams.params.IpV4Params.reserved =
+ pOld->tclasParams.ipv4.rsvd;
+ } else {
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV6Params.source,
+ (uint8_t *) pOld->tclasParams.ipv6.
+ srcIpAddr, 16);
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV6Params.dest,
+ (uint8_t *) pOld->tclasParams.ipv6.
+ dstIpAddr, 16);
+ pDot11f->info.IpParams.params.IpV6Params.src_port =
+ pOld->tclasParams.ipv6.srcPort;
+ pDot11f->info.IpParams.params.IpV6Params.dest_port =
+ pOld->tclasParams.ipv6.dstPort;
+ cdf_mem_copy((uint8_t *) &pDot11f->info.IpParams.
+ params.IpV6Params.flow_label,
+ (uint8_t *) pOld->tclasParams.ipv6.
+ flowLabel, 3);
+ }
+ break;
+ case SIR_MAC_TCLASTYPE_8021DQ:
+ pDot11f->info.Params8021dq.tag_type =
+ pOld->tclasParams.t8021dq.tag;
+ break;
+ default:
+ lim_log(pMac, LOGE,
+ FL("Bad TCLAS type %d in populate_dot11f_tclas.\n"),
+ pDot11f->classifier_type);
+ return eSIR_FAILURE;
+ }
+
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+
+} /* End populate_dot11f_wmmtclas. */
+
+tSirRetStatus populate_dot11f_wsc(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f)
+{
+
+ uint32_t wpsState;
+
+ pDot11f->Version.present = 1;
+ pDot11f->Version.major = 0x01;
+ pDot11f->Version.minor = 0x00;
+
+ if (wlan_cfg_get_int(pMac, (uint16_t) WNI_CFG_WPS_STATE, &wpsState) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, "Failed to cfg get id %d\n",
+ WNI_CFG_WPS_STATE);
+
+ pDot11f->WPSState.present = 1;
+ pDot11f->WPSState.state = (uint8_t) wpsState;
+
+ pDot11f->APSetupLocked.present = 0;
+
+ pDot11f->SelectedRegistrar.present = 0;
+
+ pDot11f->DevicePasswordID.present = 0;
+
+ pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+ pDot11f->UUID_E.present = 0;
+
+ pDot11f->RFBands.present = 0;
+
+ pDot11f->present = 1;
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f)
+{
+ const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo);
+ uint32_t devicepasswdId;
+
+ pDot11f->APSetupLocked.present = 1;
+ pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked;
+
+ pDot11f->SelectedRegistrar.present = 1;
+ pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar;
+
+ if (wlan_cfg_get_int
+ (pMac, (uint16_t) WNI_CFG_WPS_DEVICE_PASSWORD_ID,
+ &devicepasswdId) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, "Failed to cfg get id %d\n",
+ WNI_CFG_WPS_DEVICE_PASSWORD_ID);
+
+ pDot11f->DevicePasswordID.present = 1;
+ pDot11f->DevicePasswordID.id = (uint16_t) devicepasswdId;
+
+ pDot11f->SelectedRegistrarConfigMethods.present = 1;
+ pDot11f->SelectedRegistrarConfigMethods.methods =
+ pWscIeInfo->selectedRegistrarConfigMethods;
+
+ /* UUID_E and RF Bands are applicable only for dual band AP */
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus de_populate_dot11f_wsc_registrar_info(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f)
+{
+ pDot11f->APSetupLocked.present = 0;
+ pDot11f->SelectedRegistrar.present = 0;
+ pDot11f->DevicePasswordID.present = 0;
+ pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_probe_res_wpsi_es(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *pDot11f,
+ tpPESession psessionEntry)
+{
+
+ tSirWPSProbeRspIE *pSirWPSProbeRspIE;
+
+ pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE;
+
+ if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
+ pDot11f->present = 1;
+ pDot11f->Version.present = 1;
+ pDot11f->Version.major =
+ (uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4);
+ pDot11f->Version.minor =
+ (uint8_t) (pSirWPSProbeRspIE->Version & 0x0F);
+ } else {
+ pDot11f->present = 0;
+ pDot11f->Version.present = 0;
+ }
+
+ if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_STATE_PRESENT) {
+
+ pDot11f->WPSState.present = 1;
+ pDot11f->WPSState.state = (uint8_t) pSirWPSProbeRspIE->wpsState;
+ } else
+ pDot11f->WPSState.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT) {
+ pDot11f->APSetupLocked.present = 1;
+ pDot11f->APSetupLocked.fLocked =
+ pSirWPSProbeRspIE->APSetupLocked;
+ } else
+ pDot11f->APSetupLocked.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) {
+ pDot11f->SelectedRegistrar.present = 1;
+ pDot11f->SelectedRegistrar.selected =
+ pSirWPSProbeRspIE->SelectedRegistra;
+ } else
+ pDot11f->SelectedRegistrar.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT) {
+ pDot11f->DevicePasswordID.present = 1;
+ pDot11f->DevicePasswordID.id =
+ pSirWPSProbeRspIE->DevicePasswordID;
+ } else
+ pDot11f->DevicePasswordID.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT) {
+ pDot11f->SelectedRegistrarConfigMethods.present = 1;
+ pDot11f->SelectedRegistrarConfigMethods.methods =
+ pSirWPSProbeRspIE->SelectedRegistraCfgMethod;
+ } else
+ pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) {
+ pDot11f->ResponseType.present = 1;
+ pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType;
+ } else
+ pDot11f->ResponseType.present = 0;
+
+ if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_UUIDE_PRESENT) {
+ pDot11f->UUID_E.present = 1;
+ cdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSProbeRspIE->UUID_E,
+ WNI_CFG_WPS_UUID_LEN);
+ } else
+ pDot11f->UUID_E.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_MANUFACTURE_PRESENT) {
+ pDot11f->Manufacturer.present = 1;
+ pDot11f->Manufacturer.num_name =
+ pSirWPSProbeRspIE->Manufacture.num_name;
+ cdf_mem_copy(pDot11f->Manufacturer.name,
+ pSirWPSProbeRspIE->Manufacture.name,
+ pSirWPSProbeRspIE->Manufacture.num_name);
+ } else
+ pDot11f->Manufacturer.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) {
+ pDot11f->ModelName.present = 1;
+ pDot11f->ModelName.num_text =
+ pSirWPSProbeRspIE->ModelName.num_text;
+ cdf_mem_copy(pDot11f->ModelName.text,
+ pSirWPSProbeRspIE->ModelName.text,
+ pDot11f->ModelName.num_text);
+ } else
+ pDot11f->ModelName.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) {
+ pDot11f->ModelNumber.present = 1;
+ pDot11f->ModelNumber.num_text =
+ pSirWPSProbeRspIE->ModelNumber.num_text;
+ cdf_mem_copy(pDot11f->ModelNumber.text,
+ pSirWPSProbeRspIE->ModelNumber.text,
+ pDot11f->ModelNumber.num_text);
+ } else
+ pDot11f->ModelNumber.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT) {
+ pDot11f->SerialNumber.present = 1;
+ pDot11f->SerialNumber.num_text =
+ pSirWPSProbeRspIE->SerialNumber.num_text;
+ cdf_mem_copy(pDot11f->SerialNumber.text,
+ pSirWPSProbeRspIE->SerialNumber.text,
+ pDot11f->SerialNumber.num_text);
+ } else
+ pDot11f->SerialNumber.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT) {
+ pDot11f->PrimaryDeviceType.present = 1;
+ cdf_mem_copy(pDot11f->PrimaryDeviceType.oui,
+ pSirWPSProbeRspIE->PrimaryDeviceOUI,
+ sizeof(pSirWPSProbeRspIE->PrimaryDeviceOUI));
+ pDot11f->PrimaryDeviceType.primary_category =
+ (uint16_t) pSirWPSProbeRspIE->PrimaryDeviceCategory;
+ pDot11f->PrimaryDeviceType.sub_category =
+ (uint16_t) pSirWPSProbeRspIE->DeviceSubCategory;
+ } else
+ pDot11f->PrimaryDeviceType.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_DEVICENAME_PRESENT) {
+ pDot11f->DeviceName.present = 1;
+ pDot11f->DeviceName.num_text =
+ pSirWPSProbeRspIE->DeviceName.num_text;
+ cdf_mem_copy(pDot11f->DeviceName.text,
+ pSirWPSProbeRspIE->DeviceName.text,
+ pDot11f->DeviceName.num_text);
+ } else
+ pDot11f->DeviceName.present = 0;
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT) {
+ pDot11f->ConfigMethods.present = 1;
+ pDot11f->ConfigMethods.methods =
+ pSirWPSProbeRspIE->ConfigMethod;
+ } else
+ pDot11f->ConfigMethods.present = 0;
+
+ if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RF_BANDS_PRESENT) {
+ pDot11f->RFBands.present = 1;
+ pDot11f->RFBands.bands = pSirWPSProbeRspIE->RFBand;
+ } else
+ pDot11f->RFBands.present = 0;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_assoc_res_wpsi_es(tpAniSirGlobal pMac,
+ tDot11fIEWscAssocRes *pDot11f,
+ tpPESession psessionEntry)
+{
+ tSirWPSProbeRspIE *pSirWPSProbeRspIE;
+
+ pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE;
+
+ if (pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
+ pDot11f->present = 1;
+ pDot11f->Version.present = 1;
+ pDot11f->Version.major =
+ (uint8_t) ((pSirWPSProbeRspIE->Version & 0xF0) >> 4);
+ pDot11f->Version.minor =
+ (uint8_t) (pSirWPSProbeRspIE->Version & 0x0F);
+ } else {
+ pDot11f->present = 0;
+ pDot11f->Version.present = 0;
+ }
+
+ if (pSirWPSProbeRspIE->
+ FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) {
+ pDot11f->ResponseType.present = 1;
+ pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType;
+ } else
+ pDot11f->ResponseType.present = 0;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_beacon_wpsi_es(tpAniSirGlobal pMac,
+ tDot11fIEWscBeacon *pDot11f,
+ tpPESession psessionEntry)
+{
+
+ tSirWPSBeaconIE *pSirWPSBeaconIE;
+
+ pSirWPSBeaconIE = &psessionEntry->APWPSIEs.SirWPSBeaconIE;
+
+ if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) {
+ pDot11f->present = 1;
+ pDot11f->Version.present = 1;
+ pDot11f->Version.major =
+ (uint8_t) ((pSirWPSBeaconIE->Version & 0xF0) >> 4);
+ pDot11f->Version.minor =
+ (uint8_t) (pSirWPSBeaconIE->Version & 0x0F);
+ } else {
+ pDot11f->present = 0;
+ pDot11f->Version.present = 0;
+ }
+
+ if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_STATE_PRESENT) {
+
+ pDot11f->WPSState.present = 1;
+ pDot11f->WPSState.state = (uint8_t) pSirWPSBeaconIE->wpsState;
+ } else
+ pDot11f->WPSState.present = 0;
+
+ if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_APSETUPLOCK_PRESENT) {
+ pDot11f->APSetupLocked.present = 1;
+ pDot11f->APSetupLocked.fLocked = pSirWPSBeaconIE->APSetupLocked;
+ } else
+ pDot11f->APSetupLocked.present = 0;
+
+ if (pSirWPSBeaconIE->
+ FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT) {
+ pDot11f->SelectedRegistrar.present = 1;
+ pDot11f->SelectedRegistrar.selected =
+ pSirWPSBeaconIE->SelectedRegistra;
+ } else
+ pDot11f->SelectedRegistrar.present = 0;
+
+ if (pSirWPSBeaconIE->
+ FieldPresent & SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT) {
+ pDot11f->DevicePasswordID.present = 1;
+ pDot11f->DevicePasswordID.id =
+ pSirWPSBeaconIE->DevicePasswordID;
+ } else
+ pDot11f->DevicePasswordID.present = 0;
+
+ if (pSirWPSBeaconIE->
+ FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT) {
+ pDot11f->SelectedRegistrarConfigMethods.present = 1;
+ pDot11f->SelectedRegistrarConfigMethods.methods =
+ pSirWPSBeaconIE->SelectedRegistraCfgMethod;
+ } else
+ pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+ if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_UUIDE_PRESENT) {
+ pDot11f->UUID_E.present = 1;
+ cdf_mem_copy(pDot11f->UUID_E.uuid, pSirWPSBeaconIE->UUID_E,
+ WNI_CFG_WPS_UUID_LEN);
+ } else
+ pDot11f->UUID_E.present = 0;
+
+ if (pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_RF_BANDS_PRESENT) {
+ pDot11f->RFBands.present = 1;
+ pDot11f->RFBands.bands = pSirWPSBeaconIE->RFBand;
+ } else
+ pDot11f->RFBands.present = 0;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_wsc_in_probe_res(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *pDot11f)
+{
+ uint32_t cfgMethods;
+ uint32_t cfgStrLen;
+ uint32_t val;
+ uint32_t wpsVersion, wpsState;
+
+ if (wlan_cfg_get_int(pMac, (uint16_t) WNI_CFG_WPS_VERSION, &wpsVersion) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, "Failed to cfg get id %d\n",
+ WNI_CFG_WPS_VERSION);
+
+ pDot11f->Version.present = 1;
+ pDot11f->Version.major = (uint8_t) ((wpsVersion & 0xF0) >> 4);
+ pDot11f->Version.minor = (uint8_t) (wpsVersion & 0x0F);
+
+ if (wlan_cfg_get_int(pMac, (uint16_t) WNI_CFG_WPS_STATE, &wpsState) !=
+ eSIR_SUCCESS)
+ lim_log(pMac, LOGP, "Failed to cfg get id %d\n",
+ WNI_CFG_WPS_STATE);
+
+ pDot11f->WPSState.present = 1;
+ pDot11f->WPSState.state = (uint8_t) wpsState;
+
+ pDot11f->APSetupLocked.present = 0;
+
+ pDot11f->SelectedRegistrar.present = 0;
+
+ pDot11f->DevicePasswordID.present = 0;
+
+ pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+ pDot11f->ResponseType.present = 1;
+ if ((pMac->lim.wscIeInfo.reqType == REQ_TYPE_REGISTRAR) ||
+ (pMac->lim.wscIeInfo.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)) {
+ pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X;
+ } else {
+ pDot11f->ResponseType.resType = RESP_TYPE_AP;
+ }
+
+ /* UUID is a 16 byte long binary. Still use wlan_cfg_get_str to get it. */
+ pDot11f->UUID_E.present = 1;
+ cfgStrLen = WNI_CFG_WPS_UUID_LEN;
+ if (wlan_cfg_get_str(pMac,
+ WNI_CFG_WPS_UUID,
+ pDot11f->UUID_E.uuid, &cfgStrLen) != eSIR_SUCCESS) {
+ *(pDot11f->UUID_E.uuid) = '\0';
+ }
+
+ pDot11f->Manufacturer.present = 1;
+ cfgStrLen = WNI_CFG_MANUFACTURER_NAME_LEN;
+ if (wlan_cfg_get_str(pMac,
+ WNI_CFG_MANUFACTURER_NAME,
+ pDot11f->Manufacturer.name,
+ &cfgStrLen) != eSIR_SUCCESS) {
+ pDot11f->Manufacturer.num_name = 0;
+ } else {
+ pDot11f->Manufacturer.num_name =
+ (uint8_t) (cfgStrLen & 0x000000FF);
+ }
+
+ pDot11f->ModelName.present = 1;
+ cfgStrLen = WNI_CFG_MODEL_NAME_LEN;
+ if (wlan_cfg_get_str(pMac,
+ WNI_CFG_MODEL_NAME,
+ pDot11f->ModelName.text,
+ &cfgStrLen) != eSIR_SUCCESS) {
+ pDot11f->ModelName.num_text = 0;
+ } else {
+ pDot11f->ModelName.num_text =
+ (uint8_t) (cfgStrLen & 0x000000FF);
+ }
+
+ pDot11f->ModelNumber.present = 1;
+ cfgStrLen = WNI_CFG_MODEL_NUMBER_LEN;
+ if (wlan_cfg_get_str(pMac,
+ WNI_CFG_MODEL_NUMBER,
+ pDot11f->ModelNumber.text,
+ &cfgStrLen) != eSIR_SUCCESS) {
+ pDot11f->ModelNumber.num_text = 0;
+ } else {
+ pDot11f->ModelNumber.num_text =
+ (uint8_t) (cfgStrLen & 0x000000FF);
+ }
+
+ pDot11f->SerialNumber.present = 1;
+ cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN;
+ if (wlan_cfg_get_str(pMac,
+ WNI_CFG_MANUFACTURER_PRODUCT_VERSION,
+ pDot11f->SerialNumber.text,
+ &cfgStrLen) != eSIR_SUCCESS) {
+ pDot11f->SerialNumber.num_text = 0;
+ } else {
+ pDot11f->SerialNumber.num_text =
+ (uint8_t) (cfgStrLen & 0x000000FF);
+ }
+
+ pDot11f->PrimaryDeviceType.present = 1;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("cfg get prim device category failed\n"));
+ } else
+ pDot11f->PrimaryDeviceType.primary_category = (uint16_t) val;
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WPS_PIMARY_DEVICE_OUI, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP, FL("cfg get prim device OUI failed\n"));
+ } else {
+ *(pDot11f->PrimaryDeviceType.oui) =
+ (uint8_t) ((val >> 24) & 0xff);
+ *(pDot11f->PrimaryDeviceType.oui + 1) =
+ (uint8_t) ((val >> 16) & 0xff);
+ *(pDot11f->PrimaryDeviceType.oui + 2) =
+ (uint8_t) ((val >> 8) & 0xff);
+ *(pDot11f->PrimaryDeviceType.oui + 3) =
+ (uint8_t) ((val & 0xff));
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_WPS_DEVICE_SUB_CATEGORY, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("cfg get prim device sub category failed\n"));
+ } else
+ pDot11f->PrimaryDeviceType.sub_category = (uint16_t) val;
+
+ pDot11f->DeviceName.present = 1;
+ cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN;
+ if (wlan_cfg_get_str(pMac,
+ WNI_CFG_MANUFACTURER_PRODUCT_NAME,
+ pDot11f->DeviceName.text,
+ &cfgStrLen) != eSIR_SUCCESS) {
+ pDot11f->DeviceName.num_text = 0;
+ } else {
+ pDot11f->DeviceName.num_text =
+ (uint8_t) (cfgStrLen & 0x000000FF);
+ }
+
+ if (wlan_cfg_get_int(pMac,
+ WNI_CFG_WPS_CFG_METHOD,
+ &cfgMethods) != eSIR_SUCCESS) {
+ pDot11f->ConfigMethods.present = 0;
+ pDot11f->ConfigMethods.methods = 0;
+ } else {
+ pDot11f->ConfigMethods.present = 1;
+ pDot11f->ConfigMethods.methods =
+ (uint16_t) (cfgMethods & 0x0000FFFF);
+ }
+
+ pDot11f->RFBands.present = 0;
+
+ pDot11f->present = 1;
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *
+ pDot11f)
+{
+ const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo);
+ uint32_t devicepasswdId;
+
+ pDot11f->APSetupLocked.present = 1;
+ pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked;
+
+ pDot11f->SelectedRegistrar.present = 1;
+ pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar;
+
+ if (wlan_cfg_get_int
+ (pMac, (uint16_t) WNI_CFG_WPS_DEVICE_PASSWORD_ID,
+ &devicepasswdId) != eSIR_SUCCESS)
+ lim_log(pMac, LOGP, "Failed to cfg get id %d\n",
+ WNI_CFG_WPS_DEVICE_PASSWORD_ID);
+
+ pDot11f->DevicePasswordID.present = 1;
+ pDot11f->DevicePasswordID.id = (uint16_t) devicepasswdId;
+
+ pDot11f->SelectedRegistrarConfigMethods.present = 1;
+ pDot11f->SelectedRegistrarConfigMethods.methods =
+ pWscIeInfo->selectedRegistrarConfigMethods;
+
+ /* UUID_E and RF Bands are applicable only for dual band AP */
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus de_populate_dot11f_wsc_registrar_info_in_probe_res(tpAniSirGlobal pMac,
+ tDot11fIEWscProbeRes *
+ pDot11f)
+{
+ pDot11f->APSetupLocked.present = 0;
+ pDot11f->SelectedRegistrar.present = 0;
+ pDot11f->DevicePasswordID.present = 0;
+ pDot11f->SelectedRegistrarConfigMethods.present = 0;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_assoc_res_wsc_ie(tpAniSirGlobal pMac,
+ tDot11fIEWscAssocRes *pDot11f,
+ tpSirAssocReq pRcvdAssocReq)
+{
+ tDot11fIEWscAssocReq parsedWscAssocReq = { 0, };
+ uint8_t *wscIe;
+
+ wscIe =
+ limGetWscIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata,
+ pRcvdAssocReq->addIE.length);
+ if (wscIe != NULL) {
+ /* retreive WSC IE from given AssocReq */
+ dot11f_unpack_ie_wsc_assoc_req(pMac, wscIe + 2 + 4, /* EID, length, OUI */
+ wscIe[1] - 4, /* length without OUI */
+ &parsedWscAssocReq);
+ pDot11f->present = 1;
+ /* version has to be 0x10 */
+ pDot11f->Version.present = 1;
+ pDot11f->Version.major = 0x1;
+ pDot11f->Version.minor = 0x0;
+
+ pDot11f->ResponseType.present = 1;
+
+ if ((parsedWscAssocReq.RequestType.reqType ==
+ REQ_TYPE_REGISTRAR)
+ || (parsedWscAssocReq.RequestType.reqType ==
+ REQ_TYPE_WLAN_MANAGER_REGISTRAR)) {
+ pDot11f->ResponseType.resType =
+ RESP_TYPE_ENROLLEE_OPEN_8021X;
+ } else {
+ pDot11f->ResponseType.resType = RESP_TYPE_AP;
+ }
+ /* Version infomration should be taken from our capability as well as peers */
+ /* TODO: currently it takes from peers only */
+ if (parsedWscAssocReq.VendorExtension.present &&
+ parsedWscAssocReq.VendorExtension.Version2.present) {
+ pDot11f->VendorExtension.present = 1;
+ pDot11f->VendorExtension.vendorId[0] = 0x00;
+ pDot11f->VendorExtension.vendorId[1] = 0x37;
+ pDot11f->VendorExtension.vendorId[2] = 0x2A;
+ pDot11f->VendorExtension.Version2.present = 1;
+ pDot11f->VendorExtension.Version2.major =
+ parsedWscAssocReq.VendorExtension.Version2.major;
+ pDot11f->VendorExtension.Version2.minor =
+ parsedWscAssocReq.VendorExtension.Version2.minor;
+ }
+ }
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11_assoc_res_p2p_ie(tpAniSirGlobal pMac,
+ tDot11fIEP2PAssocRes *pDot11f,
+ tpSirAssocReq pRcvdAssocReq)
+{
+ uint8_t *p2pIe;
+
+ p2pIe =
+ limGetP2pIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata,
+ pRcvdAssocReq->addIE.length);
+ if (p2pIe != NULL) {
+ pDot11f->present = 1;
+ pDot11f->P2PStatus.present = 1;
+ pDot11f->P2PStatus.status = eSIR_SUCCESS;
+ pDot11f->ExtendedListenTiming.present = 0;
+ }
+ return eSIR_SUCCESS;
+}
+
+#if defined WLAN_FEATURE_VOWIFI
+
+tSirRetStatus populate_dot11f_wfatpc(tpAniSirGlobal pMac,
+ tDot11fIEWFATPC *pDot11f, uint8_t txPower,
+ uint8_t linkMargin)
+{
+ pDot11f->txPower = txPower;
+ pDot11f->linkMargin = linkMargin;
+ pDot11f->present = 1;
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus populate_dot11f_beacon_report(tpAniSirGlobal pMac,
+ tDot11fIEMeasurementReport *pDot11f,
+ tSirMacBeaconReport *pBeaconReport)
+{
+
+ pDot11f->report.Beacon.regClass = pBeaconReport->regClass;
+ pDot11f->report.Beacon.channel = pBeaconReport->channel;
+ cdf_mem_copy(pDot11f->report.Beacon.meas_start_time,
+ pBeaconReport->measStartTime,
+ sizeof(pDot11f->report.Beacon.meas_start_time));
+ pDot11f->report.Beacon.meas_duration = pBeaconReport->measDuration;
+ pDot11f->report.Beacon.condensed_PHY = pBeaconReport->phyType;
+ pDot11f->report.Beacon.reported_frame_type =
+ !pBeaconReport->bcnProbeRsp;
+ pDot11f->report.Beacon.RCPI = pBeaconReport->rcpi;
+ pDot11f->report.Beacon.RSNI = pBeaconReport->rsni;
+ cdf_mem_copy(pDot11f->report.Beacon.BSSID, pBeaconReport->bssid,
+ sizeof(tSirMacAddr));
+ pDot11f->report.Beacon.antenna_id = pBeaconReport->antennaId;
+ pDot11f->report.Beacon.parent_TSF = pBeaconReport->parentTSF;
+
+ if (pBeaconReport->numIes) {
+ pDot11f->report.Beacon.BeaconReportFrmBody.present = 1;
+ cdf_mem_copy(pDot11f->report.Beacon.BeaconReportFrmBody.
+ reportedFields, pBeaconReport->Ies,
+ pBeaconReport->numIes);
+ pDot11f->report.Beacon.BeaconReportFrmBody.num_reportedFields =
+ pBeaconReport->numIes;
+ }
+
+ return eSIR_SUCCESS;
+
+}
+
+tSirRetStatus populate_dot11f_rrm_ie(tpAniSirGlobal pMac,
+ tDot11fIERRMEnabledCap *pDot11f,
+ tpPESession psessionEntry)
+{
+ tpRRMCaps pRrmCaps;
+
+ pRrmCaps = rrm_get_capabilities(pMac, psessionEntry);
+
+ pDot11f->LinkMeasurement = pRrmCaps->LinkMeasurement;
+ pDot11f->NeighborRpt = pRrmCaps->NeighborRpt;
+ pDot11f->parallel = pRrmCaps->parallel;
+ pDot11f->repeated = pRrmCaps->repeated;
+ pDot11f->BeaconPassive = pRrmCaps->BeaconPassive;
+ pDot11f->BeaconActive = pRrmCaps->BeaconActive;
+ pDot11f->BeaconTable = pRrmCaps->BeaconTable;
+ pDot11f->BeaconRepCond = pRrmCaps->BeaconRepCond;
+ pDot11f->FrameMeasurement = pRrmCaps->FrameMeasurement;
+ pDot11f->ChannelLoad = pRrmCaps->ChannelLoad;
+ pDot11f->NoiseHistogram = pRrmCaps->NoiseHistogram;
+ pDot11f->statistics = pRrmCaps->statistics;
+ pDot11f->LCIMeasurement = pRrmCaps->LCIMeasurement;
+ pDot11f->LCIAzimuth = pRrmCaps->LCIAzimuth;
+ pDot11f->TCMCapability = pRrmCaps->TCMCapability;
+ pDot11f->triggeredTCM = pRrmCaps->triggeredTCM;
+ pDot11f->APChanReport = pRrmCaps->APChanReport;
+ pDot11f->RRMMIBEnabled = pRrmCaps->RRMMIBEnabled;
+ pDot11f->operatingChanMax = pRrmCaps->operatingChanMax;
+ pDot11f->nonOperatinChanMax = pRrmCaps->nonOperatingChanMax;
+ pDot11f->MeasurementPilot = pRrmCaps->MeasurementPilot;
+ pDot11f->MeasurementPilotEnabled = pRrmCaps->MeasurementPilotEnabled;
+ pDot11f->NeighborTSFOffset = pRrmCaps->NeighborTSFOffset;
+ pDot11f->RCPIMeasurement = pRrmCaps->RCPIMeasurement;
+ pDot11f->RSNIMeasurement = pRrmCaps->RSNIMeasurement;
+ pDot11f->BssAvgAccessDelay = pRrmCaps->BssAvgAccessDelay;
+ pDot11f->BSSAvailAdmission = pRrmCaps->BSSAvailAdmission;
+ pDot11f->AntennaInformation = pRrmCaps->AntennaInformation;
+ pDot11f->fine_time_meas_rpt = pRrmCaps->fine_time_meas_rpt;
+ pDot11f->lci_capability = pRrmCaps->lci_capability;
+ pDot11f->reserved = pRrmCaps->reserved;
+
+ pDot11f->present = 1;
+ return eSIR_SUCCESS;
+}
+#endif
+
+#if defined WLAN_FEATURE_VOWIFI_11R
+void populate_mdie(tpAniSirGlobal pMac,
+ tDot11fIEMobilityDomain *pDot11f,
+ uint8_t mdie[SIR_MDIE_SIZE])
+{
+ pDot11f->present = 1;
+ pDot11f->MDID = (uint16_t) ((mdie[1] << 8) | (mdie[0]));
+
+ /* Plugfest fix */
+ pDot11f->overDSCap = (mdie[2] & 0x01);
+ pDot11f->resourceReqCap = ((mdie[2] >> 1) & 0x01);
+
+}
+
+void populate_ft_info(tpAniSirGlobal pMac, tDot11fIEFTInfo *pDot11f)
+{
+ pDot11f->present = 1;
+ pDot11f->IECount = 0; /* TODO: put valid data during reassoc. */
+ /* All other info is zero. */
+
+}
+#endif
+
+void populate_dot11f_assoc_rsp_rates(tpAniSirGlobal pMac,
+ tDot11fIESuppRates *pSupp,
+ tDot11fIEExtSuppRates *pExt,
+ uint16_t *_11bRates, uint16_t *_11aRates)
+{
+ uint8_t num_supp = 0, num_ext = 0;
+ uint8_t i, j;
+
+ for (i = 0; (i < SIR_NUM_11B_RATES && _11bRates[i]); i++, num_supp++) {
+ pSupp->rates[num_supp] = (uint8_t) _11bRates[i];
+ }
+ for (j = 0; (j < SIR_NUM_11A_RATES && _11aRates[j]); j++) {
+ if (num_supp < 8)
+ pSupp->rates[num_supp++] = (uint8_t) _11aRates[j];
+ else
+ pExt->rates[num_ext++] = (uint8_t) _11aRates[j];
+ }
+
+ if (num_supp) {
+ pSupp->num_rates = num_supp;
+ pSupp->present = 1;
+ }
+ if (num_ext) {
+ pExt->num_rates = num_ext;
+ pExt->present = 1;
+ }
+}
+
+void populate_dot11f_timeout_interval(tpAniSirGlobal pMac,
+ tDot11fIETimeoutInterval *pDot11f,
+ uint8_t type, uint32_t value)
+{
+ pDot11f->present = 1;
+ pDot11f->timeoutType = type;
+ pDot11f->timeoutValue = value;
+}
+
+/**
+ * populate_dot11f_timing_advert_frame() - Populate the TA mgmt frame fields
+ * @pMac: the MAC context
+ * @frame: pointer to the TA frame
+ *
+ * Return: The SIR status.
+ */
+tSirRetStatus populate_dot11f_timing_advert_frame(tpAniSirGlobal mac_ctx,
+ tDot11fTimingAdvertisementFrame *frame)
+{
+ uint32_t val, codelen, len;
+ uint16_t item;
+ uint8_t temp[CFG_MAX_STR_LEN], code[3];
+ tSirRetStatus nSirStatus;
+
+ /* Capabilities */
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_PRIVACY_ENABLED, &val);
+ if (val)
+ frame->Capabilities.privacy = 1;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_SHORT_PREAMBLE, &val);
+ if (val)
+ frame->Capabilities.shortPreamble = 1;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_11H_ENABLED, &val);
+ if (val)
+ frame->Capabilities.spectrumMgt = 1;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_QOS_ENABLED, &val);
+ if (val)
+ frame->Capabilities.qos = 1;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_APSD_ENABLED, &val);
+ if (val)
+ frame->Capabilities.apsd = 1;
+
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_BLOCK_ACK_ENABLED, &val);
+ frame->Capabilities.delayedBA =
+ (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1);
+ frame->Capabilities.immediateBA =
+ (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1);
+
+ /* Country */
+ item = WNI_CFG_MAX_TX_POWER_5;
+ CFG_GET_STR(nSirStatus, mac_ctx, item, temp, len,
+ WNI_CFG_MAX_TX_POWER_5_LEN);
+ item = WNI_CFG_COUNTRY_CODE;
+ CFG_GET_STR(nSirStatus, mac_ctx, item, code, codelen, 3);
+ cdf_mem_copy(&frame->Country, code, codelen);
+ if (len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE)
+ len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE;
+
+ frame->Country.num_triplets = (uint8_t)(len / 3);
+ cdf_mem_copy((uint8_t *)&frame->Country.triplets, temp, len);
+ frame->Country.present = 1;
+
+ /* PowerConstraints */
+ wlan_cfg_get_int(mac_ctx, WNI_CFG_LOCAL_POWER_CONSTRAINT, &val);
+ frame->PowerConstraints.localPowerConstraints = (uint8_t)val;
+ frame->PowerConstraints.present = 1;
+
+ /* TimeAdvertisement */
+ frame->TimeAdvertisement.present = 1;
+ frame->TimeAdvertisement.timing_capabilities = 1;
+
+ return nSirStatus;
+}
+
+/* parser_api.c ends here. */
diff --git a/core/mac/src/sys/legacy/src/utils/src/utils_api.c b/core/mac/src/sys/legacy/src/utils/src/utils_api.c
new file mode 100644
index 0000000..524bbd2
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/utils_api.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/* ================================================================== */
+/* */
+/* File: utils_api.cc */
+/* */
+/* Description: Implemention of a few utility routines. */
+/* */
+/* Author: Neelay Das */
+/* */
+/* // */
+/* Change gHistory: */
+/* 12/15/2003 - NDA - Initial version. */
+/* */
+/* =================================================================== */
+
+#include "utils_api.h"
+
+/* ------------------------------------------------------------------- */
+/**
+ * sir_dump_buf()
+ *
+ * FUNCTION:
+ * This function is called to dump a buffer with a certain level
+ *
+ * LOGIC:
+ *
+ * ASSUMPTIONS:
+ * None.
+ *
+ * NOTE:
+ *
+ * @param pBuf: buffer pointer
+ * @return None.
+ */
+void
+sir_dump_buf(tpAniSirGlobal pMac, uint8_t modId, uint32_t level, uint8_t *buf,
+ uint32_t size)
+{
+ uint32_t i;
+
+ if (level > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(modId)])
+ return;
+
+ log_dbg(pMac, modId, level, FL("Dumping %d bytes in host order\n"),
+ size);
+
+ for (i = 0; (i + 7) < size; i += 8) {
+ log_dbg(pMac, modId, level,
+ "%02x %02x %02x %02x %02x %02x %02x %02x \n",
+ buf[i],
+ buf[i + 1],
+ buf[i + 2],
+ buf[i + 3],
+ buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
+ }
+
+ /* Dump the bytes in the last line */
+ for (; i < size; i++) {
+ log_dbg(pMac, modId, level, "%02x ", buf[i]);
+
+ if ((i + 1) == size)
+ log_dbg(pMac, modId, level, "\n");
+ }
+
+} /*** end sir_dump_buf() ***/
diff --git a/core/mac/src/sys/legacy/src/utils/src/utils_parser.c b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
new file mode 100644
index 0000000..9b91902
--- /dev/null
+++ b/core/mac/src/sys/legacy/src/utils/src/utils_parser.c
@@ -0,0 +1,827 @@
+/*
+ * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ *
+ * This file utils_parser.cc contains the code for parsing
+ * 802.11 messages.
+ * Author: Pierre Vandwalle
+ * Date: 03/18/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ *
+ */
+
+#include "ani_global.h"
+#include "utils_parser.h"
+#include "lim_ser_des_utils.h"
+
+void convert_ssid(tpAniSirGlobal pMac, tSirMacSSid *pOld, tDot11fIESSID *pNew)
+{
+ pOld->length = pNew->num_ssid;
+ cdf_mem_copy(pOld->ssId, pNew->ssid, pNew->num_ssid);
+}
+
+void convert_supp_rates(tpAniSirGlobal pMac,
+ tSirMacRateSet *pOld, tDot11fIESuppRates *pNew)
+{
+ pOld->numRates = pNew->num_rates;
+ cdf_mem_copy(pOld->rate, pNew->rates, pNew->num_rates);
+}
+
+void convert_ext_supp_rates(tpAniSirGlobal pMac,
+ tSirMacRateSet *pOld, tDot11fIEExtSuppRates *pNew)
+{
+ pOld->numRates = pNew->num_rates;
+ cdf_mem_copy(pOld->rate, pNew->rates, pNew->num_rates);
+}
+
+void convert_qos_caps(tpAniSirGlobal pMac,
+ tSirMacQosCapabilityIE *pOld, tDot11fIEQOSCapsAp *pNew)
+{
+ pOld->type = 46;
+ pOld->length = 1;
+
+ pOld->qosInfo.count = pNew->count;
+}
+
+void convert_qos_caps_station(tpAniSirGlobal pMac,
+ tSirMacQosCapabilityStaIE *pOld,
+ tDot11fIEQOSCapsStation *pNew)
+{
+ pOld->type = 46;
+ pOld->length = 1;
+
+ pOld->qosInfo.moreDataAck = pNew->more_data_ack;
+ pOld->qosInfo.maxSpLen = pNew->max_sp_length;
+ pOld->qosInfo.qack = pNew->qack;
+ pOld->qosInfo.acbe_uapsd = pNew->acbe_uapsd;
+ pOld->qosInfo.acbk_uapsd = pNew->acbk_uapsd;
+ pOld->qosInfo.acvi_uapsd = pNew->acvi_uapsd;
+ pOld->qosInfo.acvo_uapsd = pNew->acvo_uapsd;
+}
+
+tSirRetStatus convert_wpa(tpAniSirGlobal pMac,
+ tSirMacWpaInfo *pOld, tDot11fIEWPA *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into an */
+ /* array... */
+ uint8_t buffer[257];
+ uint32_t status, written = 0, nbuffer = 257;
+ status = dot11f_pack_ie_wpa(pMac, pNew, buffer, nbuffer, &written);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOG2, FL("Failed to re-pack the WPA IE (0x%0x"
+ "8).\n"), status);
+ return eSIR_FAILURE;
+ }
+
+ pOld->length = (uint8_t) written - 2;
+ cdf_mem_copy(pOld->info, buffer + 2, pOld->length);
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus convert_wpa_opaque(tpAniSirGlobal pMac,
+ tSirMacWpaInfo *pOld, tDot11fIEWPAOpaque *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into */
+ /* an opaque array. Note that we need to explicitly add the OUI! */
+ pOld->length = pNew->num_data + 4;
+ pOld->info[0] = 0x00;
+ pOld->info[1] = 0x50;
+ pOld->info[2] = 0xf2;
+ pOld->info[3] = 0x01;
+ cdf_mem_copy(pOld->info + 4, pNew->data, pNew->num_data);
+
+ return eSIR_SUCCESS;
+}
+
+#ifdef FEATURE_WLAN_WAPI
+tSirRetStatus convert_wapi_opaque(tpAniSirGlobal pMac,
+ tSirMacWapiInfo *pOld,
+ tDot11fIEWAPIOpaque *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into */
+ /* an opaque array. Note that we need to explicitly add the OUI! */
+ pOld->length = pNew->num_data;
+ cdf_mem_copy(pOld->info, pNew->data, pNew->num_data);
+
+ return eSIR_SUCCESS;
+}
+#endif
+
+tSirRetStatus convert_wsc_opaque(tpAniSirGlobal pMac,
+ tSirAddie *pOld, tDot11fIEWscIEOpaque *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into */
+ /* an opaque array. Note that we need to explicitly add the vendorIE and OUI ! */
+ uint8_t curAddIELen = pOld->length;
+
+ pOld->length = curAddIELen + pNew->num_data + 6;
+ pOld->addIEdata[curAddIELen++] = 0xdd;
+ pOld->addIEdata[curAddIELen++] = pNew->num_data + 4;
+ pOld->addIEdata[curAddIELen++] = 0x00;
+ pOld->addIEdata[curAddIELen++] = 0x50;
+ pOld->addIEdata[curAddIELen++] = 0xf2;
+ pOld->addIEdata[curAddIELen++] = 0x04;
+ cdf_mem_copy(pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data);
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus convert_p2p_opaque(tpAniSirGlobal pMac,
+ tSirAddie *pOld, tDot11fIEP2PIEOpaque *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into */
+ /* an opaque array. Note that we need to explicitly add the vendorIE and OUI ! */
+ uint8_t curAddIELen = pOld->length;
+
+ pOld->length = curAddIELen + pNew->num_data + 6;
+ pOld->addIEdata[curAddIELen++] = 0xdd;
+ pOld->addIEdata[curAddIELen++] = pNew->num_data + 4;
+ pOld->addIEdata[curAddIELen++] = 0x50;
+ pOld->addIEdata[curAddIELen++] = 0x6f;
+ pOld->addIEdata[curAddIELen++] = 0x9A;
+ pOld->addIEdata[curAddIELen++] = 0x09;
+ cdf_mem_copy(pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data);
+
+ return eSIR_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_WFD
+tSirRetStatus convert_wfd_opaque(tpAniSirGlobal pMac,
+ tSirAddie *pOld, tDot11fIEWFDIEOpaque *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into */
+ /* an opaque array. Note that we need to explicitly add the vendorIE and OUI ! */
+ uint8_t curAddIELen = pOld->length;
+
+ pOld->length = curAddIELen + pNew->num_data + 6;
+ pOld->addIEdata[curAddIELen++] = 0xdd;
+ pOld->addIEdata[curAddIELen++] = pNew->num_data + 4;
+ pOld->addIEdata[curAddIELen++] = 0x50;
+ pOld->addIEdata[curAddIELen++] = 0x6f;
+ pOld->addIEdata[curAddIELen++] = 0x9A;
+ pOld->addIEdata[curAddIELen++] = 0x0a;
+ cdf_mem_copy(pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data);
+
+ return eSIR_SUCCESS;
+}
+#endif
+
+tSirRetStatus convert_rsn(tpAniSirGlobal pMac,
+ tSirMacRsnInfo *pOld, tDot11fIERSN *pNew)
+{
+ uint8_t buffer[257];
+ uint32_t status, written = 0, nbuffer = 257;
+ status = dot11f_pack_ie_rsn(pMac, pNew, buffer, nbuffer, &written);
+ if (DOT11F_FAILED(status)) {
+ dot11f_log(pMac, LOG2, FL("Failed to re-pack the RSN IE (0x%0x"
+ "8).\n"), status);
+ return eSIR_FAILURE;
+ }
+
+ pOld->length = (uint8_t) written - 2;
+ cdf_mem_copy(pOld->info, buffer + 2, pOld->length);
+
+ return eSIR_SUCCESS;
+}
+
+tSirRetStatus convert_rsn_opaque(tpAniSirGlobal pMac,
+ tSirMacRsnInfo *pOld, tDot11fIERSNOpaque *pNew)
+{
+ /* This is awful, I know, but the old code just rammed the IE into */
+ /* an opaque array. */
+ pOld->length = pNew->num_data;
+ cdf_mem_copy(pOld->info, pNew->data, pOld->length);
+
+ return eSIR_SUCCESS;
+}
+
+void convert_power_caps(tpAniSirGlobal pMac,
+ tSirMacPowerCapabilityIE *pOld,
+ tDot11fIEPowerCaps *pNew)
+{
+ pOld->type = 33;
+ pOld->length = 2;
+ pOld->minTxPower = pNew->minTxPower;
+ pOld->maxTxPower = pNew->maxTxPower;
+}
+
+void convert_supp_channels(tpAniSirGlobal pMac,
+ tSirMacSupportedChannelIE *pOld,
+ tDot11fIESuppChannels *pNew)
+{
+ pOld->type = 36;
+ pOld->length = (pNew->num_bands * 2);
+ cdf_mem_copy((uint8_t *) pOld->supportedChannels,
+ (uint8_t *) pNew->bands, pOld->length);
+}
+
+void convert_cf_params(tpAniSirGlobal pMac,
+ tSirMacCfParamSet *pOld, tDot11fIECFParams *pNew)
+{
+ pOld->cfpCount = pNew->cfp_count;
+ pOld->cfpPeriod = pNew->cfp_period;
+ pOld->cfpMaxDuration = pNew->cfp_maxduration;
+ pOld->cfpDurRemaining = pNew->cfp_durremaining;
+}
+
+void convert_fh_params(tpAniSirGlobal pMac,
+ tSirMacFHParamSet *pOld, tDot11fIEFHParamSet *pNew)
+{
+ pOld->dwellTime = pNew->dwell_time;
+ pOld->hopSet = pNew->hop_set;
+ pOld->hopPattern = pNew->hop_pattern;
+ pOld->hopIndex = pNew->hop_index;
+}
+
+void convert_tim(tpAniSirGlobal pMac, tSirMacTim *pOld, tDot11fIETIM *pNew)
+{
+ pOld->dtimCount = pNew->dtim_count;
+ pOld->dtimPeriod = pNew->dtim_period;
+ pOld->bitmapControl = pNew->bmpctl;
+ pOld->bitmapLength = pNew->num_vbmp;
+
+ cdf_mem_copy(pOld->bitmap, pNew->vbmp, pNew->num_vbmp);
+}
+
+void convert_country(tpAniSirGlobal pMac,
+ tSirCountryInformation *pOld, tDot11fIECountry *pNew)
+{
+ int i;
+
+ cdf_mem_copy(pOld->countryString, pNew->country, COUNTRY_STRING_LENGTH);
+
+ pOld->numIntervals = pNew->num_triplets;
+
+ for (i = 0; i < pNew->num_triplets; ++i) {
+ pOld->channelTransmitPower[i].channelNumber =
+ pNew->triplets[i][0];
+ pOld->channelTransmitPower[i].numChannel = pNew->triplets[i][1];
+ pOld->channelTransmitPower[i].maxTransmitPower =
+ pNew->triplets[i][2];
+ }
+}
+
+void convert_wmm_params(tpAniSirGlobal pMac,
+ tSirMacEdcaParamSetIE *pOld, tDot11fIEWMMParams *pNew)
+{
+ pOld->type = 221;
+ pOld->length = 24;
+
+ cdf_mem_copy((uint8_t *) &pOld->qosInfo, (uint8_t *) &pNew->qosInfo,
+ 1);
+
+ pOld->acbe.aci.aifsn = pNew->acbe_aifsn;
+ pOld->acbe.aci.acm = pNew->acbe_acm;
+ pOld->acbe.aci.aci = pNew->acbe_aci;
+ pOld->acbe.cw.min = pNew->acbe_acwmin;
+ pOld->acbe.cw.max = pNew->acbe_acwmax;
+ pOld->acbe.txoplimit = pNew->acbe_txoplimit;
+
+ pOld->acbk.aci.aifsn = pNew->acbk_aifsn;
+ pOld->acbk.aci.acm = pNew->acbk_acm;
+ pOld->acbk.aci.aci = pNew->acbk_aci;
+ pOld->acbk.cw.min = pNew->acbk_acwmin;
+ pOld->acbk.cw.max = pNew->acbk_acwmax;
+ pOld->acbk.txoplimit = pNew->acbk_txoplimit;
+
+ pOld->acvi.aci.aifsn = pNew->acvi_aifsn;
+ pOld->acvi.aci.acm = pNew->acvi_acm;
+ pOld->acvi.aci.aci = pNew->acvi_aci;
+ pOld->acvi.cw.min = pNew->acvi_acwmin;
+ pOld->acvi.cw.max = pNew->acvi_acwmax;
+ pOld->acvi.txoplimit = pNew->acvi_txoplimit;
+
+ pOld->acvo.aci.aifsn = pNew->acvo_aifsn;
+ pOld->acvo.aci.acm = pNew->acvo_acm;
+ pOld->acvo.aci.aci = pNew->acvo_aci;
+ pOld->acvo.cw.min = pNew->acvo_acwmin;
+ pOld->acvo.cw.max = pNew->acvo_acwmax;
+ pOld->acvo.txoplimit = pNew->acvo_txoplimit;
+}
+
+void convert_erp_info(tpAniSirGlobal pMac,
+ tSirMacErpInfo *pOld, tDot11fIEERPInfo *pNew)
+{
+ pOld->nonErpPresent = pNew->non_erp_present;
+ pOld->useProtection = pNew->use_prot;
+ pOld->barkerPreambleMode = pNew->barker_preamble;
+}
+
+void convert_edca_param(tpAniSirGlobal pMac,
+ tSirMacEdcaParamSetIE *pOld,
+ tDot11fIEEDCAParamSet *pNew)
+{
+ pOld->type = 12;
+ pOld->length = 20;
+
+ cdf_mem_copy((uint8_t *) &pOld->qosInfo, (uint8_t *) &pNew->qos, 1);
+
+ pOld->acbe.aci.aifsn = pNew->acbe_aifsn;
+ pOld->acbe.aci.acm = pNew->acbe_acm;
+ pOld->acbe.aci.aci = pNew->acbe_aci;
+ pOld->acbe.cw.min = pNew->acbe_acwmin;
+ pOld->acbe.cw.max = pNew->acbe_acwmax;
+ pOld->acbe.txoplimit = pNew->acbe_txoplimit;
+
+ pOld->acbk.aci.aifsn = pNew->acbk_aifsn;
+ pOld->acbk.aci.acm = pNew->acbk_acm;
+ pOld->acbk.aci.aci = pNew->acbk_aci;
+ pOld->acbk.cw.min = pNew->acbk_acwmin;
+ pOld->acbk.cw.max = pNew->acbk_acwmax;
+ pOld->acbk.txoplimit = pNew->acbk_txoplimit;
+
+ pOld->acvi.aci.aifsn = pNew->acvi_aifsn;
+ pOld->acvi.aci.acm = pNew->acvi_acm;
+ pOld->acvi.aci.aci = pNew->acvi_aci;
+ pOld->acvi.cw.min = pNew->acvi_acwmin;
+ pOld->acvi.cw.max = pNew->acvi_acwmax;
+ pOld->acvi.txoplimit = pNew->acvi_txoplimit;
+
+ pOld->acvo.aci.aifsn = pNew->acvo_aifsn;
+ pOld->acvo.aci.acm = pNew->acvo_acm;
+ pOld->acvo.aci.aci = pNew->acvo_aci;
+ pOld->acvo.cw.min = pNew->acvo_acwmin;
+ pOld->acvo.cw.max = pNew->acvo_acwmax;
+ pOld->acvo.txoplimit = pNew->acvo_txoplimit;
+
+}
+
+void convert_tspec(tpAniSirGlobal pMac,
+ tSirMacTspecIE *pOld, tDot11fIETSPEC *pNew)
+{
+ pOld->tsinfo.traffic.trafficType = (uint16_t) pNew->traffic_type;
+ pOld->tsinfo.traffic.tsid = (uint16_t) pNew->tsid;
+ pOld->tsinfo.traffic.direction = (uint16_t) pNew->direction;
+ pOld->tsinfo.traffic.accessPolicy = (uint16_t) pNew->access_policy;
+ pOld->tsinfo.traffic.aggregation = (uint16_t) pNew->aggregation;
+ pOld->tsinfo.traffic.psb = (uint16_t) pNew->psb;
+ pOld->tsinfo.traffic.userPrio = (uint16_t) pNew->user_priority;
+ pOld->tsinfo.traffic.ackPolicy = (uint16_t) pNew->tsinfo_ack_pol;
+
+ pOld->tsinfo.schedule.schedule = (uint8_t) pNew->schedule;
+
+ pOld->nomMsduSz = pNew->size;
+ pOld->maxMsduSz = pNew->max_msdu_size;
+ pOld->minSvcInterval = pNew->min_service_int;
+ pOld->maxSvcInterval = pNew->max_service_int;
+ pOld->inactInterval = pNew->inactivity_int;
+ pOld->suspendInterval = pNew->suspension_int;
+ pOld->svcStartTime = pNew->service_start_time;
+ pOld->minDataRate = pNew->min_data_rate;
+ pOld->meanDataRate = pNew->mean_data_rate;
+ pOld->peakDataRate = pNew->peak_data_rate;
+ pOld->maxBurstSz = pNew->burst_size;
+ pOld->delayBound = pNew->delay_bound;
+ pOld->minPhyRate = pNew->min_phy_rate;
+ pOld->surplusBw = pNew->surplus_bw_allowance;
+ pOld->mediumTime = pNew->medium_time;
+}
+
+tSirRetStatus convert_tclas(tpAniSirGlobal pMac,
+ tSirTclasInfo *pOld, tDot11fIETCLAS *pNew)
+{
+ uint32_t length = 0;
+
+ if (DOT11F_FAILED(dot11f_get_packed_ietclas(pMac, pNew, &length))) {
+ return eSIR_FAILURE;
+ }
+
+ pOld->tclas.type = DOT11F_EID_TCLAS;
+ pOld->tclas.length = (uint8_t) length;
+ pOld->tclas.userPrio = pNew->user_priority;
+ pOld->tclas.classifierType = pNew->classifier_type;
+ pOld->tclas.classifierMask = pNew->classifier_mask;
+
+ switch (pNew->classifier_type) {
+ case 0:
+ cdf_mem_copy(pOld->tclasParams.eth.srcAddr,
+ pNew->info.EthParams.source, 6);
+ cdf_mem_copy(pOld->tclasParams.eth.dstAddr,
+ pNew->info.EthParams.dest, 6);
+ pOld->tclasParams.eth.type = pNew->info.EthParams.type;
+ break;
+ case 1:
+ pOld->version = pNew->info.IpParams.version;
+ if (4 == pNew->info.IpParams.version) {
+ pOld->tclasParams.ipv4.version = 4;
+ cdf_mem_copy(pOld->tclasParams.ipv4.srcIpAddr,
+ pNew->info.IpParams.params.IpV4Params.
+ source, 4);
+ cdf_mem_copy(pOld->tclasParams.ipv4.dstIpAddr,
+ pNew->info.IpParams.params.IpV4Params.dest,
+ 4);
+ pOld->tclasParams.ipv4.srcPort =
+ pNew->info.IpParams.params.IpV4Params.src_port;
+ pOld->tclasParams.ipv4.dstPort =
+ pNew->info.IpParams.params.IpV4Params.dest_port;
+ pOld->tclasParams.ipv4.dscp =
+ pNew->info.IpParams.params.IpV4Params.DSCP;
+ pOld->tclasParams.ipv4.protocol =
+ pNew->info.IpParams.params.IpV4Params.proto;
+ pOld->tclasParams.ipv4.rsvd =
+ pNew->info.IpParams.params.IpV4Params.reserved;
+ } else if (6 == pNew->info.IpParams.version) {
+ pOld->tclasParams.ipv6.version = 6;
+ cdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+ srcIpAddr,
+ (uint8_t *) pNew->info.IpParams.params.
+ IpV6Params.source, 16);
+ cdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+ dstIpAddr,
+ (uint8_t *) pNew->info.IpParams.params.
+ IpV6Params.dest, 16);
+ pOld->tclasParams.ipv6.srcPort =
+ pNew->info.IpParams.params.IpV6Params.src_port;
+ pOld->tclasParams.ipv6.dstPort =
+ pNew->info.IpParams.params.IpV6Params.dest_port;
+ cdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+ flowLabel,
+ (uint8_t *) pNew->info.IpParams.params.
+ IpV6Params.flow_label, 3);
+ } else {
+ return eSIR_FAILURE;
+ }
+ break;
+ case 2:
+ pOld->tclasParams.t8021dq.tag =
+ pNew->info.Params8021dq.tag_type;
+ break;
+ default:
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+void convert_wmmtspec(tpAniSirGlobal pMac,
+ tSirMacTspecIE *pOld, tDot11fIEWMMTSPEC *pNew)
+{
+ pOld->tsinfo.traffic.trafficType = (uint16_t) pNew->traffic_type;
+ pOld->tsinfo.traffic.tsid = (uint16_t) pNew->tsid;
+ pOld->tsinfo.traffic.direction = (uint16_t) pNew->direction;
+ pOld->tsinfo.traffic.accessPolicy = (uint16_t) pNew->access_policy;
+ pOld->tsinfo.traffic.aggregation = (uint16_t) pNew->aggregation;
+ pOld->tsinfo.traffic.psb = (uint16_t) pNew->psb;
+ pOld->tsinfo.traffic.userPrio = (uint16_t) pNew->user_priority;
+ pOld->tsinfo.traffic.ackPolicy = (uint16_t) pNew->tsinfo_ack_pol;
+ pOld->nomMsduSz = (pNew->fixed << 15) | pNew->size;
+ pOld->maxMsduSz = pNew->max_msdu_size;
+ pOld->minSvcInterval = pNew->min_service_int;
+ pOld->maxSvcInterval = pNew->max_service_int;
+ pOld->inactInterval = pNew->inactivity_int;
+ pOld->suspendInterval = pNew->suspension_int;
+ pOld->svcStartTime = pNew->service_start_time;
+ pOld->minDataRate = pNew->min_data_rate;
+ pOld->meanDataRate = pNew->mean_data_rate;
+ pOld->peakDataRate = pNew->peak_data_rate;
+ pOld->maxBurstSz = pNew->burst_size;
+ pOld->delayBound = pNew->delay_bound;
+ pOld->minPhyRate = pNew->min_phy_rate;
+ pOld->surplusBw = pNew->surplus_bw_allowance;
+ pOld->mediumTime = pNew->medium_time;
+}
+
+tSirRetStatus convert_wmmtclas(tpAniSirGlobal pMac,
+ tSirTclasInfo *pOld, tDot11fIEWMMTCLAS *pNew)
+{
+ uint32_t length = 0;
+
+ if (DOT11F_FAILED(dot11f_get_packed_iewmmtclas(pMac, pNew, &length))) {
+ return eSIR_FAILURE;
+ }
+
+ pOld->tclas.type = DOT11F_EID_WMMTCLAS;
+ pOld->tclas.length = (uint8_t) length;
+ pOld->tclas.userPrio = pNew->user_priority;
+ pOld->tclas.classifierType = pNew->classifier_type;
+ pOld->tclas.classifierMask = pNew->classifier_mask;
+
+ switch (pNew->classifier_type) {
+ case 0:
+ cdf_mem_copy(pOld->tclasParams.eth.srcAddr,
+ pNew->info.EthParams.source, 6);
+ cdf_mem_copy(pOld->tclasParams.eth.dstAddr,
+ pNew->info.EthParams.dest, 6);
+ pOld->tclasParams.eth.type = pNew->info.EthParams.type;
+ break;
+ case 1:
+ pOld->version = pNew->info.IpParams.version;
+ if (4 == pNew->info.IpParams.version) {
+ pOld->tclasParams.ipv4.version = 4;
+ cdf_mem_copy(pOld->tclasParams.ipv4.srcIpAddr,
+ pNew->info.IpParams.params.IpV4Params.
+ source, 4);
+ cdf_mem_copy(pOld->tclasParams.ipv4.dstIpAddr,
+ pNew->info.IpParams.params.IpV4Params.dest,
+ 4);
+ pOld->tclasParams.ipv4.srcPort =
+ pNew->info.IpParams.params.IpV4Params.src_port;
+ pOld->tclasParams.ipv4.dstPort =
+ pNew->info.IpParams.params.IpV4Params.dest_port;
+ pOld->tclasParams.ipv4.dscp =
+ pNew->info.IpParams.params.IpV4Params.DSCP;
+ pOld->tclasParams.ipv4.protocol =
+ pNew->info.IpParams.params.IpV4Params.proto;
+ pOld->tclasParams.ipv4.rsvd =
+ pNew->info.IpParams.params.IpV4Params.reserved;
+ } else if (6 == pNew->info.IpParams.version) {
+ pOld->tclasParams.ipv6.version = 6;
+ cdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+ srcIpAddr,
+ (uint8_t *) pNew->info.IpParams.params.
+ IpV6Params.source, 16);
+ cdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+ dstIpAddr,
+ (uint8_t *) pNew->info.IpParams.params.
+ IpV6Params.dest, 16);
+ pOld->tclasParams.ipv6.srcPort =
+ pNew->info.IpParams.params.IpV6Params.src_port;
+ pOld->tclasParams.ipv6.dstPort =
+ pNew->info.IpParams.params.IpV6Params.dest_port;
+ cdf_mem_copy((uint8_t *) pOld->tclasParams.ipv6.
+ flowLabel,
+ (uint8_t *) pNew->info.IpParams.params.
+ IpV6Params.flow_label, 3);
+ } else {
+ return eSIR_FAILURE;
+ }
+ break;
+ case 2:
+ pOld->tclasParams.t8021dq.tag =
+ pNew->info.Params8021dq.tag_type;
+ break;
+ default:
+ return eSIR_FAILURE;
+ }
+
+ return eSIR_SUCCESS;
+}
+
+void convert_ts_delay(tpAniSirGlobal pMac,
+ tSirMacTsDelayIE *pOld, tDot11fIETSDelay *pNew)
+{
+ pOld->type = DOT11F_EID_TSDELAY;
+ pOld->length = 4U;
+ pOld->delay = pNew->delay;
+}
+
+void convert_schedule(tpAniSirGlobal pMac,
+ tSirMacScheduleIE *pOld, tDot11fIESchedule *pNew)
+{
+ pOld->type = DOT11F_EID_SCHEDULE;
+ pOld->length = DOT11F_IE_SCHEDULE_MIN_LEN;
+
+ pOld->info.aggregation = pNew->aggregation;
+ pOld->info.tsid = pNew->tsid;
+ pOld->info.direction = pNew->direction;
+
+ pOld->svcStartTime = pNew->service_start_time;
+ pOld->svcInterval = pNew->service_interval;
+ pOld->specInterval = pNew->spec_interval;
+}
+
+void convert_wmm_schedule(tpAniSirGlobal pMac,
+ tSirMacScheduleIE *pOld, tDot11fIEWMMSchedule *pNew)
+{
+ pOld->type = DOT11F_EID_WMMSCHEDULE;
+ pOld->length = DOT11F_IE_WMMSCHEDULE_MIN_LEN;
+
+ pOld->info.aggregation = pNew->aggregation;
+ pOld->info.tsid = pNew->tsid;
+ pOld->info.direction = pNew->direction;
+
+ pOld->svcStartTime = pNew->service_start_time;
+ pOld->svcInterval = pNew->service_interval;
+ pOld->specInterval = pNew->spec_interval;
+}
+
+/**
+ @brief : This functions converts the given buffer till given size to Big endian format assuming the
+ bus is 32 bit. The size should be four byte aligned.
+ @param : ptr to be converted, size
+ @return : void
+ */
+
+void convertto_big_endian(void *ptr, uint16_t size)
+{
+ uint8_t *temp_ptr;
+ uint32_t *dest_ptr;
+
+ dest_ptr = (uint32_t *) ptr;
+ while (size) {
+ temp_ptr = (uint8_t *) dest_ptr;
+ *dest_ptr =
+ (temp_ptr[0] << 24) | (temp_ptr[1] << 16) | (temp_ptr[2] <<
+ 8) |
+ temp_ptr[3];
+ dest_ptr++;
+ size -= 4;
+ }
+}
+
+void create_scan_data_null_frame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
+ uint8_t pwrMgmt, tSirMacAddr bssid,
+ tSirMacAddr selfMacAddr)
+{
+
+ macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME;
+ macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL;
+ macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+ macMgmtHdr->fc.order = 0;
+ macMgmtHdr->fc.wep = 0;
+ macMgmtHdr->fc.moreData = 0;
+ macMgmtHdr->fc.powerMgmt = pwrMgmt;
+ macMgmtHdr->fc.retry = 0;
+ macMgmtHdr->fc.moreFrag = 0;
+ macMgmtHdr->fc.fromDS = 0;
+ macMgmtHdr->fc.toDS = 0;
+ macMgmtHdr->durationLo =
+ (uint8_t) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
+ macMgmtHdr->durationHi =
+ (uint8_t) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
+ macMgmtHdr->seqControl.fragNum = 0;
+ macMgmtHdr->seqControl.seqNumLo = 0;
+ macMgmtHdr->seqControl.seqNumHi = 2;
+ cdf_mem_copy((void *)&macMgmtHdr->da,
+ (void *)bssid, sizeof(tSirMacAddr));
+ cdf_mem_copy((void *)&macMgmtHdr->sa,
+ (void *)selfMacAddr, sizeof(tSirMacAddr));
+ cdf_mem_copy((void *)&macMgmtHdr->bssId,
+ (void *)bssid, sizeof(tSirMacAddr));
+
+ return;
+}
+
+void create_scan_cts_frame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
+ tSirMacAddr selfMac)
+{
+ macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME;
+ macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS;
+ macMgmtHdr->fc.order = 0;
+ macMgmtHdr->fc.wep = 0;
+ macMgmtHdr->fc.moreData = 0;
+ macMgmtHdr->fc.powerMgmt = 0;
+ macMgmtHdr->fc.retry = 0;
+ macMgmtHdr->fc.moreFrag = 0;
+ macMgmtHdr->fc.fromDS = 0;
+ macMgmtHdr->fc.toDS = 0;
+ macMgmtHdr->durationLo =
+ (uint8_t) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
+ macMgmtHdr->durationHi =
+ (uint8_t) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8);
+ cdf_mem_copy((void *)macMgmtHdr->da, (void *)selfMac,
+ sizeof(tSirMacAddr));
+
+ return;
+}
+
+void convert_qos_mapset_frame(tpAniSirGlobal pMac, tSirQosMapSet *Qos,
+ tDot11fIEQosMapSet *dot11fIE)
+{
+ uint8_t i, j = 0;
+ Qos->num_dscp_exceptions = (dot11fIE->num_dscp_exceptions - 16) / 2;
+ for (i = 0; i < Qos->num_dscp_exceptions; i++) {
+ Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j];
+ j++;
+ Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j];
+ j++;
+ }
+ for (i = 0; i < 8; i++) {
+ Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j];
+ j++;
+ Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j];
+ j++;
+ }
+}
+
+/**
+ @brief : This functions creates a DATA_NULL/CTS2SELF frame in Big endian format
+ @param : Global MAC structure, pointer to return the created packet, role which is Station/AP
+ @return : void
+ */
+
+void create_init_scan_raw_frame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
+ tBssSystemRole role)
+{
+#if 0
+ tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable;
+
+ if (role == eSYSTEM_STA_ROLE) {
+ macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME;
+ macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL;
+ macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+ macMgmtHdr->fc.order = 0;
+ macMgmtHdr->fc.wep = 0;
+ macMgmtHdr->fc.moreData = 0;
+ macMgmtHdr->fc.powerMgmt = 1; /* Needed for station */
+ macMgmtHdr->fc.retry = 0;
+ macMgmtHdr->fc.moreFrag = 0;
+ macMgmtHdr->fc.fromDS = 0;
+ macMgmtHdr->fc.toDS = 1;
+ macMgmtHdr->durationLo =
+ (uint8_t) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
+ macMgmtHdr->durationHi =
+ (uint8_t) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >>
+ 8);
+ macMgmtHdr->seqControl.fragNum = 0;
+ macMgmtHdr->seqControl.seqNumLo = 0;
+ macMgmtHdr->seqControl.seqNumHi = 2;
+ cdf_mem_copy((void *)&macMgmtHdr->da, (void *)pSta[0].bssId, 6);
+ cdf_mem_copy(&macMgmtHdr->sa, pSta[0].staAddr, 6);
+ cdf_mem_copy((void *)&macMgmtHdr->bssId, (void *)pSta[0].bssId,
+ 6);
+ } else if (role == eSYSTEM_AP_ROLE || role == eSYSTEM_STA_IN_IBSS_ROLE) {
+ macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME;
+ macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS;
+ macMgmtHdr->fc.order = 0;
+ macMgmtHdr->fc.wep = 0;
+ macMgmtHdr->fc.moreData = 0;
+ macMgmtHdr->fc.powerMgmt = 0; /* Needed for station */
+ macMgmtHdr->fc.retry = 0;
+ macMgmtHdr->fc.moreFrag = 0;
+ macMgmtHdr->fc.fromDS = 0;
+ macMgmtHdr->fc.toDS = 0;
+ macMgmtHdr->durationLo =
+ (uint8_t) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
+ macMgmtHdr->durationHi =
+ (uint8_t) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >>
+ 8);
+ cdf_mem_copy((void *)macMgmtHdr->da, (void *)pSta[0].staAddr,
+ 6);
+ }
+ return;
+#endif
+}
+
+/**
+ @brief : This functions creates a DATA_NULL frame in Big endian format
+ @param : Global MAC structure, pointer to return the created packet, role which is Station/AP
+ @return : void
+ */
+
+void create_finish_scan_raw_frame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr,
+ tBssSystemRole role)
+{
+#if 0
+ tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable;
+
+ if (role == eSYSTEM_STA_ROLE) {
+ macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME;
+ macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL;
+ macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION;
+ macMgmtHdr->fc.order = 0;
+ macMgmtHdr->fc.wep = 0;
+ macMgmtHdr->fc.moreData = 0;
+ macMgmtHdr->fc.powerMgmt = 0; /* Needed for station */
+ macMgmtHdr->fc.retry = 0;
+ macMgmtHdr->fc.moreFrag = 0;
+ macMgmtHdr->fc.fromDS = 0;
+ macMgmtHdr->fc.toDS = 1;
+ macMgmtHdr->durationLo =
+ (uint8_t) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff);
+ macMgmtHdr->durationHi =
+ (uint8_t) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >>
+ 8);
+ macMgmtHdr->seqControl.fragNum = 0;
+ macMgmtHdr->seqControl.seqNumLo = 0;
+ macMgmtHdr->seqControl.seqNumHi = 2;
+ cdf_mem_copy((void *)macMgmtHdr->da, (void *)pSta[0].bssId, 6);
+ cdf_mem_copy(macMgmtHdr->sa, pSta[0].staAddr, 6);
+ cdf_mem_copy((void *)macMgmtHdr->bssId, (void *)pSta[0].bssId,
+ 6);
+
+ }
+
+ return;
+#endif
+}
+
+/* utils_parser.c ends here. */